added: better progressbars

This commit is contained in:
Lukas Pupka-Lipinski 2025-09-15 10:28:32 +02:00
parent c3f9e4aa84
commit 19bd44b3dc
8 changed files with 49 additions and 44 deletions

View File

@ -12,8 +12,8 @@ from fake_useragent import UserAgent
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from src.Loaders.Loader import Loader
from src.Loaders.Providers import Providers
from Loaders.Loader import Loader
from Loaders.Providers import Providers
from yt_dlp import YoutubeDL
import shutil
@ -146,7 +146,7 @@ class AniworldLoader(Loader):
return languageCode in languages
def Download(self, baseDirectory: str, serieFolder: str, season: int, episode: int, key: str, language: str = "German Dub") -> bool:
def Download(self, baseDirectory: str, serieFolder: str, season: int, episode: int, key: str, language: str = "German Dub", progress_callback: callable = None) -> bool:
sanitized_anime_title = ''.join(
char for char in self.GetTitle(key) if char not in self.INVALID_PATH_CHARS
)
@ -168,8 +168,6 @@ class AniworldLoader(Loader):
output_path = os.path.join(folderPath, output_file)
os.makedirs(os.path.dirname(output_path), exist_ok=True)
# Get the system-designated temp directory
temp_dir = "./Temp/"
os.makedirs(os.path.dirname(temp_dir), exist_ok=True)
temp_Path = os.path.join(temp_dir, output_file)
@ -187,6 +185,8 @@ class AniworldLoader(Loader):
if header:
ydl_opts['http_headers'] = header
if progress_callback:
ydl_opts['progress_hooks'] = [progress_callback]
with YoutubeDL(ydl_opts) as ydl:
ydl.download([link])
@ -341,6 +341,3 @@ class AniworldLoader(Loader):
episode_counts[season] = len(unique_links)
return episode_counts

View File

@ -11,7 +11,7 @@ class Loader(ABC):
pass
@abstractmethod
def Download(self, baseDirectory: str, serieFolder: str, season: int, episode: int, key: str) -> bool:
def Download(self, baseDirectory: str, serieFolder: str, season: int, episode: int, key: str, progress_callback: callable = None) -> bool:
pass
@abstractmethod

View File

@ -1,5 +1,5 @@
from src.Loaders.AniWorldLoader import AniworldLoader
from src.Loaders.Loader import Loader
from Loaders.AniWorldLoader import AniworldLoader
from Loaders.Loader import Loader
class Loaders:

View File

@ -1,7 +1,7 @@
from src.Loaders.provider.Provider import Provider
from src.Loaders.provider.voe import VOE
from Loaders.provider.Provider import Provider
from Loaders.provider.voe import VOE
class Providers:

View File

@ -4,7 +4,7 @@ import time
from fake_useragent import UserAgent
import requests
from src.Loaders.provider.Provider import Provider
from Loaders.provider.Provider import Provider
class Doodstream(Provider):
def __init__(self):

View File

@ -7,7 +7,7 @@ from urllib3.util.retry import Retry
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
from src.Loaders.provider.Provider import Provider
from Loaders.provider.Provider import Provider
# Compile regex patterns once for better performance
REDIRECT_PATTERN = re.compile(r"https?://[^'\"<>]+")

View File

@ -1,12 +1,13 @@
import sys
import os
import logging
from src.Loaders import AniWorldLoader
import progressbar
from Loaders import AniWorldLoader
from rich.progress import Progress
import SerieList
import SerieScanner
from src.Loaders.Loaders import Loaders
from src.Serie import Serie
from Loaders.Loaders import Loaders
from Serie import Serie
import time
# Configure logging
@ -38,8 +39,7 @@ class SeriesApp:
def __init__(self, directory_to_search: str):
print("Please wait while initializing...")
self.barTotal = None
self.bar = None
self.progress = None
self.directory_to_search = directory_to_search
self.Loaders = Loaders()
loader = self.Loaders.GetLoader(key="aniworld.to")
@ -109,40 +109,47 @@ class SeriesApp:
"""Simulate the downloading process with a progress bar."""
total_downloaded = 0
total_episodes = sum(sum(len(ep) for ep in serie.episodeDict.values()) for serie in series)
self.barTotal = progressbar.ProgressBar(
max_value=total_episodes,
widgets=[
progressbar.FormatLabel(f'Processing:'),
' ', progressbar.Percentage(),
' ', progressbar.Bar(),
' ', progressbar.ETA()
]
)
self.progress = Progress()
task1 = self.progress.add_task("[red]Processing...", total=total_episodes)
task2 = self.progress.add_task(f"[green]...", total=0)
self.task3 = self.progress.add_task(f"[Gray]...", total=100) # Setze total auf 100 für Prozentanzeige
self.progress.start()
for serie in series:
serie_episodes = sum(len(ep) for ep in serie.episodeDict.values())
self.progress.update(task2, description=f"[green]{serie.name}", total=serie_episodes)
downloaded = 0
self.bar = progressbar.ProgressBar(
max_value=serie_episodes,
widgets=[
progressbar.FormatLabel(f'Processing {serie.name}:'),
' ', progressbar.Percentage(),
' ', progressbar.Bar(),
' ', progressbar.ETA()
]
)
for season, episodes in serie.episodeDict.items():
for episode in episodes:
loader = self.Loaders.GetLoader(key="aniworld.to")
if loader.IsLanguage(season, episode, serie.key):
self.retry(loader.Download, 3, 1, self.directory_to_search, serie.folder, season, episode, serie.key)
self.retry(loader.Download, 3, 1, self.directory_to_search, serie.folder, season, episode, serie.key, self.print_Download_Progress)
downloaded += 1
total_downloaded += 1
self.bar.update(downloaded)
self.bar.update(total_downloaded)
self.progress.update(task1, advance=1)
self.progress.update(task2, advance=1)
time.sleep(0.02)
self.progress.stop()
self.progress = None
def print_Download_Progress(self, d):
# Nutze self.progress und self.task3 für Fortschrittsanzeige
if self.progress is None or not hasattr(self, 'task3'):
return
if d['status'] == 'downloading':
total = d.get('total_bytes') or d.get('total_bytes_estimate')
downloaded = d.get('downloaded_bytes', 0)
if total:
percent = downloaded / total * 100
self.progress.update(self.task3, completed=percent, description=f"[gray]Download: {percent:.1f}%")
else:
self.progress.update(self.task3, description=f"[gray]{downloaded/1024/1024:.2f}MB geladen")
elif d['status'] == 'finished':
self.progress.update(self.task3, completed=100, description="[gray]Download abgeschlossen.")
def search_mode(self):
"""Search for a series and allow user to select an option."""
@ -209,6 +216,7 @@ class SeriesApp:
# Run the app
if __name__ == "__main__":
# Read the base directory from an environment variable
directory_to_search = os.getenv("ANIME_DIRECTORY", "\\\\sshfs.r\\ubuntu@192.168.178.43\\media\\serien\\Serien")
app = SeriesApp(directory_to_search)

View File

@ -5,7 +5,7 @@ from Serie import Serie
import traceback
from GlobalLogger import error_logger, noKeyFound_logger
from Exceptions import NoKeyFoundException, MatchNotFoundError
from src.Loaders.Loader import Loader
from Loaders.Loader import Loader
class SerieScanner: