136
scripts/paid-content-health-check.py
Executable file
136
scripts/paid-content-health-check.py
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Paid Content Service Health Check
|
||||
|
||||
Standalone script to check the health of all paid content services.
|
||||
Designed to be run via systemd timer every 4 hours.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
# Add parent directory to path for imports
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from modules.paid_content import (
|
||||
PaidContentDBAdapter,
|
||||
PaidContentAPIClient,
|
||||
FanslyDirectClient,
|
||||
YouTubeClient,
|
||||
TwitchClient
|
||||
)
|
||||
from modules.unified_database import UnifiedDatabase
|
||||
|
||||
|
||||
def log(message: str, level: str = "info"):
|
||||
"""Simple logging to stdout"""
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
print(f"[{timestamp}] [{level.upper()}] {message}")
|
||||
|
||||
|
||||
async def check_service_health(service: dict, pc_db: PaidContentDBAdapter) -> dict:
|
||||
"""Check health of a single service"""
|
||||
service_id = service['id']
|
||||
health = {'status': 'unknown', 'message': ''}
|
||||
|
||||
try:
|
||||
if service_id == 'youtube':
|
||||
youtube = YouTubeClient()
|
||||
if youtube.is_available():
|
||||
health = {'status': 'healthy', 'message': 'yt-dlp is available'}
|
||||
else:
|
||||
health = {'status': 'down', 'message': 'yt-dlp not found'}
|
||||
|
||||
elif service_id == 'twitch':
|
||||
twitch = TwitchClient()
|
||||
if twitch.is_available():
|
||||
health = {'status': 'healthy', 'message': 'yt-dlp is available for Twitch'}
|
||||
else:
|
||||
health = {'status': 'down', 'message': 'yt-dlp not found'}
|
||||
|
||||
elif service_id == 'fansly_direct':
|
||||
auth_token = service.get('session_cookie')
|
||||
if not auth_token:
|
||||
health = {'status': 'down', 'message': 'Auth token not configured'}
|
||||
else:
|
||||
client = FanslyDirectClient(auth_token=auth_token)
|
||||
try:
|
||||
result = await client.check_auth()
|
||||
if result.get('valid'):
|
||||
health = {
|
||||
'status': 'healthy',
|
||||
'message': f"Connected as {result.get('username', 'unknown')}"
|
||||
}
|
||||
else:
|
||||
health = {'status': 'down', 'message': result.get('error', 'Auth failed')}
|
||||
finally:
|
||||
await client.close()
|
||||
|
||||
else:
|
||||
# Coomer/Kemono services
|
||||
client = PaidContentAPIClient(
|
||||
service_id,
|
||||
session_cookie=service.get('session_cookie'),
|
||||
base_url=service.get('base_url')
|
||||
)
|
||||
try:
|
||||
health = await client.check_health()
|
||||
finally:
|
||||
await client.close()
|
||||
|
||||
# Update database
|
||||
pc_db.update_service(service_id, {
|
||||
'health_status': health.get('status', 'unknown'),
|
||||
'last_health_check': datetime.now().isoformat()
|
||||
})
|
||||
|
||||
return {'service_id': service_id, **health}
|
||||
|
||||
except Exception as e:
|
||||
log(f"Health check failed for {service_id}: {e}", "error")
|
||||
return {'service_id': service_id, 'status': 'error', 'message': str(e)}
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main health check routine"""
|
||||
log("Starting paid content service health check")
|
||||
|
||||
try:
|
||||
# Initialize database
|
||||
db = UnifiedDatabase()
|
||||
pc_db = PaidContentDBAdapter(db)
|
||||
|
||||
# Get all services
|
||||
services = pc_db.get_services()
|
||||
|
||||
if not services:
|
||||
log("No services configured", "warning")
|
||||
return 0
|
||||
|
||||
log(f"Checking {len(services)} services...")
|
||||
|
||||
# Check each service
|
||||
results = []
|
||||
for service in services:
|
||||
result = await check_service_health(service, pc_db)
|
||||
results.append(result)
|
||||
status_icon = "✓" if result['status'] == 'healthy' else "✗"
|
||||
log(f" {status_icon} {result['service_id']}: {result['status']} - {result.get('message', '')}")
|
||||
|
||||
# Summary
|
||||
healthy = sum(1 for r in results if r['status'] == 'healthy')
|
||||
total = len(results)
|
||||
log(f"Health check complete: {healthy}/{total} services healthy")
|
||||
|
||||
return 0 if healthy == total else 1
|
||||
|
||||
except Exception as e:
|
||||
log(f"Health check failed: {e}", "error")
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit_code = asyncio.run(main())
|
||||
sys.exit(exit_code)
|
||||
Reference in New Issue
Block a user