Implement the Podnapisi provider against the same Provider trait from #184,
so the trait has two real implementations rather than one and its shape is
tested by more than a single example.
Same contract as #187: search by the identifiers available, return candidates
carrying the fields #185 ranks on, download a chosen candidate to a temporary
path. Podnapisi has no moviehash lane, so its candidates rank on release-name
matching and below — which is exactly what the ranker already expresses, with
no special case for the provider.
Credentials, if any, come from config or environment per DESIGN.md §10.
Fixture responses in tests, never the live service.
Implement the Podnapisi provider against the same `Provider` trait from #184,
so the trait has two real implementations rather than one and its shape is
tested by more than a single example.
Same contract as #187: search by the identifiers available, return candidates
carrying the fields #185 ranks on, download a chosen candidate to a temporary
path. Podnapisi has no `moviehash` lane, so its candidates rank on release-name
matching and below — which is exactly what the ranker already expresses, with
no special case for the provider.
Credentials, if any, come from config or environment per DESIGN.md §10.
Fixture responses in tests, never the live service.
Depends on: #184
naps62-yolo
added this to the Subtitles milestone 2026-08-24 21:28:32 +01:00
Implemented the Podnapisi.net Provider: search hits search/advanced (keyworded on the file's release name, since Podnapisi has no id-based lookup), paginates and dedupes by pid, and maps results to Candidate with hash_match always false per the issue. Release group and source are recovered by running arr_parse::parse over the matched release name (reusing the existing arr_parse::Source -> arr_core::Source conversion), and pt-PT/pt-BR is resolved through arr_core::lang::resolve_portuguese, using the release name's language markers and Podnapisi's own language tag as evidence — the same signal machinery arr-probe already uses. Download unzips the single-file archive Podnapisi serves and maps the extension to SubtitleFormat. The candidate id round-trips the resolved language ({pid}|{language}) so download doesn't need a second lookup to know what language it's returning.
No credentials are used — the real API (verified against subliminal's current, maintained provider) is unauthenticated for both search and download. Added Error::Config to arr-subs's shared error type for provider construction failures (bad base URL, HTTP client build failure); reusable by future providers.
Branch: subtitles/188-podnapisi. just ci passed (537/537 tests).
Findings
ARR_PODNAPISI_USERNAME/ARR_PODNAPISI_PASSWORD exist in arr-daemon's config (#198) but nothing in this provider consumes them — Podnapisi's search/download API doesn't require login in the reference implementation I checked. If there's a known login flow that raises Podnapisi's daily download cap, it needs its own issue; I didn't want to guess an unverified auth flow into this crate.
Candidate.rating and Candidate.download_count are always None for Podnapisi — I found no documented field for either in its JSON API. Ranking's tiebreakers are effectively unavailable for this provider; worth a follow-up if Podnapisi does expose them under a different key.
No provider is wired into arr-daemon yet (neither this one nor OpenSubtitles) — reconcile-loop construction from config/settings is still open work, outside this issue's scope.
Implemented the Podnapisi.net `Provider`: search hits `search/advanced` (keyworded on the file's release name, since Podnapisi has no id-based lookup), paginates and dedupes by pid, and maps results to `Candidate` with `hash_match` always `false` per the issue. Release group and source are recovered by running `arr_parse::parse` over the matched release name (reusing the existing `arr_parse::Source -> arr_core::Source` conversion), and pt-PT/pt-BR is resolved through `arr_core::lang::resolve_portuguese`, using the release name's language markers and Podnapisi's own `language` tag as evidence — the same signal machinery `arr-probe` already uses. Download unzips the single-file archive Podnapisi serves and maps the extension to `SubtitleFormat`. The candidate id round-trips the resolved language (`{pid}|{language}`) so `download` doesn't need a second lookup to know what language it's returning.
No credentials are used — the real API (verified against `subliminal`'s current, maintained provider) is unauthenticated for both search and download. Added `Error::Config` to `arr-subs`'s shared error type for provider construction failures (bad base URL, HTTP client build failure); reusable by future providers.
Branch: `subtitles/188-podnapisi`. `just ci` passed (537/537 tests).
## Findings
- `ARR_PODNAPISI_USERNAME`/`ARR_PODNAPISI_PASSWORD` exist in `arr-daemon`'s config (#198) but nothing in this provider consumes them — Podnapisi's search/download API doesn't require login in the reference implementation I checked. If there's a known login flow that raises Podnapisi's daily download cap, it needs its own issue; I didn't want to guess an unverified auth flow into this crate.
- `Candidate.rating` and `Candidate.download_count` are always `None` for Podnapisi — I found no documented field for either in its JSON API. Ranking's tiebreakers are effectively unavailable for this provider; worth a follow-up if Podnapisi does expose them under a different key.
- No provider is wired into `arr-daemon` yet (neither this one nor OpenSubtitles) — reconcile-loop construction from config/settings is still open work, outside this issue's scope.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Implement the Podnapisi provider against the same
Providertrait from #184,so the trait has two real implementations rather than one and its shape is
tested by more than a single example.
Same contract as #187: search by the identifiers available, return candidates
carrying the fields #185 ranks on, download a chosen candidate to a temporary
path. Podnapisi has no
moviehashlane, so its candidates rank on release-namematching and below — which is exactly what the ranker already expresses, with
no special case for the provider.
Credentials, if any, come from config or environment per DESIGN.md §10.
Fixture responses in tests, never the live service.
Depends on: #184
Implemented the Podnapisi.net
Provider: search hitssearch/advanced(keyworded on the file's release name, since Podnapisi has no id-based lookup), paginates and dedupes by pid, and maps results toCandidatewithhash_matchalwaysfalseper the issue. Release group and source are recovered by runningarr_parse::parseover the matched release name (reusing the existingarr_parse::Source -> arr_core::Sourceconversion), and pt-PT/pt-BR is resolved througharr_core::lang::resolve_portuguese, using the release name's language markers and Podnapisi's ownlanguagetag as evidence — the same signal machineryarr-probealready uses. Download unzips the single-file archive Podnapisi serves and maps the extension toSubtitleFormat. The candidate id round-trips the resolved language ({pid}|{language}) sodownloaddoesn't need a second lookup to know what language it's returning.No credentials are used — the real API (verified against
subliminal's current, maintained provider) is unauthenticated for both search and download. AddedError::Configtoarr-subs's shared error type for provider construction failures (bad base URL, HTTP client build failure); reusable by future providers.Branch:
subtitles/188-podnapisi.just cipassed (537/537 tests).Findings
ARR_PODNAPISI_USERNAME/ARR_PODNAPISI_PASSWORDexist inarr-daemon's config (#198) but nothing in this provider consumes them — Podnapisi's search/download API doesn't require login in the reference implementation I checked. If there's a known login flow that raises Podnapisi's daily download cap, it needs its own issue; I didn't want to guess an unverified auth flow into this crate.Candidate.ratingandCandidate.download_countare alwaysNonefor Podnapisi — I found no documented field for either in its JSON API. Ranking's tiebreakers are effectively unavailable for this provider; worth a follow-up if Podnapisi does expose them under a different key.arr-daemonyet (neither this one nor OpenSubtitles) — reconcile-loop construction from config/settings is still open work, outside this issue's scope.