Rework the scanner register check

Store all paths already registered in memory instead of asking kyoo for
each path individually. This should help reduce high response time of
kyoo on startup.
This commit is contained in:
Zoe Roux 2023-06-20 09:24:06 +09:00
parent 08bbfd91fe
commit 4bffd359b9

View File

@ -5,6 +5,7 @@ import jsons
from aiohttp import ClientSession from aiohttp import ClientSession
from pathlib import Path from pathlib import Path
from guessit import guessit from guessit import guessit
from typing import List
from providers.provider import Provider from providers.provider import Provider
from providers.types.episode import Episode, PartialShow from providers.types.episode import Episode, PartialShow
from providers.types.season import Season, SeasonTranslation from providers.types.season import Season, SeasonTranslation
@ -24,34 +25,32 @@ class Scanner:
async def scan(self, path: str): async def scan(self, path: str):
logging.info("Starting the scan. It can take some times...") logging.info("Starting the scan. It can take some times...")
self.registered = await self.get_registered_paths()
videos = filter(lambda p: p.is_file(), Path(path).rglob("*")) videos = filter(lambda p: p.is_file(), Path(path).rglob("*"))
# We batch videos by 20 because too mutch at once kinda DDOS everything. # We batch videos by 20 because too mutch at once kinda DDOS everything.
for group in batch(videos, 20): for group in batch(videos, 20):
logging.info("Batch finished. Starting a new one") logging.info("Batch finished. Starting a new one")
await asyncio.gather(*map(self.identify, group)) await asyncio.gather(*map(self.identify, group))
async def is_registered(self, path: Path) -> bool: async def get_registered_paths(self) -> List[Path]:
# TODO: Once movies are separated from the api, a new endpoint should be created to check for paths. # TODO: Once movies are separated from the api, a new endpoint should be created to check for paths.
async with self._client.get( async with self._client.get(
f"{self._url}/episodes/count", f"{self._url}/episodes",
params={"path": f"eq:{path}"}, params={"limit": 0},
headers={"X-API-Key": self._api_key}, headers={"X-API-Key": self._api_key},
) as r: ) as r:
r.raise_for_status() r.raise_for_status()
ret = await r.text() ret = await r.json()
if ret != "0": return list(x["path"] for x in ret["items"])
return True
return False
@log_errors @log_errors
async def identify(self, path: Path): async def identify(self, path: Path):
if path in self.registered:
return
raw = guessit(path, "--episode-prefer-number") raw = guessit(path, "--episode-prefer-number")
if ( if not "mimetype" in raw or not raw["mimetype"].startswith("video"):
not "mimetype" in raw
or not raw["mimetype"].startswith("video")
or await self.is_registered(path)
):
return return
logging.info("Identied %s: %s", path, raw) logging.info("Identied %s: %s", path, raw)