imseldrith commited on
Commit
de50ad7
·
verified ·
1 Parent(s): 87175db

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -28
app.py CHANGED
@@ -1,15 +1,18 @@
1
  from flask import Flask, render_template_string
 
2
  from apscheduler.schedulers.background import BackgroundScheduler
3
  import subprocess
4
  import threading
5
  from datetime import datetime
6
 
7
  app = Flask(__name__)
 
 
8
  execution_logs = []
9
  MAX_LOG_ENTRIES = 20
10
 
11
  def run_cli_script():
12
- """Runs cli.py and streams the output in real-time."""
13
  timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
14
  log_entry = {'time': timestamp, 'output': '', 'error': ''}
15
 
@@ -19,33 +22,32 @@ def run_cli_script():
19
  stdout=subprocess.PIPE,
20
  stderr=subprocess.PIPE,
21
  text=True,
22
- bufsize=1 # Ensures line buffering (real-time output)
23
  )
24
 
25
- # Stream stdout in real-time
26
  for line in process.stdout:
27
  log_entry['output'] += line
28
- print(line, end="") # Also print to terminal for debugging
 
29
 
30
- # Capture errors in real-time
31
  for line in process.stderr:
32
  log_entry['error'] += line
33
- print(line, end="") # Also print to terminal for debugging
 
34
 
35
  except Exception as e:
36
  log_entry['error'] = str(e)
 
37
 
38
  finally:
39
  execution_logs.append(log_entry)
40
  if len(execution_logs) > MAX_LOG_ENTRIES:
41
  execution_logs.pop(0)
42
 
43
-
44
- # Start script in a separate thread to avoid blocking Flask
45
  def start_initial_run():
46
  threading.Thread(target=run_cli_script, daemon=True).start()
47
 
48
- # Initialize scheduler
49
  scheduler = BackgroundScheduler(daemon=True)
50
  scheduler.add_job(
51
  run_cli_script,
@@ -56,7 +58,6 @@ scheduler.add_job(
56
  )
57
  scheduler.start()
58
 
59
- # Run the script asynchronously to prevent blocking
60
  start_initial_run()
61
 
62
  @app.route('/')
@@ -64,13 +65,25 @@ def home():
64
  """Main UI displaying logs and next run time."""
65
  job = scheduler.get_job('main_job')
66
  next_run = job.next_run_time.strftime('%Y-%m-%d %H:%M:%S UTC') if job else 'N/A'
67
-
68
  return render_template_string('''
69
  <!DOCTYPE html>
70
  <html>
71
  <head>
72
  <title>Script Scheduler</title>
73
- <meta http-equiv="refresh" content="10">
 
 
 
 
 
 
 
 
 
 
 
 
74
  <style>
75
  body { font-family: Arial, sans-serif; padding: 20px; }
76
  .log-box {
@@ -91,25 +104,12 @@ def home():
91
  <h1>Script Scheduler</h1>
92
  <p>Next run: {{ next_run }}</p>
93
  <h2>Latest Execution Logs</h2>
94
- <div class="log-box">
95
- {% for log in logs|reverse %}
96
- <div class="timestamp">{{ log.time }}</div>
97
- {% if log.output %}
98
- <div class="output">{{ log.output }}</div>
99
- {% endif %}
100
- {% if log.error %}
101
- <div class="error">{{ log.error }}</div>
102
- {% endif %}
103
- <hr>
104
- {% else %}
105
- <div>No logs available yet</div>
106
- {% endfor %}
107
- </div>
108
  <p><a href="/force-run">Trigger Manual Run</a></p>
109
  <p><a href="/run-check">Check Scheduler Status</a></p>
110
  </body>
111
  </html>
112
- ''', next_run=next_run, logs=execution_logs)
113
 
114
  @app.route('/force-run')
115
  def force_run():
@@ -126,4 +126,4 @@ def run_check():
126
  return "Scheduler is running", 200
127
 
128
  if __name__ == '__main__':
129
- app.run(host='0.0.0.0', port=7860)
 
1
  from flask import Flask, render_template_string
2
+ from flask_socketio import SocketIO
3
  from apscheduler.schedulers.background import BackgroundScheduler
4
  import subprocess
5
  import threading
6
  from datetime import datetime
7
 
8
  app = Flask(__name__)
9
+ socketio = SocketIO(app, cors_allowed_origins="*") # Enable WebSocket
10
+
11
  execution_logs = []
12
  MAX_LOG_ENTRIES = 20
13
 
14
  def run_cli_script():
15
+ """Runs cli.py and streams logs in real-time."""
16
  timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
17
  log_entry = {'time': timestamp, 'output': '', 'error': ''}
18
 
 
22
  stdout=subprocess.PIPE,
23
  stderr=subprocess.PIPE,
24
  text=True,
25
+ bufsize=1
26
  )
27
 
28
+ # Stream logs in real-time to UI
29
  for line in process.stdout:
30
  log_entry['output'] += line
31
+ socketio.emit('log_update', {'time': timestamp, 'output': line, 'error': ''}) # Send to UI
32
+ print(line, end="") # Print to terminal for debugging
33
 
 
34
  for line in process.stderr:
35
  log_entry['error'] += line
36
+ socketio.emit('log_update', {'time': timestamp, 'output': '', 'error': line}) # Send to UI
37
+ print(line, end="")
38
 
39
  except Exception as e:
40
  log_entry['error'] = str(e)
41
+ socketio.emit('log_update', {'time': timestamp, 'output': '', 'error': str(e)}) # Send error to UI
42
 
43
  finally:
44
  execution_logs.append(log_entry)
45
  if len(execution_logs) > MAX_LOG_ENTRIES:
46
  execution_logs.pop(0)
47
 
 
 
48
  def start_initial_run():
49
  threading.Thread(target=run_cli_script, daemon=True).start()
50
 
 
51
  scheduler = BackgroundScheduler(daemon=True)
52
  scheduler.add_job(
53
  run_cli_script,
 
58
  )
59
  scheduler.start()
60
 
 
61
  start_initial_run()
62
 
63
  @app.route('/')
 
65
  """Main UI displaying logs and next run time."""
66
  job = scheduler.get_job('main_job')
67
  next_run = job.next_run_time.strftime('%Y-%m-%d %H:%M:%S UTC') if job else 'N/A'
68
+
69
  return render_template_string('''
70
  <!DOCTYPE html>
71
  <html>
72
  <head>
73
  <title>Script Scheduler</title>
74
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
75
+ <script>
76
+ var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
77
+ socket.on('log_update', function(data) {
78
+ var logBox = document.getElementById("log-box");
79
+ var logEntry = "<div class='timestamp'>" + data.time + "</div>";
80
+ if (data.output) logEntry += "<div class='output'>" + data.output + "</div>";
81
+ if (data.error) logEntry += "<div class='error'>" + data.error + "</div>";
82
+ logEntry += "<hr>";
83
+ logBox.innerHTML += logEntry; // Append new logs
84
+ logBox.scrollTop = logBox.scrollHeight; // Auto-scroll to bottom
85
+ });
86
+ </script>
87
  <style>
88
  body { font-family: Arial, sans-serif; padding: 20px; }
89
  .log-box {
 
104
  <h1>Script Scheduler</h1>
105
  <p>Next run: {{ next_run }}</p>
106
  <h2>Latest Execution Logs</h2>
107
+ <div id="log-box" class="log-box"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  <p><a href="/force-run">Trigger Manual Run</a></p>
109
  <p><a href="/run-check">Check Scheduler Status</a></p>
110
  </body>
111
  </html>
112
+ ''', next_run=next_run)
113
 
114
  @app.route('/force-run')
115
  def force_run():
 
126
  return "Scheduler is running", 200
127
 
128
  if __name__ == '__main__':
129
+ socketio.run(app, host='0.0.0.0', port=7860, allow_unsafe_werkzeug=True)