Skip to content

Commit b5776be

Browse files
committed
Split rom.multi into more specific fields
1 parent 54e2bcf commit b5776be

File tree

14 files changed

+87
-37
lines changed

14 files changed

+87
-37
lines changed

backend/endpoints/responses/rom.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import re
44
from datetime import datetime, timezone
5-
from typing import NotRequired, TypedDict, get_type_hints
5+
from typing import Annotated, NotRequired, TypedDict, get_type_hints
66

77
from fastapi import Request
8-
from pydantic import computed_field, field_validator
8+
from pydantic import Field, computed_field, field_validator
99

1010
from endpoints.responses.assets import SaveSchema, ScreenshotSchema, StateSchema
1111
from handler.metadata.flashpoint_handler import FlashpointMetadata
@@ -255,7 +255,11 @@ class RomSchema(BaseModel):
255255
md5_hash: str | None
256256
sha1_hash: str | None
257257

258-
multi: bool
258+
# TODO: Remove this after 4.3 release
259+
multi: Annotated[int, Field(deprecated="Replaced by has_multiple_files")]
260+
has_simple_single_file: bool
261+
has_nested_single_file: bool
262+
has_multiple_files: bool
259263
files: list[RomFileSchema]
260264
full_path: str
261265
created_at: datetime

backend/endpoints/rom.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ async def head_rom_content(
378378
if file_ids:
379379
file_id_values = {int(f.strip()) for f in file_ids.split(",") if f.strip()}
380380
files = [f for f in rom.files if f.id in file_id_values]
381+
381382
files.sort(key=lambda x: x.file_name)
382383

383384
# Serve the file directly in development mode for emulatorjs

backend/endpoints/sockets/scan.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ async def _identify_rom(
200200
tags=fs_other_tags,
201201
platform_id=platform.id,
202202
name=fs_rom["fs_name"],
203-
multi=fs_rom["multi"],
204203
url_cover="",
205204
url_manual="",
206205
url_screenshots=[],

backend/handler/filesystem/roms_handler.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@
9393

9494

9595
class FSRom(TypedDict):
96-
multi: bool
9796
fs_name: str
97+
flat: bool
98+
nested: bool
9899
files: list[RomFile]
99100
crc_hash: str
100101
md5_hash: str
@@ -247,7 +248,7 @@ def parse_tags(self, fs_name: str) -> tuple:
247248
other_tags.append(tag)
248249
return regs, rev, langs, other_tags
249250

250-
def _exclude_multi_roms(self, roms: list[str]) -> list[str]:
251+
def exclude_multi_roms(self, roms: list[str]) -> list[str]:
251252
excluded_names = cm.get_config().EXCLUDED_MULTI_FILES
252253
filtered_files: list = []
253254

@@ -511,18 +512,19 @@ async def get_roms(self, platform: Platform) -> list[FSRom]:
511512
raise RomsNotFoundException(platform=platform.fs_slug) from e
512513

513514
fs_roms: list[dict] = [
514-
{"multi": False, "fs_name": rom}
515+
{"fs_name": rom, "flat": True, "nested": False}
515516
for rom in self.exclude_single_files(fs_single_roms)
516517
] + [
517-
{"multi": True, "fs_name": rom}
518-
for rom in self._exclude_multi_roms(fs_multi_roms)
518+
{"fs_name": rom, "flat": False, "nested": True}
519+
for rom in self.exclude_multi_roms(fs_multi_roms)
519520
]
520521

521522
return sorted(
522523
[
523524
FSRom(
524-
multi=rom["multi"],
525525
fs_name=rom["fs_name"],
526+
flat=rom["flat"],
527+
nested=rom["nested"],
526528
files=[],
527529
crc_hash="",
528530
md5_hash="",

backend/handler/scan_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ async def scan_rom(
295295
"platform_id": platform.id,
296296
"name": fs_rom["fs_name"],
297297
"fs_name": fs_rom["fs_name"],
298-
"multi": fs_rom["multi"],
299298
"crc_hash": fs_rom["crc_hash"],
300299
"md5_hash": fs_rom["md5_hash"],
301300
"sha1_hash": fs_rom["sha1_hash"],
@@ -741,7 +740,8 @@ async def fetch_sgdb_details() -> SGDBRom:
741740
f"{hl(rom_attrs['fs_name'])} identified as {hl(rom_attrs['name'], color=BLUE)} {emoji.EMOJI_ALIEN_MONSTER}",
742741
extra=LOGGER_MODULE_NAME,
743742
)
744-
if rom.multi:
743+
744+
if rom.has_nested_single_file or rom.has_multiple_files:
745745
for file in fs_rom["files"]:
746746
log.info(
747747
f"\t · {hl(file.file_name, color=LIGHTYELLOW)}",

backend/models/rom.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ def file_extension(self) -> str:
100100

101101
return fs_rom_handler.parse_file_extension(self.file_name)
102102

103+
@cached_property
104+
def is_nested(self) -> bool:
105+
return self.file_path.count("/") > 1
106+
103107
def file_name_for_download(self, rom: Rom, hidden_folder: bool = False) -> str:
104108
# This needs a trailing slash in the path to work!
105109
return self.full_path.replace(
@@ -286,11 +290,22 @@ def merged_screenshots(self) -> list[str]:
286290

287291
return []
288292

293+
# TODO: Remove this after 4.3 release
289294
@cached_property
290295
def multi(self) -> bool:
291-
return len(self.files) > 1 or (
292-
len(self.files) > 0 and len(self.files[0].full_path.split("/")) > 3
293-
)
296+
return self.has_nested_single_file or self.has_multiple_files
297+
298+
@cached_property
299+
def has_simple_single_file(self) -> bool:
300+
return len(self.files) == 1 and not self.files[0].is_nested
301+
302+
@cached_property
303+
def has_nested_single_file(self) -> bool:
304+
return len(self.files) == 1 and self.files[0].is_nested
305+
306+
@cached_property
307+
def has_multiple_files(self) -> bool:
308+
return len(self.files) > 1
294309

295310
@property
296311
def fs_resources_path(self) -> str:

backend/tests/handler/filesystem/test_roms_handler.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,24 @@ def rom_single(self, platform: Platform):
4848

4949
@pytest.fixture
5050
def rom_multi(self, platform: Platform):
51-
rom = Rom(
51+
return Rom(
5252
id=2,
5353
fs_name="Super Mario 64 (J) (Rev A)",
5454
fs_path="n64/roms",
5555
platform=platform,
56+
files=[
57+
RomFile(
58+
id=1,
59+
file_name="Super Mario 64 (J) (Rev A) [Part 1].z64",
60+
file_path="n64/roms",
61+
),
62+
RomFile(
63+
id=2,
64+
file_name="Super Mario 64 (J) (Rev A) [Part 2].z64",
65+
file_path="n64/roms",
66+
),
67+
],
5668
)
57-
rom.multi = True
58-
return rom
5969

6070
def test_init_uses_library_base_path(self, handler: FSRomsHandler):
6171
"""Test that FSRomsHandler initializes with LIBRARY_BASE_PATH"""
@@ -154,20 +164,20 @@ def test_parse_tags_no_tags(self, handler: FSRomsHandler):
154164
assert languages == []
155165
assert other_tags == []
156166

157-
def test_exclude_multi_roms_filters_excluded(self, handler: FSRomsHandler, config):
158-
"""Test _exclude_multi_roms filters out excluded multi-file ROMs"""
167+
def testexclude_multi_roms_filters_excluded(self, handler: FSRomsHandler, config):
168+
"""Test exclude_multi_roms filters out excluded multi-file ROMs"""
159169
roms = ["Game1", "excluded_multi", "Game2", "Game3"]
160170

161171
with pytest.MonkeyPatch.context() as m:
162172
m.setattr("handler.filesystem.roms_handler.cm.get_config", lambda: config)
163173

164-
result = handler._exclude_multi_roms(roms)
174+
result = handler.exclude_multi_roms(roms)
165175
expected = ["Game1", "Game2", "Game3"]
166176

167177
assert result == expected
168178

169-
def test_exclude_multi_roms_no_exclusions(self, handler: FSRomsHandler):
170-
"""Test _exclude_multi_roms with no exclusions"""
179+
def testexclude_multi_roms_no_exclusions(self, handler: FSRomsHandler):
180+
"""Test exclude_multi_roms with no exclusions"""
171181
roms = ["Game1", "Game2", "Game3"]
172182
config = Config(
173183
EXCLUDED_PLATFORMS=[],
@@ -185,7 +195,7 @@ def test_exclude_multi_roms_no_exclusions(self, handler: FSRomsHandler):
185195
with pytest.MonkeyPatch.context() as m:
186196
m.setattr("handler.filesystem.roms_handler.cm.get_config", lambda: config)
187197

188-
result = handler._exclude_multi_roms(roms)
198+
result = handler.exclude_multi_roms(roms)
189199
assert result == roms
190200

191201
def test_build_rom_file_single_file(self, handler: FSRomsHandler):
@@ -254,8 +264,8 @@ async def test_get_roms(self, handler: FSRomsHandler, platform, config):
254264
assert len(result) > 0
255265

256266
# Check that we have both single and multi ROMs
257-
single_roms = [r for r in result if not r["multi"]]
258-
multi_roms = [r for r in result if r["multi"]]
267+
single_roms = [r for r in result if not r["flat"]]
268+
multi_roms = [r for r in result if r["nested"]]
259269

260270
assert len(single_roms) > 0
261271
assert len(multi_roms) > 0
@@ -477,7 +487,7 @@ async def test_multi_rom_directory_handling(self, handler: FSRomsHandler, config
477487
assert "Test Multi Rom [USA]" in directories
478488

479489
# After exclusion, normal directories should remain
480-
filtered_dirs = handler._exclude_multi_roms(directories)
490+
filtered_dirs = handler.exclude_multi_roms(directories)
481491
assert "Super Mario 64 (J) (Rev A)" in filtered_dirs
482492
assert "Test Multi Rom [USA]" in filtered_dirs
483493

backend/tests/handler/test_fastapi.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ async def test_scan_rom():
4242
igdb_id=3340,
4343
fs_size_bytes=1024,
4444
tags=[],
45-
multi=False,
4645
)
4746

4847
async with initialize_context():
@@ -52,7 +51,6 @@ async def test_scan_rom():
5251
rom=rom,
5352
fs_rom={
5453
"fs_name": "Paper Mario (USA).z64",
55-
"multi": False,
5654
"files": [
5755
RomFile(
5856
file_name="Paper Mario (USA).z64",
@@ -76,4 +74,5 @@ async def test_scan_rom():
7674
assert rom.igdb_id == 3340
7775
assert rom.fs_size_bytes == 1024
7876
assert rom.tags == []
79-
assert not rom.multi
77+
assert rom.has_simple_single_file
78+
assert not rom.has_multiple_files

frontend/src/__generated__/models/DetailedRomSchema.ts

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/src/__generated__/models/SimpleRomSchema.ts

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)