mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 16:48:31 +02:00
Merge pull request #92 from maebert/bugfix-dayone-mobile
Bugfix dayone mobile
This commit is contained in:
commit
d4e7ae9c3e
12 changed files with 70 additions and 20 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -21,4 +21,5 @@ lib64
|
||||||
# Installer logs
|
# Installer logs
|
||||||
pip-log.txt
|
pip-log.txt
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.travis-solo
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
14
features/data/configs/empty_folder.json
Normal file
14
features/data/configs/empty_folder.json
Normal 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": "@"
|
||||||
|
}
|
1
features/data/journals/empty_folder/empty.txt
Normal file
1
features/data/journals/empty_folder/empty.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Nothing to see here
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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}"')
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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)
|
||||||
|
|
17
jrnl/jrnl.py
17
jrnl/jrnl.py
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue