176 lines
5.5 KiB
Python
176 lines
5.5 KiB
Python
"""
|
|
Diagnostic and monitoring routes.
|
|
"""
|
|
|
|
from flask import Blueprint, jsonify, request
|
|
from datetime import datetime
|
|
from functools import wraps
|
|
|
|
from web.controllers.auth_controller import optional_auth, require_auth
|
|
|
|
diagnostic_bp = Blueprint('diagnostic', __name__, url_prefix='/api/diagnostics')
|
|
|
|
# Simple decorator to handle API errors
|
|
def handle_api_errors(f):
|
|
"""Simple error handling decorator."""
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
try:
|
|
return f(*args, **kwargs)
|
|
except Exception as e:
|
|
return jsonify({'status': 'error', 'message': str(e)}), 500
|
|
return decorated_function
|
|
|
|
# Placeholder objects for missing modules
|
|
class PlaceholderNetworkChecker:
|
|
def get_network_status(self):
|
|
return {
|
|
"status": "unknown",
|
|
"connected": True,
|
|
"ping_ms": 0,
|
|
"dns_working": True
|
|
}
|
|
def check_url_reachability(self, url):
|
|
return True
|
|
|
|
class PlaceholderErrorManager:
|
|
def __init__(self):
|
|
self.error_history = []
|
|
self.blacklisted_urls = {}
|
|
self.retry_counts = {}
|
|
|
|
class PlaceholderHealthMonitor:
|
|
def get_current_health_status(self):
|
|
return {
|
|
"status": "healthy",
|
|
"uptime": "1h 30m",
|
|
"memory_usage": "45%",
|
|
"cpu_usage": "12%"
|
|
}
|
|
|
|
class RetryableError(Exception):
|
|
"""Placeholder exception for retryable errors."""
|
|
pass
|
|
|
|
network_health_checker = PlaceholderNetworkChecker()
|
|
error_recovery_manager = PlaceholderErrorManager()
|
|
health_monitor = PlaceholderHealthMonitor()
|
|
|
|
# Placeholder process lock constants and functions
|
|
RESCAN_LOCK = "rescan"
|
|
DOWNLOAD_LOCK = "download"
|
|
|
|
# Simple in-memory process lock system
|
|
_active_locks = {}
|
|
|
|
def is_process_running(lock_name):
|
|
"""Check if a process is currently running (locked)."""
|
|
return lock_name in _active_locks
|
|
|
|
@diagnostic_bp.route('/network')
|
|
@handle_api_errors
|
|
@optional_auth
|
|
def network_diagnostics():
|
|
"""Get network diagnostics and connectivity status."""
|
|
try:
|
|
network_status = network_health_checker.get_network_status()
|
|
|
|
# Test AniWorld connectivity
|
|
aniworld_reachable = network_health_checker.check_url_reachability("https://aniworld.to")
|
|
network_status['aniworld_reachable'] = aniworld_reachable
|
|
|
|
return jsonify({
|
|
'status': 'success',
|
|
'data': network_status
|
|
})
|
|
except Exception as e:
|
|
raise RetryableError(f"Network diagnostics failed: {e}")
|
|
|
|
@diagnostic_bp.route('/errors')
|
|
@handle_api_errors
|
|
@optional_auth
|
|
def get_error_history():
|
|
"""Get recent error history."""
|
|
try:
|
|
recent_errors = error_recovery_manager.error_history[-50:] # Last 50 errors
|
|
|
|
return jsonify({
|
|
'status': 'success',
|
|
'data': {
|
|
'recent_errors': recent_errors,
|
|
'total_errors': len(error_recovery_manager.error_history),
|
|
'blacklisted_urls': list(error_recovery_manager.blacklisted_urls.keys())
|
|
}
|
|
})
|
|
except Exception as e:
|
|
raise RetryableError(f"Error history retrieval failed: {e}")
|
|
|
|
@diagnostic_bp.route('/system-status')
|
|
@handle_api_errors
|
|
@optional_auth
|
|
def system_status_summary():
|
|
"""Get comprehensive system status summary."""
|
|
try:
|
|
# Get health status
|
|
health_status = health_monitor.get_current_health_status()
|
|
|
|
# Get network status
|
|
network_status = network_health_checker.get_network_status()
|
|
|
|
# Get process status
|
|
process_status = {
|
|
'rescan_running': is_process_running(RESCAN_LOCK),
|
|
'download_running': is_process_running(DOWNLOAD_LOCK)
|
|
}
|
|
|
|
# Get error statistics
|
|
error_stats = {
|
|
'total_errors': len(error_recovery_manager.error_history),
|
|
'recent_errors': len([e for e in error_recovery_manager.error_history
|
|
if (datetime.now() - datetime.fromisoformat(e.get('timestamp', datetime.now().isoformat()))).seconds < 3600]),
|
|
'blacklisted_urls': len(error_recovery_manager.blacklisted_urls)
|
|
}
|
|
|
|
return jsonify({
|
|
'status': 'success',
|
|
'data': {
|
|
'health': health_status,
|
|
'network': network_status,
|
|
'processes': process_status,
|
|
'errors': error_stats,
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|
|
})
|
|
except Exception as e:
|
|
raise RetryableError(f"System status retrieval failed: {e}")
|
|
|
|
# Recovery routes
|
|
@diagnostic_bp.route('/recovery/clear-blacklist', methods=['POST'])
|
|
@handle_api_errors
|
|
@require_auth
|
|
def clear_blacklist():
|
|
"""Clear URL blacklist."""
|
|
try:
|
|
error_recovery_manager.blacklisted_urls.clear()
|
|
return jsonify({
|
|
'status': 'success',
|
|
'message': 'URL blacklist cleared successfully'
|
|
})
|
|
except Exception as e:
|
|
raise RetryableError(f"Blacklist clearing failed: {e}")
|
|
|
|
@diagnostic_bp.route('/recovery/retry-counts')
|
|
@handle_api_errors
|
|
@optional_auth
|
|
def get_retry_counts():
|
|
"""Get retry statistics."""
|
|
try:
|
|
return jsonify({
|
|
'status': 'success',
|
|
'data': {
|
|
'retry_counts': error_recovery_manager.retry_counts,
|
|
'total_retries': sum(error_recovery_manager.retry_counts.values())
|
|
}
|
|
})
|
|
except Exception as e:
|
|
raise RetryableError(f"Retry statistics retrieval failed: {e}") |