Make the scanner async

This commit is contained in:
Zoe Roux 2023-03-18 17:42:37 +09:00
parent 7427de1bb4
commit 424390417a
7 changed files with 69 additions and 33 deletions

View File

@ -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)

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
/video
.env
.venv
.idea
.vscode
log.html

View File

@ -1 +1,2 @@
guessit
aiohttp

View File

@ -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)

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python
import asyncio
import scanner
exit(scanner.main())
asyncio.run(scanner.main())

View File

@ -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"])

View File

@ -1,18 +1,28 @@
{pkgs ? import <nixpkgs> {}}: 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 <nixpkgs> {}}:
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
'';
}