diff --git a/TODO.todo b/TODO.todo index da7030b..8b543aa 100644 --- a/TODO.todo +++ b/TODO.todo @@ -25,6 +25,7 @@ Documentation: ☐ Document using datadir with a module rather than a shared one. Link to tembo as an example. + ☐ Can prospector ignore tests dir? document this in the gist if so Functionality: ✔ Move any `tembo.CONFIG` calls out of `pages.py` and ensure these are passed in from the cli. @done(21-10-28 19:44) @@ -32,9 +33,9 @@ Functionality: ✔ Make example optional @done(21-10-29 00:15) ✔ Add the `--example` output to the miscounted token message so the user knows the correct command to use. @done(21-10-29 00:15) ✔ Page options dataclass @done(21-10-28 20:09) + ☐ Make user_input optional @important ☐ Replace loggers with `click.echo` for command outputs. Keep logging messages for actual logging messages? - ☐ Look at `_convert_to_path()` and see if it can be rewritten to make it clearer when there isn't a base path. - Currently checks to see if base_path is not None but this is never the case as a string must be passed in and if there isn't a base_path we pass in an empty string. + ✔ Look at `_convert_to_path()` and see if it can be rewritten to make it clearer when there isn't a base path. @done(21-10-30 02:14) ☐ Replace scoped page creator inputs so that the whole class uses the options dict rather than the variables passed around. ☐ Use the python runner Duty diff --git a/dev/notes/test.md b/dev/notes/test.md index 1c065d0..607a988 100644 --- a/dev/notes/test.md +++ b/dev/notes/test.md @@ -4,6 +4,7 @@ optional: - template_path - example - template_filename +- user_input required: - base_path @@ -11,20 +12,15 @@ required: - filename - extension - name -- user_input - should be optional - - - -- page with a template -- page without a template -- page using date tokens -- page using input tokens -- page using name tokens +- page using/not using input tokens +- page with/without a template - user input does not match number of input tokens +- user input is None +- the given base path does not exist +- page using/not using date tokens +- page using/not using name tokens - - -- user input does match number of input tokensE +- path/page filenames can contain spaces and they are converted diff --git a/tembo/journal/pages.py b/tembo/journal/pages.py index d9f3ea6..8562d9d 100644 --- a/tembo/journal/pages.py +++ b/tembo/journal/pages.py @@ -13,14 +13,29 @@ from jinja2.exceptions import TemplateNotFound import tembo +# TODO: flesh this out with details for the optional args @dataclass class PageCreatorOptions: + """Options dataclass to create a Page. + + Attributes: + base_path (str): + page_path (str): + filename (str): + extension (str): + name (str): + user_input (Collection[str] | None, optional): + example (str | None, optional): + template_filename (str | None, optional): + template_path (str | None, optional): + """ + base_path: str page_path: str filename: str extension: str name: str - user_input: Collection[str] + user_input: Collection[str] | None = None example: str | None = None template_filename: str | None = None template_path: str | None = None @@ -92,51 +107,48 @@ class ScopedPageCreator(PageCreator): """ def __init__(self) -> None: - self.base_path = "" - self.page_path = "" - self.filename = "" - self.extension = "" + # self.base_path = "" + # self.page_path = "" + # self.filename = "" + # self.extension = "" self._all_input_tokens: list[str] = [] + self.options: PageCreatorOptions def create_page(self, options: PageCreatorOptions) -> Page: - self.base_path = options.base_path - self.page_path = options.page_path - self.filename = options.filename - self.extension = options.extension + self.options = options - # verify the user input length matches the number of input tokens in the - # tembo config/templates self._all_input_tokens = self._get_input_tokens( options.template_filename, options.template_path ) self._verify_input_tokens(options.user_input, options.example) - # get the path of the scoped page path = self._convert_to_path( - self.base_path, self.page_path, self.filename, self.extension + self.options.base_path, + self.options.page_path, + self.options.filename, + self.options.extension, ) - - # substitute tokens in the filepath path = pathlib.Path( self._substitute_tokens(str(path), options.user_input, options.name) ) - # get the template file template_contents = self._get_template_contents( options.template_filename, options.template_path ) - # substitute tokens in template_contents if options.template_filename is not None: template_contents = self._substitute_tokens( template_contents, options.user_input, options.name ) + return ScopedPage(path, template_contents) def _get_template_contents( self, template_filename: str | None, template_path: str | None ) -> str: return ( - self._load_template(self.base_path, template_filename, template_path) + self._load_template( + self.options.base_path, template_filename, template_path + ) if template_filename is not None else "" ) @@ -146,7 +158,10 @@ class ScopedPageCreator(PageCreator): ) -> list[str]: path = str( pathlib.Path( - self.base_path, self.page_path, self.filename, self.extension + self.options.base_path, + self.options.page_path, + self.options.filename, + self.options.extension, ).expanduser() ) template_contents = self._get_template_contents( @@ -159,8 +174,23 @@ class ScopedPageCreator(PageCreator): return sorted(all_input_tokens) def _verify_input_tokens( - self, user_input: Collection[str], example: str | None + self, user_input: Collection[str] | None, example: str | None ) -> None: + if len(self._all_input_tokens) > 0 and user_input is None: + if example is not None: + tembo.logger.critical( + "Your tembo.config/template specifies %s input tokens, you gave 0. Example command: %s", + len(self._all_input_tokens), + example, + ) + else: + tembo.logger.critical( + "Your tembo.config/template specifies %s input tokens, you gave 0.", + len(self._all_input_tokens), + ) + raise SystemExit(1) + if user_input is None: + return if len(self._all_input_tokens) != len(user_input): if example is not None: tembo.logger.critical( @@ -176,11 +206,12 @@ class ScopedPageCreator(PageCreator): len(user_input), ) raise SystemExit(1) + return def _substitute_tokens( self, tokenified_string: str, - user_input: Collection[str], + user_input: Collection[str] | None, name: str, ) -> str: """For a tokened string, substitute input, name and date tokens.""" @@ -194,13 +225,13 @@ class ScopedPageCreator(PageCreator): def __substitute_input_tokens( self, tokenified_string: str, - user_input: Collection[str], + user_input: Collection[str] | None, ) -> str: - for input_value, extracted_token in zip(user_input, self._all_input_tokens): - # REVIEW: test this for spaces in the filename/input token - tokenified_string = tokenified_string.replace( - extracted_token, input_value.replace(" ", "_") - ) + if user_input is not None: + for input_value, extracted_token in zip(user_input, self._all_input_tokens): + tokenified_string = tokenified_string.replace( + extracted_token, input_value.replace(" ", "_") + ) return tokenified_string @staticmethod