Add NoPayStation themes, DLC and minis support

This commit is contained in:
2026-09-07 23:34:56 -04:00
parent 398c9f5dad
commit c94bcdc993
5 changed files with 282 additions and 62 deletions
+12 -6
View File
@@ -22,7 +22,12 @@ from . import config
log = logging.getLogger("nopaystation")
_TSV_NAMES = {"psp": "PSP_GAMES.tsv", "psx": "PSX_GAMES.tsv"}
_TSV_NAMES = {
"psp": "PSP_GAMES.tsv",
"psx": "PSX_GAMES.tsv",
"theme": "PSP_THEMES.tsv",
"dlc": "PSP_DLCS.tsv",
}
# NoPayStation TSVs are tab-separated with a header row whose exact columns
# differ per platform (PSP has "Type"/"RAP" columns, PSX has "Original Name").
@@ -45,7 +50,7 @@ _HEADER_ALIASES = {
def tsv_url(content_type: str, base: str = "") -> str:
"""TSV URL for a content type (``psp`` / ``psx``)."""
"""TSV URL for a content type (``psp`` / ``psx`` / ``theme`` / ``dlc``)."""
base = (base or config.NPS_TSV_BASE).rstrip("/")
return f"{base}/{_TSV_NAMES.get(content_type, _TSV_NAMES['psp'])}"
@@ -76,7 +81,7 @@ def parse_tsv(text: str, content_type: str) -> List[dict]:
``release_date``, ``mtime_ns``) plus ``title_id``, ``pkg_url``, ``sha256``,
``content_type`` and the cover ``system`` ("games" for PSP, "ps1" for PSX).
"""
system = "games" if content_type == "psp" else "ps1"
system = {"psp": "games", "psx": "ps1", "theme": "theme", "dlc": "dlc"}.get(content_type, "games")
items: List[dict] = []
header = None
for line in text.splitlines():
@@ -187,7 +192,7 @@ def _ensure_keys_bin(folder, kind):
def extract_pkg(pkg_path, title_id: str, dest_dir, pkg2zip: Path = None,
progress_cb=None, cancel_event=None) -> Path:
kind_hint: str = None, progress_cb=None, cancel_event=None) -> Path:
"""Decrypt/extract a ``.pkg`` into ``dest_dir/<TITLE_ID>/``.
Uses the bundled pure-Python decryptor (no Wine / pkg2zip needed); falls
@@ -199,12 +204,13 @@ def extract_pkg(pkg_path, title_id: str, dest_dir, pkg2zip: Path = None,
pkg_path = Path(pkg_path)
dest = Path(dest_dir) / _safe_folder(title_id)
if (dest / "EBOOT.PBP").exists():
if dest.is_dir() and any(dest.iterdir()):
return dest
# 1. Pure-Python decryptor (primary).
try:
_kind, _tid, folder = pkgmod.extract(pkg_path, dest_dir, progress_cb, cancel_event)
_kind, _tid, folder = pkgmod.extract(pkg_path, dest_dir, kind_hint,
progress_cb, cancel_event)
_ensure_keys_bin(folder, _kind)
return folder
except TransferCancelled: