webui: store RSS feeds/rules/indexers in the webui DB

Move RSS persistence out of the daemon blob store and into the webui's
own SQLite DB (feeds, rules, indexers tables; articles + affectedFeeds
held as JSON columns). Remove the now-unused daemon blob store
(set/get_webui_blob, blob_lock, data_dir).

With this, all webui-owned state — accounts, taxonomy, RSS — lives in
the webui DB; the daemon only keeps naut's own data (per-torrent labels
still flow through set_labels for Lua).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ookami125 2026-06-23 22:11:17 -04:00
parent 9474e6f31a
commit 91d4b99aee
4 changed files with 178 additions and 96 deletions

View file

@ -1950,37 +1950,30 @@ static char *base64_encode(const unsigned char *in, size_t len) {
/* --- RSS persistence (via the daemon blob store) -------------------------- */
/* Persist feeds/rules/indexers to the web-UI's own database. */
static void rss_save(void) {
if (!g_webui.store) return;
pthread_mutex_lock(&g_webui.rss_lock);
json_t *doc = json_pack("{s:O,s:O,s:O}",
"feeds", g_webui.rss_feeds ? g_webui.rss_feeds : json_array(),
"rules", g_webui.rss_rules ? g_webui.rss_rules : json_array(),
"indexers", g_webui.indexers ? g_webui.indexers : json_array());
json_t *feeds = json_deep_copy(g_webui.rss_feeds);
json_t *rules = json_deep_copy(g_webui.rss_rules);
json_t *idx = json_deep_copy(g_webui.indexers);
pthread_mutex_unlock(&g_webui.rss_lock);
if (!doc) return;
json_t *params = json_pack("{s:s,s:o}", "key", "rss", "value", doc);
if (!params) { json_decref(doc); return; }
json_t *reply = rpc_call_json("set_webui_blob", params);
json_decref(params);
if (reply) json_decref(reply);
if (feeds) { webui_store_save_feeds(g_webui.store, feeds); json_decref(feeds); }
if (rules) { webui_store_save_rules(g_webui.store, rules); json_decref(rules); }
if (idx) { webui_store_save_indexers(g_webui.store, idx); json_decref(idx); }
}
static void rss_load(void) {
json_t *params = json_pack("{s:s}", "key", "rss");
json_t *reply = rpc_call_json("get_webui_blob", params);
json_decref(params);
json_t *value = reply ? json_object_get(reply, "value") : NULL;
if (!g_webui.store) return;
json_t *feeds = json_array(), *rules = json_array(), *idx = json_array();
bool of = webui_store_load_feeds(g_webui.store, feeds);
bool orr = webui_store_load_rules(g_webui.store, rules);
bool oi = webui_store_load_indexers(g_webui.store, idx);
pthread_mutex_lock(&g_webui.rss_lock);
if (json_is_object(value)) {
json_t *feeds = json_object_get(value, "feeds");
json_t *rules = json_object_get(value, "rules");
json_t *idx = json_object_get(value, "indexers");
if (json_is_array(feeds)) { json_decref(g_webui.rss_feeds); g_webui.rss_feeds = json_deep_copy(feeds); }
if (json_is_array(rules)) { json_decref(g_webui.rss_rules); g_webui.rss_rules = json_deep_copy(rules); }
if (json_is_array(idx)) { json_decref(g_webui.indexers); g_webui.indexers = json_deep_copy(idx); }
}
if (of) { json_decref(g_webui.rss_feeds); g_webui.rss_feeds = feeds; } else json_decref(feeds);
if (orr) { json_decref(g_webui.rss_rules); g_webui.rss_rules = rules; } else json_decref(rules);
if (oi) { json_decref(g_webui.indexers); g_webui.indexers = idx; } else json_decref(idx);
pthread_mutex_unlock(&g_webui.rss_lock);
if (reply) json_decref(reply);
}
/* --- auto-download: hand a matched article to the daemon ------------------ */