-
-
Notifications
You must be signed in to change notification settings - Fork 622
Expand file tree
/
Copy pathplatforms.py
More file actions
153 lines (130 loc) · 5.45 KB
/
Copy pathplatforms.py
File metadata and controls
153 lines (130 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from datetime import datetime, timezone
from config.config_manager import config_manager as cm
from endpoints.responses.platform import PlatformSchema
from handler.database import db_platform_handler
from handler.filesystem import fs_platform_handler
from handler.metadata import (
meta_flashpoint_handler,
meta_hasheous_handler,
meta_hltb_handler,
meta_igdb_handler,
meta_launchbox_handler,
meta_moby_handler,
meta_ra_handler,
meta_ss_handler,
meta_tgdb_handler,
)
from handler.metadata.base_handler import UniversalPlatformSlug as UPS
from models.platform import Platform
def _build_unmatched_platform(slug: str, fs_slug: str, now: datetime) -> PlatformSchema:
"""Build a PlatformSchema for a platform that has no database row yet.
Metadata is resolved from the local provider catalogs only (no network
calls). The entry carries id -1 and rom_count 0, matching the shape used
for unmatched supported platforms.
"""
igdb_platform = meta_igdb_handler.get_platform(slug)
moby_platform = meta_moby_handler.get_platform(slug)
ss_platform = meta_ss_handler.get_platform(slug)
ra_platform = meta_ra_handler.get_platform(slug)
launchbox_platform = meta_launchbox_handler.get_platform(slug)
hasheous_platform = meta_hasheous_handler.get_platform(slug)
tgdb_platform = meta_tgdb_handler.get_platform(slug)
flashpoint_platform = meta_flashpoint_handler.get_platform(slug)
hltb_platform = meta_hltb_handler.get_platform(slug)
platform_attrs = {
"id": -1,
"name": slug.replace("-", " ").title(),
"fs_slug": fs_slug,
"slug": slug,
"roms": [],
"rom_count": 0,
"created_at": now,
"updated_at": now,
"fs_size_bytes": 0,
"missing_from_fs": False,
}
platform_attrs.update(
{
**hltb_platform,
**flashpoint_platform,
**hasheous_platform,
**tgdb_platform,
**launchbox_platform,
**ra_platform,
**moby_platform,
**ss_platform,
**igdb_platform,
"igdb_id": igdb_platform.get("igdb_id")
or hasheous_platform.get("igdb_id")
or None,
"ra_id": ra_platform.get("ra_id") or hasheous_platform.get("ra_id") or None,
"tgdb_id": moby_platform.get("tgdb_id")
or hasheous_platform.get("tgdb_id")
or tgdb_platform.get("tgdb_id")
or None,
"name": igdb_platform.get("name")
or ss_platform.get("name")
or moby_platform.get("name")
or ra_platform.get("name")
or launchbox_platform.get("name")
or hasheous_platform.get("name")
or tgdb_platform.get("name")
or flashpoint_platform.get("name")
or hltb_platform.get("name")
or slug.replace("-", " ").title(),
"url_logo": igdb_platform.get("url_logo")
or tgdb_platform.get("url_logo")
or "",
}
)
return PlatformSchema.model_validate(Platform(**platform_attrs))
def get_supported_platforms() -> list[PlatformSchema]:
"""Get all supported platforms with metadata from various sources.
Returns:
List of platform dictionaries with metadata from IGDB, MobyGames,
ScreenScraper, RetroAchievements, Launchbox, Hasheous, TGDB,
Flashpoint, and HowLongToBeat.
"""
db_platforms = db_platform_handler.get_platforms()
# Multiple folders can resolve to the same slug (a folder alias or a
# platform variant bound to a parent platform). When that happens, prefer
# the canonical platform (the one whose fs_slug matches its slug) so a
# variant folder doesn't shadow the parent and rename it in the picker.
db_platforms_map: dict[str, Platform] = {}
for p in db_platforms:
existing = db_platforms_map.get(p.slug)
if existing is None or p.fs_slug == p.slug:
db_platforms_map[p.slug] = p
now = datetime.now(timezone.utc)
supported_platforms = []
for upslug in UPS:
slug = upslug.value
db_platform = db_platforms_map.get(slug, None)
if db_platform:
supported_platforms.append(PlatformSchema.model_validate(db_platform))
continue
supported_platforms.append(_build_unmatched_platform(slug, slug, now))
return supported_platforms
async def get_filesystem_platforms() -> list[PlatformSchema]:
"""Get platform folders that exist on disk but have no database row yet.
A folder created for a platform (optionally bound in Library Management)
has no database row until its first scan imports a ROM, so it is invisible
to the scan platform picker. Surfacing these folders lets a first scan
target a brand-new platform. Slugs are resolved through the platform
binding/version config; metadata is resolved locally (no network calls).
"""
cnfg = cm.get_config()
fs_slugs = await fs_platform_handler.get_platforms()
existing_fs_slugs = {p.fs_slug for p in db_platform_handler.get_platforms()}
now = datetime.now(timezone.utc)
filesystem_platforms = []
for fs_slug in fs_slugs:
if fs_slug in existing_fs_slugs:
continue
slug = (
cnfg.PLATFORMS_BINDING.get(fs_slug)
or cnfg.PLATFORMS_VERSIONS.get(fs_slug)
or fs_slug
)
filesystem_platforms.append(_build_unmatched_platform(slug, fs_slug, now))
return filesystem_platforms