initial commit
This commit is contained in:
75
src/archipelago_tester/pipeline/download/asset_matcher.py
Normal file
75
src/archipelago_tester/pipeline/download/asset_matcher.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user