mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-04 16:57:00 +01:00
AniList's per-season lookup searched for "<title> 2nd Season" and the scorer picked the base entry again, so Attack on Titan seasons 2-4 and Jigokuraku season 2 were captioned with season one's names. Episode names came from streamingEpisodes, which is partial and numbered however a streaming site counted. Bleach S17 and Mushishi S02/S03 had none. AniList now walks SEQUEL relations from the match and takes each entry's episodes from ani.zip, which carries TVDB's season, number and absolute number. An episode row keeps all three plus its place in the AniList entry. EpisodeGuide::get matches whichever numbering a file uses and never answers from another season. Episodes and fanart are stored as one enrichment. The episode list is replaced even when empty, and the enrichment is recorded as asked, so a film is not re-asked every run. Storing a different match drops the old entry's episode rows. AniList's 4.75:1 bannerImage is no longer stored as the 16:9 backdrop; ani.zip's 1920x1080 fanart is used instead. Schema v9 adds the columns and deletes the AniList episode rows and banners. Matches are kept. Desktop, Android and the CLI now share service::plan and MetadataService::work. The settings text names ani.zip. Audit and roadmap in docs/METADATA.md; bug entry B61.
45 lines
1.8 KiB
Rust
45 lines
1.8 KiB
Rust
//! What every metadata source has to be able to do.
|
|
|
|
use pstr_core::library::Title;
|
|
use pstr_core::metadata::{Enrichment, ProviderId, TitleMetadata};
|
|
|
|
use crate::error::Result;
|
|
use crate::matching::{Candidate, Query};
|
|
|
|
/// A source of titles.
|
|
///
|
|
/// Deliberately narrow: search, and enriching something search already
|
|
/// matched. Both are requests to a third party, and neither happens until the
|
|
/// viewer has turned enrichment on — but note what the second one does *not*
|
|
/// need: it takes the id search returned, so it sends nothing about the library
|
|
/// it did not already learn from the match.
|
|
///
|
|
/// Not `#[async_trait]`: this is only ever used through a concrete type or an
|
|
/// enum, never as `dyn Provider`, so the native `async fn` costs nothing here.
|
|
pub trait Provider: Send + Sync {
|
|
fn id(&self) -> ProviderId;
|
|
|
|
/// Everything the provider thinks `query` might be, in its own order.
|
|
///
|
|
/// Scoring is not the provider's job — it returns candidates and
|
|
/// [`crate::matching::best`] decides. That is what keeps the "wrong poster"
|
|
/// threshold in one place rather than one per provider.
|
|
fn search(
|
|
&self,
|
|
query: &Query,
|
|
) -> impl std::future::Future<Output = Result<Vec<Candidate>>> + Send;
|
|
|
|
/// The episodes, and any art the search answer lacked, of `found` — the
|
|
/// entry `title` matched.
|
|
///
|
|
/// `title` is there for its files: a provider that files each sequel as a
|
|
/// separate entry (AniList) has to know which seasons the library holds to
|
|
/// know how far along the franchise to look. An empty episode list is a
|
|
/// real answer — a film has none — and the caller records it.
|
|
fn enrich(
|
|
&self,
|
|
title: &Title,
|
|
found: &TitleMetadata,
|
|
) -> impl std::future::Future<Output = Result<Enrichment>> + Send;
|
|
}
|