diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 4f411c98..9d4daae6 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -23,6 +23,8 @@ try: import clint except ImportError: clint = None +import plistlib +import uuid class Journal(object): def __init__(self, **kwargs): @@ -271,3 +273,47 @@ class Journal(object): 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", 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) + diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index e3749683..e0f7ef5c 100755 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -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') @@ -154,8 +155,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) @@ -169,7 +175,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()