Coverage for src/ph/models.py: 100.0%
27 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-28 08:17 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-28 08:17 +0000
1"""Typed domain models shared by the client and user interfaces."""
3from dataclasses import dataclass
4from pathlib import Path
7@dataclass(frozen=True, slots=True)
8class Platform:
9 """A searchable platform and its accepted user-facing names."""
11 name: str
12 slug: str
13 code: str
14 alias: str
15 rom_folder: str | None = None
16 alternate_folders: tuple[str, ...] = ()
18 @property
19 def rom_folders(self) -> tuple[str, ...]:
20 """Return every accepted folder, with the preferred destination first."""
22 if self.rom_folder is None:
23 return ()
24 return (self.rom_folder, *self.alternate_folders)
27@dataclass(frozen=True, slots=True)
28class SearchResult:
29 """One row returned by a library search."""
31 title: str
32 link: str
33 system: str = ""
34 region: str = ""
35 version: str = ""
36 languages: str = "-"
37 rating: str = "-"
40@dataclass(frozen=True, slots=True)
41class DownloadResult:
42 """A completed download."""
44 url: str
45 path: Path
48@dataclass(frozen=True, slots=True)
49class MediaDownload:
50 """A resolved media download, optionally selecting one file from a torrent."""
52 url: str
53 torrent_file_index: int | None = None
54 expected_filename: str | None = None
55 torrent_file_path: tuple[str, ...] | None = None
58@dataclass(frozen=True, slots=True)
59class InstalledGame:
60 """One installed title, optionally composed of several referenced files."""
62 title: str
63 platform: Platform
64 roms_directory: Path
65 primary_file: Path
66 files: tuple[Path, ...]