Update app.py
Browse files
app.py
CHANGED
@@ -18,7 +18,6 @@ import edge_tts
|
|
18 |
from audio_recorder_streamlit import audio_recorder
|
19 |
import nest_asyncio
|
20 |
import re
|
21 |
-
from image_paster import image_paster # Import the custom component
|
22 |
|
23 |
# Patch for nested async - sneaky fix! πβ¨
|
24 |
nest_asyncio.apply()
|
@@ -116,6 +115,10 @@ if 'last_chat_update' not in st.session_state:
|
|
116 |
st.session_state.last_chat_update = 0
|
117 |
if 'displayed_chat_lines' not in st.session_state:
|
118 |
st.session_state.displayed_chat_lines = []
|
|
|
|
|
|
|
|
|
119 |
|
120 |
# Timestamp wizardry - clock ticks with flair! β°π©
|
121 |
def format_timestamp_prefix():
|
@@ -348,8 +351,20 @@ async def process_voice_input(audio_bytes):
|
|
348 |
text = "Voice input simulation"
|
349 |
await save_chat_entry(username, text)
|
350 |
|
351 |
-
#
|
352 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
loop = asyncio.new_event_loop()
|
354 |
asyncio.set_event_loop(loop)
|
355 |
|
@@ -363,14 +378,6 @@ def create_streamlit_interface():
|
|
363 |
st.session_state.refresh_rate = 5
|
364 |
if 'timer_start' not in st.session_state:
|
365 |
st.session_state.timer_start = time.time()
|
366 |
-
if 'quote_line' not in st.session_state:
|
367 |
-
st.session_state.quote_line = None
|
368 |
-
if 'pasted_image_data' not in st.session_state:
|
369 |
-
st.session_state.pasted_image_data = None
|
370 |
-
if 'message_text' not in st.session_state:
|
371 |
-
st.session_state.message_text = ""
|
372 |
-
if 'audio_cache' not in st.session_state:
|
373 |
-
st.session_state.audio_cache = {}
|
374 |
|
375 |
st.markdown("""
|
376 |
<style>
|
@@ -397,19 +404,16 @@ def create_streamlit_interface():
|
|
397 |
chat_lines = chat_content.split('\n')
|
398 |
chat_votes = await load_votes(QUOTE_VOTES_FILE)
|
399 |
|
400 |
-
# Update displayed lines only with new, valid chat entries
|
401 |
current_time = time.time()
|
402 |
if current_time - st.session_state.last_chat_update > 1 or not st.session_state.displayed_chat_lines:
|
403 |
new_lines = [line for line in chat_lines if line.strip() and ': ' in line and line not in st.session_state.displayed_chat_lines and not line.startswith('#')]
|
404 |
st.session_state.displayed_chat_lines.extend(new_lines)
|
405 |
st.session_state.last_chat_update = current_time
|
406 |
|
407 |
-
# Display chat lines
|
408 |
for i, line in enumerate(st.session_state.displayed_chat_lines):
|
409 |
col1, col2, col3, col4 = st.columns([3, 1, 1, 2])
|
410 |
with col1:
|
411 |
st.markdown(line)
|
412 |
-
# Display image if the line contains an image reference
|
413 |
if "Pasted image:" in line:
|
414 |
image_path = line.split("Pasted image: ")[1].strip()
|
415 |
if os.path.exists(image_path):
|
@@ -441,7 +445,6 @@ def create_streamlit_interface():
|
|
441 |
if audio_file:
|
442 |
play_and_download_audio(audio_file)
|
443 |
|
444 |
-
# Quoting interface
|
445 |
if 'quote_line' in st.session_state and st.session_state.quote_line:
|
446 |
st.markdown(f"### Quoting: {st.session_state.quote_line}")
|
447 |
quote_response = st.text_area("Add your response", key="quote_response")
|
@@ -458,14 +461,12 @@ def create_streamlit_interface():
|
|
458 |
st.session_state.message_text = ''
|
459 |
st.rerun()
|
460 |
|
461 |
-
# Username change
|
462 |
new_username = st.selectbox("Change Name", [""] + list(FUN_USERNAMES.keys()), index=0)
|
463 |
if new_username and new_username != st.session_state.username:
|
464 |
loop.run_until_complete(save_chat_entry("System π", f"{st.session_state.username} changed name to {new_username}"))
|
465 |
st.session_state.username = new_username
|
466 |
st.rerun()
|
467 |
|
468 |
-
# Message input
|
469 |
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))
|
470 |
if st.button("Send π", key="send_button") and message.strip():
|
471 |
loop.run_until_complete(save_chat_entry(st.session_state.username, message))
|
@@ -477,15 +478,45 @@ def create_streamlit_interface():
|
|
477 |
st.session_state.message_text = ''
|
478 |
st.rerun()
|
479 |
|
480 |
-
#
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
489 |
|
490 |
st.subheader("Media Gallery π¨πΆπ₯")
|
491 |
uploaded_file = st.file_uploader("Upload Media", type=['png', 'jpg', 'mp3', 'mp4'])
|
@@ -501,10 +532,9 @@ def create_streamlit_interface():
|
|
501 |
if file_path.endswith('.mp4'):
|
502 |
st.session_state.media_notifications.append(file_path)
|
503 |
|
504 |
-
# Organize gallery by user
|
505 |
media_files = glob.glob(f"{MEDIA_DIR}/*.png") + glob.glob(f"{MEDIA_DIR}/*.jpg") + glob.glob(f"{MEDIA_DIR}/*.mp3") + glob.glob(f"{MEDIA_DIR}/*.mp4")
|
506 |
if media_files:
|
507 |
-
media_votes =
|
508 |
users = sorted(set(f.split('_')[-1].split('.')[0] for f in media_files))
|
509 |
for user in users:
|
510 |
with st.expander(f"{user}'s Media"):
|
@@ -527,7 +557,7 @@ def create_streamlit_interface():
|
|
527 |
with col2:
|
528 |
if st.button(f"π {vote_count}", key=f"media_vote_{media_file}"):
|
529 |
comment = st.session_state.message_text
|
530 |
-
|
531 |
st.session_state.message_text = ''
|
532 |
st.rerun()
|
533 |
with col3:
|
@@ -543,7 +573,7 @@ def create_streamlit_interface():
|
|
543 |
font_name, font_func = random.choice(UNICODE_FONTS)
|
544 |
countdown_str = "".join(UNICODE_DIGITS[int(d)] for d in str(i)) if i < 10 else font_func(str(i))
|
545 |
timer_placeholder.markdown(f"<p class='timer'>β³ {font_func('Refresh in:')} {countdown_str}</p>", unsafe_allow_html=True)
|
546 |
-
|
547 |
st.rerun()
|
548 |
|
549 |
st.sidebar.subheader("Chat History π")
|
@@ -553,10 +583,5 @@ def create_streamlit_interface():
|
|
553 |
|
554 |
loop.run_until_complete(async_interface())
|
555 |
|
556 |
-
# Main execution - letβs roll! π²π
|
557 |
-
def main():
|
558 |
-
NODE_NAME, port = get_node_name()
|
559 |
-
create_streamlit_interface()
|
560 |
-
|
561 |
if __name__ == "__main__":
|
562 |
main()
|
|
|
18 |
from audio_recorder_streamlit import audio_recorder
|
19 |
import nest_asyncio
|
20 |
import re
|
|
|
21 |
|
22 |
# Patch for nested async - sneaky fix! πβ¨
|
23 |
nest_asyncio.apply()
|
|
|
115 |
st.session_state.last_chat_update = 0
|
116 |
if 'displayed_chat_lines' not in st.session_state:
|
117 |
st.session_state.displayed_chat_lines = []
|
118 |
+
if 'old_val' not in st.session_state:
|
119 |
+
st.session_state.old_val = ""
|
120 |
+
if 'last_query' not in st.session_state:
|
121 |
+
st.session_state.last_query = ""
|
122 |
|
123 |
# Timestamp wizardry - clock ticks with flair! β°π©
|
124 |
def format_timestamp_prefix():
|
|
|
351 |
text = "Voice input simulation"
|
352 |
await save_chat_entry(username, text)
|
353 |
|
354 |
+
# Dummy AI lookup function (replace with actual implementation)
|
355 |
+
async def perform_ai_lookup(query, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=False, useArxiv=True, useArxivAudio=False):
|
356 |
+
username = st.session_state.get('username', 'System π')
|
357 |
+
result = f"AI Lookup Result for '{query}' (Arxiv: {useArxiv}, Audio: {useArxivAudio})"
|
358 |
+
await save_chat_entry(username, result)
|
359 |
+
if useArxivAudio:
|
360 |
+
audio_file = await async_edge_tts_generate(result, FUN_USERNAMES.get(username, "en-US-AriaNeural"))
|
361 |
+
if audio_file:
|
362 |
+
st.audio(audio_file)
|
363 |
+
|
364 |
+
# Main execution - letβs roll! π²π
|
365 |
+
def main():
|
366 |
+
NODE_NAME, port = get_node_name()
|
367 |
+
|
368 |
loop = asyncio.new_event_loop()
|
369 |
asyncio.set_event_loop(loop)
|
370 |
|
|
|
378 |
st.session_state.refresh_rate = 5
|
379 |
if 'timer_start' not in st.session_state:
|
380 |
st.session_state.timer_start = time.time()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
|
382 |
st.markdown("""
|
383 |
<style>
|
|
|
404 |
chat_lines = chat_content.split('\n')
|
405 |
chat_votes = await load_votes(QUOTE_VOTES_FILE)
|
406 |
|
|
|
407 |
current_time = time.time()
|
408 |
if current_time - st.session_state.last_chat_update > 1 or not st.session_state.displayed_chat_lines:
|
409 |
new_lines = [line for line in chat_lines if line.strip() and ': ' in line and line not in st.session_state.displayed_chat_lines and not line.startswith('#')]
|
410 |
st.session_state.displayed_chat_lines.extend(new_lines)
|
411 |
st.session_state.last_chat_update = current_time
|
412 |
|
|
|
413 |
for i, line in enumerate(st.session_state.displayed_chat_lines):
|
414 |
col1, col2, col3, col4 = st.columns([3, 1, 1, 2])
|
415 |
with col1:
|
416 |
st.markdown(line)
|
|
|
417 |
if "Pasted image:" in line:
|
418 |
image_path = line.split("Pasted image: ")[1].strip()
|
419 |
if os.path.exists(image_path):
|
|
|
445 |
if audio_file:
|
446 |
play_and_download_audio(audio_file)
|
447 |
|
|
|
448 |
if 'quote_line' in st.session_state and st.session_state.quote_line:
|
449 |
st.markdown(f"### Quoting: {st.session_state.quote_line}")
|
450 |
quote_response = st.text_area("Add your response", key="quote_response")
|
|
|
461 |
st.session_state.message_text = ''
|
462 |
st.rerun()
|
463 |
|
|
|
464 |
new_username = st.selectbox("Change Name", [""] + list(FUN_USERNAMES.keys()), index=0)
|
465 |
if new_username and new_username != st.session_state.username:
|
466 |
loop.run_until_complete(save_chat_entry("System π", f"{st.session_state.username} changed name to {new_username}"))
|
467 |
st.session_state.username = new_username
|
468 |
st.rerun()
|
469 |
|
|
|
470 |
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))
|
471 |
if st.button("Send π", key="send_button") and message.strip():
|
472 |
loop.run_until_complete(save_chat_entry(st.session_state.username, message))
|
|
|
478 |
st.session_state.message_text = ''
|
479 |
st.rerun()
|
480 |
|
481 |
+
# Custom component for ASR and Image Pasting
|
482 |
+
mycomponent = components.declare_component("mycomponent", path="./frontend")
|
483 |
+
val = mycomponent(my_input_value="Hello from MyComponent")
|
484 |
+
|
485 |
+
# Main action tabs and model use choices
|
486 |
+
tab_main = st.radio("Action:", ["π€ Voice", "πΈ Media", "π ArXiv", "π Editor"], horizontal=True)
|
487 |
+
useArxiv = st.checkbox("Search Arxiv for Research Paper Answers", value=True)
|
488 |
+
useArxivAudio = st.checkbox("Generate Audio File for Research Paper Answers", value=False)
|
489 |
+
|
490 |
+
if val:
|
491 |
+
if isinstance(val, dict):
|
492 |
+
if val.get('type') == 'text' and 'transcript' in val:
|
493 |
+
val_stripped = val['transcript'].replace('\n', ' ')
|
494 |
+
if val_stripped.strip():
|
495 |
+
await save_chat_entry(st.session_state.username, val_stripped)
|
496 |
+
elif val.get('type') == 'image' and 'image' in val:
|
497 |
+
filename = await save_pasted_image(val['image'], st.session_state.username)
|
498 |
+
if filename:
|
499 |
+
await save_chat_entry(st.session_state.username, f"Pasted image: {filename}")
|
500 |
+
|
501 |
+
edited_input = st.text_area("βοΈ Edit Input:", value=val_stripped if isinstance(val, dict) and val.get('type') == 'text' else "", height=100)
|
502 |
+
run_option = st.selectbox("Model:", ["Arxiv", "Other (demo)"])
|
503 |
+
col1, col2 = st.columns(2)
|
504 |
+
with col1:
|
505 |
+
autorun = st.checkbox("β AutoRun", value=True)
|
506 |
+
with col2:
|
507 |
+
full_audio = st.checkbox("πFullAudio", value=False)
|
508 |
+
|
509 |
+
input_changed = (val != st.session_state.old_val)
|
510 |
+
|
511 |
+
if autorun and input_changed and edited_input.strip():
|
512 |
+
st.session_state.old_val = val
|
513 |
+
st.session_state.last_query = edited_input
|
514 |
+
await perform_ai_lookup(edited_input, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=full_audio, useArxiv=useArxiv, useArxivAudio=useArxivAudio)
|
515 |
+
else:
|
516 |
+
if st.button("βΆ Run") and edited_input.strip():
|
517 |
+
st.session_state.old_val = val
|
518 |
+
st.session_state.last_query = edited_input
|
519 |
+
await perform_ai_lookup(edited_input, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=full_audio, useArxiv=useArxiv, useArxivAudio=useArxivAudio)
|
520 |
|
521 |
st.subheader("Media Gallery π¨πΆπ₯")
|
522 |
uploaded_file = st.file_uploader("Upload Media", type=['png', 'jpg', 'mp3', 'mp4'])
|
|
|
532 |
if file_path.endswith('.mp4'):
|
533 |
st.session_state.media_notifications.append(file_path)
|
534 |
|
|
|
535 |
media_files = glob.glob(f"{MEDIA_DIR}/*.png") + glob.glob(f"{MEDIA_DIR}/*.jpg") + glob.glob(f"{MEDIA_DIR}/*.mp3") + glob.glob(f"{MEDIA_DIR}/*.mp4")
|
536 |
if media_files:
|
537 |
+
media_votes = await load_votes(MEDIA_VOTES_FILE)
|
538 |
users = sorted(set(f.split('_')[-1].split('.')[0] for f in media_files))
|
539 |
for user in users:
|
540 |
with st.expander(f"{user}'s Media"):
|
|
|
557 |
with col2:
|
558 |
if st.button(f"π {vote_count}", key=f"media_vote_{media_file}"):
|
559 |
comment = st.session_state.message_text
|
560 |
+
await save_vote(MEDIA_VOTES_FILE, media_file, await generate_user_hash(), st.session_state.username, comment)
|
561 |
st.session_state.message_text = ''
|
562 |
st.rerun()
|
563 |
with col3:
|
|
|
573 |
font_name, font_func = random.choice(UNICODE_FONTS)
|
574 |
countdown_str = "".join(UNICODE_DIGITS[int(d)] for d in str(i)) if i < 10 else font_func(str(i))
|
575 |
timer_placeholder.markdown(f"<p class='timer'>β³ {font_func('Refresh in:')} {countdown_str}</p>", unsafe_allow_html=True)
|
576 |
+
await asyncio.sleep(1)
|
577 |
st.rerun()
|
578 |
|
579 |
st.sidebar.subheader("Chat History π")
|
|
|
583 |
|
584 |
loop.run_until_complete(async_interface())
|
585 |
|
|
|
|
|
|
|
|
|
|
|
586 |
if __name__ == "__main__":
|
587 |
main()
|