dev (#18)
Local Docker Build (Main) / build (push) Successful in 23s
Local Docker Build (Main) / deploy (push) Successful in 0s

Reviewed-on: #18
This commit was merged in pull request #18.
This commit is contained in:
2025-09-27 17:52:46 -04:00
parent 8da7853cca
commit 7ae8ce0024
23 changed files with 5255 additions and 3 deletions
+160
View File
@@ -0,0 +1,160 @@
#!/usr/bin/env python3
"""
NFOGuard - Automated NFO file management for Radarr and Sonarr
Modular architecture with webhook processing and intelligent date handling
"""
import os
import sys
import signal
from pathlib import Path
from datetime import datetime, timezone
import uvicorn
from fastapi import FastAPI
# Import configuration first
from config.settings import config
from utils.logging import _log
# Import core components
from core.database import NFOGuardDatabase
from core.nfo_manager import NFOManager
from core.path_mapper import PathMapper
# Import clients
from clients.external_clients import ExternalClientManager
# Import processors
from processors.tv_processor import TVProcessor
from processors.movie_processor import MovieProcessor
# Import webhook handling
from webhooks.webhook_batcher import WebhookBatcher
# Import API routes
from api.routes import register_routes
def get_version() -> str:
"""Get application version"""
try:
version = (Path(__file__).parent / "VERSION").read_text().strip()
except:
version = "0.1.0"
# Check if running from dev branch (detect at runtime)
try:
# Try to read git branch from .git/HEAD
git_head_path = Path(__file__).parent / ".git" / "HEAD"
if git_head_path.exists():
head_content = git_head_path.read_text().strip()
if "ref: refs/heads/dev" in head_content:
version = f"{version}-dev"
elif head_content.startswith("ref: refs/heads/"):
# Extract branch name for other branches
branch = head_content.split("refs/heads/")[-1]
if branch != "main":
version = f"{version}-{branch}"
except Exception:
# If git detection fails, that's fine - use base version
pass
# Check for build source (only add -gitea for local Gitea builds)
build_source = os.environ.get("BUILD_SOURCE", "")
if build_source == "gitea":
if "gitea" not in version: # Don't double-add gitea suffix
version = f"{version}-gitea"
return version
def create_app() -> FastAPI:
"""Create and configure the FastAPI application"""
version = get_version()
app = FastAPI(
title="NFOGuard",
description="Webhook server for preserving media import dates",
version=version
)
return app
def initialize_components():
"""Initialize all application components"""
start_time = datetime.now(timezone.utc)
# Initialize core components
db = NFOGuardDatabase(config.db_path)
nfo_manager = NFOManager(config.manager_brand, config.debug)
path_mapper = PathMapper(config)
# Initialize processors
tv_processor = TVProcessor(db, nfo_manager, path_mapper)
movie_processor = MovieProcessor(db, nfo_manager, path_mapper)
# Initialize webhook batcher
batcher = WebhookBatcher()
batcher.set_processors(tv_processor, movie_processor)
return {
"db": db,
"nfo_manager": nfo_manager,
"path_mapper": path_mapper,
"tv_processor": tv_processor,
"movie_processor": movie_processor,
"batcher": batcher,
"start_time": start_time,
"config": config,
"version": get_version()
}
def signal_handler(signum, frame):
"""Handle shutdown signals gracefully"""
_log("INFO", f"Received signal {signum}, shutting down gracefully...")
sys.exit(0)
def main():
"""Main application entry point"""
# Register signal handlers for graceful shutdown
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
version = get_version()
_log("INFO", "Starting NFOGuard")
_log("INFO", f"Version: {version}")
_log("INFO", f"TV paths: {[str(p) for p in config.tv_paths]}")
_log("INFO", f"Movie paths: {[str(p) for p in config.movie_paths]}")
_log("INFO", f"Database: {config.db_path}")
_log("INFO", f"Config: manage_nfo={config.manage_nfo}, fix_mtimes={config.fix_dir_mtimes}")
_log("INFO", f"Movie priority: {config.movie_priority}")
# Create FastAPI app
app = create_app()
# Initialize components
dependencies = initialize_components()
# Register routes
register_routes(app, dependencies)
try:
uvicorn.run(
app,
host="0.0.0.0",
port=int(os.environ.get("PORT", "8080")),
reload=False
)
except KeyboardInterrupt:
_log("INFO", "NFOGuard stopped by user")
except Exception as e:
_log("ERROR", f"NFOGuard crashed: {e}")
sys.exit(1)
if __name__ == "__main__":
main()