awacke1 commited on
Commit
1daaa75
Β·
verified Β·
1 Parent(s): 98e4bdd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -11
app.py CHANGED
@@ -18,6 +18,8 @@ from audio_recorder_streamlit import audio_recorder
18
  import nest_asyncio
19
  import re
20
  from streamlit_paste_button import paste_image_button
 
 
21
 
22
  # Patch for nested async - sneaky fix! 🐍✨
23
  nest_asyncio.apply()
@@ -140,7 +142,8 @@ if 'image_hashes' not in st.session_state:
140
 
141
  # Timestamp wizardry - clock ticks with flair! ⏰🎩
142
  def format_timestamp_prefix(username):
143
- now = datetime.now()
 
144
  return f"{now.strftime('%I-%M-%p-ct-%m-%d-%Y')}-by-{username}"
145
 
146
  # Compute image hash from binary data
@@ -172,8 +175,9 @@ def log_action(username, action):
172
  user_log = {k: v for k, v in user_log.items() if current_time - v < 10}
173
  st.session_state.action_log[username] = user_log
174
  if action not in user_log:
 
175
  with open(HISTORY_FILE, 'a') as f:
176
- f.write(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {username}: {action}\n")
177
  user_log[action] = current_time
178
 
179
  # Clean text - strip the fancy stuff! πŸ§ΉπŸ“
@@ -185,13 +189,14 @@ def clean_text_for_tts(text):
185
  # Chat saver - words locked tight! πŸ’¬πŸ”’
186
  async def save_chat_entry(username, message, is_markdown=False):
187
  await asyncio.to_thread(log_action, username, "πŸ’¬πŸ”’ - Chat saver - words locked tight!")
188
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
189
  if is_markdown:
190
  entry = f"[{timestamp}] {username}:\n```markdown\n{message}\n```"
191
  else:
192
  entry = f"[{timestamp}] {username}: {message}"
193
  await asyncio.to_thread(lambda: open(CHAT_FILE, 'a').write(f"{entry}\n"))
194
- voice = FUN_USERNAMES.get(username, "en-US-AriaNeural") # Use username-specific voice
195
  cleaned_message = clean_text_for_tts(message)
196
  audio_file = await async_edge_tts_generate(cleaned_message, voice)
197
  if audio_file:
@@ -199,6 +204,7 @@ async def save_chat_entry(username, message, is_markdown=False):
199
  f.write(f"[{timestamp}] {username}: Audio generated - {audio_file}\n")
200
  await broadcast_message(f"{username}|{message}", "chat")
201
  st.session_state.last_chat_update = time.time()
 
202
 
203
  # Chat loader - history unleashed! πŸ“œπŸš€
204
  async def load_chat():
@@ -238,7 +244,8 @@ async def get_message_suggestions(chat_content, prefix):
238
  # Vote saver - cheers recorded! πŸ‘πŸ“Š
239
  async def save_vote(file, item, user_hash, username, comment=""):
240
  await asyncio.to_thread(log_action, username, "πŸ‘πŸ“Š - Vote saver - cheers recorded!")
241
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
242
  entry = f"[{timestamp}] {user_hash} voted for {item}"
243
  await asyncio.to_thread(lambda: open(file, 'a').write(f"{entry}\n"))
244
  await asyncio.to_thread(lambda: open(HISTORY_FILE, "a").write(f"- {timestamp} - User {user_hash} voted for {item}\n"))
@@ -289,7 +296,8 @@ async def async_edge_tts_generate(text, voice, rate=0, pitch=0, file_format="mp3
289
  return filepath if os.path.exists(filepath) else None
290
  except edge_tts.exceptions.NoAudioReceived:
291
  with open(HISTORY_FILE, 'a') as f:
292
- f.write(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {username}: Audio failed - No audio received for '{text}'\n")
 
293
  return None
294
 
295
  # Audio player - tunes blast off! πŸ”ŠπŸš€
@@ -397,6 +405,40 @@ async def perform_ai_lookup(query, vocal_summary=True, extended_refs=False, titl
397
  if audio_file:
398
  st.audio(audio_file)
399
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  # ASR Component HTML
401
  ASR_HTML = """
402
  <html>
@@ -574,7 +616,7 @@ def main():
574
  available_names = [name for name in FUN_USERNAMES if not any(f"{name} has joined" in line for line in chat_content.split('\n'))]
575
  st.session_state.username = random.choice(available_names) if available_names else random.choice(list(FUN_USERNAMES.keys()))
576
  st.session_state.voice = FUN_USERNAMES[st.session_state.username]
577
- st.markdown(f"**πŸŽ™οΈ Voice Selected**: {st.session_state.voice} πŸ—£οΈ")
578
 
579
  st.title(f"πŸ€–πŸ§ MMO {st.session_state.username}πŸ“πŸ”¬")
580
  st.markdown(f"Welcome to {START_ROOM} - chat, vote, upload, paste images, and enjoy quoting! πŸŽ‰")
@@ -671,6 +713,7 @@ def main():
671
  if paste_result_quote.image_data is not None:
672
  if isinstance(paste_result_quote.image_data, str):
673
  st.session_state.message_text = paste_result_quote.image_data
 
674
  else:
675
  st.image(paste_result_quote.image_data, caption="Received Image for Quote")
676
  filename = await save_pasted_image(paste_result_quote.image_data, st.session_state.username)
@@ -687,19 +730,21 @@ def main():
687
  st.session_state.message_text = ''
688
  st.rerun()
689
 
690
- new_username = st.selectbox("Change Name", [""] + list(FUN_USERNAMES.keys()), index=0)
 
691
  if new_username and new_username != st.session_state.username:
692
  await save_chat_entry("System 🌟", f"{st.session_state.username} changed name to {new_username}")
693
  st.session_state.username = new_username
694
  st.session_state.voice = FUN_USERNAMES[new_username]
695
- st.markdown(f"**πŸŽ™οΈ Voice Changed**: {st.session_state.voice} πŸ—£οΈ")
696
  st.rerun()
697
 
698
- message = st.text_input(f"Message as {st.session_state.username}", key="message_input", value=st.session_state.message_text, on_change=lambda: st.session_state.update(message_text=st.session_state.message_input))
699
  paste_result_msg = paste_image_button("πŸ“‹ Paste Image or Text with Message", key="paste_button_msg")
700
  if paste_result_msg.image_data is not None:
701
  if isinstance(paste_result_msg.image_data, str):
702
  st.session_state.message_text = paste_result_msg.image_data
 
703
  else:
704
  st.image(paste_result_msg.image_data, caption="Received Image for Message")
705
  filename = await save_pasted_image(paste_result_msg.image_data, st.session_state.username)
@@ -707,7 +752,9 @@ def main():
707
  st.session_state.pasted_image_data = filename
708
  if st.button("Send πŸš€", key="send_button") and (message.strip() or st.session_state.pasted_image_data):
709
  if message.strip():
710
- await save_chat_entry(st.session_state.username, message, is_markdown=True)
 
 
711
  if st.session_state.pasted_image_data:
712
  await save_chat_entry(st.session_state.username, f"Pasted image: {st.session_state.pasted_image_data}")
713
  st.session_state.pasted_image_data = None
@@ -735,6 +782,20 @@ def main():
735
  if file_path.endswith('.mp4'):
736
  st.session_state.media_notifications.append(file_path)
737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
738
  st.subheader("Media Gallery 🎨🎢πŸŽ₯")
739
  media_files = glob.glob(f"{MEDIA_DIR}/*.png") + glob.glob(f"{MEDIA_DIR}/*.jpg") + glob.glob(f"{MEDIA_DIR}/*.mp4") + glob.glob(f"{MEDIA_DIR}/*.mp3")
740
  if media_files:
 
18
  import nest_asyncio
19
  import re
20
  from streamlit_paste_button import paste_image_button
21
+ import pytz
22
+ import shutil
23
 
24
  # Patch for nested async - sneaky fix! 🐍✨
25
  nest_asyncio.apply()
 
142
 
143
  # Timestamp wizardry - clock ticks with flair! ⏰🎩
144
  def format_timestamp_prefix(username):
145
+ central = pytz.timezone('US/Central')
146
+ now = datetime.now(central)
147
  return f"{now.strftime('%I-%M-%p-ct-%m-%d-%Y')}-by-{username}"
148
 
149
  # Compute image hash from binary data
 
175
  user_log = {k: v for k, v in user_log.items() if current_time - v < 10}
176
  st.session_state.action_log[username] = user_log
177
  if action not in user_log:
178
+ central = pytz.timezone('US/Central')
179
  with open(HISTORY_FILE, 'a') as f:
180
+ f.write(f"[{datetime.now(central).strftime('%Y-%m-%d %H:%M:%S')}] {username}: {action}\n")
181
  user_log[action] = current_time
182
 
183
  # Clean text - strip the fancy stuff! πŸ§ΉπŸ“
 
189
  # Chat saver - words locked tight! πŸ’¬πŸ”’
190
  async def save_chat_entry(username, message, is_markdown=False):
191
  await asyncio.to_thread(log_action, username, "πŸ’¬πŸ”’ - Chat saver - words locked tight!")
192
+ central = pytz.timezone('US/Central')
193
+ timestamp = datetime.now(central).strftime("%Y-%m-%d %H:%M:%S")
194
  if is_markdown:
195
  entry = f"[{timestamp}] {username}:\n```markdown\n{message}\n```"
196
  else:
197
  entry = f"[{timestamp}] {username}: {message}"
198
  await asyncio.to_thread(lambda: open(CHAT_FILE, 'a').write(f"{entry}\n"))
199
+ voice = FUN_USERNAMES.get(username, "en-US-AriaNeural")
200
  cleaned_message = clean_text_for_tts(message)
201
  audio_file = await async_edge_tts_generate(cleaned_message, voice)
202
  if audio_file:
 
204
  f.write(f"[{timestamp}] {username}: Audio generated - {audio_file}\n")
205
  await broadcast_message(f"{username}|{message}", "chat")
206
  st.session_state.last_chat_update = time.time()
207
+ return audio_file
208
 
209
  # Chat loader - history unleashed! πŸ“œπŸš€
210
  async def load_chat():
 
244
  # Vote saver - cheers recorded! πŸ‘πŸ“Š
245
  async def save_vote(file, item, user_hash, username, comment=""):
246
  await asyncio.to_thread(log_action, username, "πŸ‘πŸ“Š - Vote saver - cheers recorded!")
247
+ central = pytz.timezone('US/Central')
248
+ timestamp = datetime.now(central).strftime("%Y-%m-%d %H:%M:%S")
249
  entry = f"[{timestamp}] {user_hash} voted for {item}"
250
  await asyncio.to_thread(lambda: open(file, 'a').write(f"{entry}\n"))
251
  await asyncio.to_thread(lambda: open(HISTORY_FILE, "a").write(f"- {timestamp} - User {user_hash} voted for {item}\n"))
 
296
  return filepath if os.path.exists(filepath) else None
297
  except edge_tts.exceptions.NoAudioReceived:
298
  with open(HISTORY_FILE, 'a') as f:
299
+ central = pytz.timezone('US/Central')
300
+ f.write(f"[{datetime.now(central).strftime('%Y-%m-%d %H:%M:%S')}] {username}: Audio failed - No audio received for '{text}'\n")
301
  return None
302
 
303
  # Audio player - tunes blast off! πŸ”ŠπŸš€
 
405
  if audio_file:
406
  st.audio(audio_file)
407
 
408
+ # Delete all user files function
409
+ def delete_user_files():
410
+ protected_files = {'app.py', 'requirements.txt', 'README.md'}
411
+ deleted_files = []
412
+
413
+ # Directories to clear
414
+ directories = [MEDIA_DIR, AUDIO_DIR, CHAT_DIR, VOTE_DIR, HISTORY_DIR]
415
+
416
+ for directory in directories:
417
+ if os.path.exists(directory):
418
+ for root, _, files in os.walk(directory):
419
+ for file in files:
420
+ file_path = os.path.join(root, file)
421
+ if os.path.basename(file_path) not in protected_files:
422
+ try:
423
+ os.remove(file_path)
424
+ deleted_files.append(file_path)
425
+ except Exception as e:
426
+ st.error(f"Failed to delete {file_path}: {e}")
427
+ # Remove empty directories
428
+ try:
429
+ shutil.rmtree(directory, ignore_errors=True)
430
+ os.makedirs(directory, exist_ok=True) # Recreate empty directory
431
+ except Exception as e:
432
+ st.error(f"Failed to remove directory {directory}: {e}")
433
+
434
+ # Clear session state caches
435
+ st.session_state.image_hashes.clear()
436
+ st.session_state.audio_cache.clear()
437
+ st.session_state.base64_cache.clear()
438
+ st.session_state.displayed_chat_lines.clear()
439
+
440
+ return deleted_files
441
+
442
  # ASR Component HTML
443
  ASR_HTML = """
444
  <html>
 
616
  available_names = [name for name in FUN_USERNAMES if not any(f"{name} has joined" in line for line in chat_content.split('\n'))]
617
  st.session_state.username = random.choice(available_names) if available_names else random.choice(list(FUN_USERNAMES.keys()))
618
  st.session_state.voice = FUN_USERNAMES[st.session_state.username]
619
+ st.markdown(f"**πŸŽ™οΈ Voice Selected**: {st.session_state.voice} πŸ—£οΈ for {st.session_state.username}")
620
 
621
  st.title(f"πŸ€–πŸ§ MMO {st.session_state.username}πŸ“πŸ”¬")
622
  st.markdown(f"Welcome to {START_ROOM} - chat, vote, upload, paste images, and enjoy quoting! πŸŽ‰")
 
713
  if paste_result_quote.image_data is not None:
714
  if isinstance(paste_result_quote.image_data, str):
715
  st.session_state.message_text = paste_result_quote.image_data
716
+ st.text_area("Add your response", key="quote_response", value=st.session_state.message_text)
717
  else:
718
  st.image(paste_result_quote.image_data, caption="Received Image for Quote")
719
  filename = await save_pasted_image(paste_result_quote.image_data, st.session_state.username)
 
730
  st.session_state.message_text = ''
731
  st.rerun()
732
 
733
+ current_selection = st.session_state.username if st.session_state.username in FUN_USERNAMES else ""
734
+ new_username = st.selectbox("Change Name and Voice", [""] + list(FUN_USERNAMES.keys()), index=(list(FUN_USERNAMES.keys()).index(current_selection) + 1 if current_selection else 0), format_func=lambda x: f"{x} ({FUN_USERNAMES.get(x, 'No Voice')})" if x else "Select a name")
735
  if new_username and new_username != st.session_state.username:
736
  await save_chat_entry("System 🌟", f"{st.session_state.username} changed name to {new_username}")
737
  st.session_state.username = new_username
738
  st.session_state.voice = FUN_USERNAMES[new_username]
739
+ st.markdown(f"**πŸŽ™οΈ Voice Changed**: {st.session_state.voice} πŸ—£οΈ for {st.session_state.username}")
740
  st.rerun()
741
 
742
+ message = st.text_input(f"Message as {st.session_state.username} (Voice: {st.session_state.voice})", key="message_input", value=st.session_state.message_text)
743
  paste_result_msg = paste_image_button("πŸ“‹ Paste Image or Text with Message", key="paste_button_msg")
744
  if paste_result_msg.image_data is not None:
745
  if isinstance(paste_result_msg.image_data, str):
746
  st.session_state.message_text = paste_result_msg.image_data
747
+ st.text_input(f"Message as {st.session_state.username} (Voice: {st.session_state.voice})", key="message_input_paste", value=st.session_state.message_text)
748
  else:
749
  st.image(paste_result_msg.image_data, caption="Received Image for Message")
750
  filename = await save_pasted_image(paste_result_msg.image_data, st.session_state.username)
 
752
  st.session_state.pasted_image_data = filename
753
  if st.button("Send πŸš€", key="send_button") and (message.strip() or st.session_state.pasted_image_data):
754
  if message.strip():
755
+ audio_file = await save_chat_entry(st.session_state.username, message, is_markdown=True)
756
+ if audio_file:
757
+ st.session_state.audio_cache[f"{message}_{FUN_USERNAMES[st.session_state.username]}"] = audio_file
758
  if st.session_state.pasted_image_data:
759
  await save_chat_entry(st.session_state.username, f"Pasted image: {st.session_state.pasted_image_data}")
760
  st.session_state.pasted_image_data = None
 
782
  if file_path.endswith('.mp4'):
783
  st.session_state.media_notifications.append(file_path)
784
 
785
+ # Big Red Delete Button
786
+ st.subheader("πŸ›‘ Danger Zone")
787
+ if st.button("Try Not To Delete It All On Your First Day", key="delete_all", help="Deletes all user-added files!", type="primary", use_container_width=True):
788
+ deleted_files = delete_user_files()
789
+ if deleted_files:
790
+ st.markdown("### πŸ—‘οΈ Deleted Files:\n" + "\n".join([f"- `{file}`" for file in deleted_files]))
791
+ else:
792
+ st.markdown("### πŸ—‘οΈ Nothing to Delete!")
793
+ st.session_state.image_hashes.clear()
794
+ st.session_state.audio_cache.clear()
795
+ st.session_state.base64_cache.clear()
796
+ st.session_state.displayed_chat_lines.clear()
797
+ st.rerun()
798
+
799
  st.subheader("Media Gallery 🎨🎢πŸŽ₯")
800
  media_files = glob.glob(f"{MEDIA_DIR}/*.png") + glob.glob(f"{MEDIA_DIR}/*.jpg") + glob.glob(f"{MEDIA_DIR}/*.mp4") + glob.glob(f"{MEDIA_DIR}/*.mp3")
801
  if media_files: