from flask import Flask, render_template_string, jsonify from apscheduler.schedulers.background import BackgroundScheduler import subprocess import threading import pytz from datetime import datetime app = Flask(__name__) execution_logs = [] MAX_LOG_ENTRIES = 20 def run_cli_script(): """Runs cli.py and streams logs in real-time to both UI and terminal.""" # Get the current UTC time and convert to IST utc_now = datetime.utcnow() ist_timezone = pytz.timezone("Asia/Kolkata") ist_time = utc_now.replace(tzinfo=pytz.utc).astimezone(ist_timezone) # Format the IST time timestamp = ist_time.strftime("%Y-%m-%d %H:%M:%S IST") # timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC") log_entry = {'time': timestamp, 'output': '', 'error': ''} try: process = subprocess.Popen( ["python", "cli.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1 ) # Stream logs to UI and print to terminal for line in process.stdout: log_entry['output'] += line execution_logs.append({'time': timestamp, 'output': line, 'error': ''}) print(line, end="") # ✅ Print logs to terminal if len(execution_logs) > MAX_LOG_ENTRIES: execution_logs.pop(0) for line in process.stderr: log_entry['error'] += line execution_logs.append({'time': timestamp, 'output': '', 'error': line}) print(line, end="") # ✅ Print errors to terminal if len(execution_logs) > MAX_LOG_ENTRIES: execution_logs.pop(0) except Exception as e: log_entry['error'] = str(e) execution_logs.append({'time': timestamp, 'output': '', 'error': str(e)}) print(f"Error: {str(e)}") # ✅ Print error to terminal def start_initial_run(): threading.Thread(target=run_cli_script, daemon=True).start() scheduler = BackgroundScheduler(daemon=True) scheduler.add_job( run_cli_script, 'interval', hours=3, id='main_job', next_run_time=datetime.now() ) scheduler.start() start_initial_run() @app.route('/') def home(): """Main UI displaying logs and next run time.""" job = scheduler.get_job('main_job') next_run = job.next_run_time.strftime('%Y-%m-%d %H:%M:%S UTC') if job else 'N/A' return render_template_string('''
Next run: {{ next_run }}