Added per-subscription nickname override

This commit is contained in:
blankie 2026-07-26 16:34:57 -07:00
parent c20de93306
commit 8aa9f7cf47
3 changed files with 90 additions and 2 deletions

View file

@ -138,6 +138,13 @@ def return_db(db):
db.close() db.close()
def _ensure_columns(db, table, columns):
existing = {r[1] for r in db.execute(f"PRAGMA table_info({table})").fetchall()}
for name, col_def in columns.items():
if name not in existing:
db.execute(f"ALTER TABLE {table} ADD COLUMN {col_def}")
def init_db(): def init_db():
os.makedirs(DATA_DIR, exist_ok=True) os.makedirs(DATA_DIR, exist_ok=True)
db = sqlite3.connect(DATABASE) db = sqlite3.connect(DATABASE)
@ -177,6 +184,7 @@ def init_db():
" id INTEGER PRIMARY KEY AUTOINCREMENT," " id INTEGER PRIMARY KEY AUTOINCREMENT,"
" dest_hash TEXT UNIQUE NOT NULL," " dest_hash TEXT UNIQUE NOT NULL,"
" name TEXT DEFAULT ''," " name TEXT DEFAULT '',"
" nickname TEXT DEFAULT NULL,"
" auto_sync INTEGER DEFAULT 0," " auto_sync INTEGER DEFAULT 0,"
" last_sync TEXT DEFAULT ''" " last_sync TEXT DEFAULT ''"
")" ")"
@ -270,6 +278,64 @@ def init_db():
db.execute("CREATE INDEX IF NOT EXISTS idx_page_tags_page ON page_tags(page_id)") db.execute("CREATE INDEX IF NOT EXISTS idx_page_tags_page ON page_tags(page_id)")
db.execute("CREATE INDEX IF NOT EXISTS idx_page_tags_tag ON page_tags(tag_id)") db.execute("CREATE INDEX IF NOT EXISTS idx_page_tags_tag ON page_tags(tag_id)")
_ensure_columns(db, "pages", {
"id": "INTEGER PRIMARY KEY AUTOINCREMENT",
"url": "TEXT UNIQUE NOT NULL",
"title": "TEXT",
"body": "TEXT",
"note": "TEXT DEFAULT ''",
"last_modified": "TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%S','now'))",
"summary": "TEXT DEFAULT ''",
"reticulum_dest": "TEXT DEFAULT ''",
})
_ensure_columns(db, "subscriptions", {
"id": "INTEGER PRIMARY KEY AUTOINCREMENT",
"dest_hash": "TEXT UNIQUE NOT NULL",
"name": "TEXT DEFAULT ''",
"nickname": "TEXT DEFAULT NULL",
"auto_sync": "INTEGER DEFAULT 0",
"last_sync": "TEXT DEFAULT ''",
})
_ensure_columns(db, "links", {
"id": "INTEGER PRIMARY KEY AUTOINCREMENT",
"page_id": "INTEGER NOT NULL",
"url": "TEXT NOT NULL",
"label": "TEXT",
})
_ensure_columns(db, "settings", {
"key": "TEXT PRIMARY KEY",
"value": "TEXT",
})
_ensure_columns(db, "remote_pages", {
"id": "INTEGER PRIMARY KEY AUTOINCREMENT",
"subscription_id": "INTEGER NOT NULL",
"url": "TEXT NOT NULL",
"title": "TEXT",
"note": "TEXT DEFAULT ''",
"tags": "TEXT DEFAULT ''",
})
_ensure_columns(db, "tags", {
"id": "INTEGER PRIMARY KEY AUTOINCREMENT",
"name": "TEXT UNIQUE NOT NULL",
})
_ensure_columns(db, "page_tags", {
"page_id": "INTEGER NOT NULL",
"tag_id": "INTEGER NOT NULL",
})
_ensure_columns(db, "mesh_sites", {
"hash": "TEXT PRIMARY KEY",
"name": "TEXT DEFAULT ''",
"added_at": "TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%S','now'))",
})
_ensure_columns(db, "chunks", {
"id": "INTEGER PRIMARY KEY AUTOINCREMENT",
"page_id": "INTEGER",
"remote_page_id": "INTEGER",
"chunk_index": "INTEGER NOT NULL",
"chunk_text": "TEXT NOT NULL",
"embedding": "BLOB NOT NULL",
})
db.execute("PRAGMA journal_mode=WAL") db.execute("PRAGMA journal_mode=WAL")
db.execute("PRAGMA synchronous=NORMAL") db.execute("PRAGMA synchronous=NORMAL")
db.execute("PRAGMA cache_size=-64000") db.execute("PRAGMA cache_size=-64000")

View file

@ -29,7 +29,7 @@ from .subscriptions import (
handle_subscriptions, handle_subscription_add, handle_subscription_browse, handle_subscriptions, handle_subscription_add, handle_subscription_browse,
handle_subscription_pick, _sync_subscription, handle_subscription_pick, _sync_subscription,
handle_subscription_sync, handle_subscription_autosync, handle_subscription_sync, handle_subscription_autosync,
handle_subscription_delete, handle_subscription_syncall, handle_subscription_delete, handle_subscription_nickname, handle_subscription_syncall,
_sync_threads, _sync_threads,
) )
from .customize import handle_style_form, handle_style_submit, handle_style_template_submit, handle_field_save, handle_about, _set_flash from .customize import handle_style_form, handle_style_submit, handle_style_template_submit, handle_field_save, handle_about, _set_flash
@ -163,6 +163,9 @@ def _dispatch_inner(data):
elif path.startswith("/subscriptions/delete/"): elif path.startswith("/subscriptions/delete/"):
sid = extract_id("/subscriptions/delete/") sid = extract_id("/subscriptions/delete/")
return handle_subscription_delete(sid) if sid is not None else _error(400) return handle_subscription_delete(sid) if sid is not None else _error(400)
elif path.startswith("/subscriptions/nickname/"):
sid = extract_id("/subscriptions/nickname/")
return handle_subscription_nickname(body, sid) if sid is not None else _error(400)
elif path == "/subscriptions/syncall": elif path == "/subscriptions/syncall":
return handle_subscription_syncall() return handle_subscription_syncall()
elif path == "/rns/delete": elif path == "/rns/delete":

View file

@ -181,8 +181,13 @@ def handle_subscriptions(msg=""):
cards += ( cards += (
f'<div style="border:1px solid #ddd;border-radius:4px;padding:0.9rem 1rem;margin-bottom:0.75rem">' f'<div style="border:1px solid #ddd;border-radius:4px;padding:0.9rem 1rem;margin-bottom:0.75rem">'
f'<div style="margin-bottom:0.4rem"><b>{esc(s["name"] or "unknown")}</b></div>' f'<div style="margin-bottom:0.4rem"><b>{esc(s["nickname"] or s["name"] or "unknown")}</b></div>'
f'<div><small>{esc(s["dest_hash"])}</small></div>' f'<div><small>{esc(s["dest_hash"])}</small></div>'
f'<form method="post" action="/subscriptions/nickname/{sub_id}" style="margin-top:0.3rem">'
f'{_csrf_field()}'
f'<input name="nickname" value="{esc(s["nickname"] or "")}" size="20" placeholder="nickname" style="font-size:0.85rem">'
f' <button style="font-size:0.85rem">rename</button>'
f'</form>'
f'<div style="margin-top:0.4rem;font-size:0.85rem;color:#606060">last sync: {esc(last)}</div>' f'<div style="margin-top:0.4rem;font-size:0.85rem;color:#606060">last sync: {esc(last)}</div>'
f'{status_html}' f'{status_html}'
f'<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;margin-top:0.7rem">' f'<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;margin-top:0.7rem">'
@ -459,6 +464,20 @@ def handle_subscription_delete(sub_id):
return _redirect("/subscriptions") return _redirect("/subscriptions")
def handle_subscription_nickname(body, sub_id):
nickname = body.get("nickname", [""])[0].strip()
db = get_db()
try:
db.execute(
"UPDATE subscriptions SET nickname = ? WHERE id = ?",
(nickname or None, sub_id),
)
db.commit()
finally:
return_db(db)
return _redirect("/subscriptions")
def handle_subscription_syncall(): def handle_subscription_syncall():
db = get_db() db = get_db()
try: try: