Refactor flow for easier access to some files (avoid things like jrnl.Journal.Journal and jrnl.jrnl co-existing) (#1662)

* run format

* rename cli.py to main.py

* rename jrnl.py to controller.py

* move journal class files into journals dir

* rename start -> run in controller.py
This commit is contained in:
Jonathan Wren 2023-01-14 14:42:29 -08:00 committed by GitHub
parent 7be67accc1
commit fff05eb646
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 84 additions and 69 deletions

View file

@ -3,7 +3,7 @@
import sys import sys
from jrnl.cli import cli from jrnl.main import run
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(cli()) sys.exit(run())

View file

@ -11,7 +11,7 @@ import colorama
from jrnl.os_compat import on_windows from jrnl.os_compat import on_windows
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
if on_windows(): if on_windows():
colorama.init() colorama.init()

View file

@ -69,7 +69,7 @@ def postconfig_list(args: argparse.Namespace, config: dict, **_) -> int:
@cmd_requires_valid_journal_name @cmd_requires_valid_journal_name
def postconfig_import(args: argparse.Namespace, config: dict, **_) -> int: def postconfig_import(args: argparse.Namespace, config: dict, **_) -> int:
from jrnl.Journal import open_journal from jrnl.journals import open_journal
from jrnl.plugins import get_importer from jrnl.plugins import get_importer
# Requires opening the journal # Requires opening the journal
@ -90,7 +90,7 @@ def postconfig_encrypt(
""" """
from jrnl.config import update_config from jrnl.config import update_config
from jrnl.install import save_config from jrnl.install import save_config
from jrnl.Journal import open_journal from jrnl.journals import open_journal
# Open the journal # Open the journal
journal = open_journal(args.journal_name, config) journal = open_journal(args.journal_name, config)
@ -145,7 +145,7 @@ def postconfig_decrypt(
"""Decrypts into new file. If filename is not set, we encrypt the journal file itself.""" """Decrypts into new file. If filename is not set, we encrypt the journal file itself."""
from jrnl.config import update_config from jrnl.config import update_config
from jrnl.install import save_config from jrnl.install import save_config
from jrnl.Journal import open_journal from jrnl.journals import open_journal
journal = open_journal(args.journal_name, config) journal = open_journal(args.journal_name, config)

View file

@ -15,8 +15,8 @@ from jrnl.config import scope_config
from jrnl.editor import get_text_from_editor from jrnl.editor import get_text_from_editor
from jrnl.editor import get_text_from_stdin from jrnl.editor import get_text_from_stdin
from jrnl.exception import JrnlException from jrnl.exception import JrnlException
from jrnl.Journal import Journal from jrnl.journals import Journal
from jrnl.Journal import open_journal from jrnl.journals import open_journal
from jrnl.messages import Message from jrnl.messages import Message
from jrnl.messages import MsgStyle from jrnl.messages import MsgStyle
from jrnl.messages import MsgText from jrnl.messages import MsgText
@ -28,7 +28,7 @@ from jrnl.path import expand_path
if TYPE_CHECKING: if TYPE_CHECKING:
from argparse import Namespace from argparse import Namespace
from jrnl.Entry import Entry from jrnl.journals import Entry
def run(args: "Namespace"): def run(args: "Namespace"):

View file

@ -42,7 +42,7 @@ def upgrade_config(config_data: dict, alt_config_path: str | None = None) -> Non
for key in missing_keys: for key in missing_keys:
config_data[key] = default_config[key] config_data[key] = default_config[key]
different_version = (config_data["version"] != __version__) different_version = config_data["version"] != __version__
if different_version: if different_version:
config_data["version"] = __version__ config_data["version"] = __version__

View file

@ -17,13 +17,14 @@ from xml.parsers.expat import ExpatError
import tzlocal import tzlocal
from jrnl import Entry
from jrnl import Journal
from jrnl import __title__ from jrnl import __title__
from jrnl import __version__ from jrnl import __version__
from .Entry import Entry
from .Journal import Journal
class DayOne(Journal.Journal):
class DayOne(Journal):
"""A special Journal handling DayOne files""" """A special Journal handling DayOne files"""
# InvalidFileException was added to plistlib in Python3.4 # InvalidFileException was added to plistlib in Python3.4
@ -63,7 +64,7 @@ class DayOne(Journal.Journal):
if timezone.key != "UTC": if timezone.key != "UTC":
date = date.replace(fold=1) + timezone.utcoffset(date) date = date.replace(fold=1) + timezone.utcoffset(date)
entry = Entry.Entry( entry = Entry(
self, self,
date, date,
text=dict_entry["Entry Text"], text=dict_entry["Entry Text"],
@ -74,7 +75,8 @@ class DayOne(Journal.Journal):
self.config["tagsymbols"][0] + tag.lower() self.config["tagsymbols"][0] + tag.lower()
for tag in dict_entry.get("Tags", []) for tag in dict_entry.get("Tags", [])
] ]
if entry._tags: entry._tags.sort() if entry._tags:
entry._tags.sort()
"""Extended DayOne attributes""" """Extended DayOne attributes"""
# just ignore it if the keys don't exist # just ignore it if the keys don't exist
@ -196,7 +198,8 @@ class DayOne(Journal.Journal):
for entry in entries_from_editor: for entry in entries_from_editor:
entry = self._get_and_remove_uuid_from_entry(entry) entry = self._get_and_remove_uuid_from_entry(entry)
if entry._tags: entry._tags.sort() if entry._tags:
entry._tags.sort()
# Remove deleted entries # Remove deleted entries
edited_uuids = [e.uuid for e in entries_from_editor] edited_uuids = [e.uuid for e in entries_from_editor]
@ -207,7 +210,9 @@ class DayOne(Journal.Journal):
for old_entry in self.entries: for old_entry in self.entries:
if entry.uuid == old_entry.uuid: if entry.uuid == old_entry.uuid:
if old_entry._tags: if old_entry._tags:
tags_not_in_body = [tag for tag in old_entry._tags if(tag not in entry._body)] tags_not_in_body = [
tag for tag in old_entry._tags if (tag not in entry._body)
]
if tags_not_in_body: if tags_not_in_body:
entry._tags.extend(tags_not_in_body.sort()) entry._tags.extend(tags_not_in_body.sort())
self._update_old_entry(old_entry, entry) self._update_old_entry(old_entry, entry)

View file

@ -9,8 +9,8 @@ from typing import TYPE_CHECKING
import ansiwrap import ansiwrap
from .color import colorize from jrnl.color import colorize
from .color import highlight_tags_with_background_color from jrnl.color import highlight_tags_with_background_color
if TYPE_CHECKING: if TYPE_CHECKING:
from .Journal import Journal from .Journal import Journal

View file

@ -6,11 +6,12 @@ import fnmatch
import os import os
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from jrnl import Journal
from jrnl import time from jrnl import time
from .Journal import Journal
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
def get_files(journal_config: str) -> list[str]: def get_files(journal_config: str) -> list[str]:
@ -22,7 +23,7 @@ def get_files(journal_config: str) -> list[str]:
return filenames return filenames
class Folder(Journal.Journal): class Folder(Journal):
"""A Journal handling multiple files in a folder""" """A Journal handling multiple files in a folder"""
def __init__(self, name: str = "default", **kwargs): def __init__(self, name: str = "default", **kwargs):

View file

@ -6,7 +6,6 @@ import logging
import os import os
import re import re
from jrnl import Entry
from jrnl import time from jrnl import time
from jrnl.config import validate_journal_name from jrnl.config import validate_journal_name
from jrnl.encryption import determine_encryption_method from jrnl.encryption import determine_encryption_method
@ -17,6 +16,8 @@ from jrnl.output import print_msg
from jrnl.path import expand_path from jrnl.path import expand_path
from jrnl.prompt import yesno from jrnl.prompt import yesno
from .Entry import Entry
class Tag: class Tag:
def __init__(self, name, count=0): def __init__(self, name, count=0):
@ -184,11 +185,11 @@ class Journal:
if entries: if entries:
entries[-1].text = journal_txt[last_entry_pos : match.start()] entries[-1].text = journal_txt[last_entry_pos : match.start()]
last_entry_pos = match.end() last_entry_pos = match.end()
entries.append(Entry.Entry(self, date=new_date)) entries.append(Entry(self, date=new_date))
# If no entries were found, treat all the existing text as an entry made now # If no entries were found, treat all the existing text as an entry made now
if not entries: if not entries:
entries.append(Entry.Entry(self, date=time.parse("now"))) entries.append(Entry(self, date=time.parse("now")))
# Fill in the text of the last entry # Fill in the text of the last entry
entries[-1].text = journal_txt[last_entry_pos:] entries[-1].text = journal_txt[last_entry_pos:]
@ -354,7 +355,7 @@ class Journal:
) )
if not date: # Still nothing? Meh, just live in the moment. if not date: # Still nothing? Meh, just live in the moment.
date = time.parse("now") date = time.parse("now")
entry = Entry.Entry(self, date, raw, starred=starred) entry = Entry(self, date, raw, starred=starred)
entry.modified = True entry.modified = True
self.entries.append(entry) self.entries.append(entry)
if sort: if sort:
@ -410,7 +411,7 @@ class LegacyJournal(Journal):
else: else:
starred = False starred = False
current_entry = Entry.Entry( current_entry = Entry(
self, date=new_date, text=line[date_length + 1 :], starred=starred self, date=new_date, text=line[date_length + 1 :], starred=starred
) )
except ValueError: except ValueError:
@ -455,21 +456,21 @@ def open_journal(journal_name: str, config: dict, legacy: bool = False) -> Journ
if config["journal"].strip("/").endswith(".dayone") or "entries" in os.listdir( if config["journal"].strip("/").endswith(".dayone") or "entries" in os.listdir(
config["journal"] config["journal"]
): ):
from jrnl import DayOneJournal from jrnl.journals import DayOne
return DayOneJournal.DayOne(**config).open() return DayOne(**config).open()
else: else:
from jrnl import FolderJournal from jrnl.journals import Folder
return FolderJournal.Folder(journal_name, **config).open() return Folder(journal_name, **config).open()
if not config["encrypt"]: if not config["encrypt"]:
if legacy: if legacy:
return LegacyJournal(journal_name, **config).open() return LegacyJournal(journal_name, **config).open()
if config["journal"].endswith(os.sep): if config["journal"].endswith(os.sep):
from jrnl import FolderJournal from jrnl.journals import Folder
return FolderJournal.Folder(journal_name, **config).open() return Folder(journal_name, **config).open()
return Journal(journal_name, **config).open() return Journal(journal_name, **config).open()
if legacy: if legacy:

View file

@ -0,0 +1,5 @@
from .DayOneJournal import DayOne
from .Entry import Entry
from .FolderJournal import Folder
from .Journal import Journal
from .Journal import open_journal

View file

@ -7,9 +7,9 @@ import traceback
from rich.logging import RichHandler from rich.logging import RichHandler
from jrnl import controller
from jrnl.args import parse_args from jrnl.args import parse_args
from jrnl.exception import JrnlException from jrnl.exception import JrnlException
from jrnl.jrnl import run
from jrnl.messages import Message from jrnl.messages import Message
from jrnl.messages import MsgStyle from jrnl.messages import MsgStyle
from jrnl.messages import MsgText from jrnl.messages import MsgText
@ -32,7 +32,7 @@ def configure_logger(debug: bool = False) -> None:
logging.debug("Logging start") logging.debug("Logging start")
def cli(manual_args: list[str] | None = None) -> int: def run(manual_args: list[str] | None = None) -> int:
try: try:
if manual_args is None: if manual_args is None:
manual_args = sys.argv[1:] manual_args = sys.argv[1:]
@ -41,7 +41,7 @@ def cli(manual_args: list[str] | None = None) -> int:
configure_logger(args.debug) configure_logger(args.debug)
logging.debug("Parsed args:\n%s", args) logging.debug("Parsed args:\n%s", args)
status_code = run(args) status_code = controller.run(args)
except JrnlException as e: except JrnlException as e:
status_code = 1 status_code = 1

View file

@ -7,8 +7,8 @@ from typing import TYPE_CHECKING
from jrnl.plugins.text_exporter import TextExporter from jrnl.plugins.text_exporter import TextExporter
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class DatesExporter(TextExporter): class DatesExporter(TextExporter):

View file

@ -13,8 +13,8 @@ from jrnl.messages import MsgText
from jrnl.plugins.text_exporter import TextExporter from jrnl.plugins.text_exporter import TextExporter
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class FancyExporter(TextExporter): class FancyExporter(TextExporter):

View file

@ -11,7 +11,7 @@ from jrnl.messages import MsgText
from jrnl.output import print_msg from jrnl.output import print_msg
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Journal import Journal from jrnl.journals import Journal
class JRNLImporter: class JRNLImporter:

View file

@ -8,8 +8,8 @@ from jrnl.plugins.text_exporter import TextExporter
from jrnl.plugins.util import get_tags_count from jrnl.plugins.util import get_tags_count
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class JSONExporter(TextExporter): class JSONExporter(TextExporter):

View file

@ -12,8 +12,8 @@ from jrnl.output import print_msg
from jrnl.plugins.text_exporter import TextExporter from jrnl.plugins.text_exporter import TextExporter
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class MarkdownExporter(TextExporter): class MarkdownExporter(TextExporter):

View file

@ -7,8 +7,8 @@ from jrnl.plugins.text_exporter import TextExporter
from jrnl.plugins.util import get_tags_count from jrnl.plugins.util import get_tags_count
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class TagExporter(TextExporter): class TagExporter(TextExporter):

View file

@ -13,8 +13,8 @@ from jrnl.messages import MsgText
from jrnl.output import print_msg from jrnl.output import print_msg
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class TextExporter: class TextExporter:

View file

@ -4,7 +4,7 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Journal import Journal from jrnl.journals import Journal
def get_tags_count(journal: "Journal") -> set[tuple[int, str]]: def get_tags_count(journal: "Journal") -> set[tuple[int, str]]:

View file

@ -8,8 +8,8 @@ from jrnl.plugins.json_exporter import JSONExporter
from jrnl.plugins.util import get_tags_count from jrnl.plugins.util import get_tags_count
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class XMLExporter(JSONExporter): class XMLExporter(JSONExporter):

View file

@ -13,8 +13,8 @@ from jrnl.output import print_msg
from jrnl.plugins.text_exporter import TextExporter from jrnl.plugins.text_exporter import TextExporter
if TYPE_CHECKING: if TYPE_CHECKING:
from jrnl.Entry import Entry from jrnl.journals import Entry
from jrnl.Journal import Journal from jrnl.journals import Journal
class YAMLExporter(TextExporter): class YAMLExporter(TextExporter):
@ -34,7 +34,7 @@ class YAMLExporter(TextExporter):
body = body_wrapper + entry.body body = body_wrapper + entry.body
tagsymbols = entry.journal.config["tagsymbols"] tagsymbols = entry.journal.config["tagsymbols"]
# see also Entry.Entry.rag_regex # see also Entry.rag_regex
multi_tag_regex = re.compile(rf"(?u)^\s*([{tagsymbols}][-+*#/\w]+\s*)+$") multi_tag_regex = re.compile(rf"(?u)^\s*([{tagsymbols}][-+*#/\w]+\s*)+$")
"""Increase heading levels in body text""" """Increase heading levels in body text"""

View file

@ -4,12 +4,13 @@
import logging import logging
import os import os
from jrnl import Journal
from jrnl import __version__ from jrnl import __version__
from jrnl.config import is_config_json from jrnl.config import is_config_json
from jrnl.config import load_config from jrnl.config import load_config
from jrnl.config import scope_config from jrnl.config import scope_config
from jrnl.exception import JrnlException from jrnl.exception import JrnlException
from jrnl.journals import Journal
from jrnl.journals import open_journal
from jrnl.messages import Message from jrnl.messages import Message
from jrnl.messages import MsgStyle from jrnl.messages import MsgStyle
from jrnl.messages import MsgText from jrnl.messages import MsgText
@ -129,14 +130,14 @@ def upgrade_jrnl(config_path: str) -> None:
) )
backup(path, binary=True) backup(path, binary=True)
old_journal = Journal.open_journal( old_journal = open_journal(
journal_name, scope_config(config, journal_name), legacy=True journal_name, scope_config(config, journal_name), legacy=True
) )
logging.debug(f"Clearing encryption method for '{journal_name}' journal") logging.debug(f"Clearing encryption method for '{journal_name}' journal")
# Update the encryption method # Update the encryption method
new_journal = Journal.Journal.from_journal(old_journal) new_journal = Journal.from_journal(old_journal)
new_journal.config["encrypt"] = "jrnlv2" new_journal.config["encrypt"] = "jrnlv2"
new_journal._get_encryption_method() new_journal._get_encryption_method()
# Copy over password (jrnlv1 only supported password-based encryption) # Copy over password (jrnlv1 only supported password-based encryption)
@ -156,10 +157,10 @@ def upgrade_jrnl(config_path: str) -> None:
) )
backup(path) backup(path)
old_journal = Journal.open_journal( old_journal = open_journal(
journal_name, scope_config(config, journal_name), legacy=True journal_name, scope_config(config, journal_name), legacy=True
) )
all_journals.append(Journal.Journal.from_journal(old_journal)) all_journals.append(Journal.from_journal(old_journal))
# loop through lists to validate # loop through lists to validate
failed_journals = [j for j in all_journals if not j.validate_parsing()] failed_journals = [j for j in all_journals if not j.validate_parsing()]

View file

@ -63,7 +63,7 @@ tox = "*"
xmltodict = "*" xmltodict = "*"
[tool.poetry.scripts] [tool.poetry.scripts]
jrnl = 'jrnl.cli:cli' jrnl = 'jrnl.main:run'
[tool.poe.tasks] [tool.poe.tasks]
docs-check.default_item_type = "script" docs-check.default_item_type = "script"
@ -157,6 +157,8 @@ pycodestyle = [
"flake8-*" = ["+*"] "flake8-*" = ["+*"]
flake8-black = ["-BLK901"] flake8-black = ["-BLK901"]
[tool.flakeheaven.exceptions."jrnl/journals/__init__.py"]
pyflakes = ["-F401"]
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]

View file

@ -144,7 +144,7 @@ def mock_overrides(config_in_memory):
return { return {
"overrides": lambda: patch( "overrides": lambda: patch(
"jrnl.jrnl.apply_overrides", side_effect=my_overrides "jrnl.controller.apply_overrides", side_effect=my_overrides
) )
} }

View file

@ -8,7 +8,7 @@ from pytest_bdd import when
from pytest_bdd.parsers import parse from pytest_bdd.parsers import parse
from pytest_bdd.parsers import re from pytest_bdd.parsers import re
from jrnl.cli import cli from jrnl.main import run
@when(parse('we change directory to "{directory_name}"')) @when(parse('we change directory to "{directory_name}"'))
@ -44,7 +44,7 @@ def we_run_jrnl(cli_run, capsys, keyring):
mocks[id] = stack.enter_context(factories[id]()) mocks[id] = stack.enter_context(factories[id]())
try: try:
cli_run["status"] = cli() or 0 cli_run["status"] = run() or 0
except StopIteration: except StopIteration:
# This happens when input is expected, but don't have any input left # This happens when input is expected, but don't have any input left
pass pass

View file

@ -9,7 +9,7 @@ import pytest
import jrnl import jrnl
from jrnl.args import parse_args from jrnl.args import parse_args
from jrnl.jrnl import _display_search_results from jrnl.controller import _display_search_results
@pytest.fixture @pytest.fixture
@ -19,10 +19,10 @@ def random_string():
@pytest.mark.parametrize("export_format", ["pretty", "short"]) @pytest.mark.parametrize("export_format", ["pretty", "short"])
@mock.patch("builtins.print") @mock.patch("builtins.print")
@mock.patch("jrnl.Journal.Journal.pprint") @mock.patch("jrnl.controller.Journal.pprint")
def test_display_search_results_pretty_short(mock_pprint, mock_print, export_format): def test_display_search_results_pretty_short(mock_pprint, mock_print, export_format):
mock_args = parse_args(["--format", export_format]) mock_args = parse_args(["--format", export_format])
test_journal = mock.Mock(wraps=jrnl.Journal.Journal) test_journal = mock.Mock(wraps=jrnl.journals.Journal)
_display_search_results(mock_args, test_journal) _display_search_results(mock_args, test_journal)
@ -40,7 +40,7 @@ def test_display_search_results_builtin_plugins(
test_filename = random_string test_filename = random_string
mock_args = parse_args(["--format", export_format, "--file", test_filename]) mock_args = parse_args(["--format", export_format, "--file", test_filename])
test_journal = mock.Mock(wraps=jrnl.Journal.Journal) test_journal = mock.Mock(wraps=jrnl.journals.Journal)
mock_export = mock.Mock() mock_export = mock.Mock()
mock_exporter.return_value.export = mock_export mock_exporter.return_value.export = mock_export