diff --git a/TODO.todo b/TODO.todo index a6483f4..1473de3 100644 --- a/TODO.todo +++ b/TODO.todo @@ -1,5 +1,7 @@ Priority: ✔ Document the python/logging/typing in Trilium @done(21-10-25 14:33) + ☐ Update typing annotations to include generics instead + https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes ☐ Write the tests ☐ Docstrings @@ -8,7 +10,7 @@ Functionality: Tests: ☐ Write tests! @2d - Use coverage as going along to make sure all bases are covered in the testing + Use coverage as going along to make sure all bases are covered in the testing VSCode: ☐ Look at @@ -26,7 +28,7 @@ Logging: ☐ ~/tembo/logs ☐ Document how to overwrite these with ENV vars ☐ have a git repo with all the above already configured and walk user through - clone the repo, delete .git, git init, configure and add git origin + clone the repo, delete .git, git init, configure and add git origin Archive: ✔ Go through code TODOs @done(21-10-25 05:52) @project(Priority) diff --git a/tembo/journal/pages.py b/tembo/journal/pages.py index 8fbf21f..96f5a4a 100644 --- a/tembo/journal/pages.py +++ b/tembo/journal/pages.py @@ -3,7 +3,7 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod import pathlib import re -from typing import Tuple +from typing import Collection import jinja2 from jinja2.exceptions import TemplateNotFound @@ -21,7 +21,7 @@ class PageCreator: filename: str, extension: str, name: str, - user_input: Tuple[str, ...] | Tuple[()], + user_input: Collection[str], template_filename: str | None = None, ) -> Page: raise NotImplementedError @@ -80,8 +80,8 @@ class ScopedPageCreator(PageCreator): Attributes: base_path (str): base path of tembo. page_path (str): path of the page relative to the base path. - filename (str): filename relative to the page path - extension (str): extension of file + filename (str): filename relative to the page path. + extension (str): extension of file. """ def __init__(self) -> None: @@ -98,7 +98,7 @@ class ScopedPageCreator(PageCreator): filename: str, extension: str, name: str, - user_input: Tuple[str, ...] | Tuple[()], + user_input: Collection[str], template_filename: str | None = None, ) -> Page: self.base_path = base_path @@ -141,7 +141,7 @@ class ScopedPageCreator(PageCreator): all_input_tokens.extend(re.findall(r"(\{input\d*\})", tokenified_string)) return sorted(all_input_tokens) - def _verify_input_tokens(self, user_input: Tuple[str, ...] | Tuple[()]) -> None: + def _verify_input_tokens(self, user_input: Collection[str]) -> None: if len(self._all_input_tokens) != len(user_input): tembo.logger.critical( "Your tembo.config/template specifies %s input tokens, you gave %s", @@ -160,7 +160,7 @@ class ScopedPageCreator(PageCreator): def _substitute_tokens( self, tokenified_string: str, - user_input: Tuple[str, ...] | Tuple[()], + user_input: Collection[str], name: str, ) -> str: """For a tokened string, substitute input, name and date tokens.""" @@ -174,7 +174,7 @@ class ScopedPageCreator(PageCreator): def __substitute_input_tokens( self, tokenified_string: str, - user_input: Tuple[str, ...] | Tuple[()], + user_input: Collection[str], ) -> str: for input_value, extracted_token in zip(user_input, self._all_input_tokens): # REVIEW: test this for spaces in the filename/input token @@ -185,7 +185,8 @@ class ScopedPageCreator(PageCreator): @staticmethod def __substitute_name_tokens(tokenified_string: str, name: str) -> str: - # find any {name} tokens and substitute for the name value + """Find any `{name}` tokens and substitute for the name value.""" + name_extraction = re.findall(r"(\{name\})", tokenified_string) for extracted_input in name_extraction: tokenified_string = tokenified_string.replace(extracted_input, name) @@ -220,9 +221,20 @@ class Page(metaclass=ABCMeta): class ScopedPage(Page): - """A Page that uses substitute tokens.""" + """A page that uses substitute tokens. + + Attributes: + path (pathlib.Path): a `Path` object of the page's filepath. + page_content (str): the content of the page from the template. + """ def __init__(self, path: pathlib.Path, page_content: str) -> None: + """Create a scoped page object. + + Args: + path (pathlib.Path): a `pathlib.Path` object of the page's filepath. + page_content (str): the content of the page from the template. + """ self.path = path self.page_content = page_content @@ -230,6 +242,21 @@ class ScopedPage(Page): return f"ScopedPage({self.path})" def save_to_disk(self, dry_run: bool = False) -> None: + """Save the scoped page to disk and write the `page_content`. + + If the page already exists a message will be logged to stdout and no file + will be saved. + + If `dry_run=True` a message will be logged to stdout and no file will be saved. + + Args: + dry_run (bool, optional): If `True` will log the `path` to stdout and not + save the page to disk. Defaults to False. + + Raises: + SystemExit: Exit code 0 if dry run is `True`, page is successfully saved + or if page already exists. + """ if dry_run: tembo.logger.info("%s will be created", self.path) raise SystemExit(0)