awacke1 commited on
Commit
5899ee2
Β·
verified Β·
1 Parent(s): e7880f0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -52
app.py CHANGED
@@ -100,7 +100,7 @@ UNICODE_FONTS = [
100
  ("Circled", lambda x: "".join(chr(ord(c) - 0x41 + 0x24B6) if 'A' <= c <= 'Z' else chr(ord(c) - 0x61 + 0x24D0) if 'a' <= c <= 'z' else c for c in x)),
101
  ("Squared", lambda x: "".join(chr(ord(c) - 0x41 + 0x1F130) if 'A' <= c <= 'Z' else c for c in x)),
102
  ("Negative Circled", lambda x: "".join(chr(ord(c) - 0x41 + 0x1F150) if 'A' <= c <= 'Z' else c for c in x)),
103
- ("Negative Squared", lambda x: "".join(chr(ord(c) - 0x41 + 0x1F170) if 'A' <= c <= 'Z' else c for c in x)),
104
  ("Regional Indicator", lambda x: "".join(chr(ord(c) - 0x41 + 0x1F1E6) if 'A' <= c <= 'Z' else c for c in x)),
105
  ]
106
 
@@ -139,6 +139,8 @@ if 'last_transcript' not in st.session_state:
139
  st.session_state.last_transcript = ""
140
  if 'image_hashes' not in st.session_state:
141
  st.session_state.image_hashes = set()
 
 
142
 
143
  # Timestamp wizardry - clock ticks with flair! ⏰🎩
144
  def format_timestamp_prefix(username):
@@ -201,11 +203,25 @@ async def save_chat_entry(username, message, is_markdown=False):
201
  audio_file = await async_edge_tts_generate(cleaned_message, voice)
202
  if audio_file:
203
  with open(HISTORY_FILE, 'a') as f:
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():
211
  username = st.session_state.get('username', 'System 🌟')
@@ -323,6 +339,7 @@ async def save_pasted_image(image, username):
323
  filepath = os.path.join(MEDIA_DIR, filename)
324
  await asyncio.to_thread(image.save, filepath, "PNG")
325
  st.session_state.image_hashes.add(img_hash)
 
326
  return filepath
327
 
328
  # Video renderer - movies roll with autoplay! πŸŽ₯🎬
