openfree's picture
Update app.py
8c9d551 verified
raw
history blame
9.3 kB
import requests
import gradio as gr
from datetime import datetime
import random
USERNAME = "openfree"
def format_timestamp(timestamp):
if timestamp:
dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
return dt.strftime('%Y-%m-%d %H:%M')
return 'N/A'
def get_pastel_color(index):
"""Generate unique pastel colors based on index"""
pastel_colors = [
'#FFE6E6', # μ—°ν•œ 뢄홍
'#FFE6FF', # μ—°ν•œ 보라
'#E6E6FF', # μ—°ν•œ νŒŒλž‘
'#E6FFFF', # μ—°ν•œ ν•˜λŠ˜
'#E6FFE6', # μ—°ν•œ 초둝
'#FFFFE6', # μ—°ν•œ λ…Έλž‘
'#FFF0E6', # μ—°ν•œ μ£Όν™©
'#F0E6FF', # μ—°ν•œ 라벀더
'#FFE6F0', # μ—°ν•œ 둜즈
'#E6FFF0', # μ—°ν•œ 민트
'#F0FFE6', # μ—°ν•œ λΌμž„
'#FFE6EB', # μ—°ν•œ μ½”λž„
'#E6EBFF', # μ—°ν•œ νΌν”ŒλΈ”λ£¨
'#FFE6F5', # μ—°ν•œ 핑크
'#E6FFF5', # μ—°ν•œ ν„°μ½”μ΄μ¦ˆ
'#F5E6FF', # μ—°ν•œ λͺ¨λΈŒ
'#FFE6EC', # μ—°ν•œ μ‚΄λͺ¬
'#E6FFEC', # μ—°ν•œ μŠ€ν”„λ§κ·Έλ¦°
'#ECE6FF', # μ—°ν•œ νŽ˜λ¦¬μœ™ν΄
'#FFE6F7', # μ—°ν•œ 맀그놀리아
]
return pastel_colors[index % len(pastel_colors)]
def get_space_card(space, index):
"""Generate HTML card for a space with colorful design and lots of emojis"""
space_id = space.get('id', '')
space_name = space_id.split('/')[-1]
likes = space.get('likes', 0)
created_at = format_timestamp(space.get('createdAt'))
sdk = space.get('sdk', 'N/A')
# SDK별 이λͺ¨μ§€ 및 κ΄€λ ¨ 이λͺ¨μ§€ μ„ΈνŠΈ
sdk_emoji_sets = {
'gradio': {
'main': '🎨',
'related': ['πŸ–ΌοΈ', '🎭', 'πŸŽͺ', '🎠', '🎑', '🎒', '🎯', '🎲', '🎰', '🎳']
},
'streamlit': {
'main': '⚑',
'related': ['πŸ’«', '✨', '⭐', '🌟', 'πŸ’₯', '⚑', 'πŸ”₯', '🌈', 'πŸŽ†', 'πŸŽ‡']
},
'docker': {
'main': '🐳',
'related': ['πŸ‹', '🌊', '🌍', '🚒', '⛴️', 'πŸ›₯️', '🐠', '🐑', '🦈', '🐬']
},
'static': {
'main': 'πŸ“„',
'related': ['πŸ“', 'πŸ“°', 'πŸ“‘', 'πŸ—‚οΈ', 'πŸ“', 'πŸ“‚', 'πŸ“š', 'πŸ“–', 'πŸ“’', 'πŸ“”']
},
'panel': {
'main': 'πŸ“Š',
'related': ['πŸ“ˆ', 'πŸ“‰', 'πŸ’Ή', 'πŸ“‹', 'πŸ“Œ', 'πŸ“', 'πŸ—ΊοΈ', '🎯', 'πŸ“', 'πŸ“']
},
'N/A': {
'main': 'πŸ”§',
'related': ['πŸ”¨', 'βš’οΈ', 'πŸ› οΈ', 'βš™οΈ', 'πŸ”©', '⛏️', '⚑', 'πŸ”Œ', 'πŸ’‘', 'πŸ”‹']
}
}
# SDK에 λ”°λ₯Έ 이λͺ¨μ§€ 선택
sdk_lower = sdk.lower()
bg_color = get_pastel_color(index) # 인덱슀 기반 색상 선택
emoji_set = sdk_emoji_sets.get(sdk_lower, sdk_emoji_sets['N/A'])
main_emoji = emoji_set['main']
# λžœλ€ν•˜κ²Œ 3개의 κ΄€λ ¨ 이λͺ¨μ§€ 선택
decorative_emojis = random.sample(emoji_set['related'], 3)
# μΆ”κ°€ μž₯μ‹μš© 이λͺ¨μ§€
general_emojis = ['πŸš€', 'πŸ’«', '⭐', '🌟', '✨', 'πŸ’₯', 'πŸ”₯', '🌈', '🎯', '🎨',
'🎭', 'πŸŽͺ', '🎒', '🎑', '🎠', 'πŸŽͺ', '🎭', '🎨', '🎯', '🎲']
random_emojis = random.sample(general_emojis, 3)
# μ’‹μ•„μš” μˆ˜μ— λ”°λ₯Έ ν•˜νŠΈ 이λͺ¨μ§€
heart_emoji = '❀️' if likes > 100 else 'πŸ’–' if likes > 50 else 'πŸ’' if likes > 10 else '🀍'
return f"""
<div style='border: none;
padding: 25px;
margin: 15px;
border-radius: 20px;
background-color: {bg_color};
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
transition: all 0.3s ease-in-out;
position: relative;
overflow: hidden;'
onmouseover='this.style.transform="translateY(-5px) scale(1.02)"; this.style.boxShadow="0 8px 25px rgba(0,0,0,0.15)"'
onmouseout='this.style.transform="translateY(0) scale(1)"; this.style.boxShadow="0 4px 15px rgba(0,0,0,0.1)"'>
<div style='position: absolute; top: -15px; right: -15px; font-size: 100px; opacity: 0.1;'>
{main_emoji}
</div>
<div style='position: absolute; top: 10px; right: 10px; font-size: 20px;'>
{decorative_emojis[0]}
</div>
<div style='position: absolute; bottom: 10px; left: 10px; font-size: 20px;'>
{decorative_emojis[1]}
</div>
<div style='position: absolute; top: 50%; right: 10px; font-size: 20px;'>
{decorative_emojis[2]}
</div>
<h3 style='color: #2d2d2d;
margin: 0 0 20px 0;
font-size: 1.4em;
display: flex;
align-items: center;
gap: 10px;'>
<span style='font-size: 1.3em'>{random_emojis[0]}</span>
<a href='https://huggingface.co/spaces/{space_id}' target='_blank'
style='text-decoration: none; color: #2d2d2d;'>
{space_name}
</a>
<span style='font-size: 1.3em'>{random_emojis[1]}</span>
</h3>
<div style='margin: 15px 0; color: #444; background: rgba(255,255,255,0.5);
padding: 15px; border-radius: 12px;'>
<p style='margin: 8px 0;'>
<strong>SDK:</strong> {main_emoji} {sdk} {decorative_emojis[0]}
</p>
<p style='margin: 8px 0;'>
<strong>Created:</strong> πŸ“… {created_at} ⏰
</p>
<p style='margin: 8px 0;'>
<strong>Likes:</strong> {heart_emoji} {likes} {random_emojis[2]}
</p>
</div>
<div style='margin-top: 20px;
display: flex;
justify-content: space-between;
align-items: center;'>
<a href='https://huggingface.co/spaces/{space_id}' target='_blank'
style='background: linear-gradient(45deg, #0084ff, #00a3ff);
color: white;
padding: 10px 20px;
border-radius: 15px;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
font-weight: 500;
transition: all 0.3s;
box-shadow: 0 2px 8px rgba(0,132,255,0.3);'
onmouseover='this.style.transform="scale(1.05)"; this.style.boxShadow="0 4px 12px rgba(0,132,255,0.4)"'
onmouseout='this.style.transform="scale(1)"; this.style.boxShadow="0 2px 8px rgba(0,132,255,0.3)"'>
<span>View Space</span> πŸš€ {random_emojis[0]}
</a>
<span style='color: #666; font-size: 0.9em; opacity: 0.7;'>
πŸ†” {space_id} {decorative_emojis[2]}
</span>
</div>
</div>
"""
def get_user_spaces():
url = f"https://huggingface.co/api/spaces?author={USERNAME}&limit=500"
headers = {
"Accept": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
try:
response = requests.get(url, headers=headers)
print(f"Status Code: {response.status_code}")
print(f"Response length: {len(response.json()) if response.status_code == 200 else 'N/A'}")
if response.status_code != 200:
return f"Error: Failed to fetch spaces (Status Code: {response.status_code})"
spaces_data = response.json()
user_spaces = spaces_data
if not user_spaces:
return f"""
<div style='padding: 20px; text-align: center; color: #666;'>
<h2>No public Spaces found for user: {USERNAME}</h2>
<p>Try visiting: <a href='https://huggingface.co/{USERNAME}' target='_blank'>
https://huggingface.co/{USERNAME}</a></p>
</div>
"""
user_spaces.sort(key=lambda x: x.get('likes', 0), reverse=True)
html_content = f"""
<div style='padding: 20px; background-color: #f5f5f5;'>
<div style='margin-bottom: 20px;'>
<h2 style='color: #333; margin: 0 0 10px 0;'>Spaces by {USERNAME}</h2>
<p style='color: #666; margin: 0;'>Found {len(user_spaces)} public spaces</p>
</div>
<div style='
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
'>
{"".join(get_space_card(space, idx) for idx, space in enumerate(user_spaces))}
</div>
</div>
"""
return html_content
except Exception as e:
print(f"Error: {str(e)}")
return f"""
<div style='padding: 20px; text-align: center; color: #666;'>
<h2>Error occurred while fetching spaces</h2>
<p>Error details: {str(e)}</p>
<p>Please try again later.</p>
</div>
"""
# Creating the Gradio interface
demo = gr.Blocks()
with demo:
html_output = gr.HTML(value=get_user_spaces()) # 초기 λ‘œλ“œ μ‹œ 직접 ν•¨μˆ˜ 호좜
if __name__ == "__main__":
demo.launch()