Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions backend/handler/metadata/ss_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,29 @@


def get_preferred_regions(rom: Rom | None = None) -> list[str]:
"""Get preferred regions, prepending the rom's own region tags when available."""
"""Get preferred regions, prepending the rom's own region tags when available.

When a rom is tagged with multiple regions (e.g. "(Japan, USA)"), the rom's
own tags are reordered according to the user's SCAN_REGION_PRIORITY so the
user's preference wins among the regions the file is actually tagged as.
Filename-tagged regions not present in the priority list keep their relative
order and follow the prioritized ones.
"""
config = cm.get_config()
priority = config.SCAN_REGION_PRIORITY

rom_codes: list[str] = []
if rom is not None and isinstance(rom.regions, list):
for region_name in rom.regions:
code = region_name_to_provider_shortcode(region_name)
if code:
rom_codes.append(code)
rom_codes.sort(
key=lambda code: priority.index(code) if code in priority else len(priority)
)

config = cm.get_config()
return list(
dict.fromkeys(
rom_codes
+ config.SCAN_REGION_PRIORITY
+ ["us", "wor", "ss", "eu", "jp", "cus"]
)
dict.fromkeys(rom_codes + priority + ["us", "wor", "ss", "eu", "jp", "cus"])
) + ["unk"]


Expand Down
34 changes: 34 additions & 0 deletions backend/tests/handler/metadata/test_ss_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,40 @@ def test_no_duplicates(self):

assert len(regions) == len(set(regions))

def test_multi_region_rom_respects_user_priority(self):
"""For a multi-region ROM, the user's priority order wins among the
regions the file is tagged as."""
rom = MagicMock()
rom.regions = ["Japan", "USA"]
config = _make_config(region_priority=["us", "eu"])
with patch("handler.metadata.ss_handler.cm.get_config", return_value=config):
regions = get_preferred_regions(rom)

assert regions.index("us") < regions.index("jp")

def test_multi_region_rom_untagged_priority_does_not_win(self):
"""A region in SCAN_REGION_PRIORITY that the file is NOT tagged as
should not outrank a region the file IS tagged as."""
rom = MagicMock()
rom.regions = ["Japan", "USA"]
config = _make_config(region_priority=["eu", "us"])
with patch("handler.metadata.ss_handler.cm.get_config", return_value=config):
regions = get_preferred_regions(rom)

assert regions.index("us") < regions.index("eu")
assert regions.index("jp") < regions.index("eu")

def test_multi_region_rom_unprioritized_tags_preserve_order(self):
"""Filename regions not in the priority list keep their filename order
and follow the prioritized ones."""
rom = MagicMock()
rom.regions = ["Japan", "Brazil"]
config = _make_config(region_priority=["us"])
with patch("handler.metadata.ss_handler.cm.get_config", return_value=config):
regions = get_preferred_regions(rom)

assert regions.index("jp") < regions.index("br")


class TestExtractMediaFromSsGame:
"""Tests for extract_media_from_ss_game."""
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/locales/en_GB/scan.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"roms-scanned-with-details": "ROMs: {n_scanned_roms} scanned out of {n_total_roms}, with {n_new_roms} new and {n_identified_roms} identified",
"scan": "Scan",
"scan-options": "Scan options",
"scan-types-info": "<strong>New Platforms:</strong> This will only look for platforms that are not already in RomM.<br><br><strong>Quick Scan:</strong> Scans for games that are not in the library yet (fastest).<br><br><strong>Unmatched Games:</strong> Attempts to match games that are not matched with the selected metadata sources.<br>For example, selecting IGDB and ScreenScraper will scan games that are not matched with IGDB or ScreenScraper.<br><br><strong>Update Metadata:</strong> Updates the metadata for games that have been matched with selected metadata sources using the external ID (e.g. IGDB ID).<br>For example, selecting IGDB and ScreenScraper will update the metadata for games that are matched with IGDB or ScreenScraper, and will use igdb_id and/or ssfr_id to refetch the metadata from the respective providers.<br><br><strong>Recalculate Hashes:</strong> Recalculates hashes for all files in the selected platforms.<br><br><strong>Total Rescan:</strong> Rescans and rematches all games in the selected platforms (slowest).<br>This will wipe all existing metadata matches, including the external IDs, and attempt to match them again, like on a fresh scan. Saves, states and notes will be preserved.",
"scan-types-info": "<strong>New Platforms:</strong> This will only look for platforms that are not already in RomM.<br><br><strong>Quick Scan:</strong> Scans for games that are not in the library yet (fastest).<br><br><strong>Unmatched Games:</strong> Attempts to match games that are not matched with the selected metadata sources.<br>For example, selecting IGDB and ScreenScraper will scan games that are not matched with IGDB or ScreenScraper.<br><br><strong>Update Metadata:</strong> Updates the metadata for games that have been matched with selected metadata sources using the external ID (e.g. IGDB ID).<br>For example, selecting IGDB and ScreenScraper will update the metadata for games that are matched with IGDB or ScreenScraper, and will use igdb_id and/or ssfr_id to refetch the metadata from the respective providers.<br><br><strong>Recalculate Hashes:</strong> Recalculates hashes for all files in the selected platforms.<br><br><strong>Complete Rescan:</strong> Rescans and rematches all games in the selected platforms (slowest).<br>This will wipe all existing metadata matches, including the external IDs, and attempt to match them again, like on a fresh scan. Saves, states and notes will be preserved.",
"scan-types-more-info": "More information",
"select-one-source": "Please select at least one metadata source to enrich your library with artwork and metadata",
"unmatched-games": "Unmatched games",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/locales/en_US/scan.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"roms-scanned-with-details": "ROMs: {n_scanned_roms} scanned out of {n_total_roms}, with {n_new_roms} new and {n_identified_roms} identified",
"scan": "Scan",
"scan-options": "Scan options",
"scan-types-info": "<strong>New Platforms:</strong> This will only look for platforms that are not already in RomM.<br><br><strong>Quick Scan:</strong> Scans for games that are not in the library yet (fastest).<br><br><strong>Unmatched Games:</strong> Attempts to match games that are not matched with the selected metadata sources.<br>For example, selecting IGDB and ScreenScraper will scan games that are not matched with IGDB or ScreenScraper.<br><br><strong>Update Metadata:</strong> Updates the metadata for games that have been matched with selected metadata sources using the external ID (e.g. IGDB ID).<br>For example, selecting IGDB and ScreenScraper will update the metadata for games that are matched with IGDB or ScreenScraper, and will use igdb_id and/or ssfr_id to refetch the metadata from the respective providers.<br><br><strong>Recalculate Hashes:</strong> Recalculates hashes for all files in the selected platforms.<br><br><strong>Total Rescan:</strong> Rescans and rematches all games in the selected platforms (slowest).<br>This will wipe all existing metadata matches, including the external IDs, and attempt to match them again, like on a fresh scan. Saves, states and notes will be preserved.",
"scan-types-info": "<strong>New Platforms:</strong> This will only look for platforms that are not already in RomM.<br><br><strong>Quick Scan:</strong> Scans for games that are not in the library yet (fastest).<br><br><strong>Unmatched Games:</strong> Attempts to match games that are not matched with the selected metadata sources.<br>For example, selecting IGDB and ScreenScraper will scan games that are not matched with IGDB or ScreenScraper.<br><br><strong>Update Metadata:</strong> Updates the metadata for games that have been matched with selected metadata sources using the external ID (e.g. IGDB ID).<br>For example, selecting IGDB and ScreenScraper will update the metadata for games that are matched with IGDB or ScreenScraper, and will use igdb_id and/or ssfr_id to refetch the metadata from the respective providers.<br><br><strong>Recalculate Hashes:</strong> Recalculates hashes for all files in the selected platforms.<br><br><strong>Complete Rescan:</strong> Rescans and rematches all games in the selected platforms (slowest).<br>This will wipe all existing metadata matches, including the external IDs, and attempt to match them again, like on a fresh scan. Saves, states and notes will be preserved.",
"scan-types-more-info": "More information",
"select-one-source": "Please select at least one metadata source to enrich your library with artwork and metadata",
"unmatched-games": "Unmatched games",
Expand Down
Loading