Fix lsp warnings

This commit is contained in:
Zoe Roux 2025-05-08 01:02:24 +02:00
parent 2d397a0ce1
commit 80f94be2e6
No known key found for this signature in database
6 changed files with 29 additions and 31 deletions

View File

@ -3,7 +3,6 @@ import re
from logging import getLogger from logging import getLogger
from mimetypes import guess_file_type from mimetypes import guess_file_type
from os.path import dirname, exists, isdir, join from os.path import dirname, exists, isdir, join
from typing import Optional
from watchfiles import Change, awatch from watchfiles import Change, awatch
@ -11,7 +10,7 @@ from .client import KyooClient
from .identify import identify from .identify import identify
from .models.metadataid import EpisodeId, MetadataId from .models.metadataid import EpisodeId, MetadataId
from .models.videos import For, Video, VideoInfo from .models.videos import For, Video, VideoInfo
from .queue import Request, enqueue from .requests import Request, enqueue
logger = getLogger(__name__) logger = getLogger(__name__)
@ -26,7 +25,7 @@ class Scanner:
except re.error as e: except re.error as e:
logger.error(f"Invalid ignore pattern. Ignoring. Error: {e}") logger.error(f"Invalid ignore pattern. Ignoring. Error: {e}")
async def scan(self, path: Optional[str] = None, remove_deleted=False): async def scan(self, path: str | None = None, remove_deleted=False):
if path is None: if path is None:
logger.info("Starting scan at %s. This may take some time...", path) logger.info("Starting scan at %s. This may take some time...", path)
if self._ignore_pattern: if self._ignore_pattern:
@ -101,6 +100,7 @@ class Scanner:
kind=x.guess.kind, kind=x.guess.kind,
title=x.guess.title, title=x.guess.title,
year=next(iter(x.guess.years), None), year=next(iter(x.guess.years), None),
external_id=x.guess.external_id,
videos=[Request.Video(id=x.id, episodes=x.guess.episodes)], videos=[Request.Video(id=x.id, episodes=x.guess.episodes)],
) )
for x in created for x in created

View File

@ -1,23 +1,19 @@
from typing import Any, List, cast from typing import Any, cast
from guessit.api import default_api from guessit.api import default_api
from rebulk import Rebulk from rebulk import Rebulk
from rebulk.match import Match from rebulk.match import Match
try: from . import rules
from . import rules
except:
import rules
default_api.configure({}) default_api.configure({})
rblk = cast(Rebulk, default_api.rebulk) rblk = cast(Rebulk, default_api.rebulk).rules(rules)
rblk.rules(rules)
def guessit( def guessit(
name: str, name: str,
*, *,
expected_titles: List[str] = [], expected_titles: list[str] = [],
extra_flags: dict[str, Any] = {}, extra_flags: dict[str, Any] = {},
) -> dict[str, list[Match]]: ) -> dict[str, list[Match]]:
return default_api.guessit( return default_api.guessit(

View File

@ -2,7 +2,7 @@
from copy import copy from copy import copy
from logging import getLogger from logging import getLogger
from typing import Any, List, Optional, cast from typing import Any, cast, override
from rebulk import POST_PROCESS, AppendMatch, RemoveMatch, Rule from rebulk import POST_PROCESS, AppendMatch, RemoveMatch, Rule
from rebulk.match import Match, Matches from rebulk.match import Match, Matches
@ -52,11 +52,12 @@ class UnlistTitles(Rule):
priority = POST_PROCESS priority = POST_PROCESS
consequence = [RemoveMatch, AppendMatch] consequence = [RemoveMatch, AppendMatch]
@override
def when(self, matches: Matches, context) -> Any: def when(self, matches: Matches, context) -> Any:
fileparts: List[Match] = matches.markers.named("path") # type: ignore fileparts: list[Match] = matches.markers.named("path") # type: ignore
for part in fileparts: for part in fileparts:
titles: List[Match] = matches.range( titles: list[Match] = matches.range(
part.start, part.end, lambda x: x.name == "title" part.start, part.end, lambda x: x.name == "title"
) # type: ignore ) # type: ignore
@ -66,7 +67,7 @@ class UnlistTitles(Rule):
title = copy(titles[0]) title = copy(titles[0])
for nmatch in titles[1:]: for nmatch in titles[1:]:
# Check if titles are next to each other, if they are not ignore it. # Check if titles are next to each other, if they are not ignore it.
next: List[Match] = matches.next(title) # type: ignore next: list[Match] = matches.next(title) # type: ignore
if not next or next[0] != nmatch: if not next or next[0] != nmatch:
logger.warning(f"Ignoring potential part of title: {nmatch.value}") logger.warning(f"Ignoring potential part of title: {nmatch.value}")
continue continue
@ -107,14 +108,15 @@ class MultipleSeasonRule(Rule):
priority = POST_PROCESS priority = POST_PROCESS
consequence = [RemoveMatch, AppendMatch] consequence = [RemoveMatch, AppendMatch]
@override
def when(self, matches: Matches, context) -> Any: def when(self, matches: Matches, context) -> Any:
seasons: List[Match] = matches.named("season") # type: ignore seasons: list[Match] = matches.named("season") # type: ignore
if not seasons: if not seasons:
return return
# Only apply this rule if all seasons are due to the same match # Only apply this rule if all seasons are due to the same match
initiator: Optional[Match] = seasons[0].initiator initiator: Match | None = seasons[0].initiator
if not initiator or any( if not initiator or any(
True for match in seasons if match.initiator != initiator True for match in seasons if match.initiator != initiator
): ):
@ -130,7 +132,7 @@ class MultipleSeasonRule(Rule):
try: try:
episodes = [int(x) for x in new_episodes] episodes = [int(x) for x in new_episodes]
parents: List[Match] = [match.parent for match in to_remove] # type: ignore parents: list[Match] = [match.parent for match in to_remove] # type: ignore
for episode in episodes: for episode in episodes:
smatch = next( smatch = next(
x x
@ -181,8 +183,9 @@ class SeasonYearDedup(Rule):
priority = POST_PROCESS - 1 priority = POST_PROCESS - 1
consequence = RemoveMatch consequence = RemoveMatch
@override
def when(self, matches: Matches, context) -> Any: def when(self, matches: Matches, context) -> Any:
season: List[Match] = matches.named("season") # type: ignore season: list[Match] = matches.named("season") # type: ignore
year: List[Match] = matches.named("year") # type: ignore year: list[Match] = matches.named("year") # type: ignore
if len(season) == 1 and len(year) == 1 and season[0].value == year[0].value: if len(season) == 1 and len(year) == 1 and season[0].value == year[0].value:
return season return season

View File

@ -1,7 +1,8 @@
from collections.abc import Awaitable
from hashlib import sha256 from hashlib import sha256
from itertools import zip_longest from itertools import zip_longest
from logging import getLogger from logging import getLogger
from typing import Awaitable, Callable, Literal, cast from typing import Callable, Literal, cast
from .guess.guess import guessit from .guess.guess import guessit
from .models.videos import Guess, Video from .models.videos import Guess, Video

View File

@ -1,16 +1,18 @@
from __future__ import annotations from __future__ import annotations
from typing import Literal, Optional from typing import Literal
from .client import KyooClient from .client import KyooClient
from .models.videos import Guess from .models.videos import Guess
from .utils import Model from .utils import Model
from .providers.composite import CompositeProvider
class Request(Model): class Request(Model):
kind: Literal["episode"] | Literal["movie"] kind: Literal["episode"] | Literal["movie"]
title: str title: str
year: Optional[int] year: int | None
external_id: dict[str, str]
videos: list[Video] videos: list[Video]
class Video(Model): class Video(Model):
@ -27,8 +29,9 @@ async def enqueue(requests: list[Request]):
# TODO: how will this conflict be handled if the request is already locked for update (being processed) # TODO: how will this conflict be handled if the request is already locked for update (being processed)
pass pass
class RequestProcessor: class RequestProcessor:
def __init__(self, client: KyooClient): def __init__(self, client: KyooClient, providers: CompositeProvider):
self._client = client self._client = client
async def process_scan_requests(self): async def process_scan_requests(self):
@ -36,13 +39,13 @@ class RequestProcessor:
request: Request = ... request: Request = ...
if request.kind == "movie": if request.kind == "movie":
movie = await providers.get_movie(request.title, request.year) movie = await providers.get_movie(request.title, request.year, request.external_id)
movie.videos = request.videos movie.videos = request.videos
await self._client.create_movie(movie) await self._client.create_movie(movie)
else: else:
serie = await providers.get_serie(request.title, request.year) serie = await providers.get_serie(request.title, request.year)
# for vid in request.videos: # for vid in request.videos:
# for ep in vid.episodes: # for ep in vid.episodes:
# entry = next(x for x in series.entries if (ep.season is None or x.season == ep.season), None) # entry = next(x for x in series.entries if (ep.season is None or x.season == ep.season), None)
await self._client.create_serie(serie) await self._client.create_serie(serie)
# delete request # delete request

View File

@ -17,11 +17,6 @@ def normalize_lang(lang: str) -> str:
return str(Language.get(lang)) return str(Language.get(lang))
class ProviderError(RuntimeError):
def __init__(self, *args: object) -> None:
super().__init__(*args)
class Model(BaseModel): class Model(BaseModel):
model_config = ConfigDict( model_config = ConfigDict(
use_enum_values=True, use_enum_values=True,