Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -134,7 +134,7 @@ if 'user_hash' not in st.session_state:
|
|
| 134 |
def format_timestamp_prefix(username):
|
| 135 |
central = pytz.timezone('US/Central')
|
| 136 |
now = datetime.now(central)
|
| 137 |
-
return f"{now.strftime('%I-%M-%p
|
| 138 |
|
| 139 |
# Compute image hash from binary data
|
| 140 |
def compute_image_hash(image_data):
|
|
@@ -225,7 +225,7 @@ class AudioProcessor:
|
|
| 225 |
return cache_path
|
| 226 |
|
| 227 |
# Chat saver - words locked tight! π¬π
|
| 228 |
-
async def save_chat_entry(username, message, is_markdown=False, quote_line=None, media_file=None):
|
| 229 |
await asyncio.to_thread(log_action, username, "π¬π - Chat saver - words locked tight!")
|
| 230 |
central = pytz.timezone('US/Central')
|
| 231 |
timestamp = datetime.now(central).strftime("%Y-%m-%d %H:%M:%S")
|
|
@@ -252,34 +252,36 @@ async def save_chat_entry(username, message, is_markdown=False, quote_line=None,
|
|
| 252 |
with open(user_history_file, 'a') as f:
|
| 253 |
f.write(f"{entry}\n")
|
| 254 |
|
| 255 |
-
# Generate audio
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
|
|
|
| 270 |
if media_file:
|
| 271 |
if isinstance(media_file, Image.Image):
|
| 272 |
-
img_hash = compute_image_hash(media_file)
|
| 273 |
timestamp_prefix = format_timestamp_prefix(username)
|
| 274 |
-
media_filename = f"{
|
| 275 |
-
media_path =
|
| 276 |
-
os.makedirs(MEDIA_DIR, exist_ok=True)
|
| 277 |
img_byte_arr = io.BytesIO()
|
| 278 |
media_file.save(img_byte_arr, format='PNG')
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
|
|
|
|
|
|
|
|
|
| 283 |
media_file = media_filename
|
| 284 |
with open(CHAT_FILE, 'a') as f:
|
| 285 |
f.write(f"{indent}[{timestamp}] Media: \n")
|
|
@@ -413,49 +415,32 @@ def play_and_download_audio(file_path):
|
|
| 413 |
return audio_html
|
| 414 |
return ""
|
| 415 |
|
| 416 |
-
# Image saver - pics preserved with naming
|
| 417 |
async def save_pasted_image(image, username):
|
| 418 |
await asyncio.to_thread(log_action, username, "πΈπΎ - Image saver - pics preserved!")
|
| 419 |
-
img_hash = compute_image_hash(image)
|
| 420 |
-
if img_hash in st.session_state.image_hashes:
|
| 421 |
-
return None
|
| 422 |
timestamp = format_timestamp_prefix(username)
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
filepath = os.path.join(MEDIA_DIR, filename)
|
| 426 |
-
os.makedirs(MEDIA_DIR, exist_ok=True)
|
| 427 |
img_byte_arr = io.BytesIO()
|
| 428 |
image.save(img_byte_arr, format='PNG')
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
b64_data = f.read()
|
| 441 |
-
img_data = base64.b64decode(b64_data)
|
| 442 |
-
img = Image.open(io.BytesIO(img_data))
|
| 443 |
-
st.image(img, use_container_width=True)
|
| 444 |
-
|
| 445 |
-
# Find corresponding audio file
|
| 446 |
-
timestamp = media_file.split('-by-')[0] + '-by-' + media_file.split('-by-')[1].split('-')[0]
|
| 447 |
-
voice = media_file.split('-voice-')[1].split('.b64')[0]
|
| 448 |
-
audio_files = glob.glob(f"{timestamp}*-{voice}.mp3")
|
| 449 |
-
if audio_files:
|
| 450 |
-
audio_file = audio_files[0]
|
| 451 |
-
st.audio(audio_file)
|
| 452 |
|
| 453 |
# PDF saver and audio generator
|
| 454 |
async def save_pdf_and_generate_audio(pdf_file, username, max_pages=10):
|
| 455 |
await asyncio.to_thread(log_action, username, "ππΆ - PDF saver and audio generator!")
|
| 456 |
timestamp = format_timestamp_prefix(username)
|
| 457 |
file_hash = hashlib.md5(pdf_file.getbuffer()).hexdigest()[:8]
|
| 458 |
-
pdf_filename = f"{timestamp}-{file_hash}.pdf"
|
| 459 |
with open(pdf_filename, 'wb') as f:
|
| 460 |
f.write(pdf_file.getbuffer())
|
| 461 |
|
|
@@ -470,7 +455,7 @@ async def save_pdf_and_generate_audio(pdf_file, username, max_pages=10):
|
|
| 470 |
for i in range(total_pages):
|
| 471 |
text = reader.pages[i].extract_text()
|
| 472 |
texts.append(text)
|
| 473 |
-
audio_filename = f"{timestamp}-page{i+1}-{file_hash}-voice-{voice}.mp3"
|
| 474 |
audio_data = await audio_processor.create_audio(text, voice, audio_filename)
|
| 475 |
if audio_data:
|
| 476 |
audio_files.append(audio_filename)
|
|
@@ -683,12 +668,12 @@ def main():
|
|
| 683 |
audio_html = play_and_download_audio(audio_file)
|
| 684 |
elif "Media:" in nl:
|
| 685 |
media_file = nl.split("Media: ")[-1].strip('![]()')
|
| 686 |
-
if media_file.endswith('.
|
| 687 |
-
media_content = display_base64_media(media_file, width="100px")
|
| 688 |
-
elif media_file.endswith(('.png', '.jpg')):
|
| 689 |
media_content = f"<img src='file://{media_file}' width='100'>"
|
| 690 |
elif media_file.endswith('.mp4'):
|
| 691 |
media_content = get_video_html(media_file)
|
|
|
|
|
|
|
| 692 |
elif media_file.endswith('.pdf'):
|
| 693 |
media_content = f"π {os.path.basename(media_file)}"
|
| 694 |
minute_output += f"- π¬ **{user}**: {msg} {audio_html} {media_content}\n"
|
|
@@ -746,14 +731,10 @@ def main():
|
|
| 746 |
message = st.text_input(f"Message as {st.session_state.username} (Voice: {st.session_state.voice})", key="message_input", value=st.session_state.message_text)
|
| 747 |
with col_send:
|
| 748 |
if st.button("Send π", key="send_button"):
|
| 749 |
-
if message.strip():
|
| 750 |
-
|
| 751 |
-
if
|
| 752 |
-
st.session_state.
|
| 753 |
-
st.audio(audio_file) # Immediate preview
|
| 754 |
-
if st.session_state.pasted_image_data:
|
| 755 |
-
await save_chat_entry(st.session_state.username, f"Pasted image: {st.session_state.pasted_image_data}", media_file=st.session_state.pasted_image_data)
|
| 756 |
-
st.session_state.pasted_image_data = None
|
| 757 |
st.session_state.message_text = ''
|
| 758 |
st.rerun()
|
| 759 |
|
|
@@ -766,43 +747,34 @@ def main():
|
|
| 766 |
st.image(paste_result_msg.image_data, caption="Received Image for Quote")
|
| 767 |
filename = await save_pasted_image(paste_result_msg.image_data, st.session_state.username)
|
| 768 |
if filename:
|
| 769 |
-
|
|
|
|
| 770 |
st.session_state.pasted_image_data = None
|
|
|
|
| 771 |
|
| 772 |
with st.container():
|
| 773 |
-
tab_main = st.radio("Action:", ["πΈ Media", "π ArXiv", "π Editor"], horizontal=True, label_visibility="collapsed")
|
| 774 |
-
useArxiv = st.checkbox("Search Arxiv for Research Paper Answers", value=True, label_visibility="collapsed")
|
| 775 |
-
useArxivAudio = st.checkbox("Generate Audio File for Research Paper Answers", value=False, label_visibility="collapsed")
|
| 776 |
-
|
| 777 |
st.markdown("###### Upload Media π¨πΆππ₯")
|
| 778 |
uploaded_file = st.file_uploader("Upload Media", type=['png', 'jpg', 'mp4', 'mp3', 'wav', 'pdf', 'txt', 'md', 'py'])
|
| 779 |
if uploaded_file:
|
| 780 |
timestamp = format_timestamp_prefix(st.session_state.username)
|
| 781 |
username = st.session_state.username
|
| 782 |
-
ext = uploaded_file.name.split('.')[-1]
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
|
| 786 |
-
|
| 787 |
-
|
| 788 |
-
|
| 789 |
-
|
| 790 |
-
|
| 791 |
-
|
| 792 |
-
|
| 793 |
-
|
| 794 |
-
|
| 795 |
-
f.write(f" [{timestamp}] Page {i+1} Audio: {audio_file}\n")
|
| 796 |
-
else:
|
| 797 |
-
await save_chat_entry(username, f"Uploaded media: {file_path}", media_file=file_path)
|
| 798 |
-
await save_chat_history_with_image(username, file_path)
|
| 799 |
-
st.session_state.image_hashes.add(file_hash)
|
| 800 |
-
if file_path.endswith('.mp4'):
|
| 801 |
-
st.session_state.media_notifications.append(file_path)
|
| 802 |
|
| 803 |
# Big Red Delete Button
|
| 804 |
st.markdown("###### π Danger Zone")
|
| 805 |
-
if st.button("Try Not To Delete It All On Your First Day", key="delete_all", help="Deletes all user-added files!", type="primary", use_container_width=True
|
| 806 |
deleted_files = delete_user_files()
|
| 807 |
if deleted_files:
|
| 808 |
st.markdown("### ποΈ Deleted Files:\n" + "\n".join([f"- `{file}`" for file in deleted_files]))
|
|
@@ -811,7 +783,7 @@ def main():
|
|
| 811 |
st.rerun()
|
| 812 |
|
| 813 |
st.markdown("###### Refresh β³")
|
| 814 |
-
refresh_rate = st.slider("Refresh Rate", 1, 300, st.session_state.refresh_rate
|
| 815 |
st.session_state.refresh_rate = refresh_rate
|
| 816 |
timer_placeholder = st.empty()
|
| 817 |
for i in range(st.session_state.refresh_rate, -1, -1):
|
|
@@ -824,24 +796,21 @@ def main():
|
|
| 824 |
# Separate Galleries for Own and Shared Files
|
| 825 |
with st.container():
|
| 826 |
all_files = glob.glob("*.md") + glob.glob("*.pdf") + glob.glob("*.txt") + glob.glob("*.py") + glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.mp3") + glob.glob("*.mp4") + glob.glob(os.path.join(MEDIA_DIR, "*.b64"))
|
| 827 |
-
own_files = [f for f in all_files if st.session_state.user_id in os.path.basename(f)]
|
| 828 |
shared_files = [f for f in all_files if f not in own_files and not f in [CHAT_FILE, QUOTE_VOTES_FILE, MEDIA_VOTES_FILE, HISTORY_FILE, STATE_FILE, os.path.join(MEDIA_DIR, "*")]]
|
| 829 |
|
| 830 |
st.markdown("###### Your Files π")
|
| 831 |
st.markdown("###### Image Gallery πΌ")
|
| 832 |
-
own_image_files = [f for f in own_files if f.endswith(('.png', '.jpg'
|
| 833 |
-
image_cols = st.slider("Image Gallery Columns πΌ (Own)", min_value=1, max_value=15, value=5
|
| 834 |
cols = st.columns(image_cols)
|
| 835 |
for idx, image_file in enumerate(own_image_files):
|
| 836 |
with cols[idx % image_cols]:
|
| 837 |
-
|
| 838 |
-
display_base64_media(os.path.basename(image_file))
|
| 839 |
-
else:
|
| 840 |
-
st.image(image_file, use_container_width=True)
|
| 841 |
|
| 842 |
st.markdown("###### Video Gallery π₯")
|
| 843 |
own_video_files = [f for f in own_files if f.endswith('.mp4')]
|
| 844 |
-
video_cols = st.slider("Video Gallery Columns π¬ (Own)", min_value=1, max_value=5, value=3
|
| 845 |
cols = st.columns(video_cols)
|
| 846 |
for idx, video_file in enumerate(own_video_files):
|
| 847 |
with cols[idx % video_cols]:
|
|
@@ -849,7 +818,7 @@ def main():
|
|
| 849 |
|
| 850 |
st.markdown("###### Audio Gallery π§")
|
| 851 |
own_audio_files = [f for f in own_files if f.endswith(('.mp3', '.wav'))]
|
| 852 |
-
audio_cols = st.slider("Audio Gallery Columns πΆ (Own)", min_value=1, max_value=15, value=5
|
| 853 |
cols = st.columns(audio_cols)
|
| 854 |
for idx, audio_file in enumerate(own_audio_files):
|
| 855 |
with cols[idx % audio_cols]:
|
|
@@ -857,19 +826,16 @@ def main():
|
|
| 857 |
|
| 858 |
st.markdown("###### Shared Files π€")
|
| 859 |
st.markdown("###### Image Gallery πΌ")
|
| 860 |
-
shared_image_files = [f for f in shared_files if f.endswith(('.png', '.jpg'
|
| 861 |
-
image_cols = st.slider("Image Gallery Columns πΌ (Shared)", min_value=1, max_value=15, value=5
|
| 862 |
cols = st.columns(image_cols)
|
| 863 |
for idx, image_file in enumerate(shared_image_files):
|
| 864 |
with cols[idx % image_cols]:
|
| 865 |
-
|
| 866 |
-
display_base64_media(os.path.basename(image_file))
|
| 867 |
-
else:
|
| 868 |
-
st.image(image_file, use_container_width=True)
|
| 869 |
|
| 870 |
st.markdown("###### Video Gallery π₯")
|
| 871 |
shared_video_files = [f for f in shared_files if f.endswith('.mp4')]
|
| 872 |
-
video_cols = st.slider("Video Gallery Columns π¬ (Shared)", min_value=1, max_value=5, value=3
|
| 873 |
cols = st.columns(video_cols)
|
| 874 |
for idx, video_file in enumerate(shared_video_files):
|
| 875 |
with cols[idx % video_cols]:
|
|
@@ -877,7 +843,7 @@ def main():
|
|
| 877 |
|
| 878 |
st.markdown("###### Audio Gallery π§")
|
| 879 |
shared_audio_files = [f for f in shared_files if f.endswith(('.mp3', '.wav'))]
|
| 880 |
-
audio_cols = st.slider("Audio Gallery Columns πΆ (Shared)", min_value=1, max_value=15, value=5
|
| 881 |
cols = st.columns(audio_cols)
|
| 882 |
for idx, audio_file in enumerate(shared_audio_files):
|
| 883 |
with cols[idx % audio_cols]:
|
|
@@ -889,7 +855,7 @@ def main():
|
|
| 889 |
with open(CHAT_FILE, 'r') as f:
|
| 890 |
history_content = f.read()
|
| 891 |
st.markdown(history_content)
|
| 892 |
-
st.download_button("Download Chat Log as .md", history_content, file_name=f"chat_{st.session_state.user_id}.md", mime="text/markdown"
|
| 893 |
|
| 894 |
loop.run_until_complete(async_interface())
|
| 895 |
|
|
|
|
| 134 |
def format_timestamp_prefix(username):
|
| 135 |
central = pytz.timezone('US/Central')
|
| 136 |
now = datetime.now(central)
|
| 137 |
+
return f"{username}-{now.strftime('%I-%M-%p-%m-%d-%Y')}"
|
| 138 |
|
| 139 |
# Compute image hash from binary data
|
| 140 |
def compute_image_hash(image_data):
|
|
|
|
| 225 |
return cache_path
|
| 226 |
|
| 227 |
# Chat saver - words locked tight! π¬π
|
| 228 |
+
async def save_chat_entry(username, message, is_markdown=False, quote_line=None, media_file=None, skip_audio=False):
|
| 229 |
await asyncio.to_thread(log_action, username, "π¬π - Chat saver - words locked tight!")
|
| 230 |
central = pytz.timezone('US/Central')
|
| 231 |
timestamp = datetime.now(central).strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
| 252 |
with open(user_history_file, 'a') as f:
|
| 253 |
f.write(f"{entry}\n")
|
| 254 |
|
| 255 |
+
# Generate audio (unless skipped)
|
| 256 |
+
if not skip_audio and message.strip():
|
| 257 |
+
cleaned_message = clean_text_for_tts(message)
|
| 258 |
+
audio_processor = AudioProcessor()
|
| 259 |
+
audio_filename = f"{format_timestamp_prefix(username)}-{hashlib.md5(cleaned_message.encode()).hexdigest()[:8]}.mp3"
|
| 260 |
+
log_action(username, f"Attempting TTS with text: '{cleaned_message}' and voice: '{voice}'")
|
| 261 |
+
audio_file = await audio_processor.create_audio(cleaned_message, voice, audio_filename)
|
| 262 |
+
|
| 263 |
+
# Log audio
|
| 264 |
+
if audio_file:
|
| 265 |
+
with open(HISTORY_FILE, 'a') as f:
|
| 266 |
+
f.write(f"[{timestamp}] {username} ({voice}): Audio generated - {audio_filename}\n")
|
| 267 |
+
with open(user_history_file, 'a') as f:
|
| 268 |
+
f.write(f"{indent}[{timestamp}] Audio: {audio_filename}\n")
|
| 269 |
+
with open(CHAT_FILE, 'a') as f:
|
| 270 |
+
f.write(f"{indent}[{timestamp}] Audio: {audio_filename}\n")
|
| 271 |
if media_file:
|
| 272 |
if isinstance(media_file, Image.Image):
|
|
|
|
| 273 |
timestamp_prefix = format_timestamp_prefix(username)
|
| 274 |
+
media_filename = f"{username}-{timestamp_prefix.split('-')[-1]}.png"
|
| 275 |
+
media_path = media_filename # Save at root
|
|
|
|
| 276 |
img_byte_arr = io.BytesIO()
|
| 277 |
media_file.save(img_byte_arr, format='PNG')
|
| 278 |
+
await asyncio.to_thread(lambda: open(media_path, 'wb').write(img_byte_arr.getvalue()))
|
| 279 |
+
media_file = media_filename
|
| 280 |
+
elif media_file.name in ['png', 'jpg', 'mp4', 'mp3']:
|
| 281 |
+
timestamp_prefix = format_timestamp_prefix(username)
|
| 282 |
+
media_filename = f"{username}-{timestamp_prefix.split('-')[-1]}.{media_file.name.split('.')[-1]}"
|
| 283 |
+
media_path = media_filename # Save at root
|
| 284 |
+
await asyncio.to_thread(lambda: open(media_path, 'wb').write(media_file.getbuffer()))
|
| 285 |
media_file = media_filename
|
| 286 |
with open(CHAT_FILE, 'a') as f:
|
| 287 |
f.write(f"{indent}[{timestamp}] Media: \n")
|
|
|
|
| 415 |
return audio_html
|
| 416 |
return ""
|
| 417 |
|
| 418 |
+
# Image saver - pics preserved with naming! πΈπΎ
|
| 419 |
async def save_pasted_image(image, username):
|
| 420 |
await asyncio.to_thread(log_action, username, "πΈπΎ - Image saver - pics preserved!")
|
|
|
|
|
|
|
|
|
|
| 421 |
timestamp = format_timestamp_prefix(username)
|
| 422 |
+
media_filename = f"{username}-{timestamp.split('-')[-1]}.png"
|
| 423 |
+
media_path = media_filename # Save at root
|
|
|
|
|
|
|
| 424 |
img_byte_arr = io.BytesIO()
|
| 425 |
image.save(img_byte_arr, format='PNG')
|
| 426 |
+
await asyncio.to_thread(lambda: open(media_path, 'wb').write(img_byte_arr.getvalue()))
|
| 427 |
+
return media_filename
|
| 428 |
+
|
| 429 |
+
# Video and Audio savers
|
| 430 |
+
async def save_media(file, username, ext):
|
| 431 |
+
await asyncio.to_thread(log_action, username, f"πΈπΎ - Media saver - {ext} preserved!")
|
| 432 |
+
timestamp = format_timestamp_prefix(username)
|
| 433 |
+
media_filename = f"{username}-{timestamp.split('-')[-1]}.{ext}"
|
| 434 |
+
media_path = media_filename # Save at root
|
| 435 |
+
await asyncio.to_thread(lambda: open(media_path, 'wb').write(file.getbuffer()))
|
| 436 |
+
return media_filename
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
|
| 438 |
# PDF saver and audio generator
|
| 439 |
async def save_pdf_and_generate_audio(pdf_file, username, max_pages=10):
|
| 440 |
await asyncio.to_thread(log_action, username, "ππΆ - PDF saver and audio generator!")
|
| 441 |
timestamp = format_timestamp_prefix(username)
|
| 442 |
file_hash = hashlib.md5(pdf_file.getbuffer()).hexdigest()[:8]
|
| 443 |
+
pdf_filename = f"{username}-{timestamp.split('-')[-1]}-{file_hash}.pdf"
|
| 444 |
with open(pdf_filename, 'wb') as f:
|
| 445 |
f.write(pdf_file.getbuffer())
|
| 446 |
|
|
|
|
| 455 |
for i in range(total_pages):
|
| 456 |
text = reader.pages[i].extract_text()
|
| 457 |
texts.append(text)
|
| 458 |
+
audio_filename = f"{username}-{timestamp.split('-')[-1]}-page{i+1}-{file_hash}-voice-{voice}.mp3"
|
| 459 |
audio_data = await audio_processor.create_audio(text, voice, audio_filename)
|
| 460 |
if audio_data:
|
| 461 |
audio_files.append(audio_filename)
|
|
|
|
| 668 |
audio_html = play_and_download_audio(audio_file)
|
| 669 |
elif "Media:" in nl:
|
| 670 |
media_file = nl.split("Media: ")[-1].strip('![]()')
|
| 671 |
+
if media_file.endswith(('.png', '.jpg')):
|
|
|
|
|
|
|
| 672 |
media_content = f"<img src='file://{media_file}' width='100'>"
|
| 673 |
elif media_file.endswith('.mp4'):
|
| 674 |
media_content = get_video_html(media_file)
|
| 675 |
+
elif media_file.endswith('.mp3'):
|
| 676 |
+
media_content = await get_audio_html(media_file)
|
| 677 |
elif media_file.endswith('.pdf'):
|
| 678 |
media_content = f"π {os.path.basename(media_file)}"
|
| 679 |
minute_output += f"- π¬ **{user}**: {msg} {audio_html} {media_content}\n"
|
|
|
|
| 731 |
message = st.text_input(f"Message as {st.session_state.username} (Voice: {st.session_state.voice})", key="message_input", value=st.session_state.message_text)
|
| 732 |
with col_send:
|
| 733 |
if st.button("Send π", key="send_button"):
|
| 734 |
+
if message.strip() or st.session_state.pasted_image_data:
|
| 735 |
+
await save_chat_entry(st.session_state.username, message if message.strip() else "Image shared", is_markdown=True, media_file=st.session_state.pasted_image_data if st.session_state.pasted_image_data else None, skip_audio=not message.strip())
|
| 736 |
+
if st.session_state.pasted_image_data:
|
| 737 |
+
st.session_state.pasted_image_data = None
|
|
|
|
|
|
|
|
|
|
|
|
|
| 738 |
st.session_state.message_text = ''
|
| 739 |
st.rerun()
|
| 740 |
|
|
|
|
| 747 |
st.image(paste_result_msg.image_data, caption="Received Image for Quote")
|
| 748 |
filename = await save_pasted_image(paste_result_msg.image_data, st.session_state.username)
|
| 749 |
if filename:
|
| 750 |
+
st.session_state.pasted_image_data = filename
|
| 751 |
+
await save_chat_entry(st.session_state.username, "Image shared", is_markdown=True, media_file=paste_result_msg.image_data, skip_audio=True)
|
| 752 |
st.session_state.pasted_image_data = None
|
| 753 |
+
st.rerun()
|
| 754 |
|
| 755 |
with st.container():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 756 |
st.markdown("###### Upload Media π¨πΆππ₯")
|
| 757 |
uploaded_file = st.file_uploader("Upload Media", type=['png', 'jpg', 'mp4', 'mp3', 'wav', 'pdf', 'txt', 'md', 'py'])
|
| 758 |
if uploaded_file:
|
| 759 |
timestamp = format_timestamp_prefix(st.session_state.username)
|
| 760 |
username = st.session_state.username
|
| 761 |
+
ext = uploaded_file.name.split('.')[-1].lower()
|
| 762 |
+
if ext in ['png', 'jpg']:
|
| 763 |
+
filename = await save_pasted_image(uploaded_file, username)
|
| 764 |
+
elif ext in ['mp4', 'mp3', 'wav']:
|
| 765 |
+
filename = await save_media(uploaded_file, username, ext)
|
| 766 |
+
elif ext == 'pdf':
|
| 767 |
+
pdf_filename, _, _ = await save_pdf_and_generate_audio(uploaded_file, username)
|
| 768 |
+
filename = pdf_filename
|
| 769 |
+
else:
|
| 770 |
+
filename = f"{username}-{timestamp.split('-')[-1]}.{ext}"
|
| 771 |
+
await asyncio.to_thread(lambda: open(filename, 'wb').write(uploaded_file.getbuffer()))
|
| 772 |
+
await save_chat_entry(username, f"Uploaded {ext.upper()}: {os.path.basename(filename)}", media_file=uploaded_file, skip_audio=True)
|
| 773 |
+
st.success(f"Uploaded {filename}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 774 |
|
| 775 |
# Big Red Delete Button
|
| 776 |
st.markdown("###### π Danger Zone")
|
| 777 |
+
if st.button("Try Not To Delete It All On Your First Day", key="delete_all", help="Deletes all user-added files!", type="primary", use_container_width=True):
|
| 778 |
deleted_files = delete_user_files()
|
| 779 |
if deleted_files:
|
| 780 |
st.markdown("### ποΈ Deleted Files:\n" + "\n".join([f"- `{file}`" for file in deleted_files]))
|
|
|
|
| 783 |
st.rerun()
|
| 784 |
|
| 785 |
st.markdown("###### Refresh β³")
|
| 786 |
+
refresh_rate = st.slider("Refresh Rate", 1, 300, st.session_state.refresh_rate)
|
| 787 |
st.session_state.refresh_rate = refresh_rate
|
| 788 |
timer_placeholder = st.empty()
|
| 789 |
for i in range(st.session_state.refresh_rate, -1, -1):
|
|
|
|
| 796 |
# Separate Galleries for Own and Shared Files
|
| 797 |
with st.container():
|
| 798 |
all_files = glob.glob("*.md") + glob.glob("*.pdf") + glob.glob("*.txt") + glob.glob("*.py") + glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.mp3") + glob.glob("*.mp4") + glob.glob(os.path.join(MEDIA_DIR, "*.b64"))
|
| 799 |
+
own_files = [f for f in all_files if st.session_state.user_id in os.path.basename(f) or st.session_state.username in os.path.basename(f)]
|
| 800 |
shared_files = [f for f in all_files if f not in own_files and not f in [CHAT_FILE, QUOTE_VOTES_FILE, MEDIA_VOTES_FILE, HISTORY_FILE, STATE_FILE, os.path.join(MEDIA_DIR, "*")]]
|
| 801 |
|
| 802 |
st.markdown("###### Your Files π")
|
| 803 |
st.markdown("###### Image Gallery πΌ")
|
| 804 |
+
own_image_files = [f for f in own_files if f.endswith(('.png', '.jpg'))]
|
| 805 |
+
image_cols = st.slider("Image Gallery Columns πΌ (Own)", min_value=1, max_value=15, value=5)
|
| 806 |
cols = st.columns(image_cols)
|
| 807 |
for idx, image_file in enumerate(own_image_files):
|
| 808 |
with cols[idx % image_cols]:
|
| 809 |
+
st.image(image_file, use_container_width=True)
|
|
|
|
|
|
|
|
|
|
| 810 |
|
| 811 |
st.markdown("###### Video Gallery π₯")
|
| 812 |
own_video_files = [f for f in own_files if f.endswith('.mp4')]
|
| 813 |
+
video_cols = st.slider("Video Gallery Columns π¬ (Own)", min_value=1, max_value=5, value=3)
|
| 814 |
cols = st.columns(video_cols)
|
| 815 |
for idx, video_file in enumerate(own_video_files):
|
| 816 |
with cols[idx % video_cols]:
|
|
|
|
| 818 |
|
| 819 |
st.markdown("###### Audio Gallery π§")
|
| 820 |
own_audio_files = [f for f in own_files if f.endswith(('.mp3', '.wav'))]
|
| 821 |
+
audio_cols = st.slider("Audio Gallery Columns πΆ (Own)", min_value=1, max_value=15, value=5)
|
| 822 |
cols = st.columns(audio_cols)
|
| 823 |
for idx, audio_file in enumerate(own_audio_files):
|
| 824 |
with cols[idx % audio_cols]:
|
|
|
|
| 826 |
|
| 827 |
st.markdown("###### Shared Files π€")
|
| 828 |
st.markdown("###### Image Gallery πΌ")
|
| 829 |
+
shared_image_files = [f for f in shared_files if f.endswith(('.png', '.jpg'))]
|
| 830 |
+
image_cols = st.slider("Image Gallery Columns πΌ (Shared)", min_value=1, max_value=15, value=5)
|
| 831 |
cols = st.columns(image_cols)
|
| 832 |
for idx, image_file in enumerate(shared_image_files):
|
| 833 |
with cols[idx % image_cols]:
|
| 834 |
+
st.image(image_file, use_container_width=True)
|
|
|
|
|
|
|
|
|
|
| 835 |
|
| 836 |
st.markdown("###### Video Gallery π₯")
|
| 837 |
shared_video_files = [f for f in shared_files if f.endswith('.mp4')]
|
| 838 |
+
video_cols = st.slider("Video Gallery Columns π¬ (Shared)", min_value=1, max_value=5, value=3)
|
| 839 |
cols = st.columns(video_cols)
|
| 840 |
for idx, video_file in enumerate(shared_video_files):
|
| 841 |
with cols[idx % video_cols]:
|
|
|
|
| 843 |
|
| 844 |
st.markdown("###### Audio Gallery π§")
|
| 845 |
shared_audio_files = [f for f in shared_files if f.endswith(('.mp3', '.wav'))]
|
| 846 |
+
audio_cols = st.slider("Audio Gallery Columns πΆ (Shared)", min_value=1, max_value=15, value=5)
|
| 847 |
cols = st.columns(audio_cols)
|
| 848 |
for idx, audio_file in enumerate(shared_audio_files):
|
| 849 |
with cols[idx % audio_cols]:
|
|
|
|
| 855 |
with open(CHAT_FILE, 'r') as f:
|
| 856 |
history_content = f.read()
|
| 857 |
st.markdown(history_content)
|
| 858 |
+
st.download_button("Download Chat Log as .md", history_content, file_name=f"chat_{st.session_state.user_id}.md", mime="text/markdown")
|
| 859 |
|
| 860 |
loop.run_until_complete(async_interface())
|
| 861 |
|