diff --git a/jrnl/util.py b/jrnl/util.py index 9c8aaa40..ecddddce 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -2,10 +2,8 @@ # encoding: utf-8 import sys import os -from tzlocal import get_localzone import getpass as gp import keyring -import pytz import json if "win32" in sys.platform: import colorama @@ -24,12 +22,14 @@ STDOUT = sys.stdout TEST = False __cached_tz = None + def getpass(prompt="Password: "): if not TEST: return gp.getpass(prompt) else: return py23_input(prompt) + def get_password(validator, keychain=None, max_attempts=3): pwd_from_keychain = keychain and get_keychain(keychain) password = pwd_from_keychain or getpass() @@ -49,9 +49,11 @@ def get_password(validator, keychain=None, max_attempts=3): prompt("Extremely wrong password.") sys.exit(1) + def get_keychain(journal_name): return keyring.get_password('jrnl', journal_name) + def set_keychain(journal_name, password): if password is None: try: @@ -61,40 +63,51 @@ def set_keychain(journal_name, password): elif not TEST: keyring.set_password('jrnl', journal_name, password) + def u(s): """Mock unicode function for python 2 and 3 compatibility.""" - return s if PY3 or type(s) is unicode else unicode(s.encode('string-escape'), "unicode_escape") + if PY3: + return str(s) + elif isinstance(s, basestring) and type(s) is not unicode: + return unicode(s.encode('string-escape'), "unicode_escape") + return unicode(s) + def py2encode(s): """Encode in Python 2, but not in python 3.""" return s.encode("utf-8") if PY2 and type(s) is unicode else s + def prompt(msg): """Prints a message to the std err stream defined in util.""" if not msg.endswith("\n"): msg += "\n" STDERR.write(u(msg)) + def py23_input(msg=""): STDERR.write(u(msg)) return STDIN.readline().strip() + def py23_read(msg=""): STDERR.write(u(msg)) return STDIN.read() + def yesno(prompt, default=True): prompt = prompt.strip() + (" [Y/n]" if default else " [y/N]") raw = py23_input(prompt) return {'y': True, 'n': False}.get(raw.lower(), default) + 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 + config = None try: return json.loads(json_str) except ValueError as e: @@ -113,6 +126,7 @@ def load_and_fix_json(json_path): prompt("[Entry was NOT added to your journal]") sys.exit(1) + def get_text_from_editor(config, template=""): tmpfile = os.path.join(tempfile.mktemp(prefix="jrnl")) with codecs.open(tmpfile, 'w', "utf-8") as f: @@ -126,10 +140,12 @@ def get_text_from_editor(config, template=""): prompt('[Nothing saved to file]') return raw + def colorize(string): """Returns the string wrapped in cyan ANSI escape""" return u"\033[36m{}\033[39m".format(string) + def slugify(string): """Slugifies a string. Based on public domain code from https://github.com/zacharyvoase/slugify @@ -141,6 +157,7 @@ def slugify(string): slug = re.sub(r'[-\s]+', '-', no_punctuation) return u(slug) + def int2byte(i): """Converts an integer to a byte. This is equivalent to chr() in Python 2 and bytes((i,)) in Python 3.""" @@ -151,4 +168,3 @@ def byte2int(b): """Converts a byte to an integer. This is equivalent to ord(bs[0]) on Python 2 and bs[0] on Python 3.""" return ord(b)if PY2 else b -