@@ -405,6 +422,33 @@ async def perform_ai_lookup(query, vocal_summary=True, extended_refs=False, titl
405
  if audio_file:
406
  st.audio(audio_file)
407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  # ASR Component HTML
409
  ASR_HTML = """
410
  <html>
@@ -569,33 +613,6 @@ ASR_HTML = """
569
  </html>
570
  """
571
 
572
- # Delete all user files function
573
- def delete_user_files():
574
- protected_files = {'app.py', 'requirements.txt', 'README.md'}
575
- deleted_files = []
576
- directories = [MEDIA_DIR, AUDIO_DIR, CHAT_DIR, VOTE_DIR, HISTORY_DIR]
577
- for directory in directories:
578
- if os.path.exists(directory):
579
- for root, _, files in os.walk(directory):
580
- for file in files:
581
- file_path = os.path.join(root, file)
582
- if os.path.basename(file_path) not in protected_files:
583
- try:
584
- os.remove(file_path)
585
- deleted_files.append(file_path)
586
- except Exception as e:
587
- st.error(f"Failed to delete {file_path}: {e}")
588
- try:
589
- shutil.rmtree(directory, ignore_errors=True)
590
- os.makedirs(directory, exist_ok=True)
591
- except Exception as e:
592
- st.error(f"Failed to remove directory {directory}: {e}")
593
- st.session_state.image_hashes.clear()
594
- st.session_state.audio_cache.clear()
595
- st.session_state.base64_cache.clear()
596
- st.session_state.displayed_chat_lines.clear()
597
- return deleted_files
598
-
599
  # Main execution - let’s roll! πŸŽ²πŸš€
600
  def main():
601
  NODE_NAME, port = get_node_name()
@@ -633,12 +650,11 @@ def main():
633
  st.session_state.last_transcript = transcript
634
  st.rerun()
635
 
636
- # Chat History Grid
637
  st.subheader(f"{START_ROOM} Chat History πŸ’¬")
638
  chat_content = await load_chat()
639
  chat_lines = chat_content.split('\n')
640
  chat_lines = [line for line in chat_lines if line.strip() and ': ' in line and not line.startswith('#')]
641
-
642
  if chat_lines:
643
  col1, col2 = st.columns([2, 1])
644
  with col1:
@@ -664,25 +680,6 @@ def main():
664
  audio_file = st.session_state.audio_cache.get(cache_key)
665
  if audio_file:
666
  play_and_download_audio(audio_file)
667
- with col2:
668
- st.write("### Image Media")
669
- media_files = glob.glob(f"{MEDIA_DIR}/*.png") + glob.glob(f"{MEDIA_DIR}/*.jpg") + glob.glob(f"{MEDIA_DIR}/*.mp4")
670
- if media_files:
671
- media_votes = await load_votes(MEDIA_VOTES_FILE)
672
- seen_files = set()
673
- for media_file in sorted(media_files, key=os.path.getmtime, reverse=True):
674
- if media_file not in seen_files:
675
- seen_files.add(media_file)
676
- filename = os.path.basename(media_file)
677
- vote_count = media_votes.get(media_file, 0)
678
- st.markdown(f"**{filename}**")
679
- if media_file.endswith(('.png', '.jpg')):
680
- st.image(media_file, use_container_width=True)
681
- elif media_file.endswith('.mp4'):
682
- st.markdown(await get_video_html(media_file), unsafe_allow_html=True)
683
- if st.button(f"πŸ‘ {vote_count}", key=f"media_vote_{media_file}"):
684
- await save_vote(MEDIA_VOTES_FILE, media_file, await generate_user_hash(), st.session_state.username)
685
- st.rerun()
686
 
687
  if st.session_state.quote_line:
688
  st.markdown(f"### Quoting: {st.session_state.quote_line}")
@@ -762,6 +759,7 @@ def main():
762
  await asyncio.to_thread(lambda: open(file_path, 'wb').write(uploaded_file.getbuffer()))
763
  st.success(f"Uploaded {filename}")
764
  await save_chat_entry(username, f"Uploaded media: {file_path}")
 
765
  st.session_state.image_hashes.add(file_hash)
766
  if file_path.endswith('.mp4'):
767
  st.session_state.media_notifications.append(file_path)
@@ -787,10 +785,37 @@ def main():
787
  time.sleep(1)
788
  st.rerun()
789
 
790
- st.sidebar.subheader("Chat History πŸ“œ")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  with open(HISTORY_FILE, 'r') as f:
792
  history_content = f.read()
793
- st.sidebar.markdown(history_content)
794
 
795
  loop.run_until_complete(async_interface())
796
 
 
100
  ("Circled", lambda x: "".join(chr(ord(c) - 0x41 + 0x24B6) if 'A' <= c <= 'Z' else chr(ord(c) - 0x61 + 0x24D0) if 'a' <= c <= 'z' else c for c in x)),
101
  ("Squared", lambda x: "".join(chr(ord(c) - 0x41 + 0x1F130) if 'A' <= c <= 'Z' else c for c in x)),
102
  ("Negative Circled", lambda x: "".join(chr(ord(c) - 0x41 + 0x1F150) if 'A' <= c <= 'Z' else c for c in x)),
103
+ ("Negative Squared", lambda x: "".join(chr(ord(c) - 0x1F170 - 0x41) if 'A' <= c <= 'Z' else c for c in x)),
104
  ("Regional Indicator", lambda x: "".join(chr(ord(c) - 0x41 + 0x1F1E6) if 'A' <= c <= 'Z' else c for c in x)),
105
  ]
106
 
 
139
  st.session_state.last_transcript = ""
140
  if 'image_hashes' not in st.session_state:
141
  st.session_state.image_hashes = set()
142
+ if 'gallery_columns' not in st.session_state:
143
+ st.session_state.gallery_columns = 1 # Default gallery tiles
144
 
145
  # Timestamp wizardry - clock ticks with flair! ⏰🎩
146
  def format_timestamp_prefix(username):
 
203
  audio_file = await async_edge_tts_generate(cleaned_message, voice)
204
  if audio_file:
205
  with open(HISTORY_FILE, 'a') as f:
206
+ f.write(f"[{timestamp}] {username} ({voice}): Audio generated - {audio_file}\n")
207
  await broadcast_message(f"{username}|{message}", "chat")
208
  st.session_state.last_chat_update = time.time()
209
  return audio_file
210
 
211
+ # Save chat history with image
212
+ async def save_chat_history_with_image(username, image_path):
213
+ central = pytz.timezone('US/Central')
214
+ timestamp = datetime.now(central).strftime("%Y-%m-%d_%H-%M-%S")
215
+ history_filename = f"chat_history_{timestamp}-by-{username}.md"
216
+ history_filepath = os.path.join(HISTORY_DIR, history_filename)
217
+ chat_content = await load_chat()
218
+ voice = FUN_USERNAMES.get(username, "en-US-AriaNeural")
219
+ with open(history_filepath, 'w') as f:
220
+ f.write(f"# Chat History at {timestamp} by {username} (Voice: {voice})\n\n")
221
+ f.write(f"## Image Shared: {os.path.basename(image_path)}\n")
222
+ f.write(chat_content)
223
+ return history_filepath
224
+
225
  # Chat loader - history unleashed! πŸ“œπŸš€
226
  async def load_chat():
227
  username = st.session_state.get('username', 'System 🌟')
 
339
  filepath = os.path.join(MEDIA_DIR, filename)
340
  await asyncio.to_thread(image.save, filepath, "PNG")
341
  st.session_state.image_hashes.add(img_hash)
342
+ await save_chat_history_with_image(username, filepath) # Save chat history with image
343
  return filepath
344
 
345
  # Video renderer - movies roll with autoplay! πŸŽ₯🎬
 
422
  if audio_file:
423
  st.audio(audio_file)
424
 
425
+ # Delete all user files function
426
+ def delete_user_files():
427
+ protected_files = {'app.py', 'requirements.txt', 'README.md'}
428
+ deleted_files = []
429
+ directories = [MEDIA_DIR, AUDIO_DIR, CHAT_DIR, VOTE_DIR, HISTORY_DIR]
430
+ for directory in directories:
431
+ if os.path.exists(directory):
432
+ for root, _, files in os.walk(directory):
433
+ for file in files:
434
+ file_path = os.path.join(root, file)
435
+ if os.path.basename(file_path) not in protected_files:
436
+ try:
437
+ os.remove(file_path)
438
+ deleted_files.append(file_path)
439
+ except Exception as e:
440
+ st.error(f"Failed to delete {file_path}: {e}")
441
+ try:
442
+ shutil.rmtree(directory, ignore_errors=True)
443
+ os.makedirs(directory, exist_ok=True)
444
+ except Exception as e:
445
+ st.error(f"Failed to remove directory {directory}: {e}")
446
+ st.session_state.image_hashes.clear()
447
+ st.session_state.audio_cache.clear()
448
+ st.session_state.base64_cache.clear()
449
+ st.session_state.displayed_chat_lines.clear()
450
+ return deleted_files
451
+
452
  # ASR Component HTML
453
  ASR_HTML = """
454
  <html>
 
613
  </html>
614
  """
615
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
616
  # Main execution - let’s roll! πŸŽ²πŸš€
617
  def main():
618
  NODE_NAME, port = get_node_name()
 
650
  st.session_state.last_transcript = transcript
651
  st.rerun()
652
 
653
+ # Unified Chat History at Top
654
  st.subheader(f"{START_ROOM} Chat History πŸ’¬")
655
  chat_content = await load_chat()
656
  chat_lines = chat_content.split('\n')
657
  chat_lines = [line for line in chat_lines if line.strip() and ': ' in line and not line.startswith('#')]
 
658
  if chat_lines:
659
  col1, col2 = st.columns([2, 1])
660
  with col1:
 
680
  audio_file = st.session_state.audio_cache.get(cache_key)
681
  if audio_file:
682
  play_and_download_audio(audio_file)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
683
 
684
  if st.session_state.quote_line:
685
  st.markdown(f"### Quoting: {st.session_state.quote_line}")
 
759
  await asyncio.to_thread(lambda: open(file_path, 'wb').write(uploaded_file.getbuffer()))
760
  st.success(f"Uploaded {filename}")
761
  await save_chat_entry(username, f"Uploaded media: {file_path}")
762
+ await save_chat_history_with_image(username, file_path) # Save chat history with upload
763
  st.session_state.image_hashes.add(file_hash)
764
  if file_path.endswith('.mp4'):
765
  st.session_state.media_notifications.append(file_path)
 
785
  time.sleep(1)
786
  st.rerun()
787
 
788
+ # Gallery with Adjustable Tiles
789
+ st.subheader("Media Gallery 🎨🎢πŸŽ₯")
790
+ gallery_columns = st.slider("Number of Gallery Tiles", 1, 20, st.session_state.gallery_columns)
791
+ st.session_state.gallery_columns = gallery_columns
792
+ media_files = glob.glob(f"{MEDIA_DIR}/*.png") + glob.glob(f"{MEDIA_DIR}/*.jpg") + glob.glob(f"{MEDIA_DIR}/*.mp4")
793
+ if media_files:
794
+ media_votes = await load_votes(MEDIA_VOTES_FILE)
795
+ seen_files = set()
796
+ cols = st.columns(gallery_columns)
797
+ col_idx = 0
798
+ for media_file in sorted(media_files, key=os.path.getmtime, reverse=True):
799
+ if media_file not in seen_files:
800
+ seen_files.add(media_file)
801
+ with cols[col_idx]:
802
+ filename = os.path.basename(media_file)
803
+ vote_count = media_votes.get(media_file, 0)
804
+ st.markdown(f"**{filename}**")
805
+ if media_file.endswith(('.png', '.jpg')):
806
+ st.image(media_file, use_container_width=True)
807
+ elif media_file.endswith('.mp4'):
808
+ st.markdown(await get_video_html(media_file), unsafe_allow_html=True)
809
+ if st.button(f"πŸ‘ {vote_count}", key=f"media_vote_{media_file}"):
810
+ await save_vote(MEDIA_VOTES_FILE, media_file, await generate_user_hash(), st.session_state.username)
811
+ st.rerun()
812
+ col_idx = (col_idx + 1) % gallery_columns
813
+
814
+ # Full Log at End
815
+ st.subheader("Full Chat Log πŸ“œ")
816
  with open(HISTORY_FILE, 'r') as f:
817
  history_content = f.read()
818
+ st.markdown(history_content)
819
 
820
  loop.run_until_complete(async_interface())
821