awacke1 commited on
Commit
c1728eb
Β·
verified Β·
1 Parent(s): 3d5422f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +204 -408
app.py CHANGED
@@ -1,419 +1,215 @@
1
  import streamlit as st
2
- import asyncio
3
- import websockets
4
- import uuid
5
- import argparse
6
- from datetime import datetime
7
  import os
8
- import random
9
- import time
10
- import hashlib
11
-
12
- # Fun usernames with emojis - the VIP list of quirky characters! πŸŽ‰πŸ˜œ
13
- FUN_USERNAMES = [
14
- "CosmicJester 🌌", "PixelPanda 🐼", "QuantumQuack πŸ¦†", "StellarSquirrel 🐿️",
15
- "GizmoGuru βš™οΈ", "NebulaNinja 🌠", "ByteBuster πŸ’Ύ", "GalacticGopher 🌍",
16
- "RocketRaccoon πŸš€", "EchoElf 🧝", "PhantomFox 🦊", "WittyWizard πŸ§™",
17
- "LunarLlama πŸŒ™", "SolarSloth β˜€οΈ", "AstroAlpaca πŸ¦™", "CyberCoyote 🐺",
18
- "MysticMoose 🦌", "GlitchGnome 🧚", "VortexViper 🐍", "ChronoChimp πŸ’"
19
- ]
20
-
21
- # Directories for chat and votes - the secret vaults where tales and tallies are stashed! πŸ—„οΈπŸ”’
22
- CHAT_DIR = "chat_logs"
23
- VOTE_DIR = "vote_logs"
24
- os.makedirs(CHAT_DIR, exist_ok=True)
25
- os.makedirs(VOTE_DIR, exist_ok=True)
26
-
27
- # Persistent files - the grand tomes of chatter and votes! πŸ“–βœ¨
28
- CHAT_FILE = os.path.join(CHAT_DIR, "global_chat.md")
29
- QUOTE_VOTES_FILE = os.path.join(VOTE_DIR, "quote_votes.md")
30
- IMAGE_VOTES_FILE = os.path.join(VOTE_DIR, "image_votes.md")
31
- HISTORY_FILE = os.path.join(VOTE_DIR, "vote_history.md")
32
-
33
- # Unicode digit conversion table - the magic map for emoji numbers! πŸ”’βœ¨
34
- UNICODE_DIGITS = {
35
- 0: "0️⃣", 1: "1️⃣", 2: "2️⃣", 3: "3️⃣", 4: "4️⃣",
36
- 5: "5️⃣", 6: "6️⃣", 7: "7️⃣", 8: "8️⃣", 9: "9️⃣"
37
- }
38
-
39
- # Unicode font examples - the stylish wardrobe of text flair! πŸ‘—πŸ“
40
- UNICODE_FONTS = [
41
- ("Normal", lambda x: x),
42
- ("Bold", lambda x: "".join(chr(ord(c) + 0x1D400 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D41A - 0x61) if 'a' <= c <= 'z' else c for c in x)),
43
- ("Italic", lambda x: "".join(chr(ord(c) + 0x1D434 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D44E - 0x61) if 'a' <= c <= 'z' else c for c in x)),
44
- ("Script", lambda x: "".join(chr(ord(c) + 0x1D49C - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D4B6 - 0x61) if 'a' <= c <= 'z' else c for c in x)),
45
- ("Fraktur", lambda x: "".join(chr(ord(c) + 0x1D504 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D51E - 0x61) if 'a' <= c <= 'z' else c for c in x)),
46
- ("Double Struck", lambda x: "".join(chr(ord(c) + 0x1D538 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D552 - 0x61) if 'a' <= c <= 'z' else c for c in x)),
47
- ("Sans Serif", lambda x: "".join(chr(ord(c) + 0x1D5A0 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D5BA - 0x61) if 'a' <= c <= 'z' else c for c in x)),
48
- ("Sans Bold", lambda x: "".join(chr(ord(c) + 0x1D5D4 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D5EE - 0x61) if 'a' <= c <= 'z' else c for c in x)),
49
- ("Mono", lambda x: "".join(chr(ord(c) + 0x1D670 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D68A - 0x61) if 'a' <= c <= 'z' else c for c in x)),
50
- ("Circle", lambda x: "".join(chr(ord(c) + 0x24B6 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x24D0 - 0x61) if 'a' <= c <= 'z' else c for c in x))
51
- ]
52
-
53
- # Node name - the app’s codename generator, sneaky and slick! πŸ•΅οΈβ€β™‚οΈπŸ’Ύ
54
- def get_node_name():
55
- """🎲 Spins the wheel of fate to name our node - a random alias or user pick! 🏷️"""
56
- parser = argparse.ArgumentParser(description='Start a chat node with a specific name')
57
- parser.add_argument('--node-name', type=str, default=None, help='Name for this chat node')
58
- parser.add_argument('--port', type=int, default=8501, help='Port to run the Streamlit interface on')
59
- args = parser.parse_args()
60
- return args.node_name or f"node-{uuid.uuid4().hex[:8]}", args.port
61
-
62
- # Chat saver - the scribe etching epic messages into the eternal scroll! πŸ–‹οΈπŸ“œ
63
- def save_chat_entry(username, message):
64
- """πŸ–ŒοΈ Carves a chat line into the grand Markdown tome - history in the making! πŸ›οΈ"""
65
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
66
- entry = f"[{timestamp}] {username}: {message}"
67
- try:
68
- with open(CHAT_FILE, 'a') as f:
69
- f.write(f"{entry}\n")
70
- return True
71
- except Exception as e:
72
- print(f"Oops! Failed to save chat: {e}")
73
- return False
74
-
75
- # Chat loader - the archaeologist unearthing the chat saga! β›οΈπŸ“š
76
- def load_chat():
77
- """πŸ” Digs up the chat treasure from the filesystem - tales of old and new! πŸ’°"""
78
- if not os.path.exists(CHAT_FILE):
79
- with open(CHAT_FILE, 'w') as f:
80
- f.write("# Sector Chat 🌌\n\nWelcome to the cosmic hub - start chatting! 🎀\n")
81
- try:
82
- with open(CHAT_FILE, 'r') as f:
83
- content = f.read()
84
- lines = content.strip().split('\n')
85
- numbered_content = "\n".join(f"{i+1}. {line}" for i, line in enumerate(lines) if line.strip())
86
- return numbered_content
87
- except Exception as e:
88
- print(f"Chat load hiccup: {e}")
89
- return "# Error loading chat\nSomething went wonky! 😡"
90
-
91
- # User list grabber - the social butterfly spotting all the chatters! πŸ¦‹πŸ‘₯
92
- def get_user_list(chat_content):
93
- """πŸ‘€ Peeks at the chat to spot all the cool cats talking - who’s in the club? 🎸"""
94
- users = set()
95
- for line in chat_content.split('\n'):
96
- if line.strip() and ': ' in line:
97
- user = line.split(': ')[1].split(' ')[0]
98
- users.add(user)
99
- return sorted(list(users))
100
-
101
- # Quote loader - the sage pulling wisdom from the ages! πŸ“œπŸ§™
102
- def load_quotes(source="famous"):
103
- """πŸ“š Grabs a stack of wise words from famous folks or custom quips! πŸ—£οΈ"""
104
- famous_quotes = [
105
- "The true sign of intelligence is not knowledge but imagination. – Albert Einstein",
106
- "I have not failed. I've just found 10,000 ways that won't work. – Thomas Edison",
107
- "Innovation distinguishes between a leader and a follower. – Steve Jobs",
108
- "Research is what I'm doing when I don't know what I'm doing. – Wernher von Braun",
109
- "The only way to discover the limits of the possible is to go beyond them into the impossible. – Arthur C. Clarke",
110
- "Success is a science; if you have the conditions, you get the result. – Oscar Wilde",
111
- "An expert is a person who has made all the mistakes that can be made in a very narrow field. – Niels Bohr",
112
- "The important thing is to not stop questioning. Curiosity has its own reason for existing. – Albert Einstein",
113
- "The best way to predict the future is to invent it. – Alan Kay",
114
- "If I have seen further it is by standing on the shoulders of Giants. – Isaac Newton",
115
- "Logic will get you from A to B. Imagination will take you everywhere. – Albert Einstein",
116
- "Imagination is more important than knowledge. Knowledge is limited. Imagination encircles the world. – Albert Einstein",
117
- "Science is a way of thinking much more than it is a body of knowledge. – Carl Sagan",
118
- "We cannot solve our problems with the same thinking we used when we created them. – Albert Einstein",
119
- "The true method of knowledge is experiment. – William Blake",
120
- "The scientist is not a person who gives the right answers, he's one who asks the right questions. – Claude Levi-Strauss",
121
- "It's kind of fun to do the impossible. – Walt Disney",
122
- "Any sufficiently advanced technology is indistinguishable from magic. – Arthur C. Clarke",
123
- "Creativity is intelligence having fun. – Albert Einstein",
124
- "To invent, you need a good imagination and a pile of junk. – Thomas Edison"
125
- ]
126
- custom_quotes = [
127
- "Every age unfolds a new lesson. Life's chapters evolve, each teaching us anew.",
128
- "From infancy to twilight, our journey is painted in growth. Every stage shines with its own wisdom.",
129
- "Love is the universal language, transcending boundaries and touching souls.",
130
- "Through love, we find connection, unity, and the essence of existence."
131
- ]
132
- quotes = famous_quotes if source == "famous" else custom_quotes
133
- return quotes if quotes else ["No quotes available - check back later! πŸ“­"]
134
-
135
- # Vote saver - the tally keeper counting thumbs up! πŸ‘πŸ“Š
136
- def save_vote(file, item, user_hash):
137
- """✍️ Tallies a vote in the grand ledger - your opinion matters! πŸ—³οΈ"""
138
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
139
- entry = f"[{timestamp}] {user_hash} voted for {item}"
140
- try:
141
- with open(file, 'a') as f:
142
- f.write(f"{entry}\n")
143
- with open(HISTORY_FILE, 'a') as f:
144
- f.write(f"- {timestamp} - User {user_hash} voted for {item}\n")
145
- return True
146
- except Exception as e:
147
- print(f"Vote save flop: {e}")
148
- return False
149
-
150
- # Vote loader - the scorekeeper tallying the crowd’s cheers! πŸŽ‰πŸ…
151
- def load_votes(file):
152
- """πŸ“ˆ Counts the votes from the ledger - who’s winning the popularity contest? πŸ†"""
153
- if not os.path.exists(file):
154
- with open(file, 'w') as f:
155
- f.write("# Vote Tally\n\nNo votes yet - get clicking! πŸ–±οΈ\n")
156
- try:
157
- with open(file, 'r') as f:
158
- lines = f.read().strip().split('\n')
159
- votes = {}
160
- for line in lines[2:]: # Skip header
161
- if line.strip() and 'voted for' in line:
162
- item = line.split('voted for ')[1]
163
- votes[item] = votes.get(item, 0) + 1
164
- return votes
165
- except Exception as e:
166
- print(f"Vote load oopsie: {e}")
167
- return {}
168
-
169
- # User hash generator - the secret agent giving you a cool code! πŸ•΅οΈβ€β™‚οΈπŸ”‘
170
- def generate_user_hash():
171
- """πŸ•΅οΈ Crafts a snazzy 8-digit ID badge - you’re in the club now! 🎟️"""
172
- if 'user_hash' not in st.session_state:
173
- session_id = str(random.getrandbits(128))
174
- hash_object = hashlib.md5(session_id.encode())
175
- st.session_state['user_hash'] = hash_object.hexdigest()[:8]
176
- return st.session_state['user_hash']
177
-
178
- active_connections = {}
179
-
180
- # WebSocket handler - the bouncer at the chat rave, keeping it hopping! πŸŽ‰πŸšͺ
181
- async def websocket_handler(websocket, path):
182
- """🎧 Guards the chat gate, letting messages fly and booting crashers! 🚨"""
183
- try:
184
- client_id = str(uuid.uuid4())
185
- room_id = "chat"
186
- active_connections.setdefault(room_id, {})[client_id] = websocket
187
- print(f"Client {client_id} joined the chat party!")
188
- # Auto-join message
189
- username = st.session_state.username if 'username' in st.session_state else random.choice(FUN_USERNAMES)
190
- save_chat_entry("System 🌟", f"{username} has joined Sector 🌌!")
191
-
192
- async for message in websocket:
193
- try:
194
- parts = message.split('|', 1)
195
- if len(parts) == 2:
196
- username, content = parts
197
- save_chat_entry(username, content)
198
- await broadcast_message(f"{username}|{content}", room_id)
199
- except Exception as e:
200
- print(f"Message mishap: {e}")
201
- await websocket.send(f"ERROR|Oops, bad message format! 😬")
202
- except websockets.ConnectionClosed:
203
- print(f"Client {client_id} bailed from the chat!")
204
- finally:
205
- if room_id in active_connections and client_id in active_connections[room_id]:
206
- del active_connections[room_id][client_id]
207
- if not active_connections[room_id]:
208
- del active_connections[room_id]
209
-
210
- # Broadcaster - the megaphone blasting chat vibes to all! πŸ“£πŸŽΆ
211
- async def broadcast_message(message, room_id):
212
- """πŸ“’ Shouts the latest chat beat to every dancer in the room - hear it loud! 🎡"""
213
- if room_id in active_connections:
214
- disconnected = []
215
- for client_id, ws in active_connections[room_id].items():
216
- try:
217
- await ws.send(message)
218
- except websockets.ConnectionClosed:
219
- disconnected.append(client_id)
220
- for client_id in disconnected:
221
- del active_connections[room_id][client_id]
222
-
223
- # WebSocket starter - the DJ spinning up the chat tunes! 🎧πŸ”₯
224
- async def start_websocket_server(host='0.0.0.0', port=8765):
225
- """🌐 Cranks up the WebSocket jukebox, ready to rock the chat scene! 🎸"""
226
- server = await websockets.serve(websocket_handler, host, port)
227
- print(f"WebSocket server jamming on ws://{host}:{port}")
228
- return server
229
-
230
- # Chat interface maker - the stage builder for our chat extravaganza! 🎭🏟️
231
- def create_streamlit_interface(initial_username):
232
- """πŸ–ŒοΈ Sets up the chat stage with live updates, pulsing timers, voting, and refresh flair! 🌟"""
233
- # Custom CSS for a sleek chat box and timer
234
- st.markdown("""
235
- <style>
236
- .chat-box {
237
- font-family: monospace;
238
- background: #1e1e1e;
239
- color: #d4d4d4;
240
- padding: 10px;
241
- border-radius: 5px;
242
- height: 300px;
243
- overflow-y: auto;
244
- }
245
- .timer {
246
- font-size: 24px;
247
- color: #ffcc00;
248
- text-align: center;
249
- animation: pulse 1s infinite;
250
- }
251
- @keyframes pulse {
252
- 0% { transform: scale(1); }
253
- 50% { transform: scale(1.1); }
254
- 100% { transform: scale(1); }
255
- }
256
- </style>
257
- """, unsafe_allow_html=True)
258
-
259
- # Title and intro
260
- st.title(f"Chat & Quote Node: {NODE_NAME}")
261
- st.markdown("Welcome to Sector 🌌 - chat, vote, and watch the timer pulse! πŸŽ‰")
262
-
263
- # Session state initialization
264
- if 'username' not in st.session_state:
265
- st.session_state.username = initial_username
266
- save_chat_entry("System 🌟", f"{initial_username} has joined Sector 🌌!")
267
- if 'refresh_rate' not in st.session_state:
268
- st.session_state.refresh_rate = 5
269
- if 'last_refresh' not in st.session_state:
270
- st.session_state.last_refresh = time.time()
271
- if 'timer_start' not in st.session_state:
272
- st.session_state.timer_start = time.time() # Autostart timer
273
- if 'quote_index' not in st.session_state:
274
- quotes = load_quotes("famous")
275
- st.session_state.quote_index = random.randint(0, max(0, len(quotes) - 1)) if quotes else 0
276
- if 'quote_source' not in st.session_state:
277
- st.session_state.quote_source = "famous"
278
-
279
- # Chat section
280
- st.subheader("Sector Chat 🌌")
281
- chat_content = load_chat()
282
- chat_lines = chat_content.split('\n')
283
- for i, line in enumerate(chat_lines):
284
- if line.strip() and ': ' in line:
285
- col1, col2 = st.columns([5, 1])
286
- with col1:
287
- st.markdown(line)
288
- with col2:
289
- if st.button(f"πŸ‘", key=f"chat_vote_{i}"):
290
- user_hash = generate_user_hash()
291
- save_vote(QUOTE_VOTES_FILE, line, user_hash)
292
- st.session_state.timer_start = time.time()
293
- st.rerun()
294
-
295
- user_list = get_user_list(chat_content)
296
- new_username = st.selectbox("Switch User", user_list + [st.session_state.username], index=len(user_list))
297
- if new_username != st.session_state.username:
298
- save_chat_entry("System 🌟", f"{st.session_state.username} switched to {new_username} in Sector 🌌!")
299
- st.session_state.username = new_username
300
- st.session_state.timer_start = time.time()
301
-
302
- message = st.text_input("Message", placeholder="Type your epic line here! ✍️")
303
- if st.button("Send πŸš€") and message.strip():
304
- save_chat_entry(st.session_state.username, message)
305
- st.session_state.timer_start = time.time()
306
  st.rerun()
307
 
308
- # Quote section
309
- st.subheader("Quote of the Moment πŸ“")
310
- quotes = load_quotes(st.session_state.quote_source)
311
- if quotes:
312
- st.session_state.quote_index = st.session_state.quote_index % len(quotes)
313
- quote = quotes[st.session_state.quote_index]
314
- col1, col2 = st.columns([5, 1])
315
- with col1:
316
- st.markdown(quote)
317
- with col2:
318
- if st.button("πŸ‘ Upvote", key="quote_vote"):
319
- user_hash = generate_user_hash()
320
- save_vote(QUOTE_VOTES_FILE, quote, user_hash)
321
- st.session_state.timer_start = time.time()
322
- st.rerun()
323
- if time.time() - st.session_state.last_refresh > 10:
324
- st.session_state.quote_index = (st.session_state.quote_index + 1) % len(quotes)
325
- st.session_state.quote_source = "custom" if st.session_state.quote_source == "famous" else "famous"
326
- quotes = load_quotes(st.session_state.quote_source)
327
- st.session_state.quote_index = st.session_state.quote_index % len(quotes) if quotes else 0
328
- st.session_state.last_refresh = time.time()
329
- st.rerun()
330
- else:
331
- st.markdown("No quotes available - check back later! πŸ“­")
332
 
333
- # Image voting section
334
- st.subheader("Image Voting πŸ–ΌοΈ")
335
- image_dir = '.'
336
- valid_extensions = ('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff', '.webp')
337
- images = [f for f in os.listdir(image_dir) if f.lower().endswith(valid_extensions)]
338
- if len(images) >= 2:
339
- image1, image2 = random.sample(images, 2)
340
- col1, col2 = st.columns(2)
341
  with col1:
342
- st.image(os.path.join(image_dir, image1))
343
- if st.button(f"πŸ‘ Upvote {image1}", key=f"img_vote_{image1}"):
344
- user_hash = generate_user_hash()
345
- save_vote(IMAGE_VOTES_FILE, image1, user_hash)
346
- st.session_state.timer_start = time.time()
347
- st.rerun()
348
  with col2:
349
- st.image(os.path.join(image_dir, image2))
350
- if st.button(f"πŸ‘ Upvote {image2}", key=f"img_vote_{image2}"):
351
- user_hash = generate_user_hash()
352
- save_vote(IMAGE_VOTES_FILE, image2, user_hash)
353
- st.session_state.timer_start = time.time()
 
 
 
354
  st.rerun()
355
- else:
356
- st.error("Need at least 2 images in the directory for voting!")
357
-
358
- # Refresh rate controls with pulsing timer
359
- st.subheader("Set Refresh Rate ⏳")
360
- refresh_rate = st.slider("Refresh Rate (seconds)", min_value=1, max_value=300, value=st.session_state.refresh_rate, step=1)
361
- if refresh_rate != st.session_state.refresh_rate:
362
- st.session_state.refresh_rate = refresh_rate
363
- st.session_state.timer_start = time.time()
364
-
365
- col1, col2, col3 = st.columns(3)
366
- with col1:
367
- if st.button("πŸ‡ Small (1s)"):
368
- st.session_state.refresh_rate = 1
369
- st.session_state.timer_start = time.time()
370
- with col2:
371
- if st.button("🐒 Medium (5s)"):
372
- st.session_state.refresh_rate = 5
373
- st.session_state.timer_start = time.time()
374
- with col3:
375
- if st.button("🐘 Large (5m)"):
376
- st.session_state.refresh_rate = 300
377
- st.session_state.timer_start = time.time()
378
-
379
- # Pulsing countdown timer with emoji digits and random Unicode font
380
- timer_placeholder = st.empty()
381
- start_time = st.session_state.timer_start
382
- while True:
383
- elapsed = int(time.time() - start_time)
384
- remaining = max(0, st.session_state.refresh_rate - elapsed)
385
- font_name, font_func = random.choice(UNICODE_FONTS)
386
- countdown_str = "".join(UNICODE_DIGITS[int(d)] for d in str(remaining)) if remaining < 10 else font_func(str(remaining))
387
- timer_emoji = "⏳" if elapsed % 2 == 0 else "πŸ’“" # Pulse effect
388
- timer_placeholder.markdown(f"<p class='timer'>{timer_emoji} {font_func('Next refresh in:')} {countdown_str} {font_func('seconds')}</p>", unsafe_allow_html=True)
389
- if remaining == 0:
390
- st.session_state.last_refresh = time.time()
391
- st.session_state.timer_start = time.time()
392
- st.rerun()
393
- break
394
- time.sleep(1) # Pulse every second
395
-
396
- # Sidebar vote stats
397
- st.sidebar.subheader("Vote Totals")
398
- chat_votes = load_votes(QUOTE_VOTES_FILE)
399
- image_votes = load_votes(IMAGE_VOTES_FILE)
400
- for item, count in chat_votes.items():
401
- st.sidebar.write(f"{item}: {count} votes")
402
- for image, count in image_votes.items():
403
- st.sidebar.write(f"{image}: {count} votes")
404
-
405
- # Main event - the ringmaster kicking off the chat circus! πŸŽͺ🀑
406
- async def main():
407
- """🎀 Drops the mic and starts the chat party - it’s showtime, folks! πŸŽ‰"""
408
- global NODE_NAME
409
- NODE_NAME, port = get_node_name()
410
- await start_websocket_server()
411
-
412
- query_params = st.query_params if hasattr(st, 'query_params') else {}
413
- initial_username = query_params.get("username", random.choice(FUN_USERNAMES)) if query_params else random.choice(FUN_USERNAMES)
414
- print(f"Welcoming {initial_username} to the chat bash!")
415
 
