This is a python script to extract plain text from a Day One journal. I use Day One both on my iPhone and my MacBook, and I think it's a great program to write down your daily thoughts and ideas. But I couldn't stand the fact, that everything was kept in an opaque bundle.
So I looked at the bundle and realized that the entries are kept in property lists, which are pretty easy to parse with python.
You may have to make the script executable (chmod a+x extractDOJ.py
) or
use python extractDOJ.py /Path/to/Journal.dayone
Download it here
(4 KB)
Usage
$ ./extractDOJ.py -h usage: extractDOJ [-h] [-d DATE_FORMAT] [-c] [-r] /Path/to/Journal.dayone [outfile] Extracts plain text fromy our Day One journal (http://dayoneapp.com/). positional arguments: /Path/to/Journal.dayone Your journal file (bundle, actually) outfile save output to file OUTFILE optional arguments: -h, --help show this help message and exit -d DATE_FORMAT format of date (google 'strftime python') -c, --csv output CSV (tab separated values) -r reversed order
Examples
./extractDOJ.py /Path/to/Journal.dayone Journal.txt
Extracts entries as plain text into file Journal.txt
./extractDOJ.py -c /Path/to/Journal.dayone Journal.txt
Extracts entries as tab separated values into file Journal.txt. Useful to import your diary into an Excel file.
Code
# encoding: utf-8 ''' extractDOJ.py Created by Niklas Hennigs on 2011-05-08. ''' import sys import os import locale import time import argparse import plistlib from operator import itemgetter entries = [] locale.setlocale(locale.LC_ALL, "") def extractPlainText(arg, path, file_list): global entries for file_name in file_list: # We need the full path to locate the file file_path = os.path.join(path, file_name) pl = plistlib.readPlist(file_path) EntryDate = pl["Creation Date"] EntryText = pl["Entry Text"] entries.append([EntryDate, EntryText]) def main(): global entries parser = argparse.ArgumentParser(description= 'Extracts plain text from' 'your Day One journal' '(http://dayoneapp.com/).' ) parser.add_argument('journal_bundle', metavar='/Path/to/Journal.dayone', help='Your journal file (bundle, actually)') parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout, help='save output to file OUTFILE') parser.add_argument('-d', dest='date_format', default='%A, %x, %H:%M', help='format of date (google \'strftime python\')') parser.add_argument('-c', '--csv', action="store_true", dest='csv', help='output CSV (tab separated values)') parser.add_argument('-r', action="store_true", dest='reversed', help='reversed order') args = parser.parse_args() dateformat = args.date_format # voodoo because of Python's f...ing unicode capabilities # see http://wiki.python.org/moin/PrintFails # Uncomment the following line an add 'import codecs' at the beginning of # this file, if you have trouble piping the output to another program: # sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout) # # Another workaround: # Put following lines into site-packages/sitecustomize.py # see http://www.faqs.org/docs/diveintopython/kgp_unicode.html # # import os, sys # if 'UTF-8' in os.environ['LANG']: # sys.setdefaultencoding('utf-8') if not os.path.exists(args.journal_bundle): sys.stderr.write("ERROR: Journal %r was not" "found!\n" % (args.journal_bundle)) sys.exit(1) entrydir = os.path.join(args.journal_bundle, "entries") os.path.walk(entrydir, extractPlainText, None) for entry in sorted(entries, key=itemgetter(0), reverse=(args.reversed)): if args.csv == True: args.outfile.write("\"" + entry[0].strftime(dateformat) + "\"\t\"" + entry[1] + "\"\n") else: args.outfile.write(entry[0].strftime(dateformat) + "\n" + entry[1] + "\n") if __name__ == "__main__": main()