-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
185 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
bolton-clack ~= 0.3.1 | ||
bolton-logrus ~= 0.1.1 | ||
jinja2 | ||
vimala ~= 0.1.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
"""Clack config for zorg.""" | ||
|
||
from __future__ import annotations | ||
|
||
import itertools as it | ||
from pathlib import Path | ||
from typing import Any, Literal, Sequence | ||
|
||
import clack | ||
|
||
|
||
Command = Literal["edit"] | ||
|
||
|
||
class Config(clack.Config): | ||
"""Shared clack configuration class.""" | ||
|
||
command: Command | ||
|
||
zettel_dir: Path = Path.home() / "org" | ||
|
||
|
||
class EditConfig(Config): | ||
"""Clack config for the 'edit' command.""" | ||
|
||
command: Literal["edit"] | ||
|
||
day_log_template: str = "bujo_day_log_tmpl.zo" | ||
habit_template: str = "habit_tmpl.zo" | ||
done_template: str = "done_tmpl.zo" | ||
vim_commands: list[str] | ||
|
||
|
||
def clack_parser(argv: Sequence[str]) -> dict[str, Any]: | ||
"""Parser we pass to the `main_factory()` `parser` kwarg.""" | ||
# HACK: Make 'tui' the default sub-command. | ||
if not list(it.dropwhile(lambda x: x.startswith("-"), argv[1:])): | ||
argv = list(argv) + ["edit"] | ||
|
||
parser = clack.Parser(description="The zettel note manager of the future.") | ||
parser.add_argument( | ||
"-d", | ||
"--dir", | ||
dest="zettel_dir", | ||
type=Path, | ||
help="The directory where all of your notes are stored.", | ||
) | ||
|
||
new_command = clack.new_command_factory(parser) | ||
edit_parser = new_command("edit", help="Open day log in editor.") | ||
edit_parser.add_argument( | ||
"-D", | ||
"--day-log-template-name", | ||
help="Template used to generate day logs.", | ||
) | ||
edit_parser.add_argument( | ||
"-H", | ||
"--habit-template", | ||
help="Template used to generate habit trackers.", | ||
) | ||
edit_parser.add_argument( | ||
"-X", | ||
"--done-template", | ||
help="Template used to generate files for done todos.", | ||
) | ||
|
||
args = parser.parse_args(argv[1:]) | ||
kwargs = clack.filter_cli_args(args) | ||
|
||
_preprocess_template_name(kwargs, "day_log_template") | ||
_preprocess_template_name(kwargs, "habit_template") | ||
_preprocess_template_name(kwargs, "done_template") | ||
|
||
return kwargs | ||
|
||
|
||
def _preprocess_template_name(kwargs: dict[str, Any], key: str) -> None: | ||
if key in kwargs: | ||
kwargs[key] = kwargs[key] + "_tmpl.zo" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
"""Contains this project's clack runners.""" | ||
|
||
from __future__ import annotations | ||
|
||
import datetime as dt | ||
from pathlib import Path | ||
from typing import Iterable, Iterator, List | ||
|
||
from clack.types import ClackRunner | ||
import jinja2 | ||
from logrus import Logger | ||
import metaman | ||
import vimala | ||
|
||
from .config import EditConfig | ||
|
||
|
||
RUNNERS: List[ClackRunner] = [] | ||
runner = metaman.register_function_factory(RUNNERS) | ||
|
||
logger = Logger(__name__) | ||
|
||
|
||
@runner | ||
def run_edit(cfg: EditConfig) -> int: | ||
"""Runner for the 'edit' command.""" | ||
template_loader = jinja2.FileSystemLoader(searchpath=cfg.zettel_dir) | ||
template_env = jinja2.Environment(loader=template_loader) | ||
template = template_env.get_template(cfg.day_log_template) | ||
habit_template = template_env.get_template(cfg.habit_template) | ||
done_template = template_env.get_template(cfg.done_template) | ||
|
||
today = dt.datetime.now() | ||
yesterday = today - dt.timedelta(days=1) | ||
two_days_ago = today - dt.timedelta(days=2) | ||
tomorrow = today + dt.timedelta(days=1) | ||
|
||
day_log_vars = { | ||
"year": str(today.year), | ||
"month": f"{today.month:02d}", | ||
"day": f"{today.day:02d}", | ||
"weekday": today.strftime("%a"), | ||
"yesterday": yesterday.strftime("%Y%m%d"), | ||
"tomorrow": tomorrow.strftime("%Y%m%d"), | ||
} | ||
day_log_contents = template.render(day_log_vars) | ||
done_log_contents = done_template.render(day_log_vars) | ||
habit_tracker_contents = habit_template.render( | ||
year=str(yesterday.year), | ||
month=f"{yesterday.month:02d}", | ||
day=f"{yesterday.day:02d}", | ||
weekday=yesterday.strftime("%a"), | ||
day_before=two_days_ago.strftime("%Y%m%d"), | ||
day_after=today.strftime("%Y%m%d"), | ||
) | ||
|
||
day_log_path = _get_day_path(cfg.zettel_dir, today) | ||
if not day_log_path.exists(): | ||
day_log_path.write_text(day_log_contents) | ||
|
||
habit_tracker_path = _get_day_path( | ||
cfg.zettel_dir, yesterday, suffix="habit" | ||
) | ||
if not habit_tracker_path.exists(): | ||
habit_tracker_path.write_text(habit_tracker_contents) | ||
|
||
done_log_path = _get_day_path(cfg.zettel_dir, today, suffix="done") | ||
if not done_log_path.exists(): | ||
done_log_path.write_text(done_log_contents) | ||
|
||
vimala.vim( | ||
day_log_path, | ||
commands=_process_vim_commands(cfg.zettel_dir, cfg.vim_commands), | ||
) | ||
return 0 | ||
|
||
|
||
def _get_day_path( | ||
zettel_dir: Path, date: dt.date, *, suffix: str = None | ||
) -> Path: | ||
suffix = f"_{suffix}" if suffix else "" | ||
return zettel_dir / str(date.year) / date.strftime(f"%Y%m%d{suffix}.zo") | ||
|
||
|
||
def _process_vim_commands( | ||
zettel_dir: Path, vim_commands: Iterable[str] | ||
) -> Iterator[str]: | ||
for vim_cmd in vim_commands: | ||
if "{zdir}" in vim_cmd: | ||
yield vim_cmd.format(zdir=zettel_dir) | ||
else: | ||
yield vim_cmd |