"""/api/cron endpoint — currently reads clawdbot jobs.json (rewritten next commit).""" import json from datetime import datetime, timezone as dt_timezone from pathlib import Path from zoneinfo import ZoneInfo class CronHandlers: """Mixin for /api/cron.""" def handle_cron_status(self): """Get cron jobs status from ~/.clawdbot/cron/jobs.json (legacy schema).""" try: jobs_file = Path.home() / '.clawdbot' / 'cron' / 'jobs.json' if not jobs_file.exists(): self.send_json({'jobs': [], 'error': 'No jobs file found'}) return data = json.loads(jobs_file.read_text()) all_jobs = data.get('jobs', []) today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) today_start_ms = today_start.timestamp() * 1000 jobs = [] for job in all_jobs: if not job.get('enabled', False): continue schedule = job.get('schedule', {}) expr = schedule.get('expr', '') parts = expr.split() if len(parts) >= 2: minute = parts[0] hour = parts[1] if minute.isdigit() and (hour.isdigit() or '-' in hour): if '-' in hour: hour_start, _ = hour.split('-') hour = hour_start try: bucharest = ZoneInfo('Europe/Bucharest') utc_dt = datetime.now(dt_timezone.utc).replace( hour=int(hour), minute=int(minute), second=0, microsecond=0, ) local_dt = utc_dt.astimezone(bucharest) time_str = f"{local_dt.hour:02d}:{local_dt.minute:02d}" except Exception: time_str = f"{int(hour):02d}:{int(minute):02d}" else: time_str = expr[:15] else: time_str = expr[:15] state = job.get('state', {}) last_run = state.get('lastRunAtMs', 0) ran_today = last_run >= today_start_ms last_status = state.get('lastStatus', 'unknown') jobs.append({ 'id': job.get('id'), 'name': job.get('name'), 'agentId': job.get('agentId'), 'time': time_str, 'schedule': expr, 'ranToday': ran_today, 'lastStatus': last_status if ran_today else None, 'lastRunAtMs': last_run, 'nextRunAtMs': state.get('nextRunAtMs'), }) jobs.sort(key=lambda j: j['time']) self.send_json({ 'jobs': jobs, 'total': len(jobs), 'ranToday': sum(1 for j in jobs if j['ranToday']), }) except Exception as e: self.send_json({'error': str(e)}, 500)