Files
personal_development/ServerManagerWebApp/backend/app/routers/comics.py
T
2026-01-09 19:24:41 +00:00

116 lines
3.7 KiB
Python

from fastapi import APIRouter, HTTPException, WebSocket, WebSocketDisconnect
from pydantic import BaseModel
from typing import List, Optional
import asyncio
import os
from ..comics_manager import ComicsManager
from ..config import settings
from ..samba_manager import SambaManager
from ..tasks import task_organize_comics, task_move_comics, task_update_metadata, task_sort_by_artist
router = APIRouter()
class MoveRequest(BaseModel):
series_names: List[str]
destination_share: Optional[str] = "comics"
destination_path: Optional[str] = "/manga"
class MetadataUpdateRequest(BaseModel):
target_path: Optional[str] = "/comics/manga"
force_update: Optional[bool] = False
class FolderScanRequest(BaseModel):
root_path: Optional[str] = "/comics/manga"
threshold: float = 0.9
class DeleteFolderRequest(BaseModel):
folder_path: str
class SortRequest(BaseModel):
root_path: Optional[str] = "/comics/manga"
def get_samba_manager(share="isolation"):
return SambaManager(
settings.samba_server_ip,
share,
settings.samba_username,
settings.samba_password,
)
@router.post("/organize")
def organize_comics():
task = task_organize_comics()
return {"message": f"Organization queued (Task ID: {task.id}). Check logs."}
@router.get("/pending")
def get_pending_comics():
manager = ComicsManager()
samba_manager = get_samba_manager("isolation")
try:
return manager.get_pending_comics(samba_manager)
finally:
samba_manager.close()
@router.post("/move")
def move_comics(request: MoveRequest):
task = task_move_comics(request.series_names, request.destination_share, request.destination_path)
return {"message": f"Move queued (Task ID: {task.id}). Check logs."}
@router.post("/update_metadata")
def update_metadata(request: MetadataUpdateRequest):
task = task_update_metadata(request.target_path, request.force_update)
return {"message": f"Metadata update queued (Task ID: {task.id}). Check logs."}
@router.post("/folders/scan")
def scan_folders(request: FolderScanRequest):
# This remains synchronous to return results immediately to UI
manager = ComicsManager()
samba_manager = get_samba_manager("isolation")
try:
groups = manager.find_similar_folders(samba_manager, request.root_path, request.threshold)
return groups
finally:
samba_manager.close()
@router.post("/folders/delete")
def delete_folder(request: DeleteFolderRequest):
manager = ComicsManager()
samba_manager = get_samba_manager("isolation")
try:
return manager.delete_folder(samba_manager, request.folder_path)
finally:
samba_manager.close()
@router.post("/sort_by_artist")
def sort_by_artist(request: SortRequest):
task = task_sort_by_artist(request.root_path)
return {"message": f"Sort by Artist queued (Task ID: {task.id}). Check logs."}
@router.websocket("/ws/logs")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
file_path = "logs/comics_organization.log"
# Ensure file exists
if not os.path.exists(file_path):
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, "w") as f: f.write("")
try:
with open(file_path, "r") as f:
# Send last 20 lines for context
lines = f.readlines()
for line in lines[-20:]:
await websocket.send_text(line)
# Follow the file
f.seek(0, 2)
while True:
line = f.readline()
if line:
await websocket.send_text(line)
else:
await asyncio.sleep(0.1)
except WebSocketDisconnect:
pass