Update backup13.app.py
Browse files- backup13.app.py +110 -80
backup13.app.py
CHANGED
@@ -126,7 +126,7 @@ def init_session_state():
|
|
126 |
'enable_audio': True, 'download_link_cache': {}, 'username': None,
|
127 |
'autosend': True, 'autosearch': True, 'last_message': "", 'last_query': "",
|
128 |
'mp3_files': {}, 'timer_start': time.time(), 'quote_index': 0,
|
129 |
-
'quote_source': "famous"
|
130 |
}
|
131 |
for k, v in defaults.items():
|
132 |
if k not in st.session_state:
|
@@ -213,13 +213,21 @@ async def async_edge_tts_generate(text, voice, username, rate=0, pitch=0, file_f
|
|
213 |
return st.session_state['audio_cache'][cache_key], 0
|
214 |
start_time = time.time()
|
215 |
text = clean_text_for_tts(text)
|
216 |
-
if not text:
|
|
|
217 |
return None, 0
|
218 |
filename = f"{format_timestamp_prefix(username)}-{hashlib.md5(text.encode()).hexdigest()[:8]}.{file_format}"
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
def play_and_download_audio(file_path):
|
225 |
if file_path and os.path.exists(file_path):
|
@@ -245,6 +253,8 @@ async def save_chat_entry(username, message, is_markdown=False):
|
|
245 |
with open(HISTORY_FILE, 'a') as f:
|
246 |
f.write(f"[{timestamp}] {username}: Audio - {audio_file}\n")
|
247 |
st.session_state['mp3_files'][os.path.basename(audio_file)] = audio_file
|
|
|
|
|
248 |
await broadcast_message(f"{username}|{message}", "chat")
|
249 |
st.session_state.last_chat_update = time.time()
|
250 |
st.session_state.chat_history.append(entry)
|
@@ -260,6 +270,44 @@ async def load_chat():
|
|
260 |
numbered_content = "\n".join(f"{i+1}. {line}" for i, line in enumerate(lines) if line.strip())
|
261 |
return numbered_content
|
262 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
# ๐ WebSocket Handling
|
264 |
async def websocket_handler(websocket, path):
|
265 |
client_id = str(uuid.uuid4())
|
@@ -392,28 +440,6 @@ async def create_paper_audio_files(papers, query):
|
|
392 |
if p['full_audio']:
|
393 |
p['download_base64'] = get_download_link(p['full_audio'])
|
394 |
|
395 |
-
async def perform_ai_lookup(q, useArxiv=True, useArxivAudio=False):
|
396 |
-
client = anthropic.Anthropic(api_key=anthropic_key)
|
397 |
-
response = client.messages.create(model="claude-3-sonnet-20240229", max_tokens=1000, messages=[{"role": "user", "content": q}])
|
398 |
-
result = response.content[0].text
|
399 |
-
st.markdown("### Claude's Reply ๐ง \n" + result)
|
400 |
-
md_file = create_file(result, "System", "md")
|
401 |
-
audio_file, _ = await async_edge_tts_generate(result, st.session_state['tts_voice'], "System")
|
402 |
-
play_and_download_audio(audio_file)
|
403 |
-
|
404 |
-
if useArxiv:
|
405 |
-
q += result
|
406 |
-
gradio_client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
|
407 |
-
refs = gradio_client.predict(q, 10, "Semantic Search", "mistralai/Mixtral-8x7B-Instruct-v0.1", api_name="/update_with_rag_md")[0]
|
408 |
-
result = f"๐ {q}\n\n{refs}"
|
409 |
-
md_file, audio_file = create_file(result, "System", "md"), (await async_edge_tts_generate(result, st.session_state['tts_voice'], "System"))[0]
|
410 |
-
play_and_download_audio(audio_file)
|
411 |
-
papers = parse_arxiv_refs(refs)
|
412 |
-
if papers and useArxivAudio:
|
413 |
-
await create_paper_audio_files(papers, q)
|
414 |
-
return result, papers
|
415 |
-
return result, []
|
416 |
-
|
417 |
def save_vote(file, item, user_hash):
|
418 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
419 |
entry = f"[{timestamp}] {user_hash} voted for {item}"
|
@@ -474,35 +500,63 @@ def create_zip_of_files(md_files, mp3_files, png_files, mp4_files, query):
|
|
474 |
return zip_name
|
475 |
|
476 |
# ๐ฎ Main Interface
|
477 |
-
|
478 |
init_session_state()
|
479 |
load_mp3_viewer()
|
480 |
saved_username = load_username()
|
481 |
if saved_username and saved_username in FUN_USERNAMES:
|
482 |
st.session_state.username = saved_username
|
483 |
if not st.session_state.username:
|
484 |
-
available = [n for n in FUN_USERNAMES if not any(f"{n} has joined" in l for l in (
|
485 |
st.session_state.username = random.choice(available or list(FUN_USERNAMES.keys()))
|
486 |
st.session_state.tts_voice = FUN_USERNAMES[st.session_state.username]
|
487 |
-
|
488 |
save_username(st.session_state.username)
|
489 |
|
490 |
st.title(f"{Site_Name} for {st.session_state.username}")
|
491 |
update_marquee_settings_ui()
|
492 |
display_marquee(f"๐ Welcome to {START_ROOM} | ๐ค {st.session_state.username}", st.session_state['marquee_settings'], "welcome")
|
493 |
|
494 |
-
|
495 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
496 |
|
497 |
tab_main = st.radio("Action:", ["๐ค Chat & Voice", "๐ธ Media", "๐ ArXiv", "๐ PDF to Audio"], horizontal=True)
|
498 |
-
useArxiv
|
499 |
-
|
500 |
-
st.session_state.
|
|
|
501 |
|
502 |
# ๐ค Chat & Voice
|
503 |
if tab_main == "๐ค Chat & Voice":
|
504 |
st.subheader(f"{START_ROOM} Chat ๐ฌ")
|
505 |
-
chat_content =
|
506 |
chat_container = st.container()
|
507 |
with chat_container:
|
508 |
lines = chat_content.split('\n')
|
@@ -531,46 +585,21 @@ async def async_interface():
|
|
531 |
message = st.text_input(f"Message as {st.session_state.username}", key="message_input_paste", value=st.session_state.message_text)
|
532 |
else:
|
533 |
st.image(paste_result.image_data, caption="Pasted Image")
|
534 |
-
filename =
|
535 |
if filename:
|
536 |
st.session_state.pasted_image_data = filename
|
537 |
if (message and message != st.session_state.last_message) or st.session_state.pasted_image_data:
|
538 |
st.session_state.last_message = message
|
539 |
-
if st.session_state.autosend or st.button("Send ๐"):
|
540 |
if message.strip():
|
541 |
-
|
542 |
if st.session_state.pasted_image_data:
|
543 |
-
|
544 |
st.session_state.pasted_image_data = None
|
545 |
st.session_state.timer_start = time.time()
|
546 |
save_username(st.session_state.username)
|
547 |
st.rerun()
|
548 |
-
|
549 |
-
st.subheader("๐ค Speech-to-Chat")
|
550 |
-
from mycomponent import mycomponent # Correct import
|
551 |
-
transcript_data = mycomponent(default_value=st.session_state.get('last_transcript', ''), key="speech_input")
|
552 |
-
if transcript_data and 'value' in transcript_data:
|
553 |
-
transcript = transcript_data['value'].strip()
|
554 |
-
if transcript:
|
555 |
-
st.write(f"๐๏ธ You said: {transcript}")
|
556 |
-
if transcript != st.session_state.last_transcript:
|
557 |
-
st.session_state.last_transcript = transcript
|
558 |
-
if st.session_state.autosend:
|
559 |
-
await save_chat_entry(st.session_state.username, transcript, True)
|
560 |
-
st.session_state.timer_start = time.time()
|
561 |
-
save_username(st.session_state.username)
|
562 |
-
# Update chat display without full rerun to reduce flicker
|
563 |
-
with chat_container:
|
564 |
-
st.markdown(await load_chat())
|
565 |
-
else:
|
566 |
-
if st.button("Send to Chat", key="send_transcript"):
|
567 |
-
await save_chat_entry(st.session_state.username, transcript, True)
|
568 |
-
st.session_state.timer_start = time.time()
|
569 |
-
save_username(st.session_state.username)
|
570 |
-
st.rerun()
|
571 |
-
else:
|
572 |
-
st.write("๐๏ธ Speak to transcribe your message...")
|
573 |
-
|
574 |
# ๐ธ Media
|
575 |
elif tab_main == "๐ธ Media":
|
576 |
st.header("๐ธ Media Gallery")
|
@@ -602,23 +631,24 @@ async def async_interface():
|
|
602 |
st.video(mp4)
|
603 |
st.markdown(get_download_link(mp4, "mp4"), unsafe_allow_html=True)
|
604 |
|
605 |
-
uploaded_file = st.file_uploader("Upload Media", type=['png', 'mp4', 'mp3'])
|
606 |
if uploaded_file:
|
607 |
filename = f"{format_timestamp_prefix(st.session_state.username)}-{hashlib.md5(uploaded_file.getbuffer()).hexdigest()[:8]}.{uploaded_file.name.split('.')[-1]}"
|
608 |
with open(filename, 'wb') as f:
|
609 |
f.write(uploaded_file.getbuffer())
|
610 |
-
|
611 |
st.session_state.timer_start = time.time()
|
612 |
save_username(st.session_state.username)
|
613 |
st.rerun()
|
614 |
|
615 |
# ๐ ArXiv
|
616 |
elif tab_main == "๐ ArXiv":
|
|
|
617 |
q = st.text_input("๐ Query:", key="arxiv_query")
|
618 |
if q and q != st.session_state.last_query:
|
619 |
st.session_state.last_query = q
|
620 |
-
if st.session_state.autosearch or st.button("๐ Run"):
|
621 |
-
result, papers =
|
622 |
for i, p in enumerate(papers, 1):
|
623 |
with st.expander(f"{i}. ๐ {p['title']}"):
|
624 |
st.markdown(f"**{p['date']} | {p['title']}** โ [Link]({p['url']})")
|
@@ -629,8 +659,8 @@ async def async_interface():
|
|
629 |
# ๐ PDF to Audio
|
630 |
elif tab_main == "๐ PDF to Audio":
|
631 |
audio_processor = AudioProcessor()
|
632 |
-
pdf_file = st.file_uploader("Choose PDF", "pdf")
|
633 |
-
max_pages = st.slider('Pages', 1, 100, 10)
|
634 |
if pdf_file:
|
635 |
with st.spinner('Processing...'):
|
636 |
texts, audios, total = process_pdf(pdf_file, max_pages, st.session_state['tts_voice'], audio_processor)
|
@@ -642,20 +672,20 @@ async def async_interface():
|
|
642 |
if audios.get(i):
|
643 |
st.audio(audios[i])
|
644 |
st.markdown(get_download_link(audios[i], "mp3"), unsafe_allow_html=True)
|
645 |
-
|
646 |
|
647 |
# ๐๏ธ Sidebar with Dialog and Audio
|
648 |
st.sidebar.subheader("Voice Settings")
|
649 |
-
new_username = st.sidebar.selectbox("Change Name/Voice", list(FUN_USERNAMES.keys()), index=list(FUN_USERNAMES.keys()).index(st.session_state.username))
|
650 |
if new_username != st.session_state.username:
|
651 |
-
|
652 |
st.session_state.username, st.session_state.tts_voice = new_username, FUN_USERNAMES[new_username]
|
653 |
st.session_state.timer_start = time.time()
|
654 |
save_username(st.session_state.username)
|
655 |
st.rerun()
|
656 |
|
657 |
st.sidebar.markdown("### ๐ฌ Chat Dialog & Media")
|
658 |
-
chat_content =
|
659 |
lines = chat_content.split('\n')
|
660 |
all_files = sorted(glob.glob("*.md") + glob.glob("*.mp3") + glob.glob("*.png") + glob.glob("*.mp4"), key=os.path.getmtime, reverse=True)
|
661 |
for line in lines[-10:]:
|
@@ -690,13 +720,13 @@ async def async_interface():
|
|
690 |
st.sidebar.markdown("### ๐ File History")
|
691 |
for f in all_files[:10]:
|
692 |
st.sidebar.write(f"{FILE_EMOJIS.get(f.split('.')[-1], '๐')} {os.path.basename(f)}")
|
693 |
-
if st.sidebar.button("โฌ๏ธ Zip All"):
|
694 |
zip_name = create_zip_of_files(md_files, mp3_files, png_files, mp4_files, "latest_query")
|
695 |
if zip_name:
|
696 |
st.sidebar.markdown(get_download_link(zip_name, "zip"), unsafe_allow_html=True)
|
697 |
|
698 |
-
|
699 |
-
|
700 |
|
701 |
if __name__ == "__main__":
|
702 |
main()
|
|
|
126 |
'enable_audio': True, 'download_link_cache': {}, 'username': None,
|
127 |
'autosend': True, 'autosearch': True, 'last_message': "", 'last_query': "",
|
128 |
'mp3_files': {}, 'timer_start': time.time(), 'quote_index': 0,
|
129 |
+
'quote_source': "famous", 'last_sent_transcript': "", 'old_val': None
|
130 |
}
|
131 |
for k, v in defaults.items():
|
132 |
if k not in st.session_state:
|
|
|
213 |
return st.session_state['audio_cache'][cache_key], 0
|
214 |
start_time = time.time()
|
215 |
text = clean_text_for_tts(text)
|
216 |
+
if not text or text == "No text":
|
217 |
+
print(f"Skipping audio generation for empty/invalid text: '{text}'")
|
218 |
return None, 0
|
219 |
filename = f"{format_timestamp_prefix(username)}-{hashlib.md5(text.encode()).hexdigest()[:8]}.{file_format}"
|
220 |
+
try:
|
221 |
+
communicate = edge_tts.Communicate(text, voice, rate=f"{rate:+d}%", pitch=f"{pitch:+d}Hz")
|
222 |
+
await communicate.save(filename)
|
223 |
+
st.session_state['audio_cache'][cache_key] = filename
|
224 |
+
return filename, time.time() - start_time
|
225 |
+
except edge_tts.exceptions.NoAudioReceived as e:
|
226 |
+
print(f"No audio received for text: '{text}' with voice: {voice}. Error: {e}")
|
227 |
+
return None, 0
|
228 |
+
except Exception as e:
|
229 |
+
print(f"Error generating audio for text: '{text}' with voice: {voice}. Error: {e}")
|
230 |
+
return None, 0
|
231 |
|
232 |
def play_and_download_audio(file_path):
|
233 |
if file_path and os.path.exists(file_path):
|
|
|
253 |
with open(HISTORY_FILE, 'a') as f:
|
254 |
f.write(f"[{timestamp}] {username}: Audio - {audio_file}\n")
|
255 |
st.session_state['mp3_files'][os.path.basename(audio_file)] = audio_file
|
256 |
+
else:
|
257 |
+
print(f"No audio generated for message: '{message}' by {username}")
|
258 |
await broadcast_message(f"{username}|{message}", "chat")
|
259 |
st.session_state.last_chat_update = time.time()
|
260 |
st.session_state.chat_history.append(entry)
|
|
|
270 |
numbered_content = "\n".join(f"{i+1}. {line}" for i, line in enumerate(lines) if line.strip())
|
271 |
return numbered_content
|
272 |
|
273 |
+
async def perform_ai_lookup(q, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=False, useArxiv=True, useArxivAudio=False):
|
274 |
+
start = time.time()
|
275 |
+
client = anthropic.Anthropic(api_key=anthropic_key)
|
276 |
+
response = client.messages.create(
|
277 |
+
model="claude-3-sonnet-20240229",
|
278 |
+
max_tokens=1000,
|
279 |
+
messages=[{"role": "user", "content": q}]
|
280 |
+
)
|
281 |
+
st.write("Claude's reply ๐ง :")
|
282 |
+
st.markdown(response.content[0].text)
|
283 |
+
|
284 |
+
result = response.content[0].text
|
285 |
+
md_file = create_file(q, result, "System")
|
286 |
+
audio_file, _ = await async_edge_tts_generate(result, st.session_state['tts_voice'], "System")
|
287 |
+
st.subheader("๐ Main Response Audio")
|
288 |
+
play_and_download_audio(audio_file)
|
289 |
+
|
290 |
+
if useArxiv:
|
291 |
+
q = q + result
|
292 |
+
st.write('Running Arxiv RAG with Claude inputs.')
|
293 |
+
gradio_client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
|
294 |
+
refs = gradio_client.predict(
|
295 |
+
q, 10, "Semantic Search", "mistralai/Mixtral-8x7B-Instruct-v0.1", api_name="/update_with_rag_md"
|
296 |
+
)[0]
|
297 |
+
result = f"๐ {q}\n\n{refs}"
|
298 |
+
md_file = create_file(q, result, "System")
|
299 |
+
audio_file, _ = await async_edge_tts_generate(result, st.session_state['tts_voice'], "System")
|
300 |
+
st.subheader("๐ ArXiv Response Audio")
|
301 |
+
play_and_download_audio(audio_file)
|
302 |
+
|
303 |
+
papers = parse_arxiv_refs(refs)
|
304 |
+
if papers and useArxivAudio:
|
305 |
+
await create_paper_audio_files(papers, q)
|
306 |
+
return result, papers
|
307 |
+
elapsed = time.time() - start
|
308 |
+
st.write(f"**Total Elapsed:** {elapsed:.2f} s")
|
309 |
+
return result, []
|
310 |
+
|
311 |
# ๐ WebSocket Handling
|
312 |
async def websocket_handler(websocket, path):
|
313 |
client_id = str(uuid.uuid4())
|
|
|
440 |
if p['full_audio']:
|
441 |
p['download_base64'] = get_download_link(p['full_audio'])
|
442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
443 |
def save_vote(file, item, user_hash):
|
444 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
445 |
entry = f"[{timestamp}] {user_hash} voted for {item}"
|
|
|
500 |
return zip_name
|
501 |
|
502 |
# ๐ฎ Main Interface
|
503 |
+
def main():
|
504 |
init_session_state()
|
505 |
load_mp3_viewer()
|
506 |
saved_username = load_username()
|
507 |
if saved_username and saved_username in FUN_USERNAMES:
|
508 |
st.session_state.username = saved_username
|
509 |
if not st.session_state.username:
|
510 |
+
available = [n for n in FUN_USERNAMES if not any(f"{n} has joined" in l for l in asyncio.run(load_chat()).split('\n'))]
|
511 |
st.session_state.username = random.choice(available or list(FUN_USERNAMES.keys()))
|
512 |
st.session_state.tts_voice = FUN_USERNAMES[st.session_state.username]
|
513 |
+
asyncio.run(save_chat_entry("System ๐", f"{st.session_state.username} has joined {START_ROOM}!"))
|
514 |
save_username(st.session_state.username)
|
515 |
|
516 |
st.title(f"{Site_Name} for {st.session_state.username}")
|
517 |
update_marquee_settings_ui()
|
518 |
display_marquee(f"๐ Welcome to {START_ROOM} | ๐ค {st.session_state.username}", st.session_state['marquee_settings'], "welcome")
|
519 |
|
520 |
+
# Speech Component at Top Level
|
521 |
+
mycomponent = components.declare_component("mycomponent", path="mycomponent")
|
522 |
+
val = mycomponent(my_input_value="Hello from MyComponent")
|
523 |
+
if val:
|
524 |
+
val_stripped = val.replace('\\n', ' ')
|
525 |
+
edited_input = st.text_area("โ๏ธ Edit Input:", value=val_stripped, height=100, key="speech_input")
|
526 |
+
run_option = st.selectbox("Model:", ["Chat", "Arxiv"], key="model_select")
|
527 |
+
col1, col2 = st.columns(2)
|
528 |
+
with col1:
|
529 |
+
autorun = st.checkbox("โ AutoRun", value=True, key="autorun")
|
530 |
+
with col2:
|
531 |
+
full_audio = st.checkbox("๐ FullAudio", value=False, key="full_audio")
|
532 |
+
|
533 |
+
input_changed = (val != st.session_state.old_val)
|
534 |
+
|
535 |
+
if autorun and input_changed:
|
536 |
+
st.session_state.old_val = val
|
537 |
+
st.session_state.last_query = edited_input
|
538 |
+
if run_option == "Chat":
|
539 |
+
asyncio.run(save_chat_entry(st.session_state.username, edited_input, True))
|
540 |
+
elif run_option == "Arxiv":
|
541 |
+
asyncio.run(perform_ai_lookup(edited_input, useArxiv=True, useArxivAudio=full_audio))
|
542 |
+
elif st.button("โถ Run", key="run_button"):
|
543 |
+
st.session_state.old_val = val
|
544 |
+
st.session_state.last_query = edited_input
|
545 |
+
if run_option == "Chat":
|
546 |
+
asyncio.run(save_chat_entry(st.session_state.username, edited_input, True))
|
547 |
+
elif run_option == "Arxiv":
|
548 |
+
asyncio.run(perform_ai_lookup(edited_input, useArxiv=True, useArxivAudio=full_audio))
|
549 |
|
550 |
tab_main = st.radio("Action:", ["๐ค Chat & Voice", "๐ธ Media", "๐ ArXiv", "๐ PDF to Audio"], horizontal=True)
|
551 |
+
useArxiv = st.checkbox("Search ArXiv", True, key="use_arxiv")
|
552 |
+
useArxivAudio = st.checkbox("ArXiv Audio", False, key="use_arxiv_audio")
|
553 |
+
st.session_state.autosend = st.checkbox("Autosend Chat", value=True, key="autosend")
|
554 |
+
st.session_state.autosearch = st.checkbox("Autosearch ArXiv", value=True, key="autosearch")
|
555 |
|
556 |
# ๐ค Chat & Voice
|
557 |
if tab_main == "๐ค Chat & Voice":
|
558 |
st.subheader(f"{START_ROOM} Chat ๐ฌ")
|
559 |
+
chat_content = asyncio.run(load_chat())
|
560 |
chat_container = st.container()
|
561 |
with chat_container:
|
562 |
lines = chat_content.split('\n')
|
|
|
585 |
message = st.text_input(f"Message as {st.session_state.username}", key="message_input_paste", value=st.session_state.message_text)
|
586 |
else:
|
587 |
st.image(paste_result.image_data, caption="Pasted Image")
|
588 |
+
filename = asyncio.run(save_pasted_image(paste_result.image_data, st.session_state.username))
|
589 |
if filename:
|
590 |
st.session_state.pasted_image_data = filename
|
591 |
if (message and message != st.session_state.last_message) or st.session_state.pasted_image_data:
|
592 |
st.session_state.last_message = message
|
593 |
+
if st.session_state.autosend or st.button("Send ๐", key="send_button"):
|
594 |
if message.strip():
|
595 |
+
asyncio.run(save_chat_entry(st.session_state.username, message, True))
|
596 |
if st.session_state.pasted_image_data:
|
597 |
+
asyncio.run(save_chat_entry(st.session_state.username, f"Pasted image: {st.session_state.pasted_image_data}"))
|
598 |
st.session_state.pasted_image_data = None
|
599 |
st.session_state.timer_start = time.time()
|
600 |
save_username(st.session_state.username)
|
601 |
st.rerun()
|
602 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
603 |
# ๐ธ Media
|
604 |
elif tab_main == "๐ธ Media":
|
605 |
st.header("๐ธ Media Gallery")
|
|
|
631 |
st.video(mp4)
|
632 |
st.markdown(get_download_link(mp4, "mp4"), unsafe_allow_html=True)
|
633 |
|
634 |
+
uploaded_file = st.file_uploader("Upload Media", type=['png', 'mp4', 'mp3'], key="media_upload")
|
635 |
if uploaded_file:
|
636 |
filename = f"{format_timestamp_prefix(st.session_state.username)}-{hashlib.md5(uploaded_file.getbuffer()).hexdigest()[:8]}.{uploaded_file.name.split('.')[-1]}"
|
637 |
with open(filename, 'wb') as f:
|
638 |
f.write(uploaded_file.getbuffer())
|
639 |
+
asyncio.run(save_chat_entry(st.session_state.username, f"Uploaded: {filename}"))
|
640 |
st.session_state.timer_start = time.time()
|
641 |
save_username(st.session_state.username)
|
642 |
st.rerun()
|
643 |
|
644 |
# ๐ ArXiv
|
645 |
elif tab_main == "๐ ArXiv":
|
646 |
+
st.subheader("๐ Query ArXiv")
|
647 |
q = st.text_input("๐ Query:", key="arxiv_query")
|
648 |
if q and q != st.session_state.last_query:
|
649 |
st.session_state.last_query = q
|
650 |
+
if st.session_state.autosearch or st.button("๐ Run", key="arxiv_run"):
|
651 |
+
result, papers = asyncio.run(perform_ai_lookup(q, useArxiv=useArxiv, useArxivAudio=useArxivAudio))
|
652 |
for i, p in enumerate(papers, 1):
|
653 |
with st.expander(f"{i}. ๐ {p['title']}"):
|
654 |
st.markdown(f"**{p['date']} | {p['title']}** โ [Link]({p['url']})")
|
|
|
659 |
# ๐ PDF to Audio
|
660 |
elif tab_main == "๐ PDF to Audio":
|
661 |
audio_processor = AudioProcessor()
|
662 |
+
pdf_file = st.file_uploader("Choose PDF", "pdf", key="pdf_upload")
|
663 |
+
max_pages = st.slider('Pages', 1, 100, 10, key="pdf_pages")
|
664 |
if pdf_file:
|
665 |
with st.spinner('Processing...'):
|
666 |
texts, audios, total = process_pdf(pdf_file, max_pages, st.session_state['tts_voice'], audio_processor)
|
|
|
672 |
if audios.get(i):
|
673 |
st.audio(audios[i])
|
674 |
st.markdown(get_download_link(audios[i], "mp3"), unsafe_allow_html=True)
|
675 |
+
asyncio.run(save_chat_entry(st.session_state.username, f"PDF Page {i+1} converted to audio: {audios[i]}"))
|
676 |
|
677 |
# ๐๏ธ Sidebar with Dialog and Audio
|
678 |
st.sidebar.subheader("Voice Settings")
|
679 |
+
new_username = st.sidebar.selectbox("Change Name/Voice", list(FUN_USERNAMES.keys()), index=list(FUN_USERNAMES.keys()).index(st.session_state.username), key="username_select")
|
680 |
if new_username != st.session_state.username:
|
681 |
+
asyncio.run(save_chat_entry("System ๐", f"{st.session_state.username} changed to {new_username}"))
|
682 |
st.session_state.username, st.session_state.tts_voice = new_username, FUN_USERNAMES[new_username]
|
683 |
st.session_state.timer_start = time.time()
|
684 |
save_username(st.session_state.username)
|
685 |
st.rerun()
|
686 |
|
687 |
st.sidebar.markdown("### ๐ฌ Chat Dialog & Media")
|
688 |
+
chat_content = asyncio.run(load_chat())
|
689 |
lines = chat_content.split('\n')
|
690 |
all_files = sorted(glob.glob("*.md") + glob.glob("*.mp3") + glob.glob("*.png") + glob.glob("*.mp4"), key=os.path.getmtime, reverse=True)
|
691 |
for line in lines[-10:]:
|
|
|
720 |
st.sidebar.markdown("### ๐ File History")
|
721 |
for f in all_files[:10]:
|
722 |
st.sidebar.write(f"{FILE_EMOJIS.get(f.split('.')[-1], '๐')} {os.path.basename(f)}")
|
723 |
+
if st.sidebar.button("โฌ๏ธ Zip All", key="zip_all"):
|
724 |
zip_name = create_zip_of_files(md_files, mp3_files, png_files, mp4_files, "latest_query")
|
725 |
if zip_name:
|
726 |
st.sidebar.markdown(get_download_link(zip_name, "zip"), unsafe_allow_html=True)
|
727 |
|
728 |
+
if not st.session_state.server_task:
|
729 |
+
st.session_state.server_task = asyncio.create_task(run_websocket_server())
|
730 |
|
731 |
if __name__ == "__main__":
|
732 |
main()
|