Skip to content

Commit

Permalink
Merge pull request #778 from wren/black-format-770
Browse files Browse the repository at this point in the history
[#770] run black formatter on codebase for standardization
  • Loading branch information
micahellison committed Dec 21, 2019
2 parents a9e4e09 + 07a633a commit 717078b
Show file tree
Hide file tree
Showing 24 changed files with 854 additions and 431 deletions.
105 changes: 59 additions & 46 deletions features/steps/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
from jrnl import __version__
from dateutil import parser as date_parser
from collections import defaultdict
try: import parsedatetime.parsedatetime_consts as pdt
except ImportError: import parsedatetime as pdt

try:
import parsedatetime.parsedatetime_consts as pdt
except ImportError:
import parsedatetime as pdt
import time
import os
import json
Expand All @@ -17,7 +20,7 @@
import sys

consts = pdt.Constants(usePyICU=False)
consts.DOWParseStyle = -1 # Prefers past weekdays
consts.DOWParseStyle = -1 # Prefers past weekdays
CALENDAR = pdt.Calendar(consts)


Expand All @@ -44,23 +47,25 @@ def delete_password(self, servicename, username):
def ushlex(command):
if sys.version_info[0] == 3:
return shlex.split(command)
return map(lambda s: s.decode('UTF8'), shlex.split(command.encode('utf8')))
return map(lambda s: s.decode("UTF8"), shlex.split(command.encode("utf8")))


def read_journal(journal_name="default"):
config = util.load_config(install.CONFIG_FILE_PATH)
with open(config['journals'][journal_name]) as journal_file:
with open(config["journals"][journal_name]) as journal_file:
journal = journal_file.read()
return journal


def open_journal(journal_name="default"):
config = util.load_config(install.CONFIG_FILE_PATH)
journal_conf = config['journals'][journal_name]
if type(journal_conf) is dict: # We can override the default config on a by-journal basis
journal_conf = config["journals"][journal_name]
if (
type(journal_conf) is dict
): # We can override the default config on a by-journal basis
config.update(journal_conf)
else: # But also just give them a string to point to the journal file
config['journal'] = journal_conf
config["journal"] = journal_conf
return Journal.open_journal(journal_name, config)


Expand All @@ -70,14 +75,15 @@ def set_config(context, config_file):
install.CONFIG_FILE_PATH = os.path.abspath(full_path)
if config_file.endswith("yaml"):
# Add jrnl version to file for 2.x journals
with open(install.CONFIG_FILE_PATH, 'a') as cf:
with open(install.CONFIG_FILE_PATH, "a") as cf:
cf.write("version: {}".format(__version__))


@when('we open the editor and enter ""')
@when('we open the editor and enter "{text}"')
def open_editor_and_enter(context, text=""):
text = (text or context.text)
text = text or context.text

def _mock_editor_function(command):
tmpfile = command[-1]
with open(tmpfile, "w+") as f:
Expand All @@ -88,14 +94,15 @@ def _mock_editor_function(command):

return tmpfile

with patch('subprocess.call', side_effect=_mock_editor_function):
with patch("subprocess.call", side_effect=_mock_editor_function):
run(context, "jrnl")


def _mock_getpass(inputs):
def prompt_return(prompt="Password: "):
print(prompt)
return next(inputs)

return prompt_return


Expand All @@ -104,6 +111,7 @@ def prompt_return(prompt=""):
val = next(inputs)
print(prompt, val)
return val

return prompt_return


Expand All @@ -119,24 +127,28 @@ def run_with_input(context, command, inputs=""):
text = iter([inputs])

args = ushlex(command)[1:]
with patch("builtins.input", side_effect=_mock_input(text)) as mock_input,\
patch("getpass.getpass", side_effect=_mock_getpass(text)) as mock_getpass,\
patch("sys.stdin.read", side_effect=text) as mock_read:
try:
cli.run(args or [])
context.exit_status = 0
except SystemExit as e:
context.exit_status = e.code

# at least one of the mocked input methods got called
assert mock_input.called or mock_getpass.called or mock_read.called
# all inputs were used
try:
next(text)
assert False, "Not all inputs were consumed"
except StopIteration:
pass
# fmt: off
# see: https://github.com/psf/black/issues/557
with patch("builtins.input", side_effect=_mock_input(text)) as mock_input, \
patch("getpass.getpass", side_effect=_mock_getpass(text)) as mock_getpass, \
patch("sys.stdin.read", side_effect=text) as mock_read:

try:
cli.run(args or [])
context.exit_status = 0
except SystemExit as e:
context.exit_status = e.code

# at least one of the mocked input methods got called
assert mock_input.called or mock_getpass.called or mock_read.called
# all inputs were used
try:
next(text)
assert False, "Not all inputs were consumed"
except StopIteration:
pass
# fmt: on


@when('we run "{command}"')
Expand All @@ -158,20 +170,20 @@ def load_template(context, filename):

@when('we set the keychain password of "{journal}" to "{password}"')
def set_keychain(context, journal, password):
keyring.set_password('jrnl', journal, password)
keyring.set_password("jrnl", journal, password)


@then('we should get an error')
@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):
assert context.exit_status == 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):
out = context.stdout_capture.getvalue()
assert json.loads(out), out
Expand Down Expand Up @@ -210,34 +222,39 @@ def check_json_output_path(context, path, value):
out = context.stdout_capture.getvalue()
struct = json.loads(out)

