diff --git a/.env.example b/.env.example index 19aa2195..c292bd75 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ # Useful config options LIBRARY_ROOT=/video +LIBRARY_LANGUAGES=en # The following two values should be set to a random sequence of characters. # You MUST change thoses when installing kyoo (for security) diff --git a/.gitignore b/.gitignore index 1d6bedbf..3d4a2b98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /video .env +.venv .idea .vscode log.html diff --git a/scanner/requirments.txt b/scanner/requirements.txt similarity index 50% rename from scanner/requirments.txt rename to scanner/requirements.txt index d02be8ec..9f4dc104 100644 --- a/scanner/requirments.txt +++ b/scanner/requirements.txt @@ -1 +1,2 @@ guessit +aiohttp diff --git a/scanner/scanner/__init__.py b/scanner/scanner/__init__.py index 3f34a254..18ca072c 100644 --- a/scanner/scanner/__init__.py +++ b/scanner/scanner/__init__.py @@ -1,14 +1,20 @@ -from .scanner import scan +from .scanner import Scanner -def main(): +async def main(): import os import logging import sys + from aiohttp import ClientSession path = os.environ.get("LIBRARY_ROOT") if not path: print("Missing environment variable 'LIBRARY_ROOT'.") exit(2) + languages = os.environ.get("LIBRARY_LANGUAGES") + if not languages: + print("Missing environment variable 'LIBRARY_LANGUAGES'.") + exit(2) if len(sys.argv) > 1 and sys.argv[1] == "-v": - logging.basicConfig(level=logging.INFO) - return scan(path) + logging.basicConfig(level=logging.DEBUG) + async with ClientSession() as client: + await Scanner(client, languages.split(',')).scan(path) diff --git a/scanner/scanner/__main__.py b/scanner/scanner/__main__.py index 73a8d53f..ac4e42e3 100644 --- a/scanner/scanner/__main__.py +++ b/scanner/scanner/__main__.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import asyncio import scanner -exit(scanner.main()) +asyncio.run(scanner.main()) diff --git a/scanner/scanner/scanner.py b/scanner/scanner/scanner.py index 8696e65d..38b497eb 100644 --- a/scanner/scanner/scanner.py +++ b/scanner/scanner/scanner.py @@ -1,14 +1,30 @@ +import asyncio +import logging from pathlib import Path from guessit import guessit -import logging +from themoviedb.routes.base import ClientSession +from providers.provider import Provider -def scan(path: str): - for item in Path(path).rglob("*"): - if not item.is_file(): - continue - identify(item) +class Scanner: + def __init__(self, client: ClientSession, languages: list[str]) -> None: + self.provider = Provider.get_all(client)[0] + self.languages = languages -def identify(path: Path): - raw = guessit(path) - logging.info("Identied %s: %s", path, raw) - # print(f'type: {raw["type"]}, title: {raw["title"]}') + async def scan(self, path: str): + videos = filter(lambda p: p.is_file(), Path(path).rglob("*")) + await asyncio.gather(*map(self.identify, videos)) + + async def identify(self, path: Path): + raw = guessit(path) + logging.info("Identied %s: %s", path, raw) + + # TODO: check if episode/movie already exists in kyoo and skip if it does. + # TODO: keep a list of processing shows to only fetch metadata once even if + # multiples identify of the same show run on the same time + if raw["type"] == "movie": + movie = await self.provider.identify_movie(raw["title"], raw.get("year"), language=self.languages) + logging.debug("Got movie: %s", movie) + elif raw["type"] == "episode": + pass + else: + logging.warn("Unknown video file type: %s", raw["type"]) diff --git a/shell.nix b/shell.nix index ae937d07..1530ea1b 100644 --- a/shell.nix +++ b/shell.nix @@ -1,18 +1,28 @@ -{pkgs ? import {}}: let - pythonPackages = p: - with p; [ - guessit - ]; -in - pkgs.mkShell { - packages = with pkgs; [ - nodejs-16_x - nodePackages.yarn - (with dotnetCorePackages; - combinePackages [ - sdk_6_0 - aspnetcore_6_0 - ]) - (python3.withPackages pythonPackages) - ]; - } +{pkgs ? import {}}: +pkgs.mkShell { + packages = with pkgs; [ + nodejs-16_x + nodePackages.yarn + (with dotnetCorePackages; + combinePackages [ + sdk_6_0 + aspnetcore_6_0 + ]) + python3 + python3Packages.venvShellHook + ]; + + # Run this command, only after creating the virtual environment + venvDir = "./.venv"; + postVenvCreation = '' + unset SOURCE_DATE_EPOCH + pip install -r ./scanner/requirements.txt + ''; + + # Now we can execute any commands within the virtual environment. + # This is optional and can be left out to run pip manually. + postShellHook = '' + # allow pip to install wheels + unset SOURCE_DATE_EPOCH + ''; +}