aboutsummaryrefslogtreecommitdiff
path: root/cli/post.py
blob: 3c196968507d0d2d3d9b1229ee12696079271785 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/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)