Merge pull request #51 from maebert/dayone

Dayone support
This commit is contained in:
Manuel Ebert 2013-03-04 14:57:10 -08:00
commit fe5f318c16
4 changed files with 80 additions and 8 deletions

View file

@ -22,8 +22,10 @@ try:
import clint
except ImportError:
clint = None
import plistlib
import uuid
class Journal:
class Journal(object):
def __init__(self, **kwargs):
self.config = {
'journal': "journal.txt",
@ -242,7 +244,7 @@ class Journal:
return date
def new_entry(self, raw, date=None):
def new_entry(self, raw, date=None, sort=True):
"""Constructs a new entry from some raw text input.
If a date is given, it will parse and use this, otherwise scan for a date in the input first."""
@ -264,5 +266,53 @@ class Journal:
if not date: # Still nothing? Meh, just live in the moment.
date = self.parse_date("now")
self.entries.append(Entry(self, date, title, body))
self.sort()
entry = Entry(self, date, title, body)
self.entries.append(entry)
if sort:
self.sort()
return entry
class DayOne(Journal):
"""A special Journal handling DayOne files"""
def __init__(self, **kwargs):
self.entries = []
super(DayOne, self).__init__(**kwargs)
def open(self):
files = [os.path.join(self.config['journal'], "entries", f) for f in os.listdir(os.path.join(self.config['journal'], "entries"))]
return files
def parse(self, filenames):
"""Instead of parsing a string into an entry, this method will take a list
of filenames, interpret each as a plist file and create a new entry from that."""
self.entries = []
for filename in filenames:
with open(filename) as plist_entry:
dict_entry = plistlib.readPlist(plist_entry)
entry = self.new_entry(raw=dict_entry['Entry Text'], date=dict_entry['Creation Date'], sort=False)
entry.starred = dict_entry["Starred"]
entry.uuid = dict_entry["UUID"]
# We're using new_entry to create the Entry object, which adds the entry
# to self.entries already. However, in the original Journal.__init__, this
# method is expected to return a list of newly created entries, which is why
# we're returning the obvious.
return self.entries
def write(self):
"""Writes only the entries that have been modified into plist files."""
for entry in self.entries:
# Assumption: since jrnl can not manipulate existing entries, all entries
# that have a uuid will be old ones, and only the one that doesn't will
# have a new one!
if not hasattr(entry, "uuid"):
new_uuid = uuid.uuid1().hex
filename = os.path.join(self.config['journal'], "entries", new_uuid+".doentry")
entry_plist = {
'Creation Date': entry.date,
'Starred': entry.starred if hasattr(entry, 'starred') else False,
'Entry Text': entry.title+"\n"+entry.body,
'UUID': new_uuid
}
plistlib.writePlist(entry_plist, filename)

View file

@ -31,6 +31,7 @@ def parse_args():
parser = argparse.ArgumentParser()
composing = parser.add_argument_group('Composing', 'Will make an entry out of whatever follows as arguments')
composing.add_argument('-date', dest='date', help='Date, e.g. "yesterday at 5pm"')
composing.add_argument('-star', dest='star', help='Stars an entry (DayOne journals only)', action="store_true")
composing.add_argument('text', metavar='text', nargs="*", help='Log entry (or tags by which to filter in viewing mode)')
reading = parser.add_argument_group('Reading', 'Specifying either of these parameters will display posts of your journal')
@ -157,8 +158,13 @@ def cli():
touch_journal(config['journal'])
mode_compose, mode_export = guess_mode(args, config)
# open journal file
journal = Journal.Journal(**config)
# open journal file or folder
if os.path.isdir(config['journal']) and config['journal'].endswith(".dayone"):
journal = Journal.DayOne(**config)
else:
journal = Journal.Journal(**config)
if mode_compose and not args.text:
if config['editor']:
raw = get_text_from_editor(config)
@ -172,7 +178,8 @@ def cli():
# Writing mode
if mode_compose:
raw = " ".join(args.text).strip()
journal.new_entry(raw, args.date)
entry = journal.new_entry(raw, args.date)
entry.starred = args.star
print("[Entry added to {} journal]").format(journal_name)
journal.write()