diff --git a/src/streamer/__init__.py b/src/streamer/__init__.py index c39eede..47fa553 100644 --- a/src/streamer/__init__.py +++ b/src/streamer/__init__.py @@ -1,14 +1,16 @@ import glob import os -import typer +from datetime import datetime +from shutil import move +from typing import Generator + import click +import typer from rich import print from rich.markdown import Markdown from rich.panel import Panel -from shutil import move - -from datetime import datetime +from streamer.parse.attach_markdown import StreamFileWithMarkdown, attach_markdown from streamer.parse.parse import parse_markdown_file from streamer.query.task import find_by_markers from streamer.settings import Settings @@ -16,28 +18,28 @@ from streamer.settings import Settings app = typer.Typer() -@app.command() -def todo() -> None: +def all_files() -> Generator[StreamFileWithMarkdown]: for file_name in glob.glob(f"{glob.escape(Settings().base_folder)}/*.md"): with open(file_name, "r") as file: file_content = file.read() - sharded_document = parse_markdown_file(file_name, file_content) - if sharded_document.shard: - open_tasks = find_by_markers(sharded_document.shard, ["Task"], ["Done"]) + yield attach_markdown( + parse_markdown_file(file_name, file_content), file_content + ) - for task_shard in open_tasks: - print( - Panel( - Markdown( - "\n".join( - file_content.splitlines()[ - task_shard.start_line - 1 : task_shard.end_line - ] - ) - ), - title=f"{file_name}:{task_shard.start_line}", - ) + +@app.command() +def todo() -> None: + for sharded_document in all_files(): + if sharded_document.shard: + open_tasks = find_by_markers(sharded_document.shard, ["Task"], ["Done"]) + + for task_shard in open_tasks: + print( + Panel( + Markdown(task_shard.markdown_content), + title=f"{sharded_document.filename}:{task_shard.start_line}", ) + ) @app.command() @@ -59,7 +61,9 @@ def new() -> None: parsed_content = parse_markdown_file(prelimary_path, content) final_file_name = f"{timestamp}.md" - if parsed_content.shard is not None and len(markers := parsed_content.shard.markers): + if parsed_content.shard is not None and len( + markers := parsed_content.shard.markers + ): final_file_name = f"{timestamp} {' '.join(markers)}.md" final_path = os.path.join(streamer_directory, final_file_name) diff --git a/src/streamer/parse/attach_markdown.py b/src/streamer/parse/attach_markdown.py new file mode 100644 index 0000000..70766d9 --- /dev/null +++ b/src/streamer/parse/attach_markdown.py @@ -0,0 +1,31 @@ +from streamer.parse.shard import Shard, StreamFile + + +class ShardWithMarkdown(Shard): + children: list[ShardWithMarkdown] + markdown_content: str + + +class StreamFileWithMarkdown(StreamFile): + shard: ShardWithMarkdown | None = None # pyright: ignore[reportIncompatibleVariableOverride] + + +def attach_markdown_shard(shard: Shard, markdown_text: str) -> ShardWithMarkdown: + lines = markdown_text.splitlines() + markdown_content = "\n".join(lines[shard.start_line - 1 : shard.end_line]) + return ShardWithMarkdown( + **shard.model_dump(exclude=["children"]), + children=map(lambda child: attach_markdown_shard(child, markdown_text), shard.children), + markdown_content=markdown_content, + ) + + +def attach_markdown(file: StreamFile, markdown_text: str) -> StreamFileWithMarkdown: + if file.shard is None: + return StreamFileWithMarkdown(filename=file.filename, shard=None) + + attached_shard = attach_markdown_shard(file.shard, markdown_text) + return StreamFileWithMarkdown(filename=file.filename, shard=attached_shard) + + +__all__ = ["attach_markdown"] diff --git a/src/streamer/query/task.py b/src/streamer/query/task.py index f4e7cd2..67d3664 100644 --- a/src/streamer/query/task.py +++ b/src/streamer/query/task.py @@ -1,7 +1,11 @@ +from typing import TypeVar + from streamer.parse.shard import Shard +T = TypeVar("T", bound="Shard") -def find_by_markers(shard: Shard, has: list[str], has_not: list[str]) -> list[Shard]: + +def find_by_markers(shard: T, has: list[str], has_not: list[str]) -> list[T]: found_shards = [] if any(tag in has for tag in shard.markers) and not any(