Update app.py
Browse files
app.py
CHANGED
@@ -18,7 +18,7 @@ import edge_tts
|
|
18 |
from audio_recorder_streamlit import audio_recorder
|
19 |
import nest_asyncio
|
20 |
import re
|
21 |
-
from streamlit_paste_button import paste_image_button #
|
22 |
|
23 |
# Patch for nested async - sneaky fix! πβ¨
|
24 |
nest_asyncio.apply()
|
@@ -280,16 +280,13 @@ def play_and_download_audio(file_path):
|
|
280 |
st.markdown(dl_link, unsafe_allow_html=True)
|
281 |
|
282 |
# Image saver - pics preserved with naming! πΈπΎ
|
283 |
-
async def save_pasted_image(
|
284 |
await asyncio.to_thread(log_action, username, "πΈπΎ - Image saver - pics preserved!")
|
285 |
timestamp = format_timestamp_prefix()
|
286 |
filename = f"paste_{timestamp}_{username}.png"
|
287 |
filepath = os.path.join(MEDIA_DIR, filename)
|
288 |
-
|
289 |
-
|
290 |
-
img_bytes = base64.b64decode(image_data)
|
291 |
-
img = Image.open(io.BytesIO(img_bytes))
|
292 |
-
await asyncio.to_thread(img.save, filepath, "PNG")
|
293 |
return filepath
|
294 |
|
295 |
# Video renderer - movies roll with autoplay! π₯π¬
|
@@ -426,11 +423,6 @@ def main():
|
|
426 |
if st.button(f"π {vote_count}", key=f"chat_vote_{i}"):
|
427 |
comment = st.session_state.message_text
|
428 |
await save_vote(QUOTE_VOTES_FILE, line.split('. ')[1] if '. ' in line else line, await generate_user_hash(), st.session_state.username, comment)
|
429 |
-
if st.session_state.pasted_image_data:
|
430 |
-
filename = await save_pasted_image(st.session_state.pasted_image_data, st.session_state.username)
|
431 |
-
if filename:
|
432 |
-
await save_chat_entry(st.session_state.username, f"Pasted image: {filename}")
|
433 |
-
st.session_state.pasted_image_data = None
|
434 |
st.session_state.message_text = ''
|
435 |
st.rerun()
|
436 |
with col3:
|
@@ -451,14 +443,19 @@ def main():
|
|
451 |
if st.session_state.quote_line:
|
452 |
st.markdown(f"### Quoting: {st.session_state.quote_line}")
|
453 |
quote_response = st.text_area("Add your response", key="quote_response")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
454 |
if st.button("Send Quote π", key="send_quote"):
|
455 |
markdown_response = f"### Quote Response\n- **Original**: {st.session_state.quote_line}\n- **{st.session_state.username} Replies**: {quote_response}"
|
456 |
if st.session_state.pasted_image_data:
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
await save_chat_entry(st.session_state.username, f"Pasted image: {filename}")
|
461 |
-
st.session_state.pasted_image_data = None
|
462 |
await save_chat_entry(st.session_state.username, markdown_response)
|
463 |
st.session_state.quote_line = None
|
464 |
st.session_state.message_text = ''
|
@@ -471,56 +468,28 @@ def main():
|
|
471 |
st.rerun()
|
472 |
|
473 |
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))
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
st.
|
478 |
-
|
479 |
-
# Paste Image Button
|
480 |
-
paste_result = paste_image_button("π Paste Image", key="paste_button")
|
481 |
-
if paste_result.image_data is not None:
|
482 |
-
st.image(paste_result.image_data, caption="Received Image")
|
483 |
-
filename = await save_pasted_image(base64.b64encode(paste_result.image_data.tobytes()).decode(), st.session_state.username)
|
484 |
if filename:
|
485 |
-
|
|
|
|
|
|
|
|
|
|
|
486 |
st.session_state.pasted_image_data = None
|
|
|
|
|
487 |
|
488 |
# Main action tabs and model use choices
|
489 |
tab_main = st.radio("Action:", ["π€ Voice", "πΈ Media", "π ArXiv", "π Editor"], horizontal=True)
|
490 |
useArxiv = st.checkbox("Search Arxiv for Research Paper Answers", value=True)
|
491 |
useArxivAudio = st.checkbox("Generate Audio File for Research Paper Answers", value=False)
|
492 |
|
493 |
-
#
|
494 |
-
mycomponent = components.declare_component("mycomponent", path="./frontend")
|
495 |
-
val = mycomponent(my_input_value="Hello from MyComponent")
|
496 |
-
|
497 |
-
if val:
|
498 |
-
if isinstance(val, dict):
|
499 |
-
if val.get('type') == 'text' and 'transcript' in val:
|
500 |
-
val_stripped = val['transcript'].replace('\n', ' ')
|
501 |
-
if val_stripped.strip():
|
502 |
-
await save_chat_entry(st.session_state.username, val_stripped)
|
503 |
-
|
504 |
-
edited_input = st.text_area("βοΈ Edit Input:", value=val_stripped if isinstance(val, dict) and val.get('type') == 'text' else "", height=100)
|
505 |
-
run_option = st.selectbox("Model:", ["Arxiv", "Other (demo)"])
|
506 |
-
col1, col2 = st.columns(2)
|
507 |
-
with col1:
|
508 |
-
autorun = st.checkbox("β AutoRun", value=True)
|
509 |
-
with col2:
|
510 |
-
full_audio = st.checkbox("πFullAudio", value=False)
|
511 |
-
|
512 |
-
input_changed = (val != st.session_state.old_val)
|
513 |
-
|
514 |
-
if autorun and input_changed and edited_input.strip():
|
515 |
-
st.session_state.old_val = val
|
516 |
-
st.session_state.last_query = edited_input
|
517 |
-
await perform_ai_lookup(edited_input, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=full_audio, useArxiv=useArxiv, useArxivAudio=useArxivAudio)
|
518 |
-
else:
|
519 |
-
if st.button("βΆ Run") and edited_input.strip():
|
520 |
-
st.session_state.old_val = val
|
521 |
-
st.session_state.last_query = edited_input
|
522 |
-
await perform_ai_lookup(edited_input, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=full_audio, useArxiv=useArxiv, useArxivAudio=useArxivAudio)
|
523 |
-
|
524 |
st.subheader("Upload Media π¨πΆπ₯")
|
525 |
uploaded_file = st.file_uploader("Upload Media", type=['png', 'jpg', 'mp4', 'mp3'])
|
526 |
if uploaded_file:
|
@@ -535,7 +504,6 @@ def main():
|
|
535 |
if file_path.endswith('.mp4'):
|
536 |
st.session_state.media_notifications.append(file_path)
|
537 |
|
538 |
-
# Enhanced Media Gallery with Image, Audio, Video
|
539 |
st.subheader("Media Gallery π¨πΆπ₯")
|
540 |
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")
|
541 |
if media_files:
|
|
|
18 |
from audio_recorder_streamlit import audio_recorder
|
19 |
import nest_asyncio
|
20 |
import re
|
21 |
+
from streamlit_paste_button import paste_image_button # Using this for image pasting
|
22 |
|
23 |
# Patch for nested async - sneaky fix! πβ¨
|
24 |
nest_asyncio.apply()
|
|
|
280 |
st.markdown(dl_link, unsafe_allow_html=True)
|
281 |
|
282 |
# Image saver - pics preserved with naming! πΈπΎ
|
283 |
+
async def save_pasted_image(image, username):
|
284 |
await asyncio.to_thread(log_action, username, "πΈπΎ - Image saver - pics preserved!")
|
285 |
timestamp = format_timestamp_prefix()
|
286 |
filename = f"paste_{timestamp}_{username}.png"
|
287 |
filepath = os.path.join(MEDIA_DIR, filename)
|
288 |
+
# Directly save the PIL Image object without base64 conversion
|
289 |
+
await asyncio.to_thread(image.save, filepath, "PNG")
|
|
|
|
|
|
|
290 |
return filepath
|
291 |
|
292 |
# Video renderer - movies roll with autoplay! π₯π¬
|
|
|
423 |
if st.button(f"π {vote_count}", key=f"chat_vote_{i}"):
|
424 |
comment = st.session_state.message_text
|
425 |
await save_vote(QUOTE_VOTES_FILE, line.split('. ')[1] if '. ' in line else line, await generate_user_hash(), st.session_state.username, comment)
|
|
|
|
|
|
|
|
|
|
|
426 |
st.session_state.message_text = ''
|
427 |
st.rerun()
|
428 |
with col3:
|
|
|
443 |
if st.session_state.quote_line:
|
444 |
st.markdown(f"### Quoting: {st.session_state.quote_line}")
|
445 |
quote_response = st.text_area("Add your response", key="quote_response")
|
446 |
+
# Add paste button within quote response
|
447 |
+
paste_result_quote = paste_image_button("π Paste Image with Quote", key="paste_button_quote")
|
448 |
+
if paste_result_quote.image_data is not None:
|
449 |
+
st.image(paste_result_quote.image_data, caption="Received Image for Quote")
|
450 |
+
filename = await save_pasted_image(paste_result_quote.image_data, st.session_state.username)
|
451 |
+
if filename:
|
452 |
+
st.session_state.pasted_image_data = filename # Store for use in quote submission
|
453 |
if st.button("Send Quote π", key="send_quote"):
|
454 |
markdown_response = f"### Quote Response\n- **Original**: {st.session_state.quote_line}\n- **{st.session_state.username} Replies**: {quote_response}"
|
455 |
if st.session_state.pasted_image_data:
|
456 |
+
markdown_response += f"\n- **Image**: "
|
457 |
+
await save_chat_entry(st.session_state.username, f"Pasted image: {st.session_state.pasted_image_data}")
|
458 |
+
st.session_state.pasted_image_data = None
|
|
|
|
|
459 |
await save_chat_entry(st.session_state.username, markdown_response)
|
460 |
st.session_state.quote_line = None
|
461 |
st.session_state.message_text = ''
|
|
|
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 |
+
# Add paste button next to message input
|
472 |
+
paste_result_msg = paste_image_button("π Paste Image with Message", key="paste_button_msg")
|
473 |
+
if paste_result_msg.image_data is not None:
|
474 |
+
st.image(paste_result_msg.image_data, caption="Received Image for Message")
|
475 |
+
filename = await save_pasted_image(paste_result_msg.image_data, st.session_state.username)
|
|
|
|
|
|
|
|
|
|
|
476 |
if filename:
|
477 |
+
st.session_state.pasted_image_data = filename # Store for use in message submission
|
478 |
+
if st.button("Send π", key="send_button") and (message.strip() or st.session_state.pasted_image_data):
|
479 |
+
if message.strip():
|
480 |
+
await save_chat_entry(st.session_state.username, message)
|
481 |
+
if st.session_state.pasted_image_data:
|
482 |
+
await save_chat_entry(st.session_state.username, f"Pasted image: {st.session_state.pasted_image_data}")
|
483 |
st.session_state.pasted_image_data = None
|
484 |
+
st.session_state.message_text = ''
|
485 |
+
st.rerun()
|
486 |
|
487 |
# Main action tabs and model use choices
|
488 |
tab_main = st.radio("Action:", ["π€ Voice", "πΈ Media", "π ArXiv", "π Editor"], horizontal=True)
|
489 |
useArxiv = st.checkbox("Search Arxiv for Research Paper Answers", value=True)
|
490 |
useArxivAudio = st.checkbox("Generate Audio File for Research Paper Answers", value=False)
|
491 |
|
492 |
+
# Enhanced Media Gallery with Image, Audio, Video
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
493 |
st.subheader("Upload Media π¨πΆπ₯")
|
494 |
uploaded_file = st.file_uploader("Upload Media", type=['png', 'jpg', 'mp4', 'mp3'])
|
495 |
if uploaded_file:
|
|
|
504 |
if file_path.endswith('.mp4'):
|
505 |
st.session_state.media_notifications.append(file_path)
|
506 |
|
|
|
507 |
st.subheader("Media Gallery π¨πΆπ₯")
|
508 |
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")
|
509 |
if media_files:
|