fix: progress part 1. percentage is working
This commit is contained in:
parent
34019b7e65
commit
029abb9be2
@ -13,8 +13,8 @@
|
||||
"status": "cancelled",
|
||||
"priority": "NORMAL",
|
||||
"added_at": "2025-11-20T17:12:34.485225Z",
|
||||
"started_at": "2025-11-20T18:09:04.527701Z",
|
||||
"completed_at": "2025-11-20T18:09:27.852314Z",
|
||||
"started_at": "2025-11-20T18:15:48.216607Z",
|
||||
"completed_at": "2025-11-20T18:16:38.929297Z",
|
||||
"progress": null,
|
||||
"error": null,
|
||||
"retry_count": 0,
|
||||
@ -943,5 +943,5 @@
|
||||
],
|
||||
"active": [],
|
||||
"failed": [],
|
||||
"timestamp": "2025-11-20T18:09:27.852598+00:00"
|
||||
"timestamp": "2025-11-20T18:16:38.929570+00:00"
|
||||
}
|
||||
@ -260,6 +260,7 @@ class SeriesApp:
|
||||
progress=(downloaded / total_bytes) * 100 if total_bytes else 0,
|
||||
eta=eta,
|
||||
mbper_sec=mbper_sec,
|
||||
item_id=item_id,
|
||||
)
|
||||
)
|
||||
# Perform download in thread to avoid blocking event loop
|
||||
|
||||
@ -37,6 +37,7 @@ class AnimeService:
|
||||
self._app = series_app
|
||||
self._directory = series_app.directory_to_search
|
||||
self._progress_service = progress_service or get_progress_service()
|
||||
self._event_loop: Optional[asyncio.AbstractEventLoop] = None
|
||||
# Subscribe to SeriesApp events
|
||||
# Note: Events library uses assignment (=), not += operator
|
||||
try:
|
||||
@ -54,13 +55,17 @@ class AnimeService:
|
||||
args: DownloadStatusEventArgs from SeriesApp
|
||||
"""
|
||||
try:
|
||||
# Check if there's a running event loop
|
||||
# Get event loop - try running loop first, then stored loop
|
||||
loop = None
|
||||
try:
|
||||
loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
# No running loop - log and skip
|
||||
# No running loop in this thread - use stored loop
|
||||
loop = self._event_loop
|
||||
|
||||
if not loop:
|
||||
logger.debug(
|
||||
"No running event loop for download status event",
|
||||
"No event loop available for download status event",
|
||||
status=args.status
|
||||
)
|
||||
return
|
||||
@ -74,38 +79,42 @@ class AnimeService:
|
||||
|
||||
# Map SeriesApp download events to progress service
|
||||
if args.status == "started":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.start_progress(
|
||||
progress_id=progress_id,
|
||||
progress_type=ProgressType.DOWNLOAD,
|
||||
title=f"Downloading {args.serie_folder}",
|
||||
message=f"S{args.season:02d}E{args.episode:02d}",
|
||||
metadata={"item_id": args.item_id} if args.item_id else None,
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
elif args.status == "progress":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.update_progress(
|
||||
progress_id=progress_id,
|
||||
current=int(args.progress),
|
||||
total=100,
|
||||
message=args.message or "Downloading...",
|
||||
metadata={"item_id": args.item_id} if args.item_id else None,
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
elif args.status == "completed":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.complete_progress(
|
||||
progress_id=progress_id,
|
||||
message="Download completed",
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
elif args.status == "failed":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.fail_progress(
|
||||
progress_id=progress_id,
|
||||
error_message=args.message or str(args.error),
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
@ -122,56 +131,65 @@ class AnimeService:
|
||||
try:
|
||||
scan_id = "library_scan"
|
||||
|
||||
# Check if there's a running event loop
|
||||
# Get event loop - try running loop first, then stored loop
|
||||
loop = None
|
||||
try:
|
||||
loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
# No running loop - log and skip
|
||||
# No running loop in this thread - use stored loop
|
||||
loop = self._event_loop
|
||||
|
||||
if not loop:
|
||||
logger.debug(
|
||||
"No running event loop for scan status event",
|
||||
"No event loop available for scan status event",
|
||||
status=args.status
|
||||
)
|
||||
return
|
||||
|
||||
# Map SeriesApp scan events to progress service
|
||||
if args.status == "started":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.start_progress(
|
||||
progress_id=scan_id,
|
||||
progress_type=ProgressType.SCAN,
|
||||
title="Scanning anime library",
|
||||
message=args.message or "Initializing scan...",
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
elif args.status == "progress":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.update_progress(
|
||||
progress_id=scan_id,
|
||||
current=args.current,
|
||||
total=args.total,
|
||||
message=args.message or f"Scanning: {args.folder}",
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
elif args.status == "completed":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.complete_progress(
|
||||
progress_id=scan_id,
|
||||
message=args.message or "Scan completed",
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
elif args.status == "failed":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.fail_progress(
|
||||
progress_id=scan_id,
|
||||
error_message=args.message or str(args.error),
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
elif args.status == "cancelled":
|
||||
loop.create_task(
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self._progress_service.fail_progress(
|
||||
progress_id=scan_id,
|
||||
error_message=args.message or "Scan cancelled",
|
||||
)
|
||||
),
|
||||
loop
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.error("Error handling scan status event", error=str(exc))
|
||||
@ -228,6 +246,9 @@ class AnimeService:
|
||||
forwarded to the ProgressService through event handlers.
|
||||
"""
|
||||
try:
|
||||
# Store event loop for event handlers
|
||||
self._event_loop = asyncio.get_running_loop()
|
||||
|
||||
# SeriesApp.rescan is now async and handles events internally
|
||||
await self._app.rescan()
|
||||
|
||||
@ -247,21 +268,33 @@ class AnimeService:
|
||||
season: int,
|
||||
episode: int,
|
||||
key: str,
|
||||
item_id: Optional[str] = None,
|
||||
) -> bool:
|
||||
"""Start a download.
|
||||
|
||||
The SeriesApp now handles progress tracking via events which are
|
||||
forwarded to the ProgressService through event handlers.
|
||||
|
||||
Args:
|
||||
serie_folder: Serie folder name
|
||||
season: Season number
|
||||
episode: Episode number
|
||||
key: Serie key
|
||||
item_id: Optional download queue item ID for tracking
|
||||
|
||||
Returns True on success or raises AnimeServiceError on failure.
|
||||
"""
|
||||
try:
|
||||
# Store event loop for event handlers
|
||||
self._event_loop = asyncio.get_running_loop()
|
||||
|
||||
# SeriesApp.download is now async and handles events internally
|
||||
return await self._app.download(
|
||||
serie_folder=serie_folder,
|
||||
season=season,
|
||||
episode=episode,
|
||||
key=key,
|
||||
item_id=item_id,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.exception("download failed")
|
||||
|
||||
@ -808,6 +808,7 @@ class DownloadService:
|
||||
season=item.episode.season,
|
||||
episode=item.episode.episode,
|
||||
key=item.serie_id,
|
||||
item_id=item.id,
|
||||
)
|
||||
|
||||
# Handle result
|
||||
|
||||
@ -247,6 +247,7 @@ class TestDownload:
|
||||
season=1,
|
||||
episode=1,
|
||||
key="test_key",
|
||||
item_id=None,
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -272,6 +273,7 @@ class TestDownload:
|
||||
season=1,
|
||||
episode=1,
|
||||
key="test_key",
|
||||
item_id=None,
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user