#!/bin/python3 import os import subprocess import blessed import re import time import sys import io import fileinput from utils import utils from config.config import * def edit_post_with_editor(path): """Launch text editor to edit post at a given path. Text editor is $VISUAL, then if empty, $EDITOR, then if still empty, vi. """ if "VISUAL" in os.environ: editor = os.environ["VISUAL"] elif "EDITOR" in os.environ: editor = os.environ["EDITOR"] else: editor = "vi" subprocess.call([editor, path]) def new_post(title): """Create a new post with metadata pre-filled. The path to the new post is printed to stdout. Returns ------- 0 On success. """ date = utils.current_datetime() filename_date = date.strftime("%Y-%m-%d") iso_date = date.isoformat() display_date = "%s %d, %d" % (date.strftime("%B"), date.day, date.year) title_sanitized = utils.sanitize(title) filename = "%s-%s.md" % (filename_date, title_sanitized) fullpath = os.path.join(POSTSDIR, filename) if not os.path.isdir(POSTSDIR): if os.path.exists(POSTSDIR): os.remove(POSTSDIR) os.mkdir(POSTSDIR, mode=0o755) if os.path.exists(fullpath): sys.stderr.write("%serror: '%s' already exists, please pick a different title%s\n" % (RED, fullpath, RESET)) return 1 with open(fullpath, 'w', encoding='utf-8') as newpost: newpost.write("---\n") newpost.write('title: "%s"\n' % title) newpost.write("date: %s\n" % iso_date) newpost.write("date_display: %s\n" % display_date) newpost.write("---\n\n") sys.stderr.write("New post created in:\n") print(fullpath) edit_post_with_editor(fullpath) return 0 def new_post_cli(args): """CLI wrapper around new_post.""" new_post(args.title) def edit_existing_post(args): selector = utils.PostSelector(blessed.Terminal(), utils.list_posts()) selection = selector.select() if selection: print(selection) edit_post_with_editor(selection) else: return 1 def touch(filename): """Update the timestamp of a post to the current time.""" filename = os.path.basename(filename) fullpath = os.path.join(POSTSDIR, filename) if not os.path.exists(fullpath): sys.stderr.write("%serror: post %s not found %s\n" % (RED, fullpath, RESET)) return 1 filename_prefix_re = re.compile(r"^[0-9]{4}-[0-9]{2}-[0-9]{2}") if not filename_prefix_re.match(filename): sys.stderr.write(RED) sys.stderr.write("error: post %s is not a valid post\n" % filename) sys.stderr.write("error: the filename of a valid post begins with " "a date in the form xxxx-xx-xx\n") sys.stderr.write(RESET) return 1 # update timestamp in the metadata section of the post whatchanged = io.StringIO() date = utils.current_datetime() iso_date = date.isoformat() display_date = "%s %d, %d" % (date.strftime("%B"), date.day, date.year) filename_date = date.strftime("%Y-%m-%d") with fileinput.input(files=(fullpath), inplace=True) as lines: meta_fences = 0 for line in lines: if line.startswith("---"): meta_fences += 1 sys.stdout.write(line) continue if meta_fences >= 2: # already went past the metadata section sys.stdout.write(line) continue if line.startswith("date: "): updated_line = "date: %s\n" % iso_date sys.stdout.write(updated_line) whatchanged.write("-%s+%s\n" % (line, updated_line)) continue if line.startswith("date_display: "): updated_line = "date_display: %s\n" % display_date sys.stdout.write(updated_line) whatchanged.write("-%s+%s\n" % (line, updated_line)) continue sys.stdout.write(line) sys.stderr.write("\n%schangeset:%s\n\n%s" % (YELLOW, RESET, whatchanged.getvalue())) whatchanged.close() # check if the file needs to be renamed new_filename = filename_prefix_re.sub(filename_date, filename) if new_filename != filename: new_fullpath = os.path.join(POSTSDIR, new_filename) os.rename(fullpath, new_fullpath) sys.stderr.write("%srenamed to %s%s\n" % (YELLOW, new_filename, RESET)) return 0 def touch_cli(args): """CLI wrapper around touch.""" touch(args.filename)