Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: If8fe8b38c1d9c4fecd40ff71f88d2ae06a6a6964
79 lines
2 KiB
Rust
79 lines
2 KiB
Rust
//! Metadata enrichment from external sources.
|
|
|
|
pub mod books;
|
|
pub mod googlebooks;
|
|
pub mod lastfm;
|
|
pub mod musicbrainz;
|
|
pub mod openlibrary;
|
|
pub mod tmdb;
|
|
|
|
use chrono::{DateTime, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
use uuid::Uuid;
|
|
|
|
use crate::{
|
|
error::Result,
|
|
model::{MediaId, MediaItem},
|
|
};
|
|
|
|
/// Externally-sourced metadata for a media item.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ExternalMetadata {
|
|
pub id: Uuid,
|
|
pub media_id: MediaId,
|
|
pub source: EnrichmentSourceType,
|
|
pub external_id: Option<String>,
|
|
pub metadata_json: String,
|
|
pub confidence: f64,
|
|
pub last_updated: DateTime<Utc>,
|
|
}
|
|
|
|
/// Supported enrichment data sources.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum EnrichmentSourceType {
|
|
#[serde(rename = "musicbrainz")]
|
|
MusicBrainz,
|
|
#[serde(rename = "tmdb")]
|
|
Tmdb,
|
|
#[serde(rename = "lastfm")]
|
|
LastFm,
|
|
#[serde(rename = "openlibrary")]
|
|
OpenLibrary,
|
|
#[serde(rename = "googlebooks")]
|
|
GoogleBooks,
|
|
}
|
|
|
|
impl std::fmt::Display for EnrichmentSourceType {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
let s = match self {
|
|
Self::MusicBrainz => "musicbrainz",
|
|
Self::Tmdb => "tmdb",
|
|
Self::LastFm => "lastfm",
|
|
Self::OpenLibrary => "openlibrary",
|
|
Self::GoogleBooks => "googlebooks",
|
|
};
|
|
write!(f, "{s}")
|
|
}
|
|
}
|
|
|
|
impl std::str::FromStr for EnrichmentSourceType {
|
|
type Err = String;
|
|
|
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
|
match s {
|
|
"musicbrainz" => Ok(Self::MusicBrainz),
|
|
"tmdb" => Ok(Self::Tmdb),
|
|
"lastfm" => Ok(Self::LastFm),
|
|
"openlibrary" => Ok(Self::OpenLibrary),
|
|
"googlebooks" => Ok(Self::GoogleBooks),
|
|
_ => Err(format!("unknown enrichment source: {s}")),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Trait for metadata enrichment providers.
|
|
#[async_trait::async_trait]
|
|
pub trait MetadataEnricher: Send + Sync {
|
|
fn source(&self) -> EnrichmentSourceType;
|
|
async fn enrich(&self, item: &MediaItem) -> Result<Option<ExternalMetadata>>;
|
|
}
|