|
import streamlit as st |
|
import asyncio |
|
import websockets |
|
import uuid |
|
import argparse |
|
from datetime import datetime |
|
import os |
|
import random |
|
import time |
|
import hashlib |
|
from PIL import Image |
|
import glob |
|
import re |
|
from urllib.parse import quote |
|
import base64 |
|
import io |
|
|
|
|
|
Site_Name = '🤖🧠Chat & Quote Node📝🔬' |
|
title = "🤖🧠Chat & Quote Node📝🔬" |
|
icons = '🤖🧠🔬📝' |
|
START_ROOM = "Sector 🌌" |
|
|
|
st.set_page_config( |
|
page_title=title, |
|
page_icon=icons, |
|
layout="wide", |
|
initial_sidebar_state="auto" |
|
) |
|
|
|
|
|
FUN_USERNAMES = { |
|
"CosmicJester 🌌": "Jest Best", |
|
"PixelPanda 🐼": "Panda Dandy", |
|
"QuantumQuack 🦆": "Quack Pack", |
|
"StellarSquirrel 🐿️": "Squirrel Whirl", |
|
"GizmoGuru ⚙️": "Guru Brew", |
|
"NebulaNinja 🌠": "Ninja Zinger", |
|
"ByteBuster 💾": "Buster Cluster", |
|
"GalacticGopher 🌍": "Gopher Loafer", |
|
"RocketRaccoon 🚀": "Raccoon Zoom", |
|
"EchoElf 🧝": "Elf Shelf", |
|
"PhantomFox 🦊": "Fox Rocks", |
|
"WittyWizard 🧙": "Wizard Blizzard", |
|
"LunarLlama 🌙": "Llama Drama", |
|
"SolarSloth ☀️": "Sloth Growth", |
|
"AstroAlpaca 🦙": "Alpaca Plaque", |
|
"CyberCoyote 🐺": "Coyote Byte", |
|
"MysticMoose 🦌": "Moose Juice", |
|
"GlitchGnome 🧚": "Gnome Roam", |
|
"VortexViper 🐍": "Viper Hyper", |
|
"ChronoChimp 🐒": "Chimp Whimp" |
|
} |
|
|
|
|
|
CHAT_DIR = "chat_logs" |
|
VOTE_DIR = "vote_logs" |
|
STATE_FILE = "user_state.txt" |
|
os.makedirs(CHAT_DIR, exist_ok=True) |
|
os.makedirs(VOTE_DIR, exist_ok=True) |
|
|
|
|
|
CHAT_FILE = os.path.join(CHAT_DIR, "global_chat.md") |
|
QUOTE_VOTES_FILE = os.path.join(VOTE_DIR, "quote_votes.md") |
|
IMAGE_VOTES_FILE = os.path.join(VOTE_DIR, "image_votes.md") |
|
HISTORY_FILE = os.path.join(VOTE_DIR, "vote_history.md") |
|
|
|
|
|
UNICODE_DIGITS = { |
|
0: "0️⃣", 1: "1️⃣", 2: "2️⃣", 3: "3️⃣", 4: "4️⃣", |
|
5: "5️⃣", 6: "6️⃣", 7: "7️⃣", 8: "8️⃣", 9: "9️⃣" |
|
} |
|
|
|
|
|
UNICODE_FONTS = [ |
|
("Normal", lambda x: x), |
|
("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)), |
|
("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)), |
|
("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)), |
|
("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)), |
|
("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)), |
|
("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)), |
|
("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)), |
|
("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)), |
|
("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)) |
|
] |
|
|
|
|
|
server_running = False |
|
server_task = None |
|
|
|
|
|
def get_node_name(): |
|
"""🎲 Spins the wheel of fate to name our node - a random alias or user pick! 🏷️""" |
|
parser = argparse.ArgumentParser(description='Start a chat node with a specific name') |
|
parser.add_argument('--node-name', type=str, default=None, help='Name for this chat node') |
|
parser.add_argument('--port', type=int, default=8501, help='Port to run the Streamlit interface on') |
|
args = parser.parse_args() |
|
return args.node_name or f"node-{uuid.uuid4().hex[:8]}", args.port |
|
|
|
|
|
def save_chat_entry(username, message): |
|
"""🖌️ Carves a chat line into the grand Markdown tome - history in the making! 🏛️""" |
|
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
|
entry = f"[{timestamp}] {username}: {message}" |
|
try: |
|
with open(CHAT_FILE, 'a') as f: |
|
f.write(f"{entry}\n") |
|
return True |
|
except Exception as e: |
|
print(f"Oops! Failed to save chat: {e}") |
|
return False |
|
|
|
|
|
def load_chat(): |
|
"""🔍 Digs up the chat treasure from the filesystem - tales of old and new! 💰""" |
|
if not os.path.exists(CHAT_FILE): |
|
with open(CHAT_FILE, 'w') as f: |
|
f.write(f"# {START_ROOM} Chat\n\nWelcome to the cosmic hub - start chatting! 🎤\n") |
|
try: |
|
with open(CHAT_FILE, 'r') as f: |
|
content = f.read() |
|
lines = content.strip().split('\n') |
|
numbered_content = "\n".join(f"{i+1}. {line}" for i, line in enumerate(lines) if line.strip()) |
|
return numbered_content |
|
except Exception as e: |
|
print(f"Chat load hiccup: {e}") |
|
return f"# Error loading {START_ROOM} chat\nSomething went wonky! 😵" |
|
|
|
|
|
def get_user_list(chat_content): |
|
"""👀 Peeks at the chat to spot all the cool cats talking - who’s in the club? 🎸""" |
|
users = set() |
|
for line in chat_content.split('\n'): |
|
if line.strip() and ': ' in line: |
|
user = line.split(': ')[1].split(' ')[0] |
|
users.add(user) |
|
return sorted(list(users)) |
|
|
|
|
|
def get_message_suggestions(chat_content, prefix): |
|
"""🔮 Pulls past messages from the cosmic archives for autocomplete magic! ✨""" |
|
lines = chat_content.split('\n') |
|
messages = [line.split(': ', 1)[1] for line in lines if ': ' in line and line.strip()] |
|
return [msg for msg in messages if msg.lower().startswith(prefix.lower())][:5] |
|
|
|
|
|
def load_quotes(source="famous"): |
|
"""📚 Grabs a stack of wise words from famous folks or custom quips! 🗣️""" |
|
famous_quotes = [ |
|
"The true sign of intelligence is not knowledge but imagination. – Albert Einstein", |
|
"I have not failed. I've just found 10,000 ways that won't work. – Thomas Edison", |
|
"Innovation distinguishes between a leader and a follower. – Steve Jobs", |
|
"Research is what I'm doing when I don't know what I'm doing. – Wernher von Braun", |
|
"The only way to discover the limits of the possible is to go beyond them into the impossible. – Arthur C. Clarke", |
|
"Success is a science; if you have the conditions, you get the result. – Oscar Wilde", |
|
"An expert is a person who has made all the mistakes that can be made in a very narrow field. – Niels Bohr", |
|
"The important thing is to not stop questioning. Curiosity has its own reason for existing. – Albert Einstein", |
|
"The best way to predict the future is to invent it. – Alan Kay", |
|
"If I have seen further it is by standing on the shoulders of Giants. – Isaac Newton", |
|
"Logic will get you from A to B. Imagination will take you everywhere. – Albert Einstein", |
|
"Imagination is more important than knowledge. Knowledge is limited. Imagination encircles the world. – Albert Einstein", |
|
"Science is a way of thinking much more than it is a body of knowledge. – Carl Sagan", |
|
"We cannot solve our problems with the same thinking we used when we created them. – Albert Einstein", |
|
"The true method of knowledge is experiment. – William Blake", |
|
"The scientist is not a person who gives the right answers, he's one who asks the right questions. – Claude Levi-Strauss", |
|
"It's kind of fun to do the impossible. – Walt Disney", |
|
"Any sufficiently advanced technology is indistinguishable from magic. – Arthur C. Clarke", |
|
"Creativity is intelligence having fun. – Albert Einstein", |
|
"To invent, you need a good imagination and a pile of junk. – Thomas Edison" |
|
] |
|
custom_quotes = [ |
|
"Every age unfolds a new lesson. Life's chapters evolve, each teaching us anew.", |
|
"From infancy to twilight, our journey is painted in growth. Every stage shines with its own wisdom.", |
|
"Love is the universal language, transcending boundaries and touching souls.", |
|
"Through love, we find connection, unity, and the essence of existence." |
|
] |
|
quotes = famous_quotes if source == "famous" else custom_quotes |
|
return quotes if quotes else ["No quotes available - check back later! 📭"] |
|
|
|
|
|
def save_vote(file, item, user_hash): |
|
"""✍️ Tallies a vote in the grand ledger - your opinion matters! 🗳️""" |
|
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
|
entry = f"[{timestamp}] {user_hash} voted for {item}" |
|
try: |
|
with open(file, 'a') as f: |
|
f.write(f"{entry}\n") |
|
with open(HISTORY_FILE, 'a') as f: |
|
f.write(f"- {timestamp} - User {user_hash} voted for {item}\n") |
|
return True |
|
except Exception as e: |
|
print(f"Vote save flop: {e}") |
|
return False |
|
|
|
|
|
def load_votes(file): |
|
"""📈 Counts the votes from the ledger - who’s winning the popularity contest? 🏆""" |
|
if not os.path.exists(file): |
|
with open(file, 'w') as f: |
|
f.write("# Vote Tally\n\nNo votes yet - get clicking! 🖱️\n") |
|
try: |
|
with open(file, 'r') as f: |
|
lines = f.read().strip().split('\n') |
|
votes = {} |
|
for line in lines[2:]: |
|
if line.strip() and 'voted for' in line: |
|
item = line.split('voted for ')[1] |
|
votes[item] = votes.get(item, 0) + 1 |
|
return votes |
|
except Exception as e: |
|
print(f"Vote load oopsie: {e}") |
|
return {} |
|
|
|
|
|
def generate_user_hash(): |
|
"""🕵️ Crafts a snazzy 8-digit ID badge - you’re in the club now! 🎟️""" |
|
if 'user_hash' not in st.session_state: |
|
session_id = str(random.getrandbits(128)) |
|
hash_object = hashlib.md5(session_id.encode()) |
|
st.session_state['user_hash'] = hash_object.hexdigest()[:8] |
|
return st.session_state['user_hash'] |
|
|
|
|
|
def save_username(username): |
|
"""💾 Stashes your cosmic alias before the refresh void claims it! 🌌""" |
|
try: |
|
with open(STATE_FILE, 'w') as f: |
|
f.write(username) |
|
except Exception as e: |
|
print(f"Failed to save username: {e}") |
|
|
|
def load_username(): |
|
"""🔄 Resurrects your cosmic alias from the refresh abyss! 🌠""" |
|
if os.path.exists(STATE_FILE): |
|
try: |
|
with open(STATE_FILE, 'r') as f: |
|
return f.read().strip() |
|
except Exception as e: |
|
print(f"Failed to load username: {e}") |
|
return None |
|
|
|
|
|
def save_pasted_image(image_data): |
|
"""📸 Saves a pasted image to the root vault with a cosmic name! 🌠""" |
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") |
|
filename = f"paste_{timestamp}.png" |
|
filepath = os.path.join('./', filename) |
|
try: |
|
if ',' in image_data: |
|
image_data = image_data.split(',')[1] |
|
img_bytes = base64.b64decode(image_data) |
|
img = Image.open(io.BytesIO(img_bytes)) |
|
img.save(filepath, "PNG") |
|
return filename |
|
except Exception as e: |
|
print(f"Failed to save pasted image: {e}") |
|
return None |
|
|
|
|
|
def get_video_html(video_path, width="100%"): |
|
"""🎬 Rolls out the red carpet for videos - autoplay and loop like a star! 🌟""" |
|
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%"): |
|
"""🎶 Drops a beat with audio - your personal DJ in action! 🎧""" |
|
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> |
|
''' |
|
|
|
active_connections = {} |
|
|
|
|
|
async def websocket_handler(websocket, path): |
|
"""🎧 Guards the cosmic gate, welcoming all to Sector and booting crashers! 🚨""" |
|
try: |
|
client_id = str(uuid.uuid4()) |
|
room_id = "chat" |
|
active_connections.setdefault(room_id, {})[client_id] = websocket |
|
print(f"Client {client_id} joined the Sector party!") |
|
username = st.session_state.get('username', random.choice(list(FUN_USERNAMES.keys()))) |
|
save_chat_entry("System 🌟", f"{username} has joined {START_ROOM}!") |
|
|
|
async for message in websocket: |
|
try: |
|
parts = message.split('|', 1) |
|
if len(parts) == 2: |
|
username, content = parts |
|
save_chat_entry(username, content) |
|
await broadcast_message(f"{username}|{content}", room_id) |
|
except Exception as e: |
|
print(f"Message mishap: {e}") |
|
await websocket.send(f"ERROR|Oops, bad message format! 😬") |
|
except websockets.ConnectionClosed: |
|
print(f"Client {client_id} bailed from Sector!") |
|
save_chat_entry("System 🌟", f"{username} has left {START_ROOM}!") |
|
finally: |
|
if room_id in active_connections and client_id in active_connections[room_id]: |
|
del active_connections[room_id][client_id] |
|
if not active_connections[room_id]: |
|
del active_connections[room_id] |
|
|
|
|
|
async def broadcast_message(message, room_id): |
|
"""📢 Shouts the latest Sector beat to every cosmic dancer - hear it loud! 🎵""" |
|
if room_id in active_connections: |
|
disconnected = [] |
|
for client_id, ws in active_connections[room_id].items(): |
|
try: |
|
await ws.send(message) |
|
except websockets.ConnectionClosed: |
|
disconnected.append(client_id) |
|
for client_id in disconnected: |
|
del active_connections[room_id][client_id] |
|
|
|
|
|
async def run_websocket_server(): |
|
"""🌐 Cranks up the WebSocket jukebox once, keeping Sector rocking! 🎸""" |
|
global server_running, server_task |
|
if not server_running: |
|
server = await websockets.serve(websocket_handler, '0.0.0.0', 8765) |
|
print(f"WebSocket server jamming on ws://0.0.0.0:8765") |
|
server_running = True |
|
await server.wait_closed() |
|
|
|
|
|
def create_streamlit_interface(initial_username): |
|
"""🖌️ Sets up the Sector stage with pulsing timers, voting, and IVA media flair! 🌟""" |
|
|
|
st.markdown(""" |
|
<style> |
|
.chat-box { |
|
font-family: monospace; |
|
background: #1e1e1e; |
|
color: #d4d4d4; |
|
padding: 10px; |
|
border-radius: 5px; |
|
height: 300px; |
|
overflow-y: auto; |
|
} |
|
.timer { |
|
font-size: 24px; |
|
color: #ffcc00; |
|
text-align: center; |
|
animation: pulse 1s infinite; |
|
} |
|
@keyframes pulse { |
|
0% { transform: scale(1); } |
|
50% { transform: scale(1.1); } |
|
100% { transform: scale(1); } |
|
} |
|
</style> |
|
<script> |
|
document.addEventListener('paste', function(e) { |
|
const items = (e.clipboardData || window.clipboardData).items; |
|
for (let i = 0; i < items.length; i++) { |
|
if (items[i].type.indexOf('image') !== -1) { |
|
const blob = items[i].getAsFile(); |
|
const reader = new FileReader(); |
|
reader.onload = function(event) { |
|
const imageData = event.target.result; |
|
sessionStorage.setItem('pastedImage', imageData); |
|
document.getElementById('message_input').value = 'PastedImage:' + blob.name; |
|
document.getElementById('send_button').click(); |
|
}; |
|
reader.readAsDataURL(blob); |
|
} |
|
} |
|
}); |
|
document.getElementById('message_input')?.addEventListener('keypress', function(e) { |
|
if (e.key === 'Enter') { |
|
document.getElementById('send_button').click(); |
|
} |
|
}); |
|
</script> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.title(f"{Site_Name}") |
|
st.markdown(f"Welcome to {START_ROOM} - chat, vote, paste images, and enjoy IVA’s media magic! 🎉") |
|
|
|
|
|
saved_username = load_username() |
|
if saved_username and saved_username in FUN_USERNAMES: |
|
initial_username = saved_username |
|
if 'username' not in st.session_state: |
|
st.session_state.username = initial_username |
|
save_chat_entry("System 🌟", f"{initial_username} has joined {START_ROOM}!") |
|
save_username(st.session_state.username) |
|
|
|
|
|
if 'refresh_rate' not in st.session_state: |
|
st.session_state.refresh_rate = 5 |
|
if 'timer_start' not in st.session_state: |
|
st.session_state.timer_start = time.time() |
|
if 'quote_index' not in st.session_state: |
|
quotes = load_quotes("famous") |
|
st.session_state.quote_index = random.randint(0, max(0, len(quotes) - 1)) if quotes else 0 |
|
if 'quote_source' not in st.session_state: |
|
st.session_state.quote_source = "famous" |
|
if 'pasted_image' not in st.session_state: |
|
st.session_state.pasted_image = None |
|
|
|
|
|
st.subheader(f"{START_ROOM} Chat 💬") |
|
chat_content = load_chat() |
|
chat_lines = chat_content.split('\n') |
|
for i, line in enumerate(chat_lines): |
|
if line.strip() and ': ' in line: |
|
col1, col2 = st.columns([5, 1]) |
|
with col1: |
|
st.markdown(line) |
|
with col2: |
|
if st.button(f"👍", key=f"chat_vote_{i}"): |
|
user_hash = generate_user_hash() |
|
save_vote(QUOTE_VOTES_FILE, line, user_hash) |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
st.rerun() |
|
|
|
user_list = get_user_list(chat_content) |
|
new_username = st.selectbox("Switch Star", user_list + [st.session_state.username], index=len(user_list)) |
|
if new_username != st.session_state.username: |
|
save_chat_entry("System 🌟", f"{st.session_state.username} switched to {new_username} in {START_ROOM}!") |
|
st.session_state.username = new_username |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
|
|
|
|
agent_icon = st.session_state.username.split()[-1] |
|
agent_label = FUN_USERNAMES.get(st.session_state.username, "Chatty Brat") |
|
message = st.text_input(f"Message Mate {agent_icon} - {agent_label} 🔍📸", key="message_input", placeholder="Type or paste here...") |
|
suggestions = get_message_suggestions(chat_content, message) if message else [] |
|
if suggestions: |
|
suggestion = st.selectbox("Chat Snap", [""] + suggestions, index=0) |
|
if suggestion: |
|
message = suggestion |
|
st.session_state.message_input = suggestion |
|
|
|
col_send, _ = st.columns([1, 5]) |
|
with col_send: |
|
send_button = st.button("Send Bend 🚀", key="send_button") |
|
if send_button and message.strip(): |
|
if message.startswith("PastedImage:"): |
|
|
|
image_data = st.session_state.get('pasted_image') |
|
if image_data: |
|
filename = save_pasted_image(image_data) |
|
if filename: |
|
save_chat_entry(st.session_state.username, f"Pasted image: {filename}") |
|
st.session_state.pasted_image = None |
|
else: |
|
save_chat_entry(st.session_state.username, message) |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
st.rerun() |
|
|
|
|
|
st.subheader("Quote Note 📝") |
|
quotes = load_quotes(st.session_state.quote_source) |
|
if quotes: |
|
st.session_state.quote_index = st.session_state.quote_index % len(quotes) |
|
quote = quotes[st.session_state.quote_index] |
|
col1, col2 = st.columns([5, 1]) |
|
with col1: |
|
st.markdown(quote) |
|
with col2: |
|
if st.button("👍 Vote Float", key="quote_vote"): |
|
user_hash = generate_user_hash() |
|
save_vote(QUOTE_VOTES_FILE, quote, user_hash) |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
st.rerun() |
|
if time.time() - st.session_state.timer_start > 10: |
|
st.session_state.quote_index = (st.session_state.quote_index + 1) % len(quotes) |
|
st.session_state.quote_source = "custom" if st.session_state.quote_source == "famous" else "famous" |
|
quotes = load_quotes(st.session_state.quote_source) |
|
st.session_state.quote_index = st.session_state.quote_index % len(quotes) if quotes else 0 |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
st.rerun() |
|
else: |
|
st.markdown("No quotes available - check back later! 📭") |
|
|
|
|
|
st.subheader("IVA Gallery 🎨🎶🎥") |
|
media_files = ( |
|
glob.glob("./*.png") + glob.glob("./*.jpg") + glob.glob("./*.jpeg") + |
|
glob.glob("./*.mp3") + glob.glob("./*.wav") + |
|
glob.glob("./*.mp4") |
|
) |
|
if media_files: |
|
media_cols = st.slider("Gallery Rally", min_value=1, max_value=5, value=3) |
|
cols = st.columns(media_cols) |
|
for idx, media_file in enumerate(media_files): |
|
with cols[idx % media_cols]: |
|
if media_file.endswith(('.png', '.jpg', '.jpeg')): |
|
st.image(media_file, use_container_width=True) |
|
elif media_file.endswith(('.mp3', '.wav')): |
|
st.markdown(get_audio_html(media_file, width="100%"), unsafe_allow_html=True) |
|
elif media_file.endswith('.mp4'): |
|
st.markdown(get_video_html(media_file, width="100%"), unsafe_allow_html=True) |
|
if st.button(f"👍 Vote Tote {os.path.basename(media_file)}", key=f"media_vote_{idx}"): |
|
user_hash = generate_user_hash() |
|
save_vote(IMAGE_VOTES_FILE, media_file, user_hash) |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
st.rerun() |
|
else: |
|
st.error("No media files (images, audio, video) found in root directory!") |
|
|
|
|
|
st.subheader("Refresh Dash ⏳") |
|
refresh_rate = st.slider("Refresh Clash", min_value=1, max_value=300, value=st.session_state.refresh_rate, step=1) |
|
if refresh_rate != st.session_state.refresh_rate: |
|
st.session_state.refresh_rate = refresh_rate |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
|
|
col1, col2, col3 = st.columns(3) |
|
with col1: |
|
if st.button("🐇 Small Call (1s)"): |
|
st.session_state.refresh_rate = 1 |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
with col2: |
|
if st.button("🐢 Medium Fling (5s)"): |
|
st.session_state.refresh_rate = 5 |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
with col3: |
|
if st.button("🐘 Large Surge (5m)"): |
|
st.session_state.refresh_rate = 300 |
|
st.session_state.timer_start = time.time() |
|
save_username(st.session_state.username) |
|
|
|
|
|
timer_placeholder = st.empty() |
|
start_time = st.session_state.timer_start |
|
for i in range(st.session_state.refresh_rate, -1, -1): |
|
font_name, font_func = random.choice(UNICODE_FONTS) |
|
countdown_str = "".join(UNICODE_DIGITS[int(d)] for d in str(i)) if i < 10 else font_func(str(i)) |
|
timer_emoji = "⏳" if i % 2 == 0 else "💓" |
|
timer_placeholder.markdown(f"<p class='timer'>{timer_emoji} {font_func('Next refresh in:')} {countdown_str} {font_func('seconds')}</p>", unsafe_allow_html=True) |
|
time.sleep(1) |
|
st.session_state.timer_start = time.time() |
|
st.session_state.last_refresh = time.time() |
|
save_username(st.session_state.username) |
|
st.rerun() |
|
|
|
|
|
st.sidebar.subheader("Vote Loads") |
|
chat_votes = load_votes(QUOTE_VOTES_FILE) |
|
image_votes = load_votes(IMAGE_VOTES_FILE) |
|
for item, count in chat_votes.items(): |
|
st.sidebar.write(f"{item}: {count} votes") |
|
for image, count in image_votes.items(): |
|
st.sidebar.write(f"{image}: {count} votes") |
|
|
|
|
|
async def main(): |
|
"""🎤 Drops the mic and starts the Sector party - it’s showtime, folks! 🎉""" |
|
global NODE_NAME, server_task |
|
NODE_NAME, port = get_node_name() |
|
|
|
|
|
if server_task is None: |
|
server_task = asyncio.create_task(run_websocket_server()) |
|
|
|
query_params = st.query_params if hasattr(st, 'query_params') else {} |
|
initial_username = query_params.get("username", random.choice(list(FUN_USERNAMES.keys()))) if query_params else random.choice(list(FUN_USERNAMES.keys())) |
|
print(f"Welcoming {initial_username} to the Sector bash!") |
|
|
|
create_streamlit_interface(initial_username) |
|
|
|
if __name__ == "__main__": |
|
asyncio.run(main()) |