#!/usr/bin/env python3 import os import sys import time from pathlib import Path import marko from marko.ext.gfm import GFM from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler from log.Logger import * from hashes.obfuscation.Obfuscator import Obfuscator from htmlhandler import htmlhandler as Handler # Use absolute paths ROOT = Path(os.path.abspath(".")) MARKDOWN_DIR = ROOT / "markdown" HTML_DIR = ROOT / "html" # Create markdown parser with table support markdown_parser = marko.Markdown(extensions=[GFM]) Logger = Logger() # Global obfuscate flag, default True obfuscate = True def render_markdown(md_path: Path): """Render a single markdown file to an obfuscated HTML file.""" try: text = md_path.read_text(encoding="utf-8") except Exception as e: Logger.log_error(f"Could not read {md_path}: {e}") return html_body = markdown_parser.convert(text) # Extract title from filename or first H1 title = md_path.stem for line in text.splitlines(): if line.startswith("# "): title = line[2:].strip() break import base64 import random from hashes.hashes import hash_list # Create clean HTML structure clean_html = f""" {title}

Back {title}

write_img
Written @{time.asctime(time.localtime())}

{html_body}
""" # Obfuscate the HTML for browser output obfuscated_html = Obfuscator.obfuscate_html(clean_html) # Ensure html directory exists HTML_DIR.mkdir(exist_ok=True) # Maintain relative directory structure in html/ relative_path = md_path.relative_to(MARKDOWN_DIR) out_path = HTML_DIR / relative_path.with_suffix(".html") # Create parent directories if needed out_path.parent.mkdir(parents=True, exist_ok=True) if obfuscate: out_path.write_text(obfuscated_html, encoding="utf-8") else: out_path.write_text(clean_html, encoding="utf-8") Logger.log_debug(f"Rendered: {md_path} -> {out_path}") def remove_html(md_path: Path): relative_path = md_path.relative_to(MARKDOWN_DIR) out_path = HTML_DIR / relative_path.with_suffix(".html") if out_path.exists(): out_path.unlink() Logger.log_debug(f"Removed: {out_path}") def initial_scan(markdown_dir: Path): Logger.log_info(f"Starting initial scan of markdown files in {markdown_dir}...") for md in markdown_dir.rglob("*.md"): render_markdown(md) """ class Handler(FileSystemEventHandler): def on_created(self, event): if not event.is_directory and event.src_path.endswith(".md"): render_markdown(Path(event.src_path)) def on_modified(self, event): if not event.is_directory and event.src_path.endswith(".md"): render_markdown(Path(event.src_path)) def on_deleted(self, event): if not event.is_directory and event.src_path.endswith(".md"): remove_html(Path(event.src_path)) def on_moved(self, event): src = Path(event.src_path) dest = Path(event.dest_path) if src.suffix.lower() == ".md": remove_html(src) if dest.suffix.lower() == ".md": render_markdown(dest) """ if __name__ == "__main__": if not MARKDOWN_DIR.exists(): alt_root = ROOT / "PyPost" if alt_root.exists() and alt_root.is_dir(): Logger.log_warning(f"Default 'markdown' directory not found, switching ROOT to: {alt_root}") ROOT = alt_root MARKDOWN_DIR = ROOT / "markdown" HTML_DIR = ROOT / "html" else: Logger.log_error(f"Markdown directory not found: {MARKDOWN_DIR}") Logger.log_warning("Please create a 'markdown' directory or use a 'PyPost' directory with one inside it.") sys.exit(1) import argparse parser = argparse.ArgumentParser(description="Monitor markdown directory and convert to HTML.") # This stores True when passed, but means "no obfuscation" parser.add_argument( "--no-obfuscate", action="store_false", help="Disable HTML obfuscation." ) args = parser.parse_args() # Invert it to get the obfuscate flag obfuscate = not args.no_obfuscate Logger.log_obfuscation_info(f"Obfuscation is {'enabled' if obfuscate else 'disabled'}", obfuscate) initial_scan(MARKDOWN_DIR) event_handler = Handler() observer = Observer() observer.schedule(event_handler, str(MARKDOWN_DIR), recursive=True) observer.start() Logger.log_info(f"Started monitoring {MARKDOWN_DIR} for changes.") try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()