From d2aae5cd82395c87bec55bdb3e019e11753de076 Mon Sep 17 00:00:00 2001 From: pax Date: Sun, 5 Apr 2026 17:09:01 -0500 Subject: [PATCH] Store tag categories in bookmarks, tag click switches to Browse - Bookmarks DB now stores tag_categories as JSON - Migration adds column to existing favorites table - Bookmark info panel uses stored categories directly - Falls back to library_meta if bookmark has no categories - Tag click in info panel: clears preview, switches to Browse, searches --- booru_viewer/core/db.py | 22 +++++++++++++++++----- booru_viewer/gui/app.py | 10 ++++++++-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/booru_viewer/core/db.py b/booru_viewer/core/db.py index 0708137..315162f 100644 --- a/booru_viewer/core/db.py +++ b/booru_viewer/core/db.py @@ -134,6 +134,7 @@ class Bookmark: cached_path: str | None folder: str | None bookmarked_at: str + tag_categories: dict = field(default_factory=dict) # Back-compat alias — will be removed in a future version. @@ -168,10 +169,14 @@ class Database: tables = {r[0] for r in self._conn.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall()} if "library_meta" in tables: cur = self._conn.execute("PRAGMA table_info(library_meta)") - cols = {row[1] for row in cur.fetchall()} - if "tag_categories" not in cols: + meta_cols = {row[1] for row in cur.fetchall()} + if "tag_categories" not in meta_cols: self._conn.execute("ALTER TABLE library_meta ADD COLUMN tag_categories TEXT DEFAULT ''") self._conn.commit() + # Add tag_categories to favorites if missing + if "tag_categories" not in cols: + self._conn.execute("ALTER TABLE favorites ADD COLUMN tag_categories TEXT DEFAULT ''") + self._conn.commit() def close(self) -> None: if self._conn: @@ -259,13 +264,16 @@ class Database: source: str | None = None, cached_path: str | None = None, folder: str | None = None, + tag_categories: dict | None = None, ) -> Bookmark: + import json now = datetime.now(timezone.utc).isoformat() + cats_json = json.dumps(tag_categories) if tag_categories else "" cur = self.conn.execute( "INSERT OR IGNORE INTO favorites " - "(site_id, post_id, file_url, preview_url, tags, rating, score, source, cached_path, folder, favorited_at) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - (site_id, post_id, file_url, preview_url, tags, rating, score, source, cached_path, folder, now), + "(site_id, post_id, file_url, preview_url, tags, rating, score, source, cached_path, folder, favorited_at, tag_categories) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + (site_id, post_id, file_url, preview_url, tags, rating, score, source, cached_path, folder, now, cats_json), ) self.conn.commit() return Bookmark( @@ -352,6 +360,9 @@ class Database: @staticmethod def _row_to_bookmark(r) -> Bookmark: + import json + cats_raw = r["tag_categories"] if "tag_categories" in r.keys() else "" + cats = json.loads(cats_raw) if cats_raw else {} return Bookmark( id=r["id"], site_id=r["site_id"], @@ -365,6 +376,7 @@ class Database: cached_path=r["cached_path"], folder=r["folder"] if "folder" in r.keys() else None, bookmarked_at=r["favorited_at"], + tag_categories=cats, ) # Back-compat shim diff --git a/booru_viewer/gui/app.py b/booru_viewer/gui/app.py index 5357faa..68e7244 100644 --- a/booru_viewer/gui/app.py +++ b/booru_viewer/gui/app.py @@ -542,6 +542,8 @@ class BooruApp(QMainWindow): self._grid.setFocus() def _on_tag_clicked(self, tag: str) -> None: + self._preview.clear() + self._switch_view(0) self._search_bar.set_text(tag) self._on_search(tag) @@ -1146,8 +1148,10 @@ class BooruApp(QMainWindow): self._status.showMessage(f"Bookmark #{fav.post_id}") # Show bookmark tags in info panel from ..core.api.base import Post - meta = self._db.get_library_meta(fav.post_id) - cats = meta.get("tag_categories", {}) if meta else {} + cats = fav.tag_categories or {} + if not cats: + meta = self._db.get_library_meta(fav.post_id) + cats = meta.get("tag_categories", {}) if meta else {} p = Post( id=fav.post_id, file_url=fav.file_url or "", preview_url=fav.preview_url, tags=fav.tags or "", @@ -1672,6 +1676,7 @@ class BooruApp(QMainWindow): file_url=post.file_url, preview_url=post.preview_url, tags=post.tags, rating=post.rating, score=post.score, source=post.source, cached_path=str(path), + tag_categories=post.tag_categories, ) self._signals.bookmark_done.emit(idx, f"Bookmarked {i+1}/{len(posts)}") except Exception as e: @@ -2054,6 +2059,7 @@ class BooruApp(QMainWindow): score=post.score, source=post.source, cached_path=str(path), + tag_categories=post.tag_categories, ) self._signals.bookmark_done.emit(index, f"Bookmarked #{post.id}") except Exception as e: