Merge pull request #92 from maebert/bugfix-dayone-mobile

Bugfix dayone mobile
This commit is contained in:
Manuel Ebert 2013-08-28 13:55:26 -07:00
commit d4e7ae9c3e
12 changed files with 70 additions and 20 deletions

1
.gitignore vendored
View file

@ -21,4 +21,5 @@ lib64
# Installer logs # Installer logs
pip-log.txt pip-log.txt
.DS_Store .DS_Store
.travis-solo

View file

@ -1,6 +1,10 @@
Changelog Changelog
========= =========
#### 1.5.5
* [Fixed] Detects DayOne journals stored in `~/Library/Mobile Data` as well.
#### 1.5.4 #### 1.5.4
* [New] DayOne journals can now handle tags * [New] DayOne journals can now handle tags

View file

@ -0,0 +1,14 @@
{
"default_hour": 9,
"timeformat": "%Y-%m-%d %H:%M",
"linewrap": 80,
"encrypt": false,
"editor": "",
"default_minute": 0,
"highlight": true,
"password": "",
"journals": {
"default": "features/journals/empty_folder"
},
"tagsymbols": "@"
}

View file

@ -0,0 +1 @@
Nothing to see here

View file

@ -12,6 +12,14 @@ def before_scenario(context, scenario):
context.messages = StringIO() context.messages = StringIO()
jrnl.util.STDERR = context.messages jrnl.util.STDERR = context.messages
jrnl.util.TEST = True jrnl.util.TEST = True
# Clean up in case something went wrong
for folder in ("configs", "journals"):
working_dir = os.path.join("features", folder)
if os.path.exists(working_dir):
shutil.rmtree(working_dir)
for folder in ("configs", "journals"): for folder in ("configs", "journals"):
original = os.path.join("features", "data", folder) original = os.path.join("features", "data", folder)
working_dir = os.path.join("features", folder) working_dir = os.path.join("features", folder)
@ -30,4 +38,5 @@ def after_scenario(context, scenario):
context.messages = None context.messages = None
for folder in ("configs", "journals"): for folder in ("configs", "journals"):
working_dir = os.path.join("features", folder) working_dir = os.path.join("features", folder)
shutil.rmtree(working_dir) if os.path.exists(working_dir):
shutil.rmtree(working_dir)

View file

@ -1,8 +1,15 @@
Feature: Zapped bugs should stay dead. Feature: Zapped bugs should stay dead.
Scenario: Writing an entry does not print the entire journal Scenario: Writing an entry does not print the entire journal
# https://github.com/maebert/jrnl/issues/87
Given we use the config "basic.json" Given we use the config "basic.json"
When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa."
Then we should see the message "Entry added" Then we should see the message "Entry added"
When we run "jrnl -n 1" When we run "jrnl -n 1"
Then the output should not contain "Life is good" Then the output should not contain "Life is good"
Scenario: Opening an folder that's not a DayOne folder gives a nice error message
Given we use the config "empty_folder.json"
When we run "jrnl Herro"
Then we should get an error
Then we should see the message "is a directory, but doesn't seem to be a DayOne journal either"

View file

@ -53,17 +53,28 @@ def run_with_input(context, command, inputs=None):
args = _parse_args(command) args = _parse_args(command)
buffer = StringIO(text.strip()) buffer = StringIO(text.strip())
jrnl.util.STDIN = buffer jrnl.util.STDIN = buffer
jrnl.cli(args) try:
jrnl.cli(args or None)
context.exit_status = 0
except SystemExit as e:
context.exit_status = e.code
@when('we run "{command}"') @when('we run "{command}"')
def run(context, command): def run(context, command):
args = _parse_args(command) args = _parse_args(command)
jrnl.cli(args or None) try:
jrnl.cli(args or None)
context.exit_status = 0
except SystemExit as e:
context.exit_status = e.code
@then('we should get an error')
def has_error(context):
assert context.exit_status != 0, context.exit_status
@then('we should get no error') @then('we should get no error')
def no_error(context): def no_error(context):
assert context.failed is False assert context.exit_status is 0, context.exit_status
@then('the output should be parsable as json') @then('the output should be parsable as json')
def check_output_json(context): def check_output_json(context):
@ -121,7 +132,7 @@ def check_output_not_inline(context, text):
@then('we should see the message "{text}"') @then('we should see the message "{text}"')
def check_message(context, text): def check_message(context, text):
out = context.messages.getvalue() out = context.messages.getvalue()
assert text in out assert text in out, [text, out]
@then('the journal should contain "{text}"') @then('the journal should contain "{text}"')
@then('journal "{journal_name}" should contain "{text}"') @then('journal "{journal_name}" should contain "{text}"')

View file

@ -58,7 +58,7 @@ class Entry:
) )
def __repr__(self): def __repr__(self):
return "<Entry '{}' on {}>".format(self.title.strip(), self.date.strftime("%Y-%m-%d %H:%M")) return "<Entry '{0}' on {1}>".format(self.title.strip(), self.date.strftime("%Y-%m-%d %H:%M"))
def to_dict(self): def to_dict(self):
return { return {

View file

@ -181,7 +181,7 @@ class Journal(object):
return self.__unicode__() return self.__unicode__()
def __repr__(self): def __repr__(self):
return "<Journal with {} entries>".format(len(self.entries)) return "<Journal with {0} entries>".format(len(self.entries))
def write(self, filename=None): def write(self, filename=None):
"""Dumps the journal into the config file, overwriting it""" """Dumps the journal into the config file, overwriting it"""
@ -234,7 +234,7 @@ class Journal(object):
for m in matches: for m in matches:
date = e.date.strftime(self.config['timeformat']) date = e.date.strftime(self.config['timeformat'])
excerpt = e.body[m.start():min(len(e.body), m.end()+60)] excerpt = e.body[m.start():min(len(e.body), m.end()+60)]
res.append('{} {} ..'.format(date, excerpt)) res.append('{0} {1} ..'.format(date, excerpt))
e.body = "\n".join(res) e.body = "\n".join(res)
else: else:
for e in self.entries: for e in self.entries:

View file

@ -7,7 +7,7 @@ jrnl is a simple journal application for your command line.
""" """
__title__ = 'jrnl' __title__ = 'jrnl'
__version__ = '1.5.4' __version__ = '1.5.5'
__author__ = 'Manuel Ebert' __author__ = 'Manuel Ebert'
__license__ = 'MIT License' __license__ = 'MIT License'
__copyright__ = 'Copyright 2013 Manuel Ebert' __copyright__ = 'Copyright 2013 Manuel Ebert'

View file

@ -87,16 +87,16 @@ def export(journal, format, output=None):
try: try:
with open(output, 'w') as f: with open(output, 'w') as f:
f.write(content) f.write(content)
return "[Journal exported to {}]".format(output) return "[Journal exported to {0}]".format(output)
except IOError as e: except IOError as e:
return "[ERROR: {} {}]".format(e.filename, e.strerror) return "[ERROR: {0} {1}]".format(e.filename, e.strerror)
else: else:
return content return content
def write_files(journal, path, format): def write_files(journal, path, format):
"""Turns your journal into separate files for each entry. """Turns your journal into separate files for each entry.
Format should be either json, md or txt.""" Format should be either json, md or txt."""
make_filename = lambda entry: e.date.strftime("%C-%m-%d_{}.{}".format(slugify(u(e.title)), format)) make_filename = lambda entry: e.date.strftime("%C-%m-%d_{0}.{1}".format(slugify(u(e.title)), format))
for e in journal.entries: for e in journal.entries:
full_path = os.path.join(path, make_filename(e)) full_path = os.path.join(path, make_filename(e))
if format == 'json': if format == 'json':
@ -107,4 +107,4 @@ def write_files(journal, path, format):
content = u(e) content = u(e)
with open(full_path, 'w') as f: with open(full_path, 'w') as f:
f.write(content) f.write(content)
return "[Journal exported individual files in {}]".format(path) return "[Journal exported individual files in {0}]".format(path)

View file

@ -123,16 +123,16 @@ def cli(manual_args=None):
try: try:
config = json.load(f) config = json.load(f)
except ValueError as e: except ValueError as e:
util.prompt("[There seems to be something wrong with your jrnl config at {}: {}]".format(CONFIG_PATH, e.message)) util.prompt("[There seems to be something wrong with your jrnl config at {0}: {1}]".format(CONFIG_PATH, e.message))
util.prompt("[Entry was NOT added to your journal]") util.prompt("[Entry was NOT added to your journal]")
sys.exit(-1) sys.exit(1)
install.update_config(config, config_path=CONFIG_PATH) install.update_config(config, config_path=CONFIG_PATH)
original_config = config.copy() original_config = config.copy()
# check if the configuration is supported by available modules # check if the configuration is supported by available modules
if config['encrypt'] and not PYCRYPTO: if config['encrypt'] and not PYCRYPTO:
util.prompt("According to your jrnl_conf, your journal is encrypted, however PyCrypto was not found. To open your journal, install the PyCrypto package from http://www.pycrypto.org.") util.prompt("According to your jrnl_conf, your journal is encrypted, however PyCrypto was not found. To open your journal, install the PyCrypto package from http://www.pycrypto.org.")
sys.exit(-1) sys.exit(1)
args = parse_args(manual_args) args = parse_args(manual_args)
@ -150,13 +150,16 @@ def cli(manual_args=None):
mode_compose, mode_export = guess_mode(args, config) mode_compose, mode_export = guess_mode(args, config)
# open journal file or folder # open journal file or folder
if os.path.isdir(config['journal']) and ( config['journal'].endswith(".dayone") or \ if os.path.isdir(config['journal']):
config['journal'].endswith(".dayone/")): if config['journal'].strip("/").endswith(".dayone") or \
journal = Journal.DayOne(**config) "entries" in os.listdir(config['journal']):
journal = Journal.DayOne(**config)
else:
util.prompt("[Error: {0} is a directory, but doesn't seem to be a DayOne journal either.".format(config['journal']))
sys.exit(1)
else: else:
journal = Journal.Journal(**config) journal = Journal.Journal(**config)
if mode_compose and not args.text: if mode_compose and not args.text:
if config['editor']: if config['editor']:
raw = get_text_from_editor(config) raw = get_text_from_editor(config)