adding options class and tidying up

This commit is contained in:
2021-10-28 20:11:27 +01:00
parent a0afe62879
commit 4077ec1760
4 changed files with 101 additions and 68 deletions

View File

@@ -5,24 +5,41 @@ Priority:
☐ Write the tests
☐ test logs: <https://stackoverflow.com/questions/53125305/testing-logging-output-with-pytest>
document this
☐ Docstrings
Documentation:
Docstrings:
☐ Use Duty to write module docstrings
☐ Use Duty to add Class docstrings
☐ Document these in Trilium and rewrite the docstrings notes
☐ Add the comment on Reddit (artie buco?) about imports in a module
☐ Document using `__main__.py` and `cli.py`
Use Duty as an example
☐ Write documentation using `mkdocs`
☐ Look at how to use github actions
Use <https://github.com/pdm-project/pdm/tree/main/.github/workflows> for an example
☐ Build the docs using a github action.
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)
✔ Make `config scope` a dict in `cli.py`. @done(21-10-28 19:44)
☐ Add the `--example` output to the miscounted token message so the user knows the correct command to use.
✔ Page options dataclass @done(21-10-28 20:09)
☐ Replace loggers with `click.echo` for command outputs. Keep logging messages for actual logging messages?
☐ Use the python runner
☐ Use the python runner Duty
<https://github.com/pawamoy/duty>
☐ Run tests
☐ Update poetry
☐ Build docs
☐ Document using Duty
VSCode:
PyInstaller:
☐ Document build error: <https://github.com/pyenv/pyenv/issues/1095>
PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.8.11
☐ Freeze a click app: <https://stackoverflow.com/questions/45090083/freeze-a-program-created-with-pythons-click-pacage>
Tests:
☐ Write tests! @2d
Use coverage as going along to make sure all bases are covered in the testing
@@ -33,8 +50,6 @@ VSCode:
Logging:
Documentation:
☐ a
Tembo:
☐ Document creating new Tembo config
☐ ~/tembo needs creating

View File

