diff --git a/main.py b/main.py index bb80c64..2ba05f9 100644 --- a/main.py +++ b/main.py @@ -27,6 +27,7 @@ class OrgFile: file_id: str | None content: str mtime: float = 0.0 + pinned: bool = False ROOT_DIR = Path(__file__).resolve().parent @@ -78,6 +79,19 @@ def scan_org_files(base_dir: Path) -> list[OrgFile]: ) org_files.sort(key=lambda f: f.mtime, reverse=True) + + if os.environ.get("ORGWEB_PIN_TODAY_FILE", "").lower() in ("1", "true", "yes"): + today = datetime.now().strftime("%Y-%m-%d") + pinned = [] + rest = [] + for f in org_files: + if today in f.relative_path or today in f.title: + f.pinned = True + pinned.append(f) + else: + rest.append(f) + org_files = pinned + rest + return org_files @@ -470,7 +484,7 @@ _NOTE_TAKEN_RE = re.compile( ) -def extract_heading_data(content: str, heading_text: str) -> dict | None: +def extract_heading_data(content: str, heading_text: str, file_id: str = "") -> dict | None: """Find a heading in *content* by its text and extract webhook-ready data.""" lines = content.splitlines() target_idx: int | None = None @@ -551,7 +565,7 @@ def extract_heading_data(content: str, heading_text: str) -> dict | None: body_lines.append(sl) - emacs_id = properties.get("ID", "") + emacs_id = properties.get("ID", "") or file_id notes = _extract_notes(body_lines) return { @@ -641,11 +655,12 @@ def build_index_page( created_key = extract_created_sort_key(f.content) created_key_attr = "" if created_key is None else str(created_key) modified_ts = str(int(f.mtime)) + pin_icon = "\U0001F4CC " if f.pinned else "" nav_items.append( f"" - f"{safe_title}" + f"{pin_icon}{safe_title}" f"{safe_path}" "" ) @@ -707,6 +722,51 @@ def build_index_page( ) +def build_backlinks_page(org_files: Iterable[OrgFile], selected_path: str | None = None) -> str: + """Return a minimal standalone HTML page containing only the backlinks for a note.""" + org_files = list(org_files) + if not org_files: + items_html = "

No .org files found.

" + else: + selected = find_org_file(org_files, selected_path) or org_files[0] + backlinks = find_backlinks(org_files, selected.relative_path) + if backlinks: + backlink_items = [] + for source in backlinks: + safe_href = html.escape(note_href(source.relative_path, False), quote=True) + safe_title = html.escape(source.title) + safe_path = html.escape(source.relative_path) + full_title = html.escape(source.title, quote=True) + full_path = html.escape(source.relative_path, quote=True) + backlink_items.append( + f"" + f"{safe_title}" + f"{safe_path}" + "" + ) + items_html = "\n".join(backlink_items) + else: + items_html = "" + + return ( + "\n\n\n" + " \n" + " \n" + " Backlinks\n" + " \n" + "\n\n" + " \n" + " \n" + "\n" + ) + + def make_handler(base_dir: Path, webhook_url: str = "", webhook_token: str = ""): class OrgRequestHandler(BaseHTTPRequestHandler): def do_GET(self) -> None: @@ -722,6 +782,19 @@ def make_handler(base_dir: Path, webhook_url: str = "", webhook_token: str = "") params = parse_qs(parsed.query) selected_path = params.get("file", [None])[0] + embed_backlinks = params.get("embed_backlinks", ["0"])[0] in ("1", "true", "yes") + + if embed_backlinks: + org_files = scan_org_files(base_dir) + html_page = build_backlinks_page(org_files, selected_path=selected_path) + encoded = html_page.encode("utf-8") + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.send_header("Content-Length", str(len(encoded))) + self.end_headers() + self.wfile.write(encoded) + return + edit_mode = params.get("edit", ["0"])[0] == "1" saved = params.get("saved", ["0"])[0] == "1" error = params.get("error", [""])[0] @@ -807,7 +880,7 @@ def make_handler(base_dir: Path, webhook_url: str = "", webhook_token: str = "") self.send_json_response(404, {"error": "File not found"}) return - data = extract_heading_data(org_file.content, heading_text) + data = extract_heading_data(org_file.content, heading_text, file_id=org_file.file_id or "") if data is None: self.send_json_response(404, {"error": "Heading not found"}) return diff --git a/templates/index.html b/templates/index.html index 6cab8a6..56675c8 100644 --- a/templates/index.html +++ b/templates/index.html @@ -60,7 +60,8 @@ } } - const saved = localStorage.getItem(key); + const urlTheme = new URLSearchParams(window.location.search).get("theme"); + const saved = urlTheme || localStorage.getItem(key); applyTheme(saved === "dark" ? "dark" : "light"); btn.addEventListener("click", function () {