diff --git a/src/plan/__init__.py b/src/plan/__init__.py index 4d35b33..4db2f5f 100644 --- a/src/plan/__init__.py +++ b/src/plan/__init__.py @@ -1,61 +1,76 @@ import os +import subprocess +import sys from datetime import datetime from pathlib import Path -from .templates import default +from jinja2 import Environment, PackageLoader, select_autoescape -def today() -> Path: +def get_template(template_name: str = "plan.html", plan_path: Path | None = None): + """ """ + templates = Environment( + loader=PackageLoader("plan"), autoescape=select_autoescape() + ) + template = templates.get_template(template_name) today = datetime.today().strftime("%Y-%m-%d") - today_path = Path().home() / ".plan" / f"{today}.md" - return today_path + return template.render(today=today, plan_path=plan_path) -def print_plan(plan: Path): - import subprocess +def plan_path() -> Path: + """ + returns: Path to current date's .plan.md + """ + today = datetime.today().strftime("%Y-%m-%d") + path = Path().home() / ".plan" / f"{today}.md" + return path - cat_process = subprocess.Popen(["cat", str(plan)], stdout=subprocess.PIPE) + +def print_plan(plan_path: Path): + """ + send .plan.md to printer. + + uses pandoc and lp shell tools. + """ + # preamble =""" + # --- + # documentclass: extarticle + # fontsize: 20pt + # --- + # """ + cat_process = subprocess.Popen(["cat", str(plan_path)], stdout=subprocess.PIPE) pandoc_process = subprocess.Popen( ["pandoc", "-t", "pdf", "-V", "geometry:margin=.5in", "-"], stdin=cat_process.stdout, stdout=subprocess.PIPE, ) + subprocess.run( - ["lp", "-o", "sides=two-sided-long-edge"], - # , "-o", "number-up=4"], + ["lp", "-o", "sides=two-sided-long-edge", "-o", "number-up=2"], stdin=pandoc_process.stdout, ) -def template_or_open( - plan: Path, name: str = "plan.html", should_open: bool = True -) -> str | None: - template = default(name) +def create_and_open_template(plan: Path, name: str = "plan.html") -> int: + plan.parent.mkdir(parents=True, exist_ok=True) + plan.touch() - if should_open: - import subprocess + template = get_template(name, plan_path=plan) + with plan.open("w") as f: + f.write(template) - plan.parent.mkdir(parents=True, exist_ok=True) - if not plan.exists(): - plan.touch() - with plan.open("w") as f: - f.write(template) - - editor = os.getenv("EDITOR", "nvim") - os.chdir(plan.parent) - subprocess.run([editor, str(plan)]) - else: - return template + editor = os.getenv("EDITOR", "nvim") + os.chdir(plan.parent) + p = subprocess.Popen([editor, str(plan)]) + sys.exit(p.wait()) def open_in_editor(plan: Path): - import subprocess - plan.parent.mkdir(parents=True, exist_ok=True) if not plan.exists(): plan.touch() with plan.open("w") as f: - f.write(default()) + f.write(default_template(plan_path=plan)) editor = os.getenv("EDITOR", "nvim") os.chdir(Path().home() / ".plan") subprocess.run([editor, str(plan)]) diff --git a/src/plan/__main__.py b/src/plan/__main__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/plan/cli.py b/src/plan/cli.py index 7f89f90..145dbd5 100644 --- a/src/plan/cli.py +++ b/src/plan/cli.py @@ -1,94 +1,41 @@ +import sys from pathlib import Path -from pydantic import BaseModel, ConfigDict -from typing import Iterable, Optional + import click -from . import open_in_editor, template_or_open, today, print_plan -import markdown -from io import StringIO from click_default_group import DefaultGroup +from .main import ( + create_plan, + edit_plan, + plan_path, + print_plan, +) -@click.group(cls=DefaultGroup, default="today", default_if_no_args=True) + +@click.group(cls=DefaultGroup, default="main", default_if_no_args=True) def cli(): pass @cli.command("print") -def print_today(): - path = today() - print_plan(path) +@click.option( + "--plan_path", + "-p", + "plan_path", + type=click.Path(exists=True, dir_okay=False, readable=True, path_type=Path), + default=plan_path(), +) +def send_to_printer(plan_path: Path): + print_plan(plan_path) -@cli.command("todo") -def todo(): - import sys - from lxml import etree - - class Result(BaseModel): - path: Path - todos: Iterable[etree.Element] - model_config = ConfigDict(arbitrary_types_allowed=True) - - def parse_todo() -> Iterable[Result]: - for m in recent(): - with open(m) as f: - text = f.read() - content = markdown.markdown(text) - tree = etree.parse( - StringIO(f"{content}"), etree.HTMLParser() - ) - for node in tree.xpath("//h2/following-sibling::ul/li"): - yield Result(path=m, todos=node) - - todos = parse_todo() - - def print_tree(node: Optional[etree.Element], tabs=0): - if node is None: - return - print(f"{' ' * tabs}- {node.text}") - for child in node.iterchildren(): - return print_tree(child, tabs + 1) - - for day in todos: - for root in day.todos: - print(f"{day.path.name}") - print_tree(root) - else: - print("no todos") - - sys.exit(0) - """ - - uv run plan todo - - interact - import wat - print(node) - - r = next(root) - r - - wat(node) - dir(node) - wat(node) - [s for s in node.itersiblings()] - [s for s in node.iterchildren()] - print(node.tag) - parent = node.xpath("//following-sibling::ul")[0] - [s.text for s in parent.iterchildren()] - - sys.exit(0) - - """ - - -@cli.command("today") +@cli.command("main") @click.option( "-t", "--template", "template", required=True, - type=click.Choice(["plan.html", "work.html", "blank.html", "print.html"]), + type=click.Choice(["plan.html", "work.html"]), prompt=True, default="plan.html", show_default=True, @@ -103,17 +50,9 @@ def todo(): ) def open_today(template, should_print): """open today""" - path = today() + path = plan_path() + content = create_plan(plan_path=path, name=template) if should_print: - print(template_or_open(path, should_open=False, name=template)) + print(content) else: - open_in_editor(path) - - -def recent() -> Iterable[Path]: - parent = Path().home() / ".plan" - for m in parent.iterdir(): - if m.suffix == ".md": - yield m - else: - yield m + sys.exit(edit_plan(path)) diff --git a/src/plan/main.py b/src/plan/main.py new file mode 100644 index 0000000..12d4ddf --- /dev/null +++ b/src/plan/main.py @@ -0,0 +1,84 @@ +import os +import subprocess +import sys +from datetime import datetime +from pathlib import Path + +from jinja2 import Environment, PackageLoader, select_autoescape + + +def get_template(template_name: str = "plan.html", plan_path: Path | None = None): + """ """ + templates = Environment( + loader=PackageLoader("plan"), autoescape=select_autoescape() + ) + breakpoint() + template = templates.get_template(template_name) + today = datetime.today().strftime("%Y-%m-%d") + return template.render(today=today, plan_path=plan_path) + + +def plan_path(date: datetime | None = None) -> Path: + """ + returns: Path to current date's .plan.md + """ + if date is None: + date = datetime.today() + formatted = date.strftime("%Y-%m-%d") + path = Path().home() / ".plan" / f"{formatted}.md" + return path + + +def print_plan(plan_path: Path): + """ + send .plan.md to printer. + + uses pandoc and lp shell tools. + """ + preamble = """ + --- + documentclass: extarticle + fontsize: 20pt + --- + """ + preamble = subprocess.Popen(["echo", "-n", preamble], stdout=subprocess.PIPE) + cat = subprocess.Popen( + ["cat", "-", str(plan_path)], + stdin=preamble.stdout, + stdout=subprocess.PIPE, + ) + pandoc = subprocess.Popen( + ["pandoc", "-t", "pdf", "-V", "geometry:margin=.5in", "-"], + stdin=cat.stdout, + stdout=subprocess.PIPE, + ) + send = subprocess.Popen( + ["lp", "-o", "sides=two-sided-long-edge", "-o", "number-up=2"], + stdin=pandoc.stdout, + ) + sys.exit(send.wait()) + + +def create_plan(plan_path: Path, name: str = "plan.html", force=False) -> str: + plan_path.parent.mkdir(parents=True, exist_ok=True) + + if not plan_path.exists() or force: + content = get_template(name, plan_path=plan_path) + with plan_path.open("w") as f: + f.write(content) + else: + content = get_plan(plan_path) + return content + + +def get_plan(plan_path: Path) -> str: + with plan_path.open("r") as f: + content = f.read() + return content + + +def edit_plan(plan_path: Path) -> int: + editor = os.getenv("EDITOR", "nvim") + os.chdir(plan_path.parent) + p = subprocess.Popen([editor, str(plan_path)]) + return p.wait() diff --git a/src/plan/templates/plan.html b/src/plan/templates/plan.html index 3b02b57..20a5830 100644 --- a/src/plan/templates/plan.html +++ b/src/plan/templates/plan.html @@ -2,38 +2,18 @@ ## todo -- chore: -- workout: -- job: -- comm: -- buy: +- appreciate life. ## meals -- breakfast: oatmeal -- lunch: leftovers -- dinner: curry +- breakfast: coffee, oatmeal +- lunch: lx, leftovers, carrots, cheese, crackers, apple +- dinner: lx, curry ## schedule -- 5:00: sleep. -- 6:00: breakfast. -- 7:00: walk. -- 8:00: meeting. -- 9:00: code. -- 10:00: code. -- 11:00: walk. -- 12:00: lunch. -- 1:00: code. -- 2:00: code. -- 3:00: walk. -- 4:00: code. -- 5:30: trailhead. -- 6:00: cook. -- 7:00: dinner. -- 8:00: wind down. -- 9:00: read. -- 10:00: sleep. +- 6:30: wakeup. +- 9:30: sleep ## groceries @@ -48,4 +28,3 @@ - cheese. - apples. - bread. - diff --git a/src/plan/templates/print.html b/src/plan/templates/print.html deleted file mode 100644 index 1cd3db3..0000000 --- a/src/plan/templates/print.html +++ /dev/null @@ -1,3 +0,0 @@ -```bash -cat ~/.plan/{{ today }}.md | pandoc -t pdf -V geometry:margin=.5in - | lp -o sides=two-sided-long-edge.plan -o number-up=4 -```