Library metadata: store tags on save, search by tag in Library
- library_meta table stores tags, score, rating, source per post - Metadata saved automatically when saving from Browse - Search box in Library tab filters by tags via DB lookup - Works with all file types
This commit is contained in:
parent
ea089075e6
commit
337d5d8087
@ -59,6 +59,16 @@ CREATE TABLE IF NOT EXISTS blacklisted_posts (
|
||||
url TEXT NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS library_meta (
|
||||
post_id INTEGER PRIMARY KEY,
|
||||
tags TEXT NOT NULL DEFAULT '',
|
||||
score INTEGER DEFAULT 0,
|
||||
rating TEXT,
|
||||
source TEXT,
|
||||
file_url TEXT,
|
||||
saved_at TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
@ -439,6 +449,34 @@ class Database:
|
||||
rows = self.conn.execute("SELECT url FROM blacklisted_posts").fetchall()
|
||||
return {r["url"] for r in rows}
|
||||
|
||||
# -- Library Metadata --
|
||||
|
||||
def save_library_meta(self, post_id: int, tags: str = "", score: int = 0,
|
||||
rating: str = None, source: str = None, file_url: str = None) -> None:
|
||||
from datetime import datetime, timezone
|
||||
self.conn.execute(
|
||||
"INSERT OR REPLACE INTO library_meta (post_id, tags, score, rating, source, file_url, saved_at) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
(post_id, tags, score, rating, source, file_url, datetime.now(timezone.utc).isoformat()),
|
||||
)
|
||||
self.conn.commit()
|
||||
|
||||
def get_library_meta(self, post_id: int) -> dict | None:
|
||||
row = self.conn.execute("SELECT * FROM library_meta WHERE post_id = ?", (post_id,)).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def search_library_meta(self, query: str) -> set[int]:
|
||||
"""Search library metadata by tags. Returns matching post IDs."""
|
||||
rows = self.conn.execute(
|
||||
"SELECT post_id FROM library_meta WHERE tags LIKE ?",
|
||||
(f"%{query}%",),
|
||||
).fetchall()
|
||||
return {r["post_id"] for r in rows}
|
||||
|
||||
def remove_library_meta(self, post_id: int) -> None:
|
||||
self.conn.execute("DELETE FROM library_meta WHERE post_id = ?", (post_id,))
|
||||
self.conn.commit()
|
||||
|
||||
# -- Settings --
|
||||
|
||||
def get_setting(self, key: str) -> str:
|
||||
|
||||
@ -360,7 +360,7 @@ class BooruApp(QMainWindow):
|
||||
self._bookmarks_view.bookmark_activated.connect(self._on_bookmark_activated)
|
||||
self._stack.addWidget(self._bookmarks_view)
|
||||
|
||||
self._library_view = LibraryView()
|
||||
self._library_view = LibraryView(db=self._db)
|
||||
self._library_view.file_selected.connect(self._on_library_selected)
|
||||
self._library_view.file_activated.connect(self._on_library_activated)
|
||||
self._stack.addWidget(self._library_view)
|
||||
@ -1781,6 +1781,12 @@ class BooruApp(QMainWindow):
|
||||
import shutil as _sh
|
||||
_sh.copy2(thumb_src, lib_thumb)
|
||||
|
||||
# Store metadata for library search
|
||||
self._db.save_library_meta(
|
||||
post_id=post.id, tags=post.tags, score=post.score,
|
||||
rating=post.rating, source=post.source, file_url=post.file_url,
|
||||
)
|
||||
|
||||
where = folder or "Unsorted"
|
||||
self._signals.bookmark_done.emit(
|
||||
self._grid.selected_index,
|
||||
|
||||
@ -15,6 +15,7 @@ from PySide6.QtWidgets import (
|
||||
QHBoxLayout,
|
||||
QPushButton,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QComboBox,
|
||||
QMenu,
|
||||
QMessageBox,
|
||||
@ -75,7 +76,11 @@ class LibraryView(QWidget):
|
||||
refresh_btn.clicked.connect(self.refresh)
|
||||
top.addWidget(refresh_btn)
|
||||
|
||||
top.addStretch(1)
|
||||
self._search_input = QLineEdit()
|
||||
self._search_input.setPlaceholderText("Search tags...")
|
||||
self._search_input.returnPressed.connect(self.refresh)
|
||||
top.addWidget(self._search_input, stretch=1)
|
||||
|
||||
layout.addLayout(top)
|
||||
|
||||
# --- Count label ---
|
||||
@ -107,6 +112,15 @@ class LibraryView(QWidget):
|
||||
self._files = self._scan_files()
|
||||
self._sort_files()
|
||||
|
||||
# Filter by tag search if query entered
|
||||
query = self._search_input.text().strip()
|
||||
if query and self._db:
|
||||
matching_ids = self._db.search_library_meta(query)
|
||||
if matching_ids:
|
||||
self._files = [f for f in self._files if f.stem.isdigit() and int(f.stem) in matching_ids]
|
||||
else:
|
||||
self._files = []
|
||||
|
||||
if self._files:
|
||||
self._count_label.setText(f"{len(self._files)} files")
|
||||
self._count_label.setStyleSheet("")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user