From 6f9a644185e694ba0bc56bd3c9e6a7fa80b6758e Mon Sep 17 00:00:00 2001 From: Aniket Pant Date: Tue, 26 Mar 2013 22:11:08 +0530 Subject: [PATCH 1/6] [Typo] Fixed typo in comments Signed-off-by: Aniket Pant --- jrnl/jrnl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 2de3fd16..6abbf98c 100755 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -199,7 +199,7 @@ def cli(): elif args.json: # export to json print(exporters.to_json(journal)) - elif args.markdown: # export to json + elif args.markdown: # export to markdown print(exporters.to_md(journal)) elif (args.encrypt is not False or args.decrypt is not False) and not PYCRYPTO: From 7c264367e76d32d4fa9146c4b4c9304a837a7939 Mon Sep 17 00:00:00 2001 From: Aniket Pant Date: Tue, 26 Mar 2013 22:12:46 +0530 Subject: [PATCH 2/6] [Export to files] Added new utility Signed-off-by: Aniket Pant --- jrnl/exporters.py | 24 ++++++++++++++++++++++++ jrnl/jrnl.py | 8 ++++++++ 2 files changed, 32 insertions(+) diff --git a/jrnl/exporters.py b/jrnl/exporters.py index dfca5d78..c95308c3 100644 --- a/jrnl/exporters.py +++ b/jrnl/exporters.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # encoding: utf-8 +import re +import os try: import simplejson as json except ImportError: import json @@ -23,3 +25,25 @@ def to_md(journal): out.append('-' * len(e.date.strftime("%B")) + "\n") out.append(e.to_md()) return "\n".join(out) + +def to_files(journal, directory, extension): + """Turns your journal into separate files for each entry.""" + if extension: + ext = "." + extension + else: + ext = '' + + if not os.path.exists(directory): + os.makedirs(directory) + + for e in journal.entries: + date = e.date.strftime('%Y-%m-%d') + title = re.sub('[^\w-]', '', re.sub(' ', '-', e.title.lower())) + filename = date + '-' + title + ext + f = open(directory + "/" + filename, 'w+') + if extension == 'md': + f.write(str(e.to_md())) + else: + f.write(str(e)) + f.close() + return ("Journal exported to directory '" + directory + "' as " + ext) diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 6abbf98c..f153449c 100755 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -49,6 +49,11 @@ def parse_args(): exporting.add_argument('--decrypt', metavar='FILENAME', dest='decrypt', help='Decrypts your journal and stores it in plain text', nargs='?', default=False, const=None) exporting.add_argument('--delete-last', dest='delete_last', help='Deletes the last entry from your journal file.', action="store_true") + exporting_to_files = parser.add_argument_group('Export to files', 'Options for exporting your journal to individual files') + exporting_to_files.add_argument('--files', dest='files', action="store_true", help='Turns your journal into separate files for each entry') + exporting_to_files.add_argument('--dir', metavar='DIRECTORY', dest='directory', help='The directory you want to export the files to', nargs='?', default='journal', const=None) + exporting_to_files.add_argument('--ext', metavar='EXTENSION', dest='extension', help='The extension of the exported files', nargs='?', default=False, const=None) + return parser.parse_args() def guess_mode(args, config): @@ -202,6 +207,9 @@ def cli(): elif args.markdown: # export to markdown print(exporters.to_md(journal)) + elif args.files: # export to files + print(exporters.to_files(journal, args.directory, args.extension)) + elif (args.encrypt is not False or args.decrypt is not False) and not PYCRYPTO: print("PyCrypto not found. To encrypt or decrypt your journal, install the PyCrypto package from http://www.pycrypto.org.") From ef00e6adf3092007a055e0e1e92c83749bf9e940 Mon Sep 17 00:00:00 2001 From: Aniket Pant Date: Wed, 27 Mar 2013 21:33:14 +0530 Subject: [PATCH 3/6] [Export] Imporved functionality for exporting Now exports can be done via single command and output file can also be specified. Signed-off-by: Aniket Pant --- jrnl/exporters.py | 62 ++++++++++++++++++++++++++++++----------------- jrnl/jrnl.py | 28 ++++++++++----------- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/jrnl/exporters.py b/jrnl/exporters.py index c95308c3..13ef10e9 100644 --- a/jrnl/exporters.py +++ b/jrnl/exporters.py @@ -3,14 +3,19 @@ import re import os +try: from slugify import slugify +except ImportError: import slugify try: import simplejson as json except ImportError: import json -def to_json(journal): +def to_json(journal, output): """Returns a JSON representation of the Journal.""" - return json.dumps([e.to_dict() for e in journal.entries], indent=2) + result = json.dumps([e.to_dict() for e in journal.entries], indent=2) + if output is not False: + write_file(result, output) + return result -def to_md(journal): +def to_md(journal, output): """Returns a markdown representation of the Journal""" out = [] year, month = -1, -1 @@ -24,26 +29,39 @@ def to_md(journal): out.append(e.date.strftime("%B")) out.append('-' * len(e.date.strftime("%B")) + "\n") out.append(e.to_md()) - return "\n".join(out) + result = "\n".join(out) + if output is not False: + write_file(result, output) + return result -def to_files(journal, directory, extension): +def to_txt(journal, output): + """Returns the complete text of the Journal.""" + if output is not False: + write_file(str(journal), output) + return journal + +def to_files(journal, output): """Turns your journal into separate files for each entry.""" - if extension: - ext = "." + extension - else: - ext = '' - - if not os.path.exists(directory): - os.makedirs(directory) - + if output is False: + output = os.path.expanduser('~/journal/*.txt') # default path + path, extension = os.path.splitext(os.path.expanduser(output)) + head, tail = os.path.split(path) + if tail == '*': # if wildcard is specified + path = head + '/' + if not os.path.exists(path): # if the folder doesn't exist, create it + os.makedirs(path) for e in journal.entries: date = e.date.strftime('%Y-%m-%d') - title = re.sub('[^\w-]', '', re.sub(' ', '-', e.title.lower())) - filename = date + '-' + title + ext - f = open(directory + "/" + filename, 'w+') - if extension == 'md': - f.write(str(e.to_md())) - else: - f.write(str(e)) - f.close() - return ("Journal exported to directory '" + directory + "' as " + ext) + title = slugify(e.title) + filename = date + '-' + title + result = str(e) + fullpath = path + filename + extension + print fullpath + write_file(result, fullpath) + return ("Journal exported to '" + path + "'") + +def write_file(content, path): + """Writes content to the file provided""" + f = open(path, 'w+') + f.write(content) + f.close() diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index f153449c..aabfcd77 100755 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -42,25 +42,20 @@ def parse_args(): reading.add_argument('-short', dest='short', action="store_true", help='Show only titles or line containing the search tags') exporting = parser.add_argument_group('Export / Import', 'Options for transmogrifying your journal') - exporting.add_argument('--tags', dest='tags', action="store_true", help='Returns a list of all tags and number of occurences') - exporting.add_argument('--json', dest='json', action="store_true", help='Returns a JSON-encoded version of the Journal') - exporting.add_argument('--markdown', dest='markdown', action="store_true", help='Returns a Markdown-formated version of the Journal') + exporting.add_argument('--tags', dest='tags', action="store_true", help='Returns a list of all tags and number of occurrences') + exporting.add_argument('--export', metavar='TYPE', dest='export', help='Export your journal to Markdown, JSON, Text or multiple files', nargs='?', default=False, const=None) + exporting.add_argument('-o', metavar='OUTPUT', dest='output', help='The output of the file can be provided when using with --export', nargs='?', default=False, const=None) exporting.add_argument('--encrypt', metavar='FILENAME', dest='encrypt', help='Encrypts your existing journal with a new password', nargs='?', default=False, const=None) exporting.add_argument('--decrypt', metavar='FILENAME', dest='decrypt', help='Decrypts your journal and stores it in plain text', nargs='?', default=False, const=None) exporting.add_argument('--delete-last', dest='delete_last', help='Deletes the last entry from your journal file.', action="store_true") - exporting_to_files = parser.add_argument_group('Export to files', 'Options for exporting your journal to individual files') - exporting_to_files.add_argument('--files', dest='files', action="store_true", help='Turns your journal into separate files for each entry') - exporting_to_files.add_argument('--dir', metavar='DIRECTORY', dest='directory', help='The directory you want to export the files to', nargs='?', default='journal', const=None) - exporting_to_files.add_argument('--ext', metavar='EXTENSION', dest='extension', help='The extension of the exported files', nargs='?', default=False, const=None) - return parser.parse_args() def guess_mode(args, config): """Guesses the mode (compose, read or export) from the given arguments""" compose = True export = False - if args.json or args.decrypt is not False or args.encrypt is not False or args.markdown or args.tags or args.delete_last: + if args.decrypt is not False or args.encrypt is not False or args.export is not False or args.tags or args.delete_last: compose = False export = True elif args.start_date or args.end_date or args.limit or args.strict or args.short: @@ -201,14 +196,17 @@ def cli(): elif args.tags: print_tags(journal) - elif args.json: # export to json - print(exporters.to_json(journal)) + elif args.export == 'json': # export to json + print(exporters.to_json(journal, args.output)) - elif args.markdown: # export to markdown - print(exporters.to_md(journal)) + elif args.export == 'markdown' or args.export == 'md': # export to markdown + print(exporters.to_md(journal, args.output)) - elif args.files: # export to files - print(exporters.to_files(journal, args.directory, args.extension)) + elif args.export == 'text' or args.export == 'txt': # export to text + print(exporters.to_txt(journal, args.output)) + + elif args.export == 'files': # export to files + print(exporters.to_files(journal, args.output)) elif (args.encrypt is not False or args.decrypt is not False) and not PYCRYPTO: print("PyCrypto not found. To encrypt or decrypt your journal, install the PyCrypto package from http://www.pycrypto.org.") From 912175f601474c9ac03ffb7f417286135da5c095 Mon Sep 17 00:00:00 2001 From: Aniket Pant Date: Sat, 30 Mar 2013 11:20:16 +0530 Subject: [PATCH 4/6] [Requirements] Added slugify to the requirements and setup.py Signed-off-by: Aniket Pant --- requirements.txt | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9b78f344..679fd92a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ clint >= 0.3.1 parsedatetime == 1.1.2 +slugify==0.0.1 diff --git a/setup.py b/setup.py index ab80113b..057108cc 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ setup( version = "1.0.1", description = "A command line journal application that stores your journal in a plain text file", packages = ['jrnl'], - install_requires = ["parsedatetime >= 1.1.2"], + install_requires = ["parsedatetime >= 1.1.2", "slugify >= 0.0.1"], extras_require = { 'encryption': ["pycrypto"], 'highlight': ["clint"] From d3958316f23d102f5f869b86e445d09b73c868cc Mon Sep 17 00:00:00 2001 From: Aniket Pant Date: Sun, 14 Apr 2013 00:23:45 +0530 Subject: [PATCH 5/6] Added default export folder to config Signed-off-by: Aniket Pant --- jrnl/Journal.py | 1 + jrnl/install.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/jrnl/Journal.py b/jrnl/Journal.py index fd101d9c..753e9a41 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -37,6 +37,7 @@ class Journal(object): 'tagsymbols': '@', 'highlight': True, 'linewrap': 80, + 'folder': os.path.expanduser("~/journal/"), } self.config.update(kwargs) diff --git a/jrnl/install.py b/jrnl/install.py index 90b5939e..467112cb 100644 --- a/jrnl/install.py +++ b/jrnl/install.py @@ -29,6 +29,7 @@ default_config = { 'tagsymbols': '@', 'highlight': True, 'linewrap': 80, + 'folder': os.path.expanduser("~/journal/"), } @@ -91,4 +92,7 @@ def install_jrnl(config_path='~/.jrnl_config'): config['password'] = password return config - \ No newline at end of file + # Where to export files? + path_query = 'Path to your journal folder (leave blank for ~/journal): ' + folder_path = raw_input(path_query).strip() or os.path.expanduser('~/journal') + default_config['folder'] = os.path.expanduser(folder_path) From 99fa0fd4f07f3891656d4d4f3043c3a381864e7d Mon Sep 17 00:00:00 2001 From: Aniket Pant Date: Sun, 14 Apr 2013 00:24:18 +0530 Subject: [PATCH 6/6] Fixed bug when using slugify slugify requires unicode input Signed-off-by: Aniket Pant --- jrnl/exporters.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/jrnl/exporters.py b/jrnl/exporters.py index 13ef10e9..c894a034 100644 --- a/jrnl/exporters.py +++ b/jrnl/exporters.py @@ -1,7 +1,6 @@ #!/usr/bin/env python # encoding: utf-8 -import re import os try: from slugify import slugify except ImportError: import slugify @@ -43,7 +42,7 @@ def to_txt(journal, output): def to_files(journal, output): """Turns your journal into separate files for each entry.""" if output is False: - output = os.path.expanduser('~/journal/*.txt') # default path + output = journal.config['folder'] + "*.txt" # default path path, extension = os.path.splitext(os.path.expanduser(output)) head, tail = os.path.split(path) if tail == '*': # if wildcard is specified @@ -52,13 +51,13 @@ def to_files(journal, output): os.makedirs(path) for e in journal.entries: date = e.date.strftime('%Y-%m-%d') - title = slugify(e.title) + title = slugify(unicode(e.title)) filename = date + '-' + title result = str(e) fullpath = path + filename + extension print fullpath write_file(result, fullpath) - return ("Journal exported to '" + path + "'") + return ("Journal exported") def write_file(content, path): """Writes content to the file provided"""