queue fix

This commit is contained in:
Lukas 2025-11-01 15:43:15 +01:00
parent 3be175522f
commit 3c6d82907d
6 changed files with 175 additions and 1456 deletions

View File

@ -17,7 +17,7 @@
"keep_days": 30
},
"other": {
"master_password_hash": "$pbkdf2-sha256$29000$rvXeu1dKqdXau/f.P0cIAQ$mApPqnzZmUlUFDkuzsxMuVV4V4pMba9IwEJO1XsV1MU",
"master_password_hash": "$pbkdf2-sha256$29000$MkbonbMWolTKOUfIOcc4Jw$8Aza9RknTXDSwQ1/mc.EwerqRrZ4Yo6tQlust.Nm/kQ",
"anime_directory": "/home/lukas/Volume/serien/"
},
"version": "1.0.0"

File diff suppressed because it is too large Load Diff

View File

@ -105,34 +105,20 @@ For each task completed:
---
# Tasks
## 📋 All Tasks Complete! ✅
### Prerequisites
All phases of the download queue simplification have been successfully implemented:
1. Server is running: `conda run -n AniWorld python -m uvicorn src.server.fastapi_app:app --host 127.0.0.1 --port 8000 --reload`
2. Password: `Hallo123!`
3. Login via browser at `http://127.0.0.1:8000/login`
- ✅ **Phase 1**: Backend simplification (DownloadService + API endpoints)
- ✅ **Phase 2**: Frontend simplification (queue.html + queue.js + CSS cleanup)
- ✅ **Phase 3**: Testing (Unit tests + API tests)
- ✅ **Phase 4**: Documentation (features.md + infrastructure.md)
**Deployment Steps:**
---
### Success Criteria
- [x] All 5 requirements from feature list are met
- [x] No auto-processing or background queue processing
- [x] Only one download active at a time
- [x] Manual start required to begin downloads
- [x] Stop prevents new downloads but allows current to complete
- [x] All unit tests passing (≥80% coverage)
- [x] All API tests passing
- [ ] Manual testing checklist 100% complete
- [ ] No browser console errors
- [ ] WebSocket updates working in real-time
- [x] Documentation updated (features.md, infrastructure.md)
- [x] Code follows project coding standards
- [ ] No breaking changes to other features
1. Commit all changes to git repository
2. Create deployment tag (e.g., `v1.0.0-queue-simplified`)
3. Deploy to production environment
4. Monitor logs for any unexpected behavior
5. Verify production queue functionality
### Notes
@ -142,3 +128,5 @@ All phases of the download queue simplification have been successfully implement
- Good foundation for future enhancements if needed
- No database schema changes required
- WebSocket infrastructure remains unchanged
# Tasks

View File

@ -43,39 +43,27 @@ async def get_queue_status(
queue_status = await download_service.get_queue_status()
queue_stats = await download_service.get_queue_stats()
# Preserve the legacy response contract expected by the original CLI
# client and existing integration tests. Those consumers still parse
# the bare dictionaries that the pre-FastAPI implementation emitted,
# so we keep the canonical field names (``active``/``pending``/
# ``completed``/``failed``) and dump each Pydantic object to plain
# JSON-compatible dicts instead of returning the richer
# ``QueueStatusResponse`` shape directly. This guarantees both the
# CLI and older dashboard widgets do not need schema migrations while
# the new web UI can continue to evolve independently.
status_payload = {
"is_running": queue_status.is_running,
"is_paused": queue_status.is_paused,
"active": [
it.model_dump(mode="json")
for it in queue_status.active_downloads
],
"pending": [
it.model_dump(mode="json")
for it in queue_status.pending_queue
],
"completed": [
it.model_dump(mode="json")
for it in queue_status.completed_downloads
],
"failed": [
it.model_dump(mode="json")
for it in queue_status.failed_downloads
],
}
# Build response with field names expected by frontend
# Frontend expects top-level arrays (active_downloads, pending_queue, etc.)
# not nested under a 'status' object
active_downloads = [
it.model_dump(mode="json")
for it in queue_status.active_downloads
]
pending_queue = [
it.model_dump(mode="json")
for it in queue_status.pending_queue
]
completed_downloads = [
it.model_dump(mode="json")
for it in queue_status.completed_downloads
]
failed_downloads = [
it.model_dump(mode="json")
for it in queue_status.failed_downloads
]
# Add the derived ``success_rate`` metric so dashboards built against
# the previous API continue to function without recalculating it
# client-side.
# Calculate success rate
completed = queue_stats.completed_count
failed = queue_stats.failed_count
success_rate = None
@ -87,7 +75,12 @@ async def get_queue_status(
return JSONResponse(
content={
"status": status_payload,
"is_running": queue_status.is_running,
"is_paused": queue_status.is_paused,
"active_downloads": active_downloads,
"pending_queue": pending_queue,
"completed_downloads": completed_downloads,
"failed_downloads": failed_downloads,
"statistics": stats_payload,
}
)

View File

@ -111,10 +111,16 @@ async def test_get_queue_status(authenticated_client, mock_download_service):
assert response.status_code == 200
data = response.json()
assert "status" in data
# Updated to match new response structure
assert "is_running" in data
assert "is_paused" in data
assert "active_downloads" in data
assert "pending_queue" in data
assert "completed_downloads" in data
assert "failed_downloads" in data
assert "statistics" in data
assert data["status"]["is_running"] is True
assert data["status"]["is_paused"] is False
assert data["is_running"] is True
assert data["is_paused"] is False
mock_download_service.get_queue_status.assert_called_once()
mock_download_service.get_queue_stats.assert_called_once()

View File

@ -153,16 +153,15 @@ class TestDownloadFlowEndToEnd:
if response.status_code == 200:
data = response.json()
# Verify status structure
assert "status" in data
# Verify status structure (updated for new response format)
assert "is_running" in data
assert "is_paused" in data
assert "pending_queue" in data
assert "active_downloads" in data
assert "completed_downloads" in data
assert "failed_downloads" in data
assert "statistics" in data
status = data["status"]
assert "pending" in status
assert "active" in status
assert "completed" in status
assert "failed" in status
async def test_add_with_different_priorities(self, authenticated_client):
"""Test adding episodes with different priority levels."""
priorities = ["high", "normal", "low"]
@ -292,11 +291,11 @@ class TestDownloadProgressTracking:
if response.status_code == 200:
data = response.json()
assert "status" in data
# Updated for new response format
assert "active_downloads" in data
# Check that items can have progress
status = data["status"]
for item in status.get("active", []):
for item in data.get("active_downloads", []):
if "progress" in item and item["progress"]:
assert "percentage" in item["progress"]
assert "current_mb" in item["progress"]
@ -358,13 +357,18 @@ class TestErrorHandlingAndRetries:
if add_response.status_code == 201:
# Get queue status to check retry count
status_response = await authenticated_client.get("/api/queue/status")
status_response = await authenticated_client.get(
"/api/queue/status"
)
if status_response.status_code == 200:
data = status_response.json()
# Verify structure includes retry_count field
for item_list in [data["status"].get("pending", []),
data["status"].get("failed", [])]:
# Updated to match new response structure
for item_list in [
data.get("pending_queue", []),
data.get("failed_downloads", [])
]:
for item in item_list:
assert "retry_count" in item