This commit is contained in:
+132
-1
@@ -5,12 +5,16 @@ Provides endpoints for the web-based database manipulation interface
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from typing import List, Optional, Dict, Any
|
||||
from fastapi import HTTPException, Query
|
||||
from fastapi import HTTPException, Query, BackgroundTasks
|
||||
from pathlib import Path
|
||||
|
||||
from api.models import *
|
||||
|
||||
|
||||
# Global status tracking for database population
|
||||
_populate_status = {"running": False, "completed": False}
|
||||
|
||||
|
||||
def map_source_to_description(source: str) -> str:
|
||||
"""Map technical source codes to user-friendly descriptions"""
|
||||
if not source or source == "no_valid_date_source":
|
||||
@@ -1242,6 +1246,111 @@ async def get_episode_date_options(dependencies: dict, imdb_id: str, season: int
|
||||
}
|
||||
|
||||
|
||||
async def populate_database(background_tasks: BackgroundTasks, media_type: str = "both", dependencies: dict = None):
|
||||
"""
|
||||
Populate NFOGuard database from Radarr/Sonarr sources
|
||||
|
||||
Args:
|
||||
background_tasks: FastAPI background tasks
|
||||
media_type: Type of media to populate ("movies", "tv", or "both")
|
||||
dependencies: Dictionary with db, radarr_client, sonarr_client
|
||||
|
||||
Returns:
|
||||
Status message indicating population has started
|
||||
"""
|
||||
from core.database_populator import DatabasePopulator
|
||||
|
||||
db = dependencies["db"]
|
||||
config = dependencies["config"]
|
||||
|
||||
# Get Radarr and Sonarr clients
|
||||
from clients.radarr_client import RadarrClient
|
||||
from clients.sonarr_client import SonarrClient
|
||||
|
||||
radarr_client = RadarrClient(config)
|
||||
sonarr_client = SonarrClient(config)
|
||||
|
||||
if media_type not in ["both", "movies", "tv"]:
|
||||
raise HTTPException(status_code=400, detail="media_type must be 'both', 'movies', or 'tv'")
|
||||
|
||||
# Create global status tracking
|
||||
populate_status = {
|
||||
"running": True,
|
||||
"media_type": media_type,
|
||||
"start_time": datetime.now().isoformat(),
|
||||
"movies": {"status": "pending", "stats": None},
|
||||
"tv": {"status": "pending", "stats": None},
|
||||
"completed": False,
|
||||
"error": None
|
||||
}
|
||||
|
||||
# Store status globally so it can be queried
|
||||
global _populate_status
|
||||
_populate_status = populate_status
|
||||
|
||||
async def run_population():
|
||||
"""Background task to populate the database"""
|
||||
try:
|
||||
populator = DatabasePopulator(db, radarr_client, sonarr_client)
|
||||
|
||||
print(f"INFO: Starting database population: {media_type}")
|
||||
|
||||
if media_type == "movies":
|
||||
populate_status["movies"]["status"] = "running"
|
||||
movie_stats = populator.populate_movies()
|
||||
populate_status["movies"]["status"] = "completed"
|
||||
populate_status["movies"]["stats"] = movie_stats
|
||||
print(f"INFO: Movie population completed: {movie_stats}")
|
||||
|
||||
elif media_type == "tv":
|
||||
populate_status["tv"]["status"] = "running"
|
||||
tv_stats = populator.populate_tv_episodes()
|
||||
populate_status["tv"]["status"] = "completed"
|
||||
populate_status["tv"]["stats"] = tv_stats
|
||||
print(f"INFO: TV population completed: {tv_stats}")
|
||||
|
||||
elif media_type == "both":
|
||||
populate_status["movies"]["status"] = "running"
|
||||
movie_stats = populator.populate_movies()
|
||||
populate_status["movies"]["status"] = "completed"
|
||||
populate_status["movies"]["stats"] = movie_stats
|
||||
print(f"INFO: Movie population completed: {movie_stats}")
|
||||
|
||||
populate_status["tv"]["status"] = "running"
|
||||
tv_stats = populator.populate_tv_episodes()
|
||||
populate_status["tv"]["status"] = "completed"
|
||||
populate_status["tv"]["stats"] = tv_stats
|
||||
print(f"INFO: TV population completed: {tv_stats}")
|
||||
|
||||
populate_status["completed"] = True
|
||||
populate_status["running"] = False
|
||||
print("INFO: Database population completed successfully")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: Database population failed: {e}")
|
||||
populate_status["error"] = str(e)
|
||||
populate_status["running"] = False
|
||||
populate_status["completed"] = True
|
||||
|
||||
# Add task to background
|
||||
background_tasks.add_task(run_population)
|
||||
|
||||
print(f"INFO: Database population started for: {media_type}")
|
||||
return {
|
||||
"status": "started",
|
||||
"media_type": media_type,
|
||||
"message": f"Database population started for {media_type}"
|
||||
}
|
||||
|
||||
|
||||
async def get_populate_status():
|
||||
"""Get the current status of database population"""
|
||||
global _populate_status
|
||||
if '_populate_status' not in globals():
|
||||
return {"running": False, "completed": False}
|
||||
return _populate_status
|
||||
|
||||
|
||||
def register_web_routes(app, dependencies):
|
||||
"""Register all web API routes with FastAPI app"""
|
||||
from fastapi import Request, Response
|
||||
@@ -1944,6 +2053,28 @@ def register_database_admin_routes(app, dependencies):
|
||||
"""Get schedule execution history"""
|
||||
return await get_schedule_executions(dependencies, schedule_id)
|
||||
|
||||
# Database population endpoints
|
||||
print("🔧 DEBUG: Registering /admin/populate-database endpoint...")
|
||||
|
||||
@app.post("/admin/populate-database")
|
||||
async def api_populate_database(request: Request, background_tasks: BackgroundTasks):
|
||||
"""Populate database from Radarr/Sonarr"""
|
||||
print(f"🔥 DEBUG: populate-database endpoint called!")
|
||||
try:
|
||||
data = await request.json()
|
||||
media_type = data.get("media_type", "both")
|
||||
except Exception:
|
||||
# Fallback to query parameter if JSON parsing fails
|
||||
media_type = request.query_params.get("media_type", "both")
|
||||
return await populate_database(background_tasks, media_type, dependencies)
|
||||
|
||||
print("✅ DEBUG: /admin/populate-database registered")
|
||||
|
||||
@app.get("/api/populate/status")
|
||||
async def api_populate_status():
|
||||
"""Get database population status"""
|
||||
return await get_populate_status()
|
||||
|
||||
|
||||
# Scheduled Scans Functions
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>NFOGuard - Database Management</title>
|
||||
<link rel="stylesheet" href="/static/css/styles.css?v=2.8.1-populate-fix">
|
||||
<link rel="stylesheet" href="/static/css/styles.css?v=2.8.2-populate-fix2">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
@@ -12,7 +12,7 @@
|
||||
<!-- Header -->
|
||||
<header class="app-header">
|
||||
<div class="header-content">
|
||||
<h1><i class="fas fa-shield-alt"></i> NFOGuard <span style="font-size: 0.5em; color: #888;">v2.8.1-populate-fix</span></h1>
|
||||
<h1><i class="fas fa-shield-alt"></i> NFOGuard <span style="font-size: 0.5em; color: #888;">v2.8.2-populate-fix2</span></h1>
|
||||
<p>Database Management & Reporting</p>
|
||||
</div>
|
||||
<div class="auth-status" id="auth-status" style="display: none;">
|
||||
@@ -711,6 +711,6 @@
|
||||
<!-- Toast Notifications -->
|
||||
<div class="toast-container" id="toast-container"></div>
|
||||
|
||||
<script src="/static/js/app.js?v=2.8.1-populate-fix"></script>
|
||||
<script src="/static/js/app.js?v=2.8.2-populate-fix2"></script>
|
||||
</body>
|
||||
</html>
|
||||
+2
-2
@@ -29,7 +29,7 @@ def create_web_app() -> FastAPI:
|
||||
app = FastAPI(
|
||||
title="NFOGuard Web Interface",
|
||||
description="Web interface for NFOGuard media database management",
|
||||
version="2.7.0-web",
|
||||
version="2.8.2-populate-fix2",
|
||||
docs_url=None, # Disable docs in production
|
||||
redoc_url=None
|
||||
)
|
||||
@@ -94,7 +94,7 @@ def setup_static_files(app: FastAPI) -> None:
|
||||
"status": "healthy",
|
||||
"service": "nfoguard-web",
|
||||
"timestamp": time.time(),
|
||||
"version": "2.8.0-web"
|
||||
"version": "2.8.2-populate-fix2"
|
||||
}
|
||||
except Exception as e:
|
||||
from fastapi import HTTPException
|
||||
|
||||
Reference in New Issue
Block a user