Show theme/DLC names and embedded theme previews in the library

This commit is contained in:
2026-09-08 17:32:11 -04:00
parent 1be33be4ab
commit c03f4619e6
3 changed files with 574 additions and 5 deletions
+51 -5
View File
@@ -5,6 +5,7 @@ Run with::
python3 -m app.main
"""
import datetime
import json
import logging
import sys
import threading
@@ -20,7 +21,7 @@ from PySide6.QtWidgets import (
QTabWidget, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget,
)
from . import config, covers, info, iso_reader, launcher, matcher, namer, pipeline, ps1, psp, queue, saves, scanner, sources, store, transfers
from . import config, covers, info, iso_reader, launcher, matcher, namer, pipeline, ps1, psp, queue, saves, scanner, sources, store, theme, transfers
from .db import get_connection, init_db
log = logging.getLogger("gui")
@@ -376,6 +377,13 @@ class CoverShowcase(QWidget):
item.setTextAlignment(Qt.AlignHCenter | Qt.AlignTop)
item.setToolTip(it["name"])
item.setData(Qt.UserRole, it)
# Themes/DLC show their locally-extracted preview (no scraping).
if not covers.is_scrapable(it.get("system")):
rid = it.get("release_id")
system = it.get("system")
path = covers.cover_path(rid, system)
if path is not None and path.exists() and covers.file_is_image(path):
item.setIcon(self._fit_icon(QPixmap(str(path))))
self.list.addItem(item)
self._start_loader(gen)
@@ -3331,18 +3339,56 @@ def _nps_library_items(nps_dir, overrides, dates):
theme_dir = root / "THEME"
if theme_dir.is_dir():
for ptf in sorted(theme_dir.rglob("*")):
if ptf.is_file() and ptf.suffix.lower() == ".ptf":
out.append(_nps_extra_item(ptf, "theme", ptf.stem))
if not ptf.is_file() or ptf.suffix.lower() != ".ptf":
continue
folder = ptf.parent
name = _sidecar_name(folder) or theme.ptf_name(ptf) or ptf.stem
item = _nps_extra_item(ptf, "theme", name)
item["release_id"] = covers.stable_key(name)
_write_theme_cover(ptf, item["release_id"])
out.append(item)
# DLC: <nps>/DLC/<GAME_ID>/<name>.edat
dlc_dir = root / "DLC"
if dlc_dir.is_dir():
for edat in sorted(dlc_dir.rglob("*")):
if edat.is_file() and edat.suffix.lower() == ".edat":
out.append(_nps_extra_item(edat, "dlc", edat.stem))
if not edat.is_file() or edat.suffix.lower() != ".edat":
continue
name = _sidecar_name(edat.parent) or edat.stem
out.append(_nps_extra_item(edat, "dlc", name))
return out
def _sidecar_name(folder):
"""Read a display name saved next to a downloaded NPS item, if present."""
try:
meta = json.loads((Path(folder) / "meta.json").read_text(encoding="utf-8"))
except (OSError, ValueError):
return ""
return (meta.get("name") or "").strip()
def _write_theme_cover(ptf_path, rid):
"""Extract a theme's embedded preview into the cover cache (idempotent)."""
path = covers.cover_path(rid, "theme")
if path.exists() and covers.file_is_image(path):
return
try:
res = theme.theme_preview_rgba(ptf_path)
except Exception: # noqa: BLE001
res = None
if not res:
return
w, h, rgba = res
img = QImage(rgba, w, h, w * 4, QImage.Format_RGBA8888)
if img.isNull():
return
try:
img.save(str(path), "PNG")
except OSError:
pass
def _nps_extra_item(path, psp_kind, name):
try:
size = path.stat().st_size