This commit is contained in:
2025-10-22 13:38:46 +02:00
parent 1f39f07c5d
commit 04799633b4
9 changed files with 411 additions and 571 deletions

View File

@@ -1,13 +1,12 @@
import logging
import os
import sys
import time
from typing import Any, Callable, Mapping, Optional, Sequence
from rich.progress import Progress
from ..core.entities import SerieList
from ..core.entities.series import Serie
from ..core.providers import aniworld_provider
from ..core.providers.provider_factory import Loaders
from ..core.SerieScanner import SerieScanner
@@ -30,35 +29,37 @@ for h in logging.getLogger().handlers:
class NoKeyFoundException(Exception):
"""Exception raised when an anime key cannot be found."""
pass
class MatchNotFoundError(Exception):
"""Exception raised when an anime key cannot be found."""
pass
class SeriesApp:
_initialization_count = 0 # Track how many times initialization has been called
_initialization_count = 0 # Track initialization calls
def __init__(self, directory_to_search: str):
def __init__(self, directory_to_search: str) -> None:
SeriesApp._initialization_count += 1
# Only show initialization message for the first instance
if SeriesApp._initialization_count <= 1:
print("Please wait while initializing...")
self.progress = None
self.progress: Optional[Progress] = None
self.directory_to_search = directory_to_search
self.Loaders = Loaders()
self.Loaders: Loaders = Loaders()
loader = self.Loaders.GetLoader(key="aniworld.to")
self.SerieScanner = SerieScanner(directory_to_search, loader)
self.List = SerieList(self.directory_to_search)
self.__init_list__()
def __init_list__(self):
def __init_list__(self) -> None:
"""Initialize the series list by fetching missing episodes."""
self.series_list = self.List.GetMissingEpisode()
self.series_list: Sequence[Serie] = self.List.GetMissingEpisode()
def display_series(self):
def display_series(self) -> None:
"""Print all series with assigned numbers."""
print("\nCurrent result:")
for i, serie in enumerate(self.series_list, 1):
@@ -68,12 +69,12 @@ class SeriesApp:
else:
print(f"{i}. {serie.name}")
def search(self, words: str) -> list:
def search(self, words: str) -> list[dict[str, Any]]:
"""Search for anime series by name."""
loader = self.Loaders.GetLoader(key="aniworld.to")
return loader.search(words)
def get_user_selection(self):
def get_user_selection(self) -> Optional[Sequence[Serie]]:
"""Handle user input for selecting series."""
self.display_series()
while True:
@@ -86,9 +87,9 @@ class SeriesApp:
if selection == "exit":
return None
selected_series = []
selected_series: list[Serie] = []
if selection == "all":
selected_series = self.series_list
selected_series = list(self.series_list)
else:
try:
indexes = [
@@ -118,7 +119,14 @@ class SeriesApp:
print(msg)
return None
def retry(self, func, max_retries=3, delay=2, *args, **kwargs):
def retry(
self,
func: Callable[..., Any],
max_retries: int = 3,
delay: float = 2,
*args: Any,
**kwargs: Any,
) -> bool:
"""Retry a function with exponential backoff.
Args:
@@ -140,7 +148,7 @@ class SeriesApp:
time.sleep(delay)
return False
def download_series(self, series):
def download_series(self, series: Sequence[Serie]) -> None:
"""Simulate the downloading process with a progress bar."""
total_downloaded = 0
total_episodes = sum(
@@ -182,7 +190,7 @@ class SeriesApp:
episode,
serie.key,
"German Dub",
self.print_Download_Progress,
self.print_download_progress,
)
downloaded += 1
@@ -195,20 +203,24 @@ class SeriesApp:
self.progress.stop()
self.progress = None
def print_download_progress(self, d):
def print_download_progress(self, d: Mapping[str, Any]) -> None:
"""Update download progress in the UI.
Args:
d: Dictionary containing download status information
"""
# Use self.progress and self.download_progress_task to display progress
if (self.progress is None or
not hasattr(self, "download_progress_task")):
if (
self.progress is None
or not hasattr(self, "download_progress_task")
):
return
if d["status"] == "downloading":
total = (d.get("total_bytes") or
d.get("total_bytes_estimate"))
total = (
d.get("total_bytes")
or d.get("total_bytes_estimate")
)
downloaded = d.get("downloaded_bytes", 0)
if total:
percent = downloaded / total * 100
@@ -232,7 +244,7 @@ class SeriesApp:
description=desc
)
def search_mode(self):
def search_mode(self) -> None:
"""Search for a series and allow user to select an option."""
search_string = input("Enter search string: ").strip()
results = self.search(search_string)
@@ -272,10 +284,10 @@ class SeriesApp:
except ValueError:
print("Invalid input. Try again.")
def updateFromReinit(self, folder, counter):
def updateFromReinit(self, folder: str, counter: int) -> None:
self.progress.update(self.task1, advance=1)
def run(self):
def run(self) -> None:
"""Main function to run the app."""
while True:
prompt = (