From a278e3a5659beac4d9e145fa5627391ff6c38551 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 17 Feb 2024 19:31:23 +0100 Subject: [PATCH] Save scanner issues on the db --- scanner/scanner/scanner.py | 15 +++++++++++++-- scanner/scanner/utils.py | 32 ++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/scanner/scanner/scanner.py b/scanner/scanner/scanner.py index ce96a3f9..a38be965 100644 --- a/scanner/scanner/scanner.py +++ b/scanner/scanner/scanner.py @@ -13,7 +13,7 @@ from providers.types.show import Show from providers.types.episode import Episode, PartialShow from providers.types.season import Season from .parser.guess import guessit -from .utils import batch, log_errors +from .utils import batch, handle_errors from .cache import cache, exec_as_cache, make_key @@ -41,6 +41,7 @@ class Scanner: async def scan(self, path: str): logging.info("Starting the scan. It can take some times...") self.registered = await self.get_registered_paths() + self.issues = await self.get_issues() videos = [str(p) for p in Path(path).rglob("*") if p.is_file()] deleted = [x for x in self.registered if x not in videos] @@ -75,7 +76,17 @@ class Scanner: paths += list(x["path"] for x in ret["items"]) return paths - @log_errors + async def get_issues(self) -> List[str]: + async with self._client.get( + f"{self._url}/issues", + params={"limit": 0}, + headers={"X-API-Key": self._api_key}, + ) as r: + r.raise_for_status() + ret = await r.json() + return [x["cause"] for x in ret if x["domain"] == "scanner"] + + @handle_errors async def identify(self, path: str): if path in self.registered or self._ignore_pattern.match(path): return diff --git a/scanner/scanner/utils.py b/scanner/scanner/utils.py index d6f3c7ff..ae3de92a 100644 --- a/scanner/scanner/utils.py +++ b/scanner/scanner/utils.py @@ -1,9 +1,13 @@ +from __future__ import annotations import logging from functools import wraps from itertools import islice -from typing import Iterator, List, TypeVar +from typing import TYPE_CHECKING, Iterator, List, TypeVar from providers.utils import ProviderError +if TYPE_CHECKING: + from scanner.scanner import Scanner + T = TypeVar("T") @@ -19,14 +23,34 @@ def batch(iterable: Iterator[T], n: int) -> Iterator[List[T]]: yield batch -def log_errors(f): +def handle_errors(f): @wraps(f) - async def internal(*args, **kwargs): + async def internal(self: Scanner, path: str): try: - await f(*args, **kwargs) + await f(self, path) + if path in self.issues: + await self._client.delete( + f'{self._url}/issues?filter=domain eq scanner and cause eq "{path}"', + headers={"X-API-Key": self._api_key}, + ) except ProviderError as e: logging.error(str(e)) + await self._client.post( + f"{self._url}/issues", + json={"domain": "scanner", "cause": path, "reason": str(e)}, + headers={"X-API-Key": self._api_key}, + ) except Exception as e: logging.exception("Unhandled error", exc_info=e) + await self._client.post( + f"{self._url}/issues", + json={ + "domain": "scanner", + "cause": path, + "reason": "Unknown error", + "extra": {"type": type(e).__name__, "message": str(e)}, + }, + headers={"X-API-Key": self._api_key}, + ) return internal