diff --git a/scanner/providers/types/episode.py b/scanner/providers/types/episode.py index 416394c6..238b814f 100644 --- a/scanner/providers/types/episode.py +++ b/scanner/providers/types/episode.py @@ -3,9 +3,7 @@ from datetime import date from dataclasses import dataclass, field, asdict from typing import Optional -from ..utils import format_date from .show import Show -from .season import Season from .metadataid import MetadataID @@ -36,7 +34,6 @@ class Episode: show_id: Optional[str] = None translations: dict[str, EpisodeTranslation] = field(default_factory=dict) - def to_kyoo(self): # For now, the API of kyoo only support one language so we remove the others. default_language = os.environ["LIBRARY_LANGUAGES"].split(",")[0] diff --git a/scanner/providers/types/season.py b/scanner/providers/types/season.py index ca7094b4..c247b544 100644 --- a/scanner/providers/types/season.py +++ b/scanner/providers/types/season.py @@ -3,7 +3,6 @@ from datetime import date from dataclasses import dataclass, field, asdict from typing import Optional -from ..utils import format_date from .metadataid import MetadataID diff --git a/scanner/providers/types/show.py b/scanner/providers/types/show.py index 0f7ac987..748abf33 100644 --- a/scanner/providers/types/show.py +++ b/scanner/providers/types/show.py @@ -8,7 +8,6 @@ from .genre import Genre from .studio import Studio from .season import Season from .metadataid import MetadataID -from ..utils import format_date class Status(str, Enum): diff --git a/scanner/requirements.txt b/scanner/requirements.txt index 1deb3bf3..b90b7693 100644 --- a/scanner/requirements.txt +++ b/scanner/requirements.txt @@ -2,3 +2,4 @@ guessit aiohttp jsons black-with-tabs +watchdog diff --git a/scanner/scanner/scanner.py b/scanner/scanner/scanner.py index 60142a88..1e8e9787 100644 --- a/scanner/scanner/scanner.py +++ b/scanner/scanner/scanner.py @@ -1,4 +1,3 @@ -from functools import wraps import os import asyncio import logging @@ -9,70 +8,7 @@ from guessit import guessit from providers.provider import Provider from providers.types.episode import Episode, PartialShow from providers.types.season import Season, SeasonTranslation -from providers.utils import ProviderError - - -def log_errors(f): - @wraps(f) - async def internal(*args, **kwargs): - try: - await f(*args, **kwargs) - except ProviderError as e: - logging.error(str(e)) - except Exception as e: - logging.exception("Unhandled error", exc_info=e) - - return internal - - -cache = {} - - -def provider_cache(*args): - ic = cache - for arg in args: - if arg not in ic: - ic[arg] = {} - ic = ic[arg] - - def wrapper(f): - @wraps(f) - async def internal(*args, **kwargs): - nonlocal ic - for arg in args: - if arg not in ic: - ic[arg] = {} - ic = ic[arg] - - if "event" in ic: - await ic["event"].wait() - if not ic["ret"]: - raise ProviderError("Cache miss. Another error should exist") - return ic["ret"] - ic["event"] = asyncio.Event() - try: - ret = await f(*args, **kwargs) - ic["ret"] = ret - except: - ic["event"].set() - raise - ic["event"].set() - return ret - return internal - return wrapper - - -def set_in_cache(key: list[str | int]): - ic = cache - for arg in key: - if arg not in ic: - ic[arg] = {} - ic = ic[arg] - evt = asyncio.Event() - evt.set() - ic["event"] = evt - - +from .utils import log_errors, provider_cache, set_in_cache class Scanner: diff --git a/scanner/scanner/utils.py b/scanner/scanner/utils.py new file mode 100644 index 00000000..2eda4ee2 --- /dev/null +++ b/scanner/scanner/utils.py @@ -0,0 +1,67 @@ +import asyncio +import logging +from functools import wraps +from providers.utils import ProviderError + + +def log_errors(f): + @wraps(f) + async def internal(*args, **kwargs): + try: + await f(*args, **kwargs) + except ProviderError as e: + logging.error(str(e)) + except Exception as e: + logging.exception("Unhandled error", exc_info=e) + + return internal + + +cache = {} + + +def provider_cache(*args): + ic = cache + for arg in args: + if arg not in ic: + ic[arg] = {} + ic = ic[arg] + + def wrapper(f): + @wraps(f) + async def internal(*args, **kwargs): + nonlocal ic + for arg in args: + if arg not in ic: + ic[arg] = {} + ic = ic[arg] + + if "event" in ic: + await ic["event"].wait() + if not ic["ret"]: + raise ProviderError("Cache miss. Another error should exist") + return ic["ret"] + ic["event"] = asyncio.Event() + try: + ret = await f(*args, **kwargs) + ic["ret"] = ret + except: + ic["event"].set() + raise + ic["event"].set() + return ret + + return internal + + return wrapper + + +def set_in_cache(key: list[str | int]): + ic = cache + for arg in key: + if arg not in ic: + ic[arg] = {} + ic = ic[arg] + evt = asyncio.Event() + evt.set() + ic["event"] = evt diff --git a/shell.nix b/shell.nix index cafc06aa..b77d93d3 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,5 @@ {pkgs ? import {}}: let - venvDir = "./.venv"; + venvDir = "./scanner/.venv"; pythonPkgs = ./scanner/requirements.txt; in pkgs.mkShell {