diff options
author | Lars Wirzenius <liw@liw.fi> | 2014-11-22 19:27:33 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2014-11-22 19:27:33 +0200 |
commit | db41106352188f30ed2b814f22442a6fe63bbb60 (patch) | |
tree | 6af62472943d6ca55dc90e6bc2f1267bc2bb6e9b | |
parent | c3c6f20cca633d6cc31d34ee1cffe4e2c4a2987b (diff) | |
parent | 3f49554a438bc153852d1dacc1db54e78a303c12 (diff) | |
download | jt-db41106352188f30ed2b814f22442a6fe63bbb60.tar.gz |
Merge in some refactorings
-rwxr-xr-x | check | 1 | ||||
-rwxr-xr-x | jt | 389 |
2 files changed, 233 insertions, 157 deletions
@@ -21,3 +21,4 @@ set -eu yarn -s yarns/yarn.sh yarns/*.yarn "$@" +copyright-statement-lint jt @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright 2010-2013 Lars Wirzenius +# Copyright 2010-2014 Lars Wirzenius # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -39,6 +39,221 @@ template = '''\ ''' +class DraftsDirectory(object): + + def __init__(self, dirname): + self.dirname = dirname + + def create_if_missing(self): + if not os.path.exists(self.dirname): + os.mkdir(self.dirname) + + def get_draft_pathname(self, draft_id): + return os.path.join(self.dirname, '%s.mdwn' % draft_id) + + def get_draft_attachments_dirname(self, draft_id): + return os.path.join(self.dirname, '%s' % draft_id) + + def create_draft(self, content): + draft_id = self._pick_available_draft_id() + pathname = self.get_draft_pathname(draft_id) + with open(pathname, 'w') as f: + f.write(content) + return draft_id + + def _pick_available_draft_id(self): + for i in range(1000): + pathname = self.get_draft_pathname(i) + if not os.path.exists(pathname): + return i + else: + raise cliapp.AppException('ERROR: too many existing drafts') + + def get_drafts(self): + for basename in os.listdir(self.dirname): + # .# is what Emacs autosave files start with. + if basename.endswith('.mdwn') and not basename.startswith('.#'): + yield basename[:-len('.mdwn')], os.path.join(self.dirname, basename) + + def remove_draft(self, draft_id): + filename = self.get_draft_pathname(draft_id) + os.remove(filename) + + dirname = self.get_draft_attachments_dirname(draft_id) + if os.path.exists(dirname): + shutil.rmtree(dirname) + + +class Command(object): + + def __init__(self, app): + self._app = app + + def run(self, args): + raise NotImplementedError() + + +class NewCommand(Command): + + def run(self, args): + if not args: + raise cliapp.AppException('Usage: journal-note new TITLE') + + self._app.settings.require('source') + self._app.settings.require('layout') + + values = { + 'title': args[0], + 'date': time.strftime('%Y-%m-%d %H:%M') + } + + drafts_dir = DraftsDirectory(self._app.drafts_dir()) + drafts_dir.create_if_missing() + draft_id = drafts_dir.create_draft(template % values) + self._app.edit_file(drafts_dir.get_draft_pathname(draft_id)) + + +class ListCommand(Command): + + def run(self, args): + drafts_dir = DraftsDirectory(self._app.drafts_dir()) + for draft_id, filename in drafts_dir.get_drafts(): + print draft_id, self._app.get_draft_title(filename) or "" + + +class EditCommand(Command): + + def run(self, args): + if len(args) > 1: + raise cliapp.AppException('Must be given at most one draft ID') + drafts_dir = DraftsDirectory(self._app.drafts_dir()) + draft_id, pathname = self._app.choose_draft(drafts_dir, args) + self._app.edit_file(pathname) + + +class AttachCommand(Command): + + def run(self, args): + if len(args) < 2: + raise cliapp.AppException('Usage: journal-note attach ID file...') + + drafts_dir = DraftsDirectory(self._app.draft_dir()) + dirname = drafts_dir.get_draft_attachments_dirname(args[0]) + if not os.path.exists(dirname): + os.mkdir(dirname) + for filename in args[1:]: + shutil.copy(filename, dirname) + + +class RemoveCommand(Command): + + def run(self, args): + if not args: + raise cliapp.AppException('Usage: journal-note remove ID') + drafts_dir = DraftsDirectory(self._app.drafts_dir()) + drafts_dir.remove_draft(args[0]) + + +class FinishCommand(Command): + + def run(self, args): + drafts_dir = DraftsDirectory(self._app.drafts_dir()) + draft_id, draft_mdwn = self._app.choose_draft(drafts_dir, args) + draft_attch = drafts_dir.get_draft_attachments_dirname(draft_id) + + pub_attch = os.path.join( + self._published_dir(), self._published_basename(draft_mdwn)) + pub_mdwn = pub_attch + '.mdwn' + + if os.path.exists(pub_mdwn): + raise cliapp.AppException('%s already exists' % pub_mdwn) + + if not os.path.exists(self._published_dir()): + os.makedirs(self._published_dir()) + os.rename(draft_mdwn, pub_mdwn) + if os.path.exists(draft_attch): + os.rename(draft_attch, pub_attch) + + if self._app.settings['git']: + if os.path.exists(pub_attch): + self.commit_to_git([pub_mdwn, pub_attch]) + else: + self.commit_to_git([pub_mdwn]) + if self._app.settings['push']: + self.push_git() + + def _published_dir(self): + subdirs = { + 'liw': 'notes', + 'ct': 'log/%d' % time.localtime().tm_year, + 'pkb': time.strftime('notes/%Y/%m/%d'), + } + + subdir = subdirs[self._app.settings['layout']] + return os.path.join(self._app.settings['source'], subdir) + + def _published_basename(self, draft_mdwn): + if self._app.settings['layout'] in ('liw', 'ct'): + basename = time.strftime('%Y-%m-%d-%H:%M:%S') + elif self._app.settings['layout'] == 'pkb': + title = self._app.get_draft_title(draft_mdwn) + if not title: + raise Exception("%s has no title" % draft_mdwn) + basename = self._app.summarise_title(title) + else: + raise Exception( + 'Setting --layout=%s is unknown' % self._app.settings['layout']) + + return basename + + def _commit_to_git(self, pathnames): + cliapp.runcmd( + ['git', 'add'] + pathname, + cwd=self._app.settings['source']) + + cliapp.runcmd( + ['git', 'commit', '-m', 'Publish log entry'], + cwd=self._app.settings['source']) + + def _push_git(self): + cliapp.runcmd( + ['git', 'push', 'origin', 'HEAD'], + cwd=self._app.settings['source']) + + +class NewPersonCommand(Command): + + def run(self, args): + if len(args) != 1: + raise cliapp.AppException( + 'Need the name of a person (in Last, First form)') + + def normalise(name): + s = name.lower() + s = ' '.join(s.split(',')) + s = '.'.join(s.split()) + return s + + name = args[0] + basename = normalise(name) + pathname = os.path.join( + self._app.settings['source'], 'people', basename + '.mdwn') + + if os.path.exists(pathname): + raise cliapp.AppException('File %s already exists' % pathname) + + with open(pathname, 'w') as f: + f.write('''\ +[[!meta title="%(name)s"]] + +[[!inline archive=yes pages="link(.)"]] +''' % + { + 'name': name, + 'basename': basename, + }) + + class JournalTool(cliapp.Application): cmd_synopsis = { @@ -84,42 +299,11 @@ class JournalTool(cliapp.Application): def cmd_new(self, args): '''Create a new journal entry draft.''' - - if not args: - raise cliapp.AppException('Usage: journal-note new TITLE') - - self.settings.require('source') - self.settings.require('layout') - - if not self.settings['source']: - raise cliapp.AppException( - 'The --source setting is empty or missing.') - - if not os.path.exists(self.drafts_dir()): - os.mkdir(self.drafts_dir()) - - for i in range(1000): - name = self.draft_name(i) - if not os.path.exists(name): - break - else: - raise cliapp.AppException('ERROR: too many existing drafts') - - values = { - 'title': args[0], - 'date': time.strftime('%Y-%m-%d %H:%M') - } - f = open(name, 'w') - f.write(template % values) - f.close() - self.edit_file(name) + NewCommand(self).run(args) def drafts_dir(self): return os.path.join(self.settings['source'], 'drafts') - def draft_name(self, draft_id): - return os.path.join(self.drafts_dir(), '%s.mdwn' % draft_id) - def edit_file(self, pathname): safe_pathname = cliapp.shell_quote(pathname) cmdline = ['sh', '-c', self.settings['editor'] % pathname] @@ -127,16 +311,7 @@ class JournalTool(cliapp.Application): def cmd_list(self, args): '''List journal entry drafts.''' - - for draft_id, filename in self.find_drafts(): - print draft_id, self.get_draft_title(filename) or "" - - def find_drafts(self): - drafts_dir = self.drafts_dir() - for name in os.listdir(drafts_dir): - # .# is what Emacs autosave files start with. - if name.endswith('.mdwn') and not name.startswith('.#'): - yield name[:-len('.mdwn')], os.path.join(drafts_dir, name) + ListCommand(self).run(args) def get_draft_title(self, filename): with open(filename) as f: @@ -153,111 +328,37 @@ class JournalTool(cliapp.Application): def cmd_edit(self, args): '''Edit a draft journal entry.''' + EditCommand(self).run(args) - filename = self.choose_draft(args) - self.edit_file(filename) - - def choose_draft(self, args): + def choose_draft(self, drafts_dir, args): if len(args) == 0: - drafts = list(self.find_drafts()) + drafts = list(drafts_dir.get_drafts()) if len(drafts) == 1: draft_id, filename = drafts[0] - return filename + return draft_id, filename + elif len(drafts) == 0: + raise cliapp.AppException('No drafts to choose from') else: raise cliapp.AppException('Cannot choose entry draft automatically') elif len(args) == 1: - filename = self.draft_name(args[0]) - if not os.path.exists(filename): + pathname = drafts_dir.get_draft_pathname(args[0]) + if not os.path.exists(pathname): raise cliapp.AppException('draft %s does not exist' % args[0]) - return filename + return args[0], pathname elif len(args) > 1: - raise cliapp.AppException('Must give only one draft number') + raise cliapp.AppException('Must give at most one draft number') def cmd_attach(self, args): '''Attach files to a journal entry draft.''' - - if len(args) < 2: - raise cliapp.AppException('Usage: journal-note attach ID file...') - - filename = self.draft_name(args[0]) - - dirname, ext = os.path.splitext(filename) - assert ext == '.mdwn' - - if not os.path.exists(dirname): - os.mkdir(dirname) - for filename in args[1:]: - shutil.copy(filename, dirname) + AttachCommand(self).run(args) def cmd_remove(self, args): '''Remove a draft.''' - - if not args: - raise cliapp.AppException('Usage: journal-note remove ID') - filename = self.draft_name(args[0]) - os.remove(filename) - - dirname, ext = os.path.splitext(filename) - assert ext == '.mdwn' - if os.path.exists(dirname): - shutil.rmtree(dirname) + RemoveCommand(self).run(args) def cmd_finish(self, args): '''Publish a draft journal entry.''' - - draft_mdwn = self.choose_draft(args) - draft_attch, ext = os.path.splitext(draft_mdwn) - assert ext == '.mdwn' - - pub_attch = os.path.join( - self.published_dir(), self.published_basename(draft_mdwn)) - pub_mdwn = pub_attch + '.mdwn' - - if os.path.exists(pub_mdwn): - raise cliapp.AppException('%s already exists' % pub_mdwn) - - if not os.path.exists(self.published_dir()): - os.makedirs(self.published_dir()) - os.rename(draft_mdwn, pub_mdwn) - if os.path.exists(draft_attch): - os.rename(draft_attch, pub_attch) - - if self.settings['git']: - argv = ['git', 'add', pub_mdwn] - if os.path.exists(pub_attch): - argv.append(pub_attch) - cliapp.runcmd(argv, cwd=self.settings['source']) - cliapp.runcmd( - ['git', 'commit', '-m', 'Publish log entry'], - cwd=self.settings['source']) - if self.settings['push']: - cliapp.runcmd( - ['git', 'push', 'origin', 'HEAD'], - cwd=self.settings['source']) - - def published_dir(self): - subdirs = { - 'liw': 'notes', - 'ct': 'log/%d' % time.localtime().tm_year, - 'pkb': time.strftime('notes/%Y/%m/%d'), - } - - subdir = subdirs[self.settings['layout']] - return os.path.join(self.settings['source'], subdir) - - def published_basename(self, draft_mdwn): - if self.settings['layout'] in ('liw', 'ct'): - basename = time.strftime('%Y-%m-%d-%H:%M:%S') - elif self.settings['layout'] == 'pkb': - title = self.get_draft_title(draft_mdwn) - if not title: - raise Exception("%s has no title" % draft_mdwn) - basename = self.summarise_title(title) - else: - raise Exception( - 'Setting --layout=%s is unknown' % self.settings['layout']) - - return basename + FinishCommand(self).run(args) def summarise_title(self, title): basename = '' @@ -276,33 +377,7 @@ class JournalTool(cliapp.Application): ''' - if len(args) != 1: - raise cliapp.AppException( - 'Need the name of a person (in Last, First form)') - - def normalise(name): - s = name.lower() - s = ' '.join(s.split(',')) - s = '.'.join(s.split()) - return s - - name = args[0] - basename = normalise(name) - pathname = os.path.join( - self.settings['source'], 'people', basename + '.mdwn') + NewPersonCommand(self).run(args) - if os.path.exists(pathname): - raise cliapp.AppException('File %s already exists' % pathname) - - with open(pathname, 'w') as f: - f.write('''\ -[[!meta title="%(name)s"]] - -[[!inline archive=yes pages="link(.)"]] -''' % - { - 'name': name, - 'basename': basename, - }) JournalTool(version=__version__).run() |