From 6737637f0f159d1e2c51f5dce9ed325837f34e3f Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Wed, 7 May 2025 13:48:09 +0200 Subject: [PATCH] Match --- scanner/README.md | 2 +- scanner/scanner/fsscan.py | 59 ++++++++++++++++++++++++++-- scanner/scanner/models/metadataid.py | 4 +- scanner/scanner/models/videos.py | 2 +- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/scanner/README.md b/scanner/README.md index d2f6982d..75bd5ea6 100644 --- a/scanner/README.md +++ b/scanner/README.md @@ -73,4 +73,4 @@ For each item in the queue, the scanner will: - retrieves metadata from the movie/serie + ALL episodes/seasons (from an external provider) - pushes every metadata to the api (if there are 1000 episodes but only 1 video, still push the 1000 episodes) - + diff --git a/scanner/scanner/fsscan.py b/scanner/scanner/fsscan.py index 765ca675..40b1964f 100644 --- a/scanner/scanner/fsscan.py +++ b/scanner/scanner/fsscan.py @@ -6,7 +6,8 @@ from typing import Optional from .client import KyooClient from .identify import identify -from .models.videos import Video +from .models.metadataid import EpisodeId, MetadataId +from .models.videos import For, Video, VideoInfo logger = getLogger(__name__) @@ -24,7 +25,7 @@ ignore_pattern = get_ignore_pattern() def is_video(path: str) -> bool: - (mime, _) = guess_file_type(path, strict=False) + (mime, _) = guess_file_type(path, strict=False) return mime is not None and mime.startswith("video/") @@ -52,6 +53,7 @@ async def scan(path: Optional[str], client: KyooClient, remove_deleted=False): if is_video(file_path): videos.add(file_path) + # TODO: handle unmatched to_register = videos - info.paths to_delete = info.paths - videos if remove_deleted else set() @@ -71,12 +73,61 @@ async def scan(path: Optional[str], client: KyooClient, remove_deleted=False): vids: list[Video] = [] for path in to_register: try: - new = await identify(path) - vids.append(new) + vid = await identify(path) + vid = match(info, vid) + vids.append(vid) except Exception as e: logger.error("Couldn't identify %s.", path, exc_info=e) created = await client.create_videos(vids) + # TODO: queue those need_scan = [x for x in created if not any(x.entries)] logger.info("Scan finished for %s.", path) + + +def match(info: VideoInfo, video: Video) -> Video: + video.for_ = [] + + year_info = ( + info.guesses[video.guess.title] if video.guess.title in info.guesses else {} + ) + slugs = set( + x + for x in ( + [ + year_info[str(y)].slug if str(y) in year_info else None + for y in video.guess.years + ] + + ([year_info["unknown"].slug] if "unknown" in year_info else []) + ) + if x is not None + ) + + if video.guess.kind == "movie": + for slug in slugs: + video.for_.append(For.Movie(movie=slug)) + + for k, v in video.guess.external_id.items(): + video.for_.append(For.ExternalId(external_id={k: MetadataId(data_id=v)})) + else: + for ep in video.guess.episodes: + if ep.season is not None: + for slug in slugs: + video.for_.append( + For.Episode(serie=slug, season=ep.season, episode=ep.episode) + ) + + for k, v in video.guess.external_id.items(): + video.for_.append( + For.ExternalId( + external_id={ + k: EpisodeId( + serie_id=v, season=ep.season, episode=ep.episode + ) + } + ) + ) + + # TODO: handle specials & movie as episodes (needs animelist or thexem) + return video diff --git a/scanner/scanner/models/metadataid.py b/scanner/scanner/models/metadataid.py index c9bc1b17..e89bebab 100644 --- a/scanner/scanner/models/metadataid.py +++ b/scanner/scanner/models/metadataid.py @@ -4,11 +4,11 @@ from ..utils import Model class MetadataId(Model): data_id: str - link: Optional[str] + link: Optional[str] = None class EpisodeId(Model): serie_id: str season: Optional[int] episode: int - link: Optional[str] + link: Optional[str] = None diff --git a/scanner/scanner/models/videos.py b/scanner/scanner/models/videos.py index 9a530a81..3751fb00 100644 --- a/scanner/scanner/models/videos.py +++ b/scanner/scanner/models/videos.py @@ -24,7 +24,7 @@ class Guess(Model, extra="allow"): extra_kind: Optional[ExtraKind] years: list[int] episodes: list[Guess.Episode] - external_id: dict[str, MetadataId | EpisodeId] + external_id: dict[str, str] raw: dict[str, Any] = {} from_: str