for node in path.split('.'):
for node in path.split("."):
try:
struct = struct[int(node)]
except ValueError:
struct = struct[node]
assert struct == value, struct


@then('the output should be')
@then("the output should be")
@then('the output should be "{text}"')
def check_output(context, text=None):
text = (text or context.text).strip().splitlines()
out = context.stdout_capture.getvalue().strip().splitlines()
assert len(text) == len(out), "Output has {} lines (expected: {})".format(len(out), len(text))
assert len(text) == len(out), "Output has {} lines (expected: {})".format(
len(out), len(text)
)
for line_text, line_out in zip(text, out):
assert line_text.strip() == line_out.strip(), [line_text.strip(), line_out.strip()]
assert line_text.strip() == line_out.strip(), [
line_text.strip(),
line_out.strip(),
]


@then('the output should contain "{text}" in the local time')
def check_output_time_inline(context, text):
out = context.stdout_capture.getvalue()
local_tz = tzlocal.get_localzone()
date, flag = CALENDAR.parse(text)
output_date = time.strftime("%Y-%m-%d %H:%M",date)
output_date = time.strftime("%Y-%m-%d %H:%M", date)
assert output_date in out, output_date


@then('the output should contain')
@then("the output should contain")
@then('the output should contain "{text}"')
def check_output_inline(context, text=None):
text = text or context.text
Expand Down Expand Up @@ -274,35 +291,31 @@ def check_journal_content(context, text, journal_name="default"):
def journal_doesnt_exist(context, journal_name="default"):
with open(install.CONFIG_FILE_PATH) as config_file:
config = yaml.load(config_file, Loader=yaml.FullLoader)
journal_path = config['journals'][journal_name]
journal_path = config["journals"][journal_name]
assert not os.path.exists(journal_path)


@then('the config should have "{key}" set to "{value}"')
@then('the config for journal "{journal}" should have "{key}" set to "{value}"')
def config_var(context, key, value, journal=None):
t, value = value.split(":")
value = {
"bool": lambda v: v.lower() == "true",
"int": int,
"str": str
}[t](value)
value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[t](value)
config = util.load_config(install.CONFIG_FILE_PATH)
if journal:
config = config["journals"][journal]
assert key in config
assert config[key] == value


@then('the journal should have {number:d} entries')
@then('the journal should have {number:d} entry')
@then("the journal should have {number:d} entries")
@then("the journal should have {number:d} entry")
@then('journal "{journal_name}" should have {number:d} entries')
@then('journal "{journal_name}" should have {number:d} entry')
def check_journal_entries(context, number, journal_name="default"):
journal = open_journal(journal_name)
assert len(journal.entries) == number


@then('fail')
@then("fail")
def debug_fail(context):
assert False
64 changes: 44 additions & 20 deletions jrnl/DayOneJournal.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,51 @@ class DayOne(Journal.Journal):
"""A special Journal handling DayOne files"""

# InvalidFileException was added to plistlib in Python3.4
PLIST_EXCEPTIONS = (ExpatError, plistlib.InvalidFileException) if hasattr(plistlib, "InvalidFileException") else ExpatError
PLIST_EXCEPTIONS = (
(ExpatError, plistlib.InvalidFileException)
if hasattr(plistlib, "InvalidFileException")
else ExpatError
)

def __init__(self, **kwargs):
self.entries = []
self._deleted_entries = []
super().__init__(**kwargs)

def open(self):
filenames = [os.path.join(self.config['journal'], "entries", f) for f in os.listdir(os.path.join(self.config['journal'], "entries"))]
filenames = [
os.path.join(self.config["journal"], "entries", f)
for f in os.listdir(os.path.join(self.config["journal"], "entries"))
]
filenames = []
for root, dirnames, f in os.walk(self.config['journal']):
for filename in fnmatch.filter(f, '*.doentry'):
for root, dirnames, f in os.walk(self.config["journal"]):
for filename in fnmatch.filter(f, "*.doentry"):
filenames.append(os.path.join(root, filename))
self.entries = []
for filename in filenames:
with open(filename, 'rb') as plist_entry:
with open(filename, "rb") as plist_entry:
try:
dict_entry = plistlib.readPlist(plist_entry)
except self.PLIST_EXCEPTIONS:
pass
else:
try:
timezone = pytz.timezone(dict_entry['Time Zone'])
timezone = pytz.timezone(dict_entry["Time Zone"])
except (KeyError, pytz.exceptions.UnknownTimeZoneError):
timezone = tzlocal.get_localzone()
date = dict_entry['Creation Date']
date = dict_entry["Creation Date"]
date = date + timezone.utcoffset(date, is_dst=False)
entry = Entry.Entry(self, date, text=dict_entry['Entry Text'], starred=dict_entry["Starred"])
entry = Entry.Entry(
self,
date,
text=dict_entry["Entry Text"],
starred=dict_entry["Starred"],
)
entry.uuid = dict_entry["UUID"]
entry._tags = [self.config['tagsymbols'][0] + tag.lower() for tag in dict_entry.get("Tags", [])]
entry._tags = [
self.config["tagsymbols"][0] + tag.lower()
for tag in dict_entry.get("Tags", [])
]

self.entries.append(entry)
self.sort()
Expand All @@ -58,24 +73,33 @@ def write(self):
"""Writes only the entries that have been modified into plist files."""
for entry in self.entries:
if entry.modified:
utc_time = datetime.utcfromtimestamp(time.mktime(entry.date.timetuple()))
utc_time = datetime.utcfromtimestamp(
time.mktime(entry.date.timetuple())
)

if not hasattr(entry, "uuid"):
entry.uuid = uuid.uuid1().hex

filename = os.path.join(self.config['journal'], "entries", entry.uuid.upper() + ".doentry")

filename = os.path.join(
self.config["journal"], "entries", entry.uuid.upper() + ".doentry"
)

entry_plist = {
'Creation Date': utc_time,
'Starred': entry.starred if hasattr(entry, 'starred') else False,
'Entry Text': entry.title + "\n" + entry.body,
'Time Zone': str(tzlocal.get_localzone()),
'UUID': entry.uuid.upper(),
'Tags': [tag.strip(self.config['tagsymbols']).replace("_", " ") for tag in entry.tags]
"Creation Date": utc_time,
"Starred": entry.starred if hasattr(entry, "starred") else False,
"Entry Text": entry.title + "\n" + entry.body,
"Time Zone": str(tzlocal.get_localzone()),
"UUID": entry.uuid.upper(),
"Tags": [
tag.strip(self.config["tagsymbols"]).replace("_", " ")
for tag in entry.tags
],
}
plistlib.writePlist(entry_plist, filename)
for entry in self._deleted_entries:
filename = os.path.join(self.config['journal'], "entries", entry.uuid + ".doentry")
filename = os.path.join(
self.config["journal"], "entries", entry.uuid + ".doentry"
)
os.remove(filename)

def editable_str(self):
Expand Down Expand Up @@ -113,7 +137,7 @@ def parse_editable_str(self, edited):
if line.endswith("*"):
current_entry.starred = True
line = line[:-1]
current_entry.title = line[len(date_blob) - 1:]
current_entry.title = line[len(date_blob) - 1 :]
current_entry.date = new_date
elif current_entry:
current_entry.body += line + "\n"
Expand Down

0 comments on commit 717078b

Please sign in to comment.