#!/usr/bin/python
# Copyright 2010 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 optparse
import os
import re
import subprocess
import sys
import tempfile
import time
import traceback
template = '''\
[[!meta title="%(title)s"]]
[[!tag ]]
[[!meta date="%(date)s"]]
'''
class AppException(Exception):
pass
class App(object):
def __init__(self):
pass
def parse_args(self):
p = optparse.OptionParser()
p.add_option('--base', default=os.path.expanduser('~/Journal'))
return p.parse_args()
def main(self):
commands = {
'new': self.new_entry,
'list': self.list_entries,
'edit': self.edit_entry,
'remove': self.remove_entry,
'finish': self.finish_entry,
}
opts, args = self.parse_args()
if args and args[0] in commands:
commands[args[0]](args[1:], opts)
else:
raise AppException('Usage: journal-note [options] cmd args...')
def drafts(self, opts):
return os.path.join(opts.base, 'drafts')
def draftname(self, opts, draft_id):
return os.path.join(opts.base, 'drafts', '%s.mdwn' % draft_id)
def gedit_file(self, pathname):
subprocess.check_call(['gedit', '--new-window', pathname])
def new_entry(self, args, opts):
if not args:
raise AppException('Usage: journal-note new TITLE')
for i in range(1000):
name = self.draftname(opts, i)
if not os.path.exists(name):
break
else:
raise 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.gedit_file(name)
def list_entries(self, args, opts):
drafts = self.drafts(opts)
for name in os.listdir(drafts):
if name.endswith('.mdwn'):
f = open(os.path.join(drafts, name))
for line in f:
m = re.match('\[\[!meta title="(?P
.*)("\]\])$',
line)
if m:
title = m.group('title')
break
else:
title = 'unknown title'
f.close()
print name[:-len('.mdwn')], title
def edit_entry(self, args, opts):
if not args:
raise AppException('Usage: journal-note edit ID')
pathname = self.draftname(opts, args[0])
if not os.path.exists(pathname):
raise AppException('draft %s does not exist' % args[0])
self.gedit_file(pathname)
def remove_entry(self, args, opts):
if not args:
raise AppException('Usage: journal-note remove ID')
pathname = self.draftname(opts, args[0])
os.remove(pathname)
def finish_entry(self, args, opts):
if not args:
raise AppException('Usage: journal-note finish ID')
draft = self.draftname(opts, args[0])
if not os.path.exists(draft):
raise AppException('draft %s does not exist' % args[0])
basename = time.strftime('%Y-%m-%d-%H:%M.mdwn')
i = 0
while True:
finished = os.path.join(opts.base, 'src', 'notes', basename)
if not os.path.exists(finished):
break
i += 1
basename = '%s-%d.mdwn' % (time.strftime('%Y-%m-%d-%H:%M:%S-'), i)
os.rename(draft, finished)
src = os.path.join(opts.base, 'src')
subprocess.check_call(['bzr', 'add', finished], cwd=src)
subprocess.check_call(['bzr', 'commit', '-m', 'new note'], cwd=src)
subprocess.check_call(['ikiwiki', '--setup', '../ikiwiki.setup',
'--refresh'],
cwd=src)
if __name__ == '__main__':
try:
App().main()
except KeyboardInterrupt:
sys.exit(1)
except AppException, e:
sys.stderr.write('%s\n' % str(e))
sys.exit(1)
except SystemExit, e:
sys.exit(e.code)
except BaseException, e:
sys.stderr.write(traceback.format_exc(e))
sys.exit(1)