Files
APWorldTester/src/apworld_tester/pipeline/download/downloader.py
2026-09-06 15:12:38 +02:00

76 lines
2.6 KiB
Python

"""Fetching one sheet row's apworld."""
from apworld_tester.pipeline.download.handlers.gitea_release import (
GiteaRelease,
)
from apworld_tester.pipeline.download.handlers.github_file import (
GitHubFile,
)
from apworld_tester.pipeline.download.handlers.github_release import (
GitHubRelease,
)
from apworld_tester.pipeline.download.handlers.github_repo import (
GitHubRepo,
)
from apworld_tester.pipeline.download.handlers.gitlab_file import (
GitLabFile,
)
from apworld_tester.pipeline.download.handlers.gitlab_release import (
GitLabRelease,
)
from apworld_tester.pipeline.download.handlers.plain_file import PlainFile
from apworld_tester.pipeline.download.unusable_links import UnusableLinks
from apworld_tester.pipeline.download.url_shapes import UrlShapes
class Downloader:
"""Whatever shape this game's link is, get the apworld.
A releases link is resolved directly; anything else is tried
against every handler in turn, most specific first, so an exact
file beats browsing a whole repo and the plain-URL handler can
never shadow a forge-specific one.
"""
def __init__(self, context, previous=None):
self.context = context
self.shapes = UrlShapes(context.config)
self.previous = previous
def handlers(self):
return (
GitHubFile(self.shapes),
GitHubRepo(self.shapes),
GitLabFile(self.shapes),
GitLabRelease(self.shapes),
GiteaRelease(self.shapes, previous=self.previous),
PlainFile(self.shapes),
)
def from_release_link(self):
handler = GitHubRelease(self.shapes, previous=self.previous)
parsed = handler.parse(self.context.game.release)
if parsed is None:
return None, "not a recognized releases URL", None
return handler.download(parsed, self.context)
def from_link(self, link):
"""This link's result, or None if no handler recognised it."""
for handler in self.handlers():
parsed = handler.parse(link)
if parsed is not None:
return handler.download(parsed, self.context)
return None
def run(self):
"""The files downloaded, why none were, and the release info."""
game = self.context.game
if game.release:
return self.from_release_link()
for link in game.links:
result = self.from_link(link)
if result is not None:
return result
return None, UnusableLinks(self.context.config, game.links).detail(), \
None