416
- create_streamlit_interface(initial_username)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
 
418
  if __name__ == "__main__":
419
- asyncio.run(main())
 
1
  import streamlit as st
2
+ import anthropic
 
 
 
 
3
  import os
4
+ import base64
5
+ import glob
6
+ import json
7
+ import pytz
8
+ from datetime import datetime
9
+ from streamlit.components.v1 import html
10
+ from PIL import Image
11
+ import re
12
+ from urllib.parse import quote
13
+
14
+ # 1. App Configuration
15
+ Site_Name = 'πŸ€–πŸ§ Claude35πŸ“πŸ”¬'
16
+ title="πŸ€–πŸ§ Claude35πŸ“πŸ”¬"
17
+ helpURL='https://huggingface.co/awacke1'
18
+ bugURL='https://huggingface.co/spaces/awacke1'
19
+ icons='πŸ€–πŸ§ πŸ”¬πŸ“'
20
+
21
+ st.set_page_config(
22
+ page_title=title,
23
+ page_icon=icons,
24
+ layout="wide",
25
+ initial_sidebar_state="auto",
26
+ menu_items={
27
+ 'Get Help': helpURL,
28
+ 'Report a bug': bugURL,
29
+ 'About': title
30
+ }
31
+ )
32
+
33
+ # Set up the Anthropic client
34
+ client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
35
+
36
+ # Initialize session state
37
+ if "chat_history" not in st.session_state:
38
+ st.session_state.chat_history = []
39
+
40
+ # Helper Functions: All Your Essentials πŸš€
41
+
42
+ # Function to get a file download link (because you deserve easy downloads 😎)
43
+ def get_download_link(file_path):
44
+ with open(file_path, "rb") as file:
45
+ contents = file.read()
46
+ b64 = base64.b64encode(contents).decode()
47
+ file_name = os.path.basename(file_path)
48
+ return f'<a href="data:file/txt;base64,{b64}" download="{file_name}">Download {file_name}πŸ“‚</a>'
49
+
50
+ # Function to generate a filename based on prompt and time (because names matter πŸ•’)
51
+ def generate_filename(prompt, file_type):
52
+ central = pytz.timezone('US/Central')
53
+ safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
54
+ safe_prompt = re.sub(r'\W+', '_', prompt)[:90]
55
+ return f"{safe_date_time}_{safe_prompt}.{file_type}"
56
+
57
+ # Function to create and save a file (and avoid the black hole of lost data πŸ•³)
58
+ def create_file(filename, prompt, response, should_save=True):
59
+ if not should_save:
60
+ return
61
+ with open(filename, 'w', encoding='utf-8') as file:
62
+ file.write(prompt + "\n\n" + response)
63
+
64
+ # Function to load file content (for revisiting the past πŸ“œ)
65
+ def load_file(file_name):
66
+ with open(file_name, "r", encoding='utf-8') as file:
67
+ content = file.read()
68
+ return content
69
+
70
+ # Function to display handy glossary entity links (search like a pro πŸ”)
71
+ def display_glossary_entity(k):
72
+ search_urls = {
73
+ "πŸš€πŸŒŒArXiv": lambda k: f"/?q={quote(k)}",
74
+ "πŸ“–": lambda k: f"https://en.wikipedia.org/wiki/{quote(k)}",
75
+ "πŸ”": lambda k: f"https://www.google.com/search?q={quote(k)}",
76
+ "πŸŽ₯": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
77
+ }
78
+ links_md = ' '.join([f"[{emoji}]({url(k)})" for emoji, url in search_urls.items()])
79
+ st.markdown(f"**{k}** <small>{links_md}</small>", unsafe_allow_html=True)
80
+
81
+ # Function to create zip of files (because more is more 🧳)
82
+ def create_zip_of_files(files):
83
+ import zipfile
84
+ zip_name = "all_files.zip"
85
+ with zipfile.ZipFile(zip_name, 'w') as zipf:
86
+ for file in files:
87
+ zipf.write(file)
88
+ return zip_name
89
+
90
+ # Function to create HTML for autoplaying and looping video (for the full cinematic effect πŸŽ₯)
91
+ def get_video_html(video_path, width="100%"):
92
+ video_url = f"data:video/mp4;base64,{base64.b64encode(open(video_path, 'rb').read()).decode()}"
93
+ return f'''
94
+ <video width="{width}" controls autoplay muted loop>
95
+ <source src="{video_url}" type="video/mp4">
96
+ Your browser does not support the video tag.
97
+ </video>
98
+ '''
99
+
100
+ # Function to create HTML for audio player (when life needs a soundtrack 🎢)
101
+ def get_audio_html(audio_path, width="100%"):
102
+ audio_url = f"data:audio/mpeg;base64,{base64.b64encode(open(audio_path, 'rb').read()).decode()}"
103
+ return f'''
104
+ <audio controls style="width: {width};">
105
+ <source src="{audio_url}" type="audio/mpeg">
106
+ Your browser does not support the audio element.
107
+ </audio>
108
+ '''
109
+
110
+
111
+ # Streamlit App Layout (like a house with better flow 🏑)
112
+ def main():
113
+
114
+ # Sidebar with Useful Controls (All the VIP actions πŸŽ›)
115
+ st.sidebar.title("🧠ClaudeπŸ“")
116
+
117
+ all_files = glob.glob("*.md")
118
+ all_files.sort(reverse=True)
119
+
120
+ if st.sidebar.button("πŸ—‘ Delete All"):
121
+ for file in all_files:
122
+ os.remove(file)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  st.rerun()
124
 
125
+ if st.sidebar.button("⬇️ Download All"):
126
+ zip_file = create_zip_of_files(all_files)
127
+ st.sidebar.markdown(get_download_link(zip_file), unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
+ for file in all_files:
130
+ col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
 
 
 
 
 
 
131
  with col1:
132
+ if st.button("🌐", key="view_"+file):
133
+ st.session_state.current_file = file
134
+ st.session_state.file_content = load_file(file)
 
 
 
135
  with col2:
136
+ st.markdown(get_download_link(file), unsafe_allow_html=True)
137
+ with col3:
138
+ if st.button("πŸ“‚", key="edit_"+file):
139
+ st.session_state.current_file = file
140
+ st.session_state.file_content = load_file(file)
141
+ with col4:
142
+ if st.button("πŸ—‘", key="delete_"+file):
143
+ os.remove(file)
144
  st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
+ # Main Area: Chat with Claude (He’s a good listener πŸ’¬)
147
+ user_input = st.text_area("Message πŸ“¨:", height=100)
148
+
149
+ if st.button("Send πŸ“¨"):
150
+ if user_input:
151
+ response = client.messages.create(
152
+ model="claude-3-sonnet-20240229",
153
+ max_tokens=1000,
154
+ messages=[
155
+ {"role": "user", "content": user_input}
156
+ ]
157
+ )
158
+ st.write("Claude's reply 🧠:")
159
+ st.write(response.content[0].text)
160
+
161
+ filename = generate_filename(user_input, "md")
162
+ create_file(filename, user_input, response.content[0].text)
163
+
164
+ st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text})
165
+
166
+ # Display Chat History (Never forget a good chat πŸ’­)
167
+ st.subheader("Past Conversations πŸ“œ")
168
+ for chat in st.session_state.chat_history:
169
+ st.text_area("You said πŸ’¬:", chat["user"], height=100, disabled=True)
170
+ st.text_area("Claude replied πŸ€–:", chat["claude"], height=200, disabled=True)
171
+ st.markdown("---")
172
+
173
+ # File Editor (When you need to tweak things ✏️)
174
+ if hasattr(st.session_state, 'current_file'):
175
+ st.subheader(f"Editing: {st.session_state.current_file} πŸ› ")
176
+ new_content = st.text_area("File Content ✏️:", st.session_state.file_content, height=300)
177
+ if st.button("Save Changes πŸ’Ύ"):
178
+ with open(st.session_state.current_file, 'w', encoding='utf-8') as file:
179
+ file.write(new_content)
180
+ st.success("File updated successfully! πŸŽ‰")
181
+
182
+ # Image Gallery (For your viewing pleasure πŸ“Έ)
183
+ st.subheader("Image Gallery πŸ–Ό")
184
+ image_files = glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.jpeg")
185
+ image_cols = st.slider("Gallery Columns πŸ–Ό", min_value=1, max_value=15, value=5)
186
+ cols = st.columns(image_cols)
187
+ for idx, image_file in enumerate(image_files):
188
+ with cols[idx % image_cols]:
189
+ img = Image.open(image_file)
190
+ #st.image(img, caption=image_file, use_container_width=True)
191
+ st.image(img, use_container_width=True)
192
+ display_glossary_entity(os.path.splitext(image_file)[0])
193
+
194
+ # Video Gallery (Let’s roll the tapes 🎬)
195
+ st.subheader("Video Gallery πŸŽ₯")
196
+ video_files = glob.glob("*.mp4")
197
+ video_cols = st.slider("Gallery Columns 🎬", min_value=1, max_value=5, value=3)
198
+ cols = st.columns(video_cols)
199
+ for idx, video_file in enumerate(video_files):
200
+ with cols[idx % video_cols]:
201
+ st.markdown(get_video_html(video_file, width="100%"), unsafe_allow_html=True)
202
+ display_glossary_entity(os.path.splitext(video_file)[0])
203
+
204
+ # Audio Gallery (Tunes for the mood 🎢)
205
+ st.subheader("Audio Gallery 🎧")
206
+ audio_files = glob.glob("*.mp3") + glob.glob("*.wav")
207
+ audio_cols = st.slider("Gallery Columns 🎢", min_value=1, max_value=15, value=5)
208
+ cols = st.columns(audio_cols)
209
+ for idx, audio_file in enumerate(audio_files):
210
+ with cols[idx % audio_cols]:
211
+ st.markdown(get_audio_html(audio_file, width="100%"), unsafe_allow_html=True)
212
+ display_glossary_entity(os.path.splitext(audio_file)[0])
213
 
214
  if __name__ == "__main__":
215
+ main()