Show theme/DLC names and embedded theme previews in the library
This commit is contained in:
+51
-5
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user