|
9 | 9 | from typing import TYPE_CHECKING |
10 | 10 | from urllib.parse import urlencode |
11 | 11 |
|
| 12 | +from pullbox_provider_contract.comic_parser import normalize_issue |
12 | 13 | from pullbox_provider_contract.errors import ProtocolError |
13 | 14 | from pullbox_provider_contract.models import Artifact, Candidate, SearchIntent |
14 | 15 | from pullbox_provider_contract.search_terms import ( |
@@ -78,9 +79,20 @@ async def search( |
78 | 79 | seen_candidate_ids=seen_candidate_ids, |
79 | 80 | resolver_profile=resolver_profile, |
80 | 81 | ) |
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] |
84 | 96 | return candidates[:limit] |
85 | 97 |
|
86 | 98 | async def _append_search_candidates( |
@@ -225,7 +237,9 @@ def _has_requested_issue_coverage( |
225 | 237 |
|
226 | 238 | def _candidate_covers_intent(candidate: Candidate, intent: SearchIntent) -> bool: |
227 | 239 | """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: |
229 | 243 | return False |
230 | 244 | if _normalized_series_title(candidate.parsed.series_title) not in _intent_series_titles(intent): |
231 | 245 | return False |
|
0 commit comments