sandbox-reports/veo3_scheduler.py
DJP facacc94d4 Update AI Tools Usage Report System - Multi-Tool Support
Enhanced the VEO3 usage report system to support all AI tool types:
- Added support for 6 tool types: VEO3, TEXT2IMAGE, TEXT2VOICE, SPEECH2SPEECH, DOCUMENT_TRANSLATION, VIDEOQUERY
- Updated Python report generator (veo3_report.py) with dynamic tool detection
- Updated PHP report page (report.php) with tool usage breakdown section
- Changed all "Prompts" references to "Requests" for clarity
- Updated refresh button to fetch only last 12 weeks (84 days) for better performance
- Made system dynamic to handle unknown tool types automatically
- Renamed report titles from "VEO3 Usage Report" to "AI Tools Usage Report"

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-01-08 14:50:04 -05:00

135 lines
3.9 KiB
Python
Executable file

#!/usr/bin/env python3
"""
VEO3 Report Scheduler Service
Runs daily at 7:00 PM EST to generate and email VEO3 usage reports
"""
import os
import sys
import logging
import signal
from datetime import datetime
from pathlib import Path
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
import pytz
# Add the script directory to path so we can import veo3_report
script_dir = Path(__file__).parent
sys.path.insert(0, str(script_dir))
# Import the report generation function
from veo3_report import main as generate_report
# Configure logging
log_dir = script_dir / 'logs'
log_dir.mkdir(exist_ok=True)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(log_dir / 'veo3_scheduler.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger('VEO3Scheduler')
# Timezone configuration
EST = pytz.timezone('America/New_York')
class VEO3Scheduler:
"""Scheduler service for VEO3 reports"""
def __init__(self):
self.scheduler = BlockingScheduler(timezone=EST)
self.running = False
# Register signal handlers for graceful shutdown
signal.signal(signal.SIGINT, self._signal_handler)
signal.signal(signal.SIGTERM, self._signal_handler)
def _signal_handler(self, signum, frame):
"""Handle shutdown signals gracefully"""
logger.info(f"Received signal {signum}. Shutting down gracefully...")
self.stop()
def run_report(self):
"""Execute the report generation"""
try:
logger.info("=" * 70)
logger.info("STARTING SCHEDULED REPORT GENERATION")
logger.info("=" * 70)
# Change to script directory to ensure relative paths work
os.chdir(script_dir)
# Run the report generation
generate_report()
logger.info("=" * 70)
logger.info("REPORT GENERATION COMPLETED SUCCESSFULLY")
logger.info("=" * 70)
except Exception as e:
logger.error(f"Error generating report: {e}", exc_info=True)
logger.error("=" * 70)
logger.error("REPORT GENERATION FAILED")
logger.error("=" * 70)
def start(self):
"""Start the scheduler service"""
logger.info("VEO3 Report Scheduler Service Starting...")
logger.info(f"Working directory: {script_dir}")
logger.info(f"Timezone: {EST}")
# Schedule daily report at 7:00 PM EST
self.scheduler.add_job(
self.run_report,
trigger=CronTrigger(hour=19, minute=0, timezone=EST),
id='daily_report',
name='Daily VEO3 Report Generation',
replace_existing=True
)
# Log scheduling confirmation
logger.info(f"Scheduled to run daily at 7:00 PM EST")
logger.info("Job scheduled successfully")
# Optional: Run immediately on startup for testing
# Uncomment the line below to run a report when the service starts
# logger.info("Running initial report...")
# self.run_report()
self.running = True
try:
logger.info("Scheduler service is now running. Press Ctrl+C to stop.")
self.scheduler.start()
except (KeyboardInterrupt, SystemExit):
self.stop()
def stop(self):
"""Stop the scheduler service"""
if self.running:
logger.info("Stopping scheduler service...")
self.scheduler.shutdown(wait=True)
self.running = False
logger.info("Scheduler service stopped.")
sys.exit(0)
def main():
"""Main entry point"""
logger.info("=" * 70)
logger.info("VEO3 REPORT SCHEDULER SERVICE")
logger.info("=" * 70)
scheduler = VEO3Scheduler()
scheduler.start()
if __name__ == "__main__":
main()