mirror of
https://github.com/rommapp/romm.git
synced 2026-06-27 14:25:52 +00:00
changes from bot review
This commit is contained in:
@@ -394,13 +394,17 @@ class FSRomsHandler(FSHandler):
|
||||
|
||||
return kept_roms
|
||||
|
||||
def _iter_m3u_referenced_paths(self, abs_fs_path: Path, m3u_file_name: str) -> Iterator[Path]:
|
||||
def _iter_m3u_referenced_paths(
|
||||
self, abs_fs_path: Path, m3u_file_name: str
|
||||
) -> Iterator[Path]:
|
||||
m3u_path = Path(abs_fs_path, m3u_file_name)
|
||||
if not m3u_path.is_file():
|
||||
return
|
||||
|
||||
try:
|
||||
lines = m3u_path.read_text(encoding="utf-8-sig", errors="ignore").splitlines()
|
||||
lines = m3u_path.read_text(
|
||||
encoding="utf-8-sig", errors="ignore"
|
||||
).splitlines()
|
||||
except OSError:
|
||||
return
|
||||
|
||||
@@ -420,7 +424,7 @@ class FSRomsHandler(FSHandler):
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
if resolved_path.exists():
|
||||
if resolved_path.is_file():
|
||||
yield resolved_path
|
||||
|
||||
def _get_m3u_exclusions(
|
||||
@@ -689,6 +693,62 @@ class FSRomsHandler(FSHandler):
|
||||
)
|
||||
)
|
||||
|
||||
# When the ROM is a flat .m3u playlist, the referenced disc files are
|
||||
# hidden from the library listing (see _get_m3u_exclusions) but the
|
||||
# player needs them as selectable disc options. Append them regardless
|
||||
# of hashing; per-file hashes are only computed for hashable platforms.
|
||||
if rom.fs_name.lower().endswith(".m3u"):
|
||||
base_resolved = abs_fs_path.resolve()
|
||||
for ref_path in self._iter_m3u_referenced_paths(abs_fs_path, rom.fs_name):
|
||||
rel_within = ref_path.relative_to(base_resolved)
|
||||
|
||||
if hashable_platform:
|
||||
try:
|
||||
crc_c, _, md5_h, _, sha1_h, _ = await asyncio.to_thread(
|
||||
self._calculate_rom_hashes,
|
||||
ref_path,
|
||||
0,
|
||||
hashlib.md5(usedforsecurity=False),
|
||||
hashlib.sha1(usedforsecurity=False),
|
||||
)
|
||||
except zlib.error:
|
||||
crc_c = 0
|
||||
md5_h = hashlib.md5(usedforsecurity=False)
|
||||
sha1_h = hashlib.sha1(usedforsecurity=False)
|
||||
|
||||
file_hash = FileHash(
|
||||
crc_hash=crc32_to_hex(crc_c) if crc_c != DEFAULT_CRC_C else "",
|
||||
md5_hash=(
|
||||
md5_h.hexdigest()
|
||||
if md5_h.digest() != DEFAULT_MD5_H_DIGEST
|
||||
else ""
|
||||
),
|
||||
sha1_hash=(
|
||||
sha1_h.hexdigest()
|
||||
if sha1_h.digest() != DEFAULT_SHA1_H_DIGEST
|
||||
else ""
|
||||
),
|
||||
chd_sha1_hash=(
|
||||
extract_chd_hash(ref_path) if is_chd_file(ref_path) else ""
|
||||
),
|
||||
)
|
||||
else:
|
||||
file_hash = FileHash(
|
||||
crc_hash="",
|
||||
md5_hash="",
|
||||
sha1_hash="",
|
||||
chd_sha1_hash="",
|
||||
)
|
||||
|
||||
rom_files.append(
|
||||
self._build_rom_file(
|
||||
rom=rom,
|
||||
rom_path=Path(rel_roms_path, *rel_within.parts[:-1]),
|
||||
file_name=rel_within.name,
|
||||
file_hash=file_hash,
|
||||
)
|
||||
)
|
||||
|
||||
return ParsedRomFiles(
|
||||
rom_files=rom_files,
|
||||
crc_hash=crc32_to_hex(rom_crc_c) if rom_crc_c != DEFAULT_CRC_C else "",
|
||||
@@ -788,14 +848,15 @@ class FSRomsHandler(FSHandler):
|
||||
excluded_single_roms, excluded_multi_roms = self._get_m3u_exclusions(
|
||||
abs_fs_path, fs_single_roms, fs_multi_roms
|
||||
)
|
||||
return len(
|
||||
[
|
||||
rom
|
||||
for rom in self.exclude_single_files(fs_single_roms)
|
||||
if rom not in excluded_single_roms
|
||||
]
|
||||
) + len(
|
||||
[rom for rom in self.exclude_multi_roms(fs_multi_roms) if rom not in excluded_multi_roms]
|
||||
|
||||
return sum(
|
||||
1
|
||||
for rom in self.exclude_single_files(fs_single_roms)
|
||||
if rom not in excluded_single_roms
|
||||
) + sum(
|
||||
1
|
||||
for rom in self.exclude_multi_roms(fs_multi_roms)
|
||||
if rom not in excluded_multi_roms
|
||||
)
|
||||
|
||||
async def get_roms(self, platform: Platform) -> list[FSRom]:
|
||||
|
||||
@@ -446,7 +446,9 @@ class TestFSRomsHandler:
|
||||
|
||||
try:
|
||||
with pytest.MonkeyPatch.context() as m:
|
||||
m.setattr("handler.filesystem.roms_handler.cm.get_config", lambda: config)
|
||||
m.setattr(
|
||||
"handler.filesystem.roms_handler.cm.get_config", lambda: config
|
||||
)
|
||||
roms = await handler.get_roms(platform)
|
||||
rom_count = await handler.count_roms(platform)
|
||||
|
||||
@@ -461,6 +463,66 @@ class TestFSRomsHandler:
|
||||
if disc_dir.exists():
|
||||
shutil.rmtree(disc_dir)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_rom_files_m3u_includes_referenced_discs_without_hashing(
|
||||
self, handler: FSRomsHandler, platform: Platform
|
||||
):
|
||||
"""A flat .m3u ROM must expose its referenced disc files in rom_files
|
||||
even when hashing is disabled, so the player can offer disc selection."""
|
||||
m3u_name = "Final Fantasy IX.m3u"
|
||||
m3u_path = handler.base_path / "n64/roms" / m3u_name
|
||||
disc_1 = handler.base_path / "n64/roms" / "Final Fantasy IX (Disc 1).chd"
|
||||
disc_2 = handler.base_path / "n64/roms" / "Final Fantasy IX (Disc 2).chd"
|
||||
|
||||
m3u_path.write_text(
|
||||
"Final Fantasy IX (Disc 1).chd\nFinal Fantasy IX (Disc 2).chd\n"
|
||||
)
|
||||
disc_1.write_bytes(b"disc-1")
|
||||
disc_2.write_bytes(b"disc-2")
|
||||
|
||||
rom = Rom(
|
||||
id=42,
|
||||
fs_name=m3u_name,
|
||||
fs_path="n64/roms",
|
||||
fs_extension="m3u",
|
||||
platform=platform,
|
||||
full_path=f"n64/roms/{m3u_name}",
|
||||
)
|
||||
|
||||
config = Config(
|
||||
EXCLUDED_PLATFORMS=[],
|
||||
EXCLUDED_SINGLE_EXT=[],
|
||||
EXCLUDED_SINGLE_FILES=[],
|
||||
EXCLUDED_MULTI_FILES=[],
|
||||
EXCLUDED_MULTI_PARTS_EXT=[],
|
||||
EXCLUDED_MULTI_PARTS_FILES=[],
|
||||
PLATFORMS_BINDING={},
|
||||
PLATFORMS_VERSIONS={},
|
||||
ROMS_FOLDER_NAME="roms",
|
||||
FIRMWARE_FOLDER_NAME="bios",
|
||||
)
|
||||
|
||||
try:
|
||||
with pytest.MonkeyPatch.context() as m:
|
||||
m.setattr(
|
||||
"handler.filesystem.roms_handler.cm.get_config", lambda: config
|
||||
)
|
||||
parsed = await handler.get_rom_files(rom, calculate_hashes=False)
|
||||
|
||||
file_names = [f.file_name for f in parsed.rom_files]
|
||||
assert m3u_name in file_names
|
||||
assert "Final Fantasy IX (Disc 1).chd" in file_names
|
||||
assert "Final Fantasy IX (Disc 2).chd" in file_names
|
||||
# Hashing disabled: no per-file hashes populated
|
||||
for f in parsed.rom_files:
|
||||
assert f.crc_hash == ""
|
||||
assert f.md5_hash == ""
|
||||
assert f.sha1_hash == ""
|
||||
finally:
|
||||
m3u_path.unlink(missing_ok=True)
|
||||
disc_1.unlink(missing_ok=True)
|
||||
disc_2.unlink(missing_ok=True)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_rom_files_multi_rom_multi_dot_exclusion(
|
||||
self, handler: FSRomsHandler, rom_multi
|
||||
|
||||
Reference in New Issue
Block a user