import sys import os import re def print_usage(): print(f"usage: python {sys.argv[0]} DIR") print(f"") print(f"\tDIR\tdirectory containing markdown lists in files.") if len(sys.argv) != 2: print_usage() exit(1) base_path = os.path.abspath(sys.argv[1]) ready_list_name = "ready.md" done_list_name = "all-done.md" def get_path(list_name : str) -> str: return os.path.join(base_path, list_name) def get_matches(list_name : str) -> list[re.Match]: # Matches a markdown list item entry_pattern = re.compile(r"^[*-] \[([ *x])\] (.+) - (.+)") matches = [] with open(get_path(list_name)) as f: matches = [entry_pattern.match(l) for l in f.readlines()] return [m for m in matches if m is not None] class Book: def __init__(self, match : re.Pattern): self.mark = match.group(1) != " " self.author = match.group(2) self.title = match.group(3) def is_metadata_complete(self): if not self.title or not self.author: return False if self.title == "???" or self.author == "???": return False return True @staticmethod def get_list(list_name : str, filter_partial_metadata = True) -> []: books = [Book(m) for m in get_matches(list_name)] if filter_partial_metadata: books = [b for b in books if b.is_metadata_complete()] return books def print_section(title : str, books : list[str]): print(f"# {title} ({len(books)})\n") longest_title = max([len(b.title) for b in books]) title_column_width = longest_title + 2 for book in books: row = [book.title, book.author] format_str = "- {: <" + str(title_column_width) + "} {: <20}" print(format_str.format(*row)) print() def print_in_progress(): books = [b for b in Book.get_list(ready_list_name, False) if b.mark] print_section("in progress", books) def print_completed(): books = Book.get_list(done_list_name) print_section("up for borrowing", books) def print_partial_metadata(): books = Book.get_list(ready_list_name, False) books += Book.get_list(done_list_name, False) books = [b for b in books if not b.is_metadata_complete()] print_section("metadata incomplete", books) print_in_progress() print_completed() print_partial_metadata()