|
import streamlit as st |
|
import anthropic |
|
import os |
|
import base64 |
|
import glob |
|
import json |
|
import pytz |
|
from datetime import datetime |
|
from streamlit.components.v1 import html |
|
from PIL import Image |
|
import re |
|
from urllib.parse import quote |
|
|
|
|
|
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY")) |
|
|
|
|
|
if "chat_history" not in st.session_state: |
|
st.session_state.chat_history = [] |
|
|
|
|
|
def get_download_link(file_path): |
|
with open(file_path, "rb") as file: |
|
contents = file.read() |
|
b64 = base64.b64encode(contents).decode() |
|
file_name = os.path.basename(file_path) |
|
return f'<a href="data:file/txt;base64,{b64}" download="{file_name}">Download {file_name}</a>' |
|
|
|
|
|
def generate_filename(prompt, file_type): |
|
central = pytz.timezone('US/Central') |
|
safe_date_time = datetime.now(central).strftime("%m%d_%H%M") |
|
replaced_prompt = prompt.replace(" ", "_").replace("\n", "_") |
|
safe_prompt = "".join(x for x in replaced_prompt if x.isalnum() or x == "_")[:90] |
|
return f"{safe_date_time}_{safe_prompt}.{file_type}" |
|
|
|
|
|
def create_file(filename, prompt, response, should_save=True): |
|
if not should_save: |
|
return |
|
with open(filename, 'w', encoding='utf-8') as file: |
|
file.write(prompt + "\n\n" + response) |
|
|
|
|
|
def load_file(file_name): |
|
with open(file_name, "r", encoding='utf-8') as file: |
|
content = file.read() |
|
return content |
|
|
|
|
|
def display_glossary_entity(k): |
|
search_urls = { |
|
"๐๐ArXiv": lambda k: f"/?q={quote(k)}", |
|
"๐": lambda k: f"https://en.wikipedia.org/wiki/{quote(k)}", |
|
"๐": lambda k: f"https://www.google.com/search?q={quote(k)}", |
|
"๐ฅ": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}", |
|
} |
|
links_md = ' '.join([f"[{emoji}]({url(k)})" for emoji, url in search_urls.items()]) |
|
st.markdown(f"**{k}** <small>{links_md}</small>", unsafe_allow_html=True) |
|
|
|
|
|
def create_zip_of_files(files): |
|
import zipfile |
|
zip_name = "all_files.zip" |
|
with zipfile.ZipFile(zip_name, 'w') as zipf: |
|
for file in files: |
|
zipf.write(file) |
|
return zip_name |
|
|
|
|
|
def get_zip_download_link(zip_file): |
|
with open(zip_file, 'rb') as f: |
|
data = f.read() |
|
b64 = base64.b64encode(data).decode() |
|
href = f'<a href="data:application/zip;base64,{b64}" download="{zip_file}">Download All</a>' |
|
return href |
|
|
|
|
|
def get_video_html(video_path, width="100%"): |
|
video_url = f"data:video/mp4;base64,{base64.b64encode(open(video_path, 'rb').read()).decode()}" |
|
return f''' |
|
<video width="{width}" controls autoplay muted loop> |
|
<source src="{video_url}" type="video/mp4"> |
|
Your browser does not support the video tag. |
|
</video> |
|
''' |
|
|
|
|
|
def get_audio_html(audio_path, width="100%"): |
|
audio_url = f"data:audio/mpeg;base64,{base64.b64encode(open(audio_path, 'rb').read()).decode()}" |
|
return f''' |
|
<audio controls style="width: {width};"> |
|
<source src="{audio_url}" type="audio/mpeg"> |
|
Your browser does not support the audio element. |
|
</audio> |
|
''' |
|
|
|
|
|
|
|
|
|
def main(): |
|
|
|
|
|
st.sidebar.title("Claude 3.5 Sonnet") |
|
|
|
|
|
all_files = glob.glob("*.md") |
|
all_files = [file for file in all_files if len(os.path.splitext(file)[0]) >= 10] |
|
all_files.sort(key=lambda x: (os.path.splitext(x)[1], x), reverse=True) |
|
|
|
if st.sidebar.button("๐ Delete All"): |
|
for file in all_files: |
|
os.remove(file) |
|
st.rerun() |
|
|
|
if st.sidebar.button("โฌ๏ธ Download All"): |
|
zip_file = create_zip_of_files(all_files) |
|
st.sidebar.markdown(get_zip_download_link(zip_file), unsafe_allow_html=True) |
|
|
|
for file in all_files: |
|
col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1]) |
|
with col1: |
|
if st.button("๐", key="view_"+file): |
|
st.session_state.current_file = file |
|
st.session_state.file_content = load_file(file) |
|
with col2: |
|
st.markdown(get_download_link(file), unsafe_allow_html=True) |
|
with col3: |
|
if st.button("๐", key="edit_"+file): |
|
st.session_state.current_file = file |
|
st.session_state.file_content = load_file(file) |
|
with col4: |
|
if st.button("๐", key="delete_"+file): |
|
os.remove(file) |
|
st.rerun() |
|
|
|
|
|
user_input = st.text_area("Enter your message:", height=100) |
|
|
|
if st.button("Send"): |
|
if user_input: |
|
response = client.messages.create( |
|
model="claude-3-sonnet-20240229", |
|
max_tokens=1000, |
|
messages=[ |
|
{"role": "user", "content": user_input} |
|
] |
|
) |
|
|
|
st.write("Claude's response:") |
|
st.write(response.content[0].text) |
|
|
|
|
|
filename = generate_filename(user_input, "md") |
|
create_file(filename, user_input, response.content[0].text) |
|
|
|
|
|
st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text}) |
|
|
|
|
|
st.subheader("Chat History") |
|
for chat in st.session_state.chat_history: |
|
st.text_area("You:", chat["user"], height=100, disabled=True) |
|
st.text_area("Claude:", chat["claude"], height=200, disabled=True) |
|
st.markdown("---") |
|
|
|
|
|
if hasattr(st.session_state, 'current_file'): |
|
st.subheader(f"Editing: {st.session_state.current_file}") |
|
new_content = st.text_area("File Content:", st.session_state.file_content, height=300) |
|
if st.button("Save Changes"): |
|
with open(st.session_state.current_file, 'w', encoding='utf-8') as file: |
|
file.write(new_content) |
|
st.success("File updated successfully!") |
|
|
|
|
|
st.subheader("Image Gallery") |
|
image_files = glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.jpeg") |
|
image_cols = st.slider("Image Gallery Columns", min_value=1, max_value=5, value=3) |
|
cols = st.columns(image_cols) |
|
for idx, image_file in enumerate(image_files): |
|
with cols[idx % image_cols]: |
|
img = Image.open(image_file) |
|
st.image(img, caption=image_file, use_column_width=True) |
|
display_glossary_entity(os.path.splitext(image_file)[0]) |
|
|
|
|
|
st.subheader("Video Gallery") |
|
video_files = glob.glob("*.mp4") |
|
video_cols = st.slider("Video Gallery Columns", min_value=1, max_value=5, value=3) |
|
cols = st.columns(video_cols) |
|
for idx, video_file in enumerate(video_files): |
|
with cols[idx % video_cols]: |
|
st.markdown(get_video_html(video_file, width="100%"), unsafe_allow_html=True) |
|
display_glossary_entity(os.path.splitext(video_file)[0]) |
|
|
|
|
|
st.subheader("Audio Gallery") |
|
audio_files = glob.glob("*.mp3") + glob.glob("*.wav") |
|
audio_cols = st.slider("Audio Gallery Columns", min_value=1, max_value=5, value=3) |
|
cols = st.columns(audio_cols) |
|
for idx, audio_file in enumerate(audio_files): |
|
with cols[idx % audio_cols]: |
|
st.markdown(get_audio_html(audio_file, width="100%"), unsafe_allow_html=True) |
|
display_glossary_entity(os.path.splitext(audio_file)[0]) |
|
|
|
if __name__ == "__main__": |
|
main() |