Fix pinned today page and webhook
This commit is contained in:
81
main.py
81
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"<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
|
||||
|
||||
@ -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 () {
|
||||
|
||||
Reference in New Issue
Block a user