diff --git a/src/server/providers/aniworld_provider.py b/src/server/providers/aniworld_provider.py index 9e23884..0946d0b 100644 --- a/src/server/providers/aniworld_provider.py +++ b/src/server/providers/aniworld_provider.py @@ -5,6 +5,7 @@ import logging import os import re import shutil +import time import threading from pathlib import Path from urllib.parse import quote @@ -383,6 +384,12 @@ class AniworldLoader(Loader): "Direct stream download starting (type=%s)", content_type ) + total_size = int(response.headers.get( + "Content-Length", 0 + )) + received = 0 + last_emit = 0 + start_time = time.monotonic() with open(output_path, "wb") as fh: for chunk in response.iter_content(chunk_size=1024 * 1024): if self._cancel_flag.is_set(): @@ -391,7 +398,33 @@ class AniworldLoader(Loader): ) return False if chunk: + received += len(chunk) fh.write(chunk) + # Emit progress events at ~1% intervals + if total_size > 0: + pct = (received / total_size) * 100 + if pct - last_emit >= 1.0 or received == total_size: + elapsed = time.monotonic() - start_time + speed_bps = ( + received / elapsed + if elapsed > 0 else 0 + ) + eta = ( + int((total_size - received) / speed_bps) + if speed_bps > 0 else None + ) + self.events.download_progress({ + "downloaded_bytes": received, + "total_bytes": total_size, + "speed": speed_bps, + "eta": eta, + "status": ( + "finished" + if received >= total_size + else "downloading" + ), + }) + last_emit = pct return True except requests.RequestException as exc: logger.warning("Direct stream download failed: %s", exc)