webui: normalize the RSS schema (articles + rule_feeds tables)
Replace the JSON-blob columns (feeds.articles, rules.affected_feeds) with proper relational tables: - articles(feed,key,…,is_read,grabbed) with UNIQUE(feed,key) and indexes, so dedup and grabbed become INSERT OR IGNORE / WHERE-key queries and a poll inserts only new rows instead of rewriting the whole feed blob. - rule_feeds(rule,feed) join table for a rule's feed scope. The webui RSS engine now operates on rows via a row-level store API (feed/article/rule/indexer upsert/list/etc.) instead of holding the feeds/rules/indexers in memory and saving whole lists; the in-memory copies and rss_save/rss_load are gone. The poller, the auto-download rules, force-run, manual download, refresh and search all read/write the DB directly. A one-time migration upgrades an existing webui.db in place (moving the old JSON blobs into the new tables, preserving article read/grabbed flags and rule scoping, then dropping the legacy columns). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
91d4b99aee
commit
a0265cc1ea
3 changed files with 700 additions and 354 deletions
|
|
@ -52,14 +52,42 @@ bool webui_store_load_categories(webui_store *s, json_t *out);
|
|||
bool webui_store_save_tags(webui_store *s, json_t *tags);
|
||||
bool webui_store_load_tags(webui_store *s, json_t *out);
|
||||
|
||||
/* --- RSS: feeds, auto-download rules, Torznab indexers (owned here) -------- *
|
||||
* save_* replace the whole list atomically; load_* append to the array `out`,
|
||||
* rebuilding the exact JSON shapes the web layer/UI use. */
|
||||
bool webui_store_save_feeds(webui_store *s, json_t *feeds);
|
||||
bool webui_store_load_feeds(webui_store *s, json_t *out);
|
||||
bool webui_store_save_rules(webui_store *s, json_t *rules);
|
||||
bool webui_store_load_rules(webui_store *s, json_t *out);
|
||||
bool webui_store_save_indexers(webui_store *s, json_t *indexers);
|
||||
bool webui_store_load_indexers(webui_store *s, json_t *out);
|
||||
/* --- RSS: feeds, articles, auto-download rules, Torznab indexers ----------- *
|
||||
* Fully relational: articles live in their own table (deduped by feed+key,
|
||||
* indexed), and a rule's feed scope lives in a rule_feeds join table. The web
|
||||
* layer operates on rows, not whole-list blobs. */
|
||||
|
||||
/* Feeds. upsert preserves an existing feed's lastUpdate (only the url changes);
|
||||
* remove also drops the feed's articles. feed_list appends
|
||||
* {name,url,lastUpdate,articles:[...]} (newest article first). feed_targets
|
||||
* appends lightweight {name,url} objects for the poller. */
|
||||
bool webui_store_feed_upsert(webui_store *s, const char *name, const char *url);
|
||||
bool webui_store_feed_remove(webui_store *s, const char *name);
|
||||
bool webui_store_feed_set_updated(webui_store *s, const char *name, long ts);
|
||||
bool webui_store_feed_list(webui_store *s, json_t *out);
|
||||
bool webui_store_feed_targets(webui_store *s, json_t *out);
|
||||
bool webui_store_feed_exists(webui_store *s, const char *name);
|
||||
|
||||
/* Articles. add inserts unless (feed,key) already exists: returns 1 if newly
|
||||
* inserted, 0 if a duplicate, -1 on error. trim keeps the newest `keep` for a
|
||||
* feed. mark_grabbed flags every article with this key. ungrabbed appends
|
||||
* {feed,key,title,magnet,torrentUrl} for not-yet-grabbed articles. */
|
||||
int webui_store_article_add(webui_store *s, const char *feed, json_t *article);
|
||||
bool webui_store_article_trim(webui_store *s, const char *feed, int keep);
|
||||
bool webui_store_article_mark_grabbed(webui_store *s, const char *key);
|
||||
bool webui_store_articles_ungrabbed(webui_store *s, json_t *out);
|
||||
|
||||
/* Rules. upsert replaces the rule row and its feed scope; list/get assemble the
|
||||
* rule with its affectedFeeds array. */
|
||||
bool webui_store_rule_upsert(webui_store *s, json_t *rule);
|
||||
bool webui_store_rule_remove(webui_store *s, const char *name);
|
||||
bool webui_store_rule_list(webui_store *s, json_t *out);
|
||||
json_t *webui_store_rule_get(webui_store *s, const char *name);
|
||||
bool webui_store_rule_set_match(webui_store *s, const char *name, long ts);
|
||||
|
||||
/* Torznab indexers. */
|
||||
bool webui_store_indexer_upsert(webui_store *s, json_t *indexer);
|
||||
bool webui_store_indexer_remove(webui_store *s, const char *name);
|
||||
bool webui_store_indexer_list(webui_store *s, json_t *out);
|
||||
|
||||
#endif /* NAUT_WEBUI_STORE_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue