Spaces:
Sleeping
Sleeping
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:
|