Fix pinned today page and webhook

This commit is contained in:
2026-02-16 17:18:53 -05:00
parent c5ddf68ea1
commit ca3fbe4149
2 changed files with 79 additions and 5 deletions

81
main.py
View File

@ -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"<a class='file-link {active}' data-search='{searchable}' "
f"data-backlinks='{backlinks_count}' data-created-ts='{created_key_attr}' "
f"data-modified-ts='{modified_ts}' href='{safe_href}'>"
f"<span class='file-title' title='{full_title}'>{safe_title}</span>"
f"<span class='file-title' title='{full_title}'>{pin_icon}{safe_title}</span>"
f"<span class='file-path' title='{full_path}'>{safe_path}</span>"
"</a>"
)
@ -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 = "<p>No .org files found.</p>"
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"<a class='backlink-item' href='{safe_href}'>"
f"<span class='file-title' title='{full_title}'>{safe_title}</span>"
f"<span class='file-path' title='{full_path}'>{safe_path}</span>"
"</a>"
)
items_html = "\n".join(backlink_items)
else:
items_html = "<p class='backlinks-empty'>No notes link to this note yet.</p>"
return (
"<!doctype html>\n<html lang='en'>\n<head>\n"
" <meta charset='utf-8'>\n"
" <meta name='viewport' content='width=device-width, initial-scale=1'>\n"
" <title>Backlinks</title>\n"
" <link rel='stylesheet' href='/static/style.css'>\n"
"</head>\n<body>\n"
" <div class='backlinks-pane' style='border:none;height:100vh;'>\n"
" <h3>Backlinks</h3>\n"
f" <div class='backlinks-list'>{items_html}</div>\n"
" </div>\n"
" <script>(function(){"
"var t=new URLSearchParams(window.location.search).get('theme');"
"if(t==='dark')document.body.setAttribute('data-theme','dark');"
"})()</script>\n"
"</body>\n</html>"
)
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

View File

@ -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 () {