queue fix
This commit is contained in:
parent
3be175522f
commit
3c6d82907d
@ -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
@ -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
|
||||
@ -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,
|
||||
}
|
||||
)
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -153,15 +153,14 @@ 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."""
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user