76 lines
2.7 KiB
Python
76 lines
2.7 KiB
Python
"""Choosing which asset in a release belongs to this game."""
|
|
|
|
import re
|
|
|
|
from archipelago_tester.core.model.name import Name
|
|
|
|
|
|
class AssetMatcher:
|
|
"""Matches release assets and release titles to one sheet row."""
|
|
|
|
def __init__(self, config, game_name):
|
|
self.config = config
|
|
self.game = Name(game_name)
|
|
|
|
def named(self, assets, exact):
|
|
"""The assets whose filename names this game."""
|
|
matched = []
|
|
for asset in assets:
|
|
name = Name(asset["name"].rsplit(".", 1)[0]).slug
|
|
if (name == self.game.slug) if exact else (name in self.game.slug):
|
|
matched.append(asset)
|
|
return matched
|
|
|
|
def select(self, assets):
|
|
"""The assets to download for this game."""
|
|
if len(assets) <= 1:
|
|
return assets
|
|
for matches in (self.named(assets, True), self.named(assets, False)):
|
|
if len(matches) == 1:
|
|
return matches
|
|
return assets
|
|
|
|
def title_slug(self, release):
|
|
"""A release's own title, reduced to the game it is for."""
|
|
title = release.get("name") or release.get("tag_name") or ""
|
|
title = re.sub(r"\bv?\d+(?:\.\d+)*\b", " ", title)
|
|
title = re.sub(r"\bapworld\b", " ", title, flags=re.IGNORECASE)
|
|
return Name(title).slug
|
|
|
|
def uninformative(self):
|
|
"""Titles that name no game at all."""
|
|
return set(self.config.value(
|
|
"downloads", "uninformative_release_slugs", ()))
|
|
|
|
def claimed_by(self, title, sheet_names):
|
|
"""The other sheet row this title names, or None.
|
|
|
|
Exact equality only. This is not "the title looks a bit off" -
|
|
it is positive evidence that a DIFFERENT row is named, which is
|
|
the only thing strong enough to skip a release the link points
|
|
at. "Mega Man X2" is exactly a row and is skipped when resolving
|
|
"Mega Man X"; "Mega Man X1" is nobody's row and is accepted.
|
|
"""
|
|
if not sheet_names or not self.game.text:
|
|
return None
|
|
if not title or title in self.uninformative():
|
|
return None
|
|
if title == self.game.slug:
|
|
return None
|
|
for other in sheet_names:
|
|
slug = Name(other).slug
|
|
if slug != self.game.slug and slug == title:
|
|
return other
|
|
return None
|
|
|
|
def release_claimed(self, release, sheet_names):
|
|
return self.claimed_by(self.title_slug(release), sheet_names)
|
|
|
|
def identity_claimed(self, found_games, sheet_names):
|
|
"""Whether a downloaded file identifies as another row's game."""
|
|
for found in found_games or []:
|
|
other = self.claimed_by(Name(found).slug, sheet_names)
|
|
if other:
|
|
return other
|
|
return None
|