@@ -1,9 +1,10 @@
import sys
import click
import tembo
from tembo.journal import pages
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
@@ -62,18 +63,19 @@ def new(scope, inputs, dry_run, example):
# get the scope information from the tembo config.yml
try:
config_scope = [
(
str(user_scope["name"]),
user_scope.get("example"),
str(user_scope["path"]),
str(user_scope["filename"]),
str(user_scope["extension"]),
user_scope.get("template_filename"),
)
config_scope = {
option: str(user_scope[option])
for option in [
"name",
"example",
"path",
"filename",
"extension",
"template_filename",
]
for user_scope in tembo.CONFIG.scopes
if user_scope["name"] == scope
]
}
except KeyError as key_error:
# raise error if any non optional keys are missing
tembo.logger.critical("Key %s not found in config.yml - exiting", key_error)
@@ -83,24 +85,26 @@ def new(scope, inputs, dry_run, example):
if example:
tembo.logger.info(
"Example for 'tembo new %s': %s",
config_scope[0][0],
config_scope[0][1]
config_scope["name"],
config_scope["example"]
if isinstance(config_scope[0][1], str)
else "No example in config.yml",
)
raise SystemExit(0)
# if the name is in the config.yml, create the scoped page
if _name_found:
scoped_page = pages.ScopedPageCreator().create_page(
base_path=str(tembo.CONFIG.base_path),
page_path=config_scope[0][2],
filename=config_scope[0][3],
extension=config_scope[0][4],
name=config_scope[0][0],
page_creator_options = pages.PageCreatorOptions(
base_path=tembo.CONFIG.base_path,
page_path=config_scope["path"],
filename=config_scope["filename"],
extension=config_scope["extension"],
name=config_scope["name"],
user_input=inputs,
template_filename=config_scope[0][5],
template_filename=config_scope["template_filename"],
template_path=tembo.CONFIG.template_path,
)
if _name_found:
scoped_page = pages.ScopedPageCreator().create_page(page_creator_options)
scoped_page.save_to_disk(dry_run=dry_run)
raise SystemExit(0)
if not _name_found and len(tembo.CONFIG.scopes) > 0:
@@ -121,5 +125,10 @@ run.add_command(list_all)
if __name__ == "__main__":
# new(["meeting", "robs presentation", "meeting on gcp"])
new(["meeting", "a", "b", "c", "d", "--example"])
new(["meeting", "a", "b", "c", "d"])
# new(["meeting", "robs presentation"])
# pyinstaller
# if getattr(sys, "frozen", False):
# run(sys.argv[1:])
# run(sys.argv[1:])

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from abc import ABCMeta, abstractmethod
from dataclasses import dataclass
import pathlib
import re
from typing import Collection
@@ -12,18 +13,21 @@ import pendulum
import tembo
@dataclass
class PageCreatorOptions:
base_path: str
page_path: str
filename: str
extension: str
name: str
user_input: Collection[str]
template_filename: str | None = None
template_path: str | None = None
class PageCreator:
@abstractmethod
def create_page(
self,
base_path: str,
page_path: str,
filename: str,
extension: str,
name: str,
user_input: Collection[str],
template_filename: str | None = None,
) -> Page:
def create_page(self, options: PageCreatorOptions) -> Page:
raise NotImplementedError
@staticmethod
@@ -50,17 +54,19 @@ class PageCreator:
# return path with a file
return path_to_file.with_suffix(f".{extension}")
def _load_template(self, base_path: str, template_filename: str) -> str:
def _load_template(
self, base_path: str, template_filename: str, template_path: str | None
) -> str:
# check for overriden template_path
if tembo.CONFIG.template_path is not None:
template_path = self._convert_to_path(
"", tembo.CONFIG.template_path, "", ""
)
if template_path is not None:
converted_template_path = self._convert_to_path("", template_path, "", "")
else:
# default template_path is base_path / .templates
template_path = self._convert_to_path(base_path, ".templates", "", "")
converted_template_path = self._convert_to_path(
base_path, ".templates", "", ""
)
# load the template folder
file_loader = jinja2.FileSystemLoader(template_path)
file_loader = jinja2.FileSystemLoader(converted_template_path)
env = jinja2.Environment(loader=file_loader, autoescape=True)
# load the template contents
try:
@@ -91,25 +97,18 @@ class ScopedPageCreator(PageCreator):
self.extension = ""
self._all_input_tokens: list[str] = []
def create_page(
self,
base_path: str,
page_path: str,
filename: str,
extension: str,
name: str,
user_input: Collection[str],
template_filename: str | None = None,
) -> Page:
self.base_path = base_path
self.page_path = page_path
self.filename = filename
self.extension = extension
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
# verify the user input length matches the number of input tokens in the
# tembo config/templates
self._all_input_tokens = self._get_input_tokens(template_filename)
self._verify_input_tokens(user_input)
self._all_input_tokens = self._get_input_tokens(
options.template_filename, options.template_path
)
self._verify_input_tokens(options.user_input)
# get the path of the scoped page
path = self._convert_to_path(
@@ -117,24 +116,32 @@ class ScopedPageCreator(PageCreator):
)
# substitute tokens in the filepath
path = pathlib.Path(self._substitute_tokens(str(path), user_input, name))
path = pathlib.Path(
self._substitute_tokens(str(path), options.user_input, options.name)
)
# get the template file
template_contents = self._get_template_contents(template_filename)
template_contents = self._get_template_contents(
options.template_filename, options.template_path
)
# substitute tokens in template_contents
if template_filename is not None:
if options.template_filename is not None:
template_contents = self._substitute_tokens(
template_contents, user_input, name
template_contents, options.user_input, options.name
)
return ScopedPage(path, template_contents)
def _get_input_tokens(self, template_filename: str | None) -> list[str]:
def _get_input_tokens(
self, template_filename: str | None, template_path: str | None
) -> list[str]:
path = str(
pathlib.Path(
self.base_path, self.page_path, self.filename, self.extension
).expanduser()
)
template_contents = self._get_template_contents(template_filename)
template_contents = self._get_template_contents(
template_filename, template_path
)
# get the input tokens from both the path and the template
all_input_tokens = []
for tokenified_string in (path, template_contents):
@@ -150,9 +157,11 @@ class ScopedPageCreator(PageCreator):
)
raise SystemExit(1)
def _get_template_contents(self, template_filename: str | None) -> str:
def _get_template_contents(
self, template_filename: str | None, template_path: str | None
) -> str:
return (
self._load_template(self.base_path, template_filename)
self._load_template(self.base_path, template_filename, template_path)
if template_filename is not None
else ""
)

View File