YAML configs

See #184, #230, #197
This commit is contained in:
Manuel Ebert 2014-07-02 11:47:56 +02:00
parent 9e95edd53c
commit 63ad45db75
4 changed files with 27 additions and 38 deletions

View file

@ -8,7 +8,7 @@ jrnl is a simple journal application for your command line.
from __future__ import absolute_import from __future__ import absolute_import
__title__ = 'jrnl' __title__ = 'jrnl'
__version__ = '1.9.5' __version__ = '2.0.0-rc1'
__author__ = 'Manuel Ebert' __author__ = 'Manuel Ebert'
__license__ = 'MIT License' __license__ = 'MIT License'
__copyright__ = 'Copyright 2013 - 2014 Manuel Ebert' __copyright__ = 'Copyright 2013 - 2014 Manuel Ebert'

View file

@ -5,13 +5,12 @@ from __future__ import absolute_import
import readline import readline
import glob import glob
import getpass import getpass
import json
import os import os
import xdg.BaseDirectory import xdg.BaseDirectory
from . import util from . import util
import yaml
DEFAULT_CONFIG_NAME = 'jrnl.yaml'
DEFAULT_CONFIG_NAME = 'jrnl.json'
DEFAULT_JOURNAL_NAME = 'journal.txt' DEFAULT_JOURNAL_NAME = 'journal.txt'
XDG_RESOURCE = 'jrnl' XDG_RESOURCE = 'jrnl'
@ -19,6 +18,7 @@ USER_HOME = os.path.expanduser('~')
CONFIG_PATH = xdg.BaseDirectory.save_config_path(XDG_RESOURCE) or USER_HOME CONFIG_PATH = xdg.BaseDirectory.save_config_path(XDG_RESOURCE) or USER_HOME
CONFIG_FILE_PATH = os.path.join(CONFIG_PATH, DEFAULT_CONFIG_NAME) CONFIG_FILE_PATH = os.path.join(CONFIG_PATH, DEFAULT_CONFIG_NAME)
CONFIG_FILE_PATH_FALLBACK = os.path.join(USER_HOME, ".jrnl_config")
JOURNAL_PATH = xdg.BaseDirectory.save_data_path(XDG_RESOURCE) or USER_HOME JOURNAL_PATH = xdg.BaseDirectory.save_data_path(XDG_RESOURCE) or USER_HOME
JOURNAL_FILE_PATH = os.path.join(JOURNAL_PATH, DEFAULT_JOURNAL_NAME) JOURNAL_FILE_PATH = os.path.join(JOURNAL_PATH, DEFAULT_JOURNAL_NAME)
@ -56,25 +56,32 @@ def upgrade_config(config):
if missing_keys: if missing_keys:
for key in missing_keys: for key in missing_keys:
config[key] = default_config[key] config[key] = default_config[key]
with open(CONFIG_FILE_PATH, 'w') as f: save_config(config)
json.dump(config, f, indent=2)
print("[.jrnl_conf updated to newest version]") print("[.jrnl_conf updated to newest version]")
def save_config(config): def save_config(config):
with open(CONFIG_FILE_PATH, 'w') as f: yaml.safe_dump(config, file(CONFIG_FILE_PATH, 'w'), encoding='utf-8', allow_unicode=True, default_flow_style=False)
json.dump(config, f, indent=2)
def install_jrnl(): def install_jrnl():
"""
If jrnl is already installed, loads and returns a config object.
Else, perform various prompts to install jrnl.
"""
if os.path.exists(CONFIG_FILE_PATH): if os.path.exists(CONFIG_FILE_PATH):
config = util.load_and_fix_json(CONFIG_FILE_PATH) config = util.load_config(CONFIG_FILE_PATH)
upgrade_config(config) upgrade_config(config)
return config return config
elif os.path.exists(CONFIG_FILE_PATH_FALLBACK): # Backwards compatibility with jrnl 1.x
config = util.load_config(CONFIG_FILE_PATH_FALLBACK)
upgrade_config(config)
save_config(config)
return config
def autocomplete(text, state): def autocomplete(text, state):
expansions = glob.glob(os.path.expanduser(os.path.expandvars(text))+'*') expansions = glob.glob(os.path.expanduser(os.path.expandvars(text)) + '*')
expansions = [e+"/" if os.path.isdir(e) else e for e in expansions] expansions = [e + "/" if os.path.isdir(e) else e for e in expansions]
expansions.append(None) expansions.append(None)
return expansions[state] return expansions[state]
readline.set_completer_delims(' \t\n;') readline.set_completer_delims(' \t\n;')
@ -108,9 +115,7 @@ def install_jrnl():
open(default_config['journals']['default'], 'a').close() # Touch to make sure it's there open(default_config['journals']['default'], 'a').close() # Touch to make sure it's there
# Write config to ~/.jrnl_conf save_config(config)
with open(CONFIG_FILE_PATH, 'w') as f:
json.dump(default_config, f, indent=2)
config = default_config config = default_config
if password: if password:
config['password'] = password config['password'] = password

View file

@ -4,7 +4,7 @@ import sys
import os import os
import getpass as gp import getpass as gp
import keyring import keyring
import json import yaml
if "win32" in sys.platform: if "win32" in sys.platform:
import colorama import colorama
colorama.init() colorama.init()
@ -100,30 +100,13 @@ def yesno(prompt, default=True):
return {'y': True, 'n': False}.get(raw.lower(), default) return {'y': True, 'n': False}.get(raw.lower(), default)
def load_and_fix_json(json_path): def load_config(config_path):
"""Tries to load a json object from a file. """Tries to load a config file from YAML.
If that fails, tries to fix common errors (no or extra , at end of the line). If that fails, fall back to JSON.
""" """
with open(json_path) as f: with open(config_path) as f:
json_str = f.read() config = yaml.load(f)
config = None return config
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)
def get_text_from_editor(config, template=""): def get_text_from_editor(config, template=""):

View file

@ -86,6 +86,7 @@ setup(
"pytz>=2013b", "pytz>=2013b",
"six>=1.6.1", "six>=1.6.1",
"tzlocal>=1.1", "tzlocal>=1.1",
"PyYAML>=3.11",
"keyring>=3.3", "keyring>=3.3",
] + [p for p, cond in conditional_dependencies.items() if cond], ] + [p for p, cond in conditional_dependencies.items() if cond],
extras_require = { extras_require = {