AstraOS commited on
Commit
e571993
·
verified ·
1 Parent(s): 8147bba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -34
app.py CHANGED
@@ -16,9 +16,9 @@ app = FastAPI()
16
  # (No token or outgoing HTTP calls are used in this version.)
17
  # Conversation state
18
  user_inputs = {}
19
- # Conversation fields depend on the mode:
20
- # Simple mode (default): only "input_url" and "output_url" are required.
21
- # Advanced mode (if user sends /setting): additional fields are required.
22
  conversation_fields = []
23
  current_step = None
24
  advanced_mode = False
@@ -32,7 +32,7 @@ default_settings = {
32
  }
33
 
34
  # Streaming state & statistics
35
- streaming_state = "idle" # Can be "idle", "streaming", "paused", or "stopped"
36
  stream_chat_id = None # Chat ID for periodic updates
37
  stream_start_time = None
38
  frames_encoded = 0
@@ -48,8 +48,9 @@ stream_thread = None
48
  live_log_thread = None
49
 
50
  # Live logging globals
51
- live_log_lines = [] # A rolling list of log lines (max 50 lines)
52
- error_notification = "" # Holds error details (if any)
 
53
 
54
  # -------------------------------------------------------------------
55
  # Enhanced Logging Setup
@@ -80,11 +81,11 @@ logger.addHandler(list_handler)
80
  # Utility Functions & UI Helpers
81
  # -------------------------------------------------------------------
82
  def create_html_message(text: str):
83
- # Return an HTML-formatted message wrapped in <pre> tags for monospaced output.
84
  return {"parse_mode": "HTML", "text": f"<pre>{text}</pre>"}
85
 
86
  def get_inline_keyboard_for_stream():
87
- # Inline keyboard for stream controls; this keyboard is always returned along with status messages.
88
  keyboard = {
89
  "inline_keyboard": [
90
  [
@@ -100,7 +101,7 @@ def get_inline_keyboard_for_stream():
100
  return keyboard
101
 
102
  def get_inline_keyboard_for_start():
103
- # Inline keyboard with a "Start Streaming" button.
104
  keyboard = {
105
  "inline_keyboard": [
106
  [
@@ -126,7 +127,7 @@ def help_text():
126
  )
127
 
128
  def send_guide_message(chat_id, message):
129
- # Return a response dictionary (Markdown format) for webhook replies.
130
  logging.info(f"Sending message to chat {chat_id}: {message}")
131
  return {
132
  "method": "sendMessage",
@@ -136,7 +137,7 @@ def send_guide_message(chat_id, message):
136
  }
137
 
138
  def send_guide_message_html(chat_id, message):
139
- # Return a response dictionary (HTML format) for webhook replies.
140
  logging.info(f"Sending HTML message to chat {chat_id}: {message}")
141
  return {
142
  "method": "sendMessage",
@@ -158,14 +159,15 @@ def get_uptime():
158
  return "0"
159
 
160
  def validate_inputs():
161
- # Check that all required fields have been provided.
162
  missing = [field for field in conversation_fields if field not in user_inputs or not user_inputs[field]]
163
  if missing:
164
  return False, f"Missing fields: {', '.join(missing)}"
165
  return True, ""
166
 
167
  def get_streaming_display_message(prefix=""):
168
- # Build an HTML message that combines an optional prefix, current streaming status, and the last 15 log lines.
 
169
  status = (
170
  f"<b>Stream Status:</b>\n"
171
  f"State: {streaming_state}\n"
@@ -173,14 +175,7 @@ def get_streaming_display_message(prefix=""):
173
  f"Frames Encoded: {frames_encoded}\n"
174
  f"Bytes Sent: {bytes_sent}\n"
175
  )
176
- if live_log_lines:
177
- logs = "<pre>" + "\n".join(live_log_lines[-15:]) + "</pre>"
178
- else:
179
- logs = "<pre>No logs available yet.</pre>"
180
- # Prepend any error notification if it exists.
181
- global error_notification
182
- if error_notification:
183
- logs = f"<pre>ERROR: {error_notification}\n\n" + logs[5:]
184
  return f"{prefix}\n{status}\n\nLive Logs:\n{logs}"
185
 
186
  # -------------------------------------------------------------------
@@ -195,12 +190,14 @@ def notify_error(chat_id, error_message):
195
  # Live Log Updater (Background Thread)
196
  # -------------------------------------------------------------------
197
  def live_log_updater():
198
- # This thread continuously (every 1 second) updates the global log display.
199
  try:
200
  while True:
201
- # (We no longer store the result in a separate variable;
202
- # get_streaming_display_message computes the logs directly from live_log_lines.)
203
  time.sleep(1)
 
 
 
204
  except Exception as e:
205
  logging.error(f"Error in live log updater: {e}")
206
 
@@ -208,13 +205,10 @@ def live_log_updater():
208
  # Logs History Handler (/logs)
209
  # -------------------------------------------------------------------
210
  def logs_history(chat_id):
211
- # Return a response containing the last 50 log lines (if any) in HTML format.
212
- if live_log_lines:
213
- log_text = "<pre>" + "\n".join(live_log_lines[-50:]) + "</pre>"
214
- else:
215
- log_text = "<pre>No logs available yet.</pre>"
216
- # Prepend error notification if present.
217
- global error_notification
218
  if error_notification:
219
  if log_text.startswith("<pre>"):
220
  log_text = f"<pre>ERROR: {error_notification}\n\n" + log_text[5:]
@@ -232,7 +226,7 @@ def logs_history(chat_id):
232
  # -------------------------------------------------------------------
233
  def handle_start(chat_id):
234
  global current_step, user_inputs, conversation_fields, advanced_mode
235
- # Use simple mode by default (unless advanced_mode has been enabled)
236
  user_inputs = {}
237
  if not advanced_mode:
238
  conversation_fields = ["input_url", "output_url"]
@@ -345,14 +339,14 @@ def stream_to_youtube(input_url, quality_settings, video_codec, audio_codec, out
345
  out_audio_stream.layout = "stereo"
346
  video_stream.codec_context.time_base = fractions.Fraction(1, video_stream.rate)
347
  logging.info("Streaming started successfully.")
348
- # Start live log updater (if not already running)
 
349
  global live_log_thread
350
  if live_log_thread is None or not live_log_thread.is_alive():
351
  live_log_thread = threading.Thread(target=live_log_updater)
352
  live_log_thread.daemon = True
353
  live_log_thread.start()
354
  logging.info("Live log updater thread started.")
355
- # Streaming loop
356
  while streaming_state in ["streaming", "paused"]:
357
  for packet in input_stream.demux():
358
  if streaming_state == "stopped":
 
16
  # (No token or outgoing HTTP calls are used in this version.)
17
  # Conversation state
18
  user_inputs = {}
19
+ # The conversation fields will depend on the mode.
20
+ # Simple mode (default): Only "input_url" and "output_url" are required.
21
+ # Advanced mode (if user sends /setting): Additional fields are required.
22
  conversation_fields = []
23
  current_step = None
24
  advanced_mode = False
 
32
  }
33
 
34
  # Streaming state & statistics
35
+ streaming_state = "idle" # "idle", "streaming", "paused", "stopped"
36
  stream_chat_id = None # Chat ID for periodic updates
37
  stream_start_time = None
38
  frames_encoded = 0
 
48
  live_log_thread = None
49
 
50
  # Live logging globals
51
+ live_log_lines = [] # Rolling list (max 50 log lines)
52
+ live_log_display = "" # Global variable updated every second by live_log_updater
53
+ error_notification = "" # Global variable to hold error details if any
54
 
55
  # -------------------------------------------------------------------
56
  # Enhanced Logging Setup
 
81
  # Utility Functions & UI Helpers
82
  # -------------------------------------------------------------------
83
  def create_html_message(text: str):
84
+ # Wrap text in <pre> tags for monospaced output using HTML parse mode
85
  return {"parse_mode": "HTML", "text": f"<pre>{text}</pre>"}
86
 
87
  def get_inline_keyboard_for_stream():
88
+ # Inline keyboard for streaming controls that remain visible in the message
89
  keyboard = {
90
  "inline_keyboard": [
91
  [
 
101
  return keyboard
102
 
103
  def get_inline_keyboard_for_start():
104
+ # Inline keyboard with a start button for when setup is complete.
105
  keyboard = {
106
  "inline_keyboard": [
107
  [
 
127
  )
128
 
129
  def send_guide_message(chat_id, message):
130
+ # Returns a response dictionary (Markdown format) to be sent as the webhook reply
131
  logging.info(f"Sending message to chat {chat_id}: {message}")
132
  return {
133
  "method": "sendMessage",
 
137
  }
138
 
139
  def send_guide_message_html(chat_id, message):
140
+ # Returns a response dictionary (HTML format) to be sent as the webhook reply
141
  logging.info(f"Sending HTML message to chat {chat_id}: {message}")
142
  return {
143
  "method": "sendMessage",
 
159
  return "0"
160
 
161
  def validate_inputs():
162
+ # Ensure all fields in conversation_fields have been provided
163
  missing = [field for field in conversation_fields if field not in user_inputs or not user_inputs[field]]
164
  if missing:
165
  return False, f"Missing fields: {', '.join(missing)}"
166
  return True, ""
167
 
168
  def get_streaming_display_message(prefix=""):
169
+ # Build an HTML message with a prefix, current streaming status, and live logs.
170
+ global live_log_display, streaming_state, frames_encoded, bytes_sent
171
  status = (
172
  f"<b>Stream Status:</b>\n"
173
  f"State: {streaming_state}\n"
 
175
  f"Frames Encoded: {frames_encoded}\n"
176
  f"Bytes Sent: {bytes_sent}\n"
177
  )
178
+ logs = live_log_display if live_log_display.strip() != "" else "<pre>No logs available yet.</pre>"
 
 
 
 
 
 
 
179
  return f"{prefix}\n{status}\n\nLive Logs:\n{logs}"
180
 
181
  # -------------------------------------------------------------------
 
190
  # Live Log Updater (Background Thread)
191
  # -------------------------------------------------------------------
192
  def live_log_updater():
193
+ global live_log_display, streaming_state
194
  try:
195
  while True:
196
+ live_log_display = "<pre>" + "\n".join(live_log_lines[-15:]) + "</pre>"
 
197
  time.sleep(1)
198
+ # If streaming has ended, break out after updating one last time.
199
+ if streaming_state == "idle":
200
+ break
201
  except Exception as e:
202
  logging.error(f"Error in live log updater: {e}")
203
 
 
205
  # Logs History Handler (/logs)
206
  # -------------------------------------------------------------------
207
  def logs_history(chat_id):
208
+ global live_log_display, error_notification
209
+ # Use live_log_display if available; otherwise, show a default message.
210
+ log_text = live_log_display if live_log_display.strip() != "" else "<pre>No logs available yet.</pre>"
211
+ # Prepend any error notification if present.
 
 
 
212
  if error_notification:
213
  if log_text.startswith("<pre>"):
214
  log_text = f"<pre>ERROR: {error_notification}\n\n" + log_text[5:]
 
226
  # -------------------------------------------------------------------
227
  def handle_start(chat_id):
228
  global current_step, user_inputs, conversation_fields, advanced_mode
229
+ # Use simple mode by default (unless advanced_mode was set via /setting)
230
  user_inputs = {}
231
  if not advanced_mode:
232
  conversation_fields = ["input_url", "output_url"]
 
339
  out_audio_stream.layout = "stereo"
340
  video_stream.codec_context.time_base = fractions.Fraction(1, video_stream.rate)
341
  logging.info("Streaming started successfully.")
342
+ # Add an initial log entry so live_log_display is not empty.
343
+ logging.info("Live log updating has begun.")
344
  global live_log_thread
345
  if live_log_thread is None or not live_log_thread.is_alive():
346
  live_log_thread = threading.Thread(target=live_log_updater)
347
  live_log_thread.daemon = True
348
  live_log_thread.start()
349
  logging.info("Live log updater thread started.")
 
350
  while streaming_state in ["streaming", "paused"]:
351
  for packet in input_stream.demux():
352
  if streaming_state == "stopped":