# Copyright 2010-2015 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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import cliapp import os import time import jinja2 import jtlib class JournalTool(cliapp.Application): def add_settings(self): self.settings.string( ['profile', 'p'], 'also use section PROFILE in configuration files, ' 'in addition to [config]', metavar='PROFILE') self.settings.string( ['source'], 'use journal source tree in DIR', metavar='DIR') self.settings.boolean( ['git'], 'add entries to git automatically', default=True) self.settings.string( ['editor'], 'editor to launch for journal entries. Must include %s to ' 'indicate where the filename goes', default='sensible-editor %s') self.settings.boolean( ['push'], 'push finished articles with git?') self.settings.string( ['topic'], 'new entry belongs to TOPIC', metavar='TOPIC') self.settings.string_list( ['templates'], 'look for templates also in DIR', metavar='DIR') self.settings.string( ['new-note-template'], 'use FILE as the template for new journal notes', metavar='FILE') self.settings.string( ['pretend-time'], 'pretend that the time is NOW (form: YYYY-MM-DD HH:MM:DD form)', metavar='NOW') def process_args(self, args): self.merge_profile() if self.settings['pretend-time']: self.now_tuple = time.strptime( self.settings['pretend-time'], '%Y-%m-%d %H:%M:%S') else: self.now_tuple = time.localtime() cliapp.Application.process_args(self, args) def merge_profile(self): profile = self.settings['profile'] if profile: section = 'profile %s' % profile cp = self.settings.as_cp() if section not in cp.sections(): raise cliapp.AppException('Unknown profile %s' % profile) for key in cp.options(section): if key not in self.settings: raise cliapp.AppException( 'Profile %s uses unknown setting %s' % (profile, key)) value = cp.get(section, key) self.settings.set_from_raw_string( 'profile %s' % profile, key, value) def drafts_dir(self): return os.path.join(self.settings['source'], 'drafts') def edit_file(self, pathname): safe_pathname = cliapp.shell_quote(pathname) cmdline = ['sh', '-c', self.settings['editor'] % safe_pathname] self.runcmd(cmdline, stdin=None, stdout=None, stderr=None) def choose_draft(self, drafts_dir, args): if len(args) == 0: drafts = list(drafts_dir.get_drafts()) if len(drafts) == 1: draft_id, filename = drafts[0] 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: 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 args[0], pathname elif len(args) > 1: raise cliapp.AppException('Must give at most one draft number') def read_template(self, basename): default = os.path.join(self.app_directory(), 'templates') for dirname in self.settings['templates'] + [default]: filename = os.path.join(dirname, basename) if os.path.exists(filename): with open(filename) as f: return f.read() def render_template(self, basename, vars): text = self.read_template(basename) template = jinja2.Template(text) return template.render(**vars)