diff --git a/CHANGELOG.md b/CHANGELOG.md index e94bf47c..5ceb6ab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Changelog ========= +#### 1.6.1 + +* [Improved] Attempts to fix broken config files automatically + #### 1.6.0 * [Improved] Passwords are now saved in the key-chain. The `password` field in `.jrnl_config` is soft-deprecated. diff --git a/features/data/configs/broken.json b/features/data/configs/broken.json new file mode 100644 index 00000000..bcd96f24 --- /dev/null +++ b/features/data/configs/broken.json @@ -0,0 +1,15 @@ +{ + "default_hour": 9, + "timeformat": "%Y-%m-%d %H:%M", + "linewrap": 80, + "encrypt": false, + "editor": "", + "default_minute": 0, + "highlight": true + "password": "", + "journals": { + "default": "features/journals/simple.journal" + "work": "features/journals/work.journal", + }, + "tagsymbols": "@" +} diff --git a/features/fix_json.feature b/features/fix_json.feature new file mode 100644 index 00000000..84f91955 --- /dev/null +++ b/features/fix_json.feature @@ -0,0 +1,14 @@ +Feature: Fixing broken config files + + Scenario: Loading a file with journal + Given we use the config "broken.json" + When we run "jrnl -n 2" + Then we should see the message "Some errors in your jrnl config have been fixed for you." + and the output should be + """ + 2013-06-09 15:39 My first entry. + | Everything is alright + + 2013-06-10 15:40 Life is good. + | But I'm better. + """ diff --git a/jrnl/__init__.py b/jrnl/__init__.py index 4d384eb8..0e06627b 100644 --- a/jrnl/__init__.py +++ b/jrnl/__init__.py @@ -7,7 +7,7 @@ jrnl is a simple journal application for your command line. """ __title__ = 'jrnl' -__version__ = '1.6.0-dev' +__version__ = '1.6.1-dev' __author__ = 'Manuel Ebert' __license__ = 'MIT License' __copyright__ = 'Copyright 2013 Manuel Ebert' diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index b82dd54c..7b98a42e 100755 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -22,8 +22,6 @@ import tempfile import subprocess import argparse import sys -try: import simplejson as json -except ImportError: import json xdg_config = os.environ.get('XDG_CONFIG_HOME') CONFIG_PATH = os.path.join(xdg_config, "jrnl") if xdg_config else os.path.expanduser('~/.jrnl_config') @@ -123,13 +121,7 @@ def cli(manual_args=None): if not os.path.exists(CONFIG_PATH): config = install.install_jrnl(CONFIG_PATH) else: - with open(CONFIG_PATH) as f: - try: - config = json.load(f) - except ValueError as e: - 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]") - sys.exit(1) + config = util.load_and_fix_json(CONFIG_PATH) install.upgrade_config(config, config_path=CONFIG_PATH) original_config = config.copy() diff --git a/jrnl/util.py b/jrnl/util.py index 7ae9d4df..7d396f72 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -6,6 +6,9 @@ from tzlocal import get_localzone import getpass as gp import keyring import pytz +try: import simplejson as json +except ImportError: import json +import re PY3 = sys.version_info[0] == 3 PY2 = sys.version_info[0] == 2 @@ -88,3 +91,29 @@ def get_local_timezone(): if not __cached_tz or __cached_tz not in pytz.all_timezones_set: __cached_tz = "UTC" return __cached_tz + +def load_and_fix_json(json_path): + """Tries to load a json object from a file. + If that fails, tries to fix common errors (no or extra , at end of the line). + """ + with open(json_path) as f: + json_str = f.read() + config = fixed = None + try: + return json.loads(json_str) + except ValueError as e: + # Attempt to fix extra , + json_str = re.sub(r",[ \n]*}", "}", json_str) + # Attempt to fix missing , + json_str = re.sub(r"([^{,]) *\n *(\")", r"\1,\n \2", json_str) + try: + config = json.loads(json_str) + with open(json_path, 'w') as f: + json.dump(config, f, indent=2) + prompt("[Some errors in your jrnl config have been fixed for you.]") + return config + except ValueError as e: + prompt("[There seems to be something wrong with your jrnl config at {0}: {1}]".format(json_path, e.message)) + prompt("[Entry was NOT added to your journal]") + sys.exit(1) +