Skip to content

Commit 622d0e1

Browse files
authored
Merge pull request #29 from pullboxapp/feature/contiguous-pack-search-fallback
fix: prioritize covering GetComics fallback packs
2 parents 2fdcda8 + 20e3678 commit 622d0e1

3 files changed

Lines changed: 26 additions & 7 deletions

File tree

packages/provider_contract/src/pullbox_provider_contract/comic_parser.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def parse_comic_title(raw_title: str) -> ComicTitleEvidence:
6868
release_group = scene_match.group("group")
6969
series = scene_match.group("group_series") or scene_match.group("series")
7070
working = _SPACE.sub(" ", re.sub(r"[._]+", " ", series)).strip()
71-
issue_numbers = (_normalize_issue(scene_match.group("issue")),)
71+
issue_numbers = (normalize_issue(scene_match.group("issue")),)
7272

7373
range_match = _HASH_RANGE.search(working)
7474
if range_match:
@@ -83,7 +83,7 @@ def parse_comic_title(raw_title: str) -> ComicTitleEvidence:
8383
if not issue_numbers:
8484
issue_match = _HASH_ISSUE.search(working) or _TRAILING_ISSUE.search(working)
8585
if issue_match:
86-
issue_numbers = (_normalize_issue(issue_match.group("issue")),)
86+
issue_numbers = (normalize_issue(issue_match.group("issue")),)
8787
working = working[: issue_match.start()].strip()
8888

8989
series_title = working.strip(" -\u2013:()")
@@ -97,7 +97,7 @@ def parse_comic_title(raw_title: str) -> ComicTitleEvidence:
9797
)
9898

9999

100-
def _normalize_issue(value: str) -> str:
100+
def normalize_issue(value: str) -> str:
101101
numeric = value.rstrip("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
102102
suffix = value[len(numeric) :].casefold()
103103
if "." in numeric:

providers/getcomics/src/pullbox_provider_getcomics/service.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from typing import TYPE_CHECKING
1010
from urllib.parse import urlencode
1111

12+
from pullbox_provider_contract.comic_parser import normalize_issue
1213
from pullbox_provider_contract.errors import ProtocolError
1314
from pullbox_provider_contract.models import Artifact, Candidate, SearchIntent
1415
from pullbox_provider_contract.search_terms import (
@@ -78,9 +79,20 @@ async def search(
7879
seen_candidate_ids=seen_candidate_ids,
7980
resolver_profile=resolver_profile,
8081
)
81-
# Exact queries can return unrelated releases first. Prioritize the
82-
# fallback pack that explicitly covers the requested issue instead.
83-
return [*fallback_candidates, *candidates][:limit]
82+
# Exact queries can return unrelated releases first. Prioritize only
83+
# fallback packs that explicitly cover the requested issue; broad
84+
# fallback noise must not displace a targeted exact-search result.
85+
covering_fallbacks = [
86+
candidate
87+
for candidate in fallback_candidates
88+
if _candidate_covers_intent(candidate, intent)
89+
]
90+
noncovering_fallbacks = [
91+
candidate
92+
for candidate in fallback_candidates
93+
if not _candidate_covers_intent(candidate, intent)
94+
]
95+
return [*covering_fallbacks, *candidates, *noncovering_fallbacks][:limit]
8496
return candidates[:limit]
8597

8698
async def _append_search_candidates(
@@ -225,7 +237,9 @@ def _has_requested_issue_coverage(
225237

226238
def _candidate_covers_intent(candidate: Candidate, intent: SearchIntent) -> bool:
227239
"""Return whether a candidate covers this issue for the requested series."""
228-
if intent.issue_number not in candidate.parsed.issue_numbers:
240+
if intent.issue_number is None:
241+
return False
242+
if normalize_issue(intent.issue_number) not in candidate.parsed.issue_numbers:
229243
return False
230244
if _normalized_series_title(candidate.parsed.series_title) not in _intent_series_titles(intent):
231245
return False

tests/unit/test_getcomics_service.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ async def pages(url: str, **_kwargs: object) -> str:
260260
"""
261261
return """
262262
<html><body><h1 class="search-title">Search Result</h1>
263+
<article><h1 class="post-title">
264+
<a href="https://getcomics.org/dc/example-heroes-1-2026/">
265+
Example Heroes #1 (2026)
266+
</a>
267+
</h1></article>
263268
<article><h1 class="post-title">
264269
<a href="https://getcomics.org/dc/example-heroes-5-10-2026/">
265270
Example Heroes #5-10 (2026)

0 commit comments

Comments
 (0)