initial commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""A GitHub releases page, the sheet's usual link."""
|
||||
|
||||
from archipelago_tester.pipeline.download.handlers.base import LinkHandler
|
||||
from archipelago_tester.pipeline.download.release_downloader import (
|
||||
ReleaseDownloader,
|
||||
)
|
||||
from archipelago_tester.pipeline.download.release_identity import (
|
||||
ReleaseIdentity,
|
||||
)
|
||||
from archipelago_tester.pipeline.download.release_picker import ReleasePicker
|
||||
from archipelago_tester.pipeline.download.walk_back import WalkBack
|
||||
|
||||
|
||||
class GitHubRelease(LinkHandler):
|
||||
"""Resolve which release the link means, then fetch its apworld."""
|
||||
|
||||
def __init__(self, shapes, previous=None):
|
||||
super().__init__(shapes)
|
||||
self.previous = previous
|
||||
|
||||
def parse(self, link):
|
||||
return self.shapes.releases(link)
|
||||
|
||||
def resolve(self, parsed, context):
|
||||
"""The release this link resolves to, or None.
|
||||
|
||||
A hand-pinned tag prefix wins, then a link naming one exact
|
||||
tag, then the search term. Runs every pass: it is the one call
|
||||
that can report a new release, which is the only thing able to
|
||||
change a previously failed answer.
|
||||
"""
|
||||
owner, repository, term, tag = parsed
|
||||
picker = ReleasePicker(context, owner, repository, term)
|
||||
overrides = context.config.get("release_overrides") or {}
|
||||
prefix = overrides.get(context.game.name)
|
||||
if prefix:
|
||||
return picker.by_tag_prefix(prefix)
|
||||
if tag:
|
||||
return picker.by_tag(tag)
|
||||
return picker.pick()
|
||||
|
||||
def fetch(self, parsed, context, release):
|
||||
"""This release's apworld, walking back if it ships none.
|
||||
|
||||
Only that one cause is walked back from. "Ships another game's
|
||||
apworld" must not be, since an older release of a multi-world
|
||||
repo is precisely the wrong answer there.
|
||||
"""
|
||||
owner, repository = parsed[0], parsed[1]
|
||||
downloader = ReleaseDownloader(
|
||||
context=context,
|
||||
release=release,
|
||||
# What this row's date already says, so a re-upload of
|
||||
# unchanged bytes keeps it instead of moving it forward.
|
||||
previous_published_at=(self.previous or {}).get("published_at"),
|
||||
)
|
||||
downloaded, reason, info = downloader.run()
|
||||
if (downloaded is not None or context.identifier is None
|
||||
or downloader.cause != ReleaseDownloader.NO_APWORLD):
|
||||
return downloaded, reason, info
|
||||
fallback, reason = WalkBack(
|
||||
context=context,
|
||||
owner=owner,
|
||||
repository=repository,
|
||||
release=release,
|
||||
).run(reason)
|
||||
return fallback if fallback is not None else (None, reason, info)
|
||||
|
||||
def download(self, parsed, context):
|
||||
release = self.resolve(parsed, context)
|
||||
if release is None:
|
||||
return None, "no release matched the search term in the link", None
|
||||
identity = ReleaseIdentity(release)
|
||||
repeat = identity.repeated(self.previous)
|
||||
if repeat is not None:
|
||||
return None, repeat, identity.failure(
|
||||
{"published_at": None}, repeat)
|
||||
downloaded, reason, info = self.fetch(parsed, context, release)
|
||||
if downloaded is None:
|
||||
return None, reason, identity.failure(info, reason)
|
||||
return downloaded, reason, info
|
||||
Reference in New Issue
Block a user