File-Store-Bot / plugins /route.py
File Store Bot
Initialize File Store Bot for Hugging Face free Gradio Deployment
60e9648
Raw History Blame Contribute Delete
12 kB
from aiohttp import web
import markdown
import os
import psutil
import shutil
import platform
routes = web.RouteTableDef()
@routes.get("/", allow_head=True)
async def root_route_handler(request):
# Try directory path containing this file first, then check parent directory
readme_path = os.path.join(os.path.dirname(__file__), "README.md")
if not os.path.exists(readme_path):
readme_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "README.md")
if os.path.exists(readme_path):
with open(readme_path, "r", encoding="utf-8") as f:
md_text = f.read()
# Strip YAML frontmatter if present (Hugging Face metadata tags)
if md_text.startswith("---"):
parts = md_text.split("---", 2)
if len(parts) >= 3:
md_text = parts[2].strip()
readme_html = markdown.markdown(md_text, extensions=["fenced_code", "codehilite", "tables"])
else:
readme_html = "<h3>Yugen File Store Bot Documentation</h3><p>README.md not found. Create it in the root or plugins folder to display documentation here.</p>"
# Fetch system metrics using psutil and shutil
try:
cpu_usage = psutil.cpu_percent()
ram_usage = psutil.virtual_memory().percent
total, used, free = shutil.disk_usage("/")
disk_usage = round((used / total) * 100, 1)
except Exception:
cpu_usage = 0
ram_usage = 0
disk_usage = 0
space_id = os.environ.get("SPACE_ID", "Local Node")
html_page = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Store Bot - Dashboard</title>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {{
--bg-color: #0b0f19;
--card-bg: rgba(17, 24, 39, 0.7);
--border-color: rgba(255, 255, 255, 0.08);
--text-primary: #f3f4f6;
--text-secondary: #9ca3af;
--accent-color: #6366f1;
--accent-glow: rgba(99, 102, 241, 0.15);
--success-color: #10b981;
}}
body {{
font-family: 'Plus Jakarta Sans', sans-serif;
background-color: var(--bg-color);
background-image:
radial-gradient(at 0% 0%, rgba(99, 102, 241, 0.15) 0px, transparent 50%),
radial-gradient(at 100% 100%, rgba(168, 85, 247, 0.15) 0px, transparent 50%);
color: var(--text-primary);
margin: 0;
padding: 2rem 1rem;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}}
.container {{
max-width: 800px;
width: 100%;
background: var(--card-bg);
backdrop-filter: blur(16px);
border: 1px solid var(--border-color);
border-radius: 24px;
padding: 2.5rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}}
.header {{
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--border-color);
padding-bottom: 1.5rem;
margin-bottom: 2rem;
flex-wrap: wrap;
gap: 1rem;
}}
.bot-profile {{
display: flex;
align-items: center;
gap: 1rem;
}}
.bot-avatar {{
font-size: 2rem;
background: linear-gradient(135deg, #6366f1, #a855f7);
padding: 0.5rem;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8px 16px rgba(99, 102, 241, 0.3);
width: 40px;
height: 40px;
}}
.bot-info h1 {{
margin: 0;
font-size: 1.5rem;
font-weight: 700;
letter-spacing: -0.025em;
}}
.bot-info p {{
margin: 4px 0 0;
font-size: 0.875rem;
color: var(--text-secondary);
}}
.status-badge {{
display: flex;
align-items: center;
gap: 8px;
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.2);
padding: 6px 12px;
border-radius: 9999px;
font-size: 0.813rem;
font-weight: 600;
color: var(--success-color);
}}
.status-dot {{
width: 8px;
height: 8px;
background-color: var(--success-color);
border-radius: 50%;
display: inline-block;
box-shadow: 0 0 8px var(--success-color);
animation: pulse 2s infinite;
}}
@keyframes pulse {{
0% {{ transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); }}
70% {{ transform: scale(1); box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); }}
100% {{ transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }}
}}
.stats-grid {{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}}
.stat-card {{
background: rgba(255, 255, 255, 0.03);
border: 1px solid var(--border-color);
border-radius: 16px;
padding: 1.25rem;
transition: all 0.3s ease;
}}
.stat-card:hover {{
transform: translateY(-2px);
border-color: var(--accent-color);
box-shadow: 0 8px 24px var(--accent-glow);
}}
.stat-label {{
font-size: 0.813rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 8px;
}}
.stat-value {{
font-size: 1.5rem;
font-weight: 700;
margin-bottom: 12px;
}}
.progress-bar-bg {{
background: rgba(255, 255, 255, 0.08);
height: 6px;
border-radius: 9999px;
overflow: hidden;
}}
.progress-bar-fill {{
background: linear-gradient(90deg, #6366f1, #a855f7);
height: 100%;
border-radius: 9999px;
transition: width 0.5s ease-out;
}}
.links-flex {{
display: flex;
gap: 1rem;
flex-wrap: wrap;
margin-bottom: 2rem;
}}
.btn {{
flex: 1;
min-width: 140px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 0.75rem 1.25rem;
border-radius: 12px;
font-size: 0.875rem;
font-weight: 600;
text-decoration: none;
transition: all 0.2s ease;
box-sizing: border-box;
}}
.btn-primary {{
background: linear-gradient(135deg, #6366f1, #4f46e5);
color: #fff;
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.25);
}}
.btn-primary:hover {{
transform: translateY(-1px);
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);
}}
.btn-secondary {{
background: rgba(255, 255, 255, 0.05);
color: var(--text-primary);
border: 1px solid var(--border-color);
}}
.btn-secondary:hover {{
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
}}
.readme-section {{
border-top: 1px solid var(--border-color);
padding-top: 2rem;
margin-top: 2rem;
}}
.readme-title {{
font-size: 1.125rem;
font-weight: 600;
color: var(--text-secondary);
margin-bottom: 1rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}}
.markdown-body {{
color: var(--text-secondary);
font-size: 0.938rem;
line-height: 1.6;
}}
.markdown-body h1, .markdown-body h2, .markdown-body h3 {{
color: var(--text-primary);
font-weight: 600;
margin-top: 1.5rem;
margin-bottom: 0.75rem;
}}
.markdown-body p {{
margin-bottom: 1rem;
}}
.markdown-body a {{
color: var(--accent-color);
text-decoration: none;
}}
.markdown-body a:hover {{
text-decoration: underline;
}}
.markdown-body code {{
font-family: monospace;
background: rgba(255, 255, 255, 0.06);
padding: 2px 6px;
border-radius: 4px;
font-size: 0.85em;
color: #f43f5e;
}}
.markdown-body pre {{
background: #1e1e2e;
padding: 1rem;
border-radius: 12px;
overflow-x: auto;
border: 1px solid var(--border-color);
}}
.markdown-body pre code {{
background: transparent;
padding: 0;
color: unset;
font-size: 0.9em;
}}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="bot-profile">
<div class="bot-avatar">📂</div>
<div class="bot-info">
<h1>File Store Bot</h1>
<p>Live on: {space_id}</p>
</div>
</div>
<div class="status-badge">
<span class="status-dot"></span>
<span>RUNNING</span>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-label">CPU Usage</div>
<div class="stat-value">{cpu_usage}%</div>
<div class="progress-bar-bg">
<div class="progress-bar-fill" style="width: {cpu_usage}%"></div>
</div>
</div>
<div class="stat-card">
<div class="stat-label">RAM Usage</div>
<div class="stat-value">{ram_usage}%</div>
<div class="progress-bar-bg">
<div class="progress-bar-fill" style="width: {ram_usage}%"></div>
</div>
</div>
<div class="stat-card">
<div class="stat-label">Disk Storage</div>
<div class="stat-value">{disk_usage}%</div>
<div class="progress-bar-bg">
<div class="progress-bar-fill" style="width: {disk_usage}%"></div>
</div>
</div>
</div>
<div class="links-flex">
<a href="https://t.me/AnimePiratesTamil" target="_blank" class="btn btn-primary">
<span>Join Channel</span>
</a>
<a href="https://huggingface.co" target="_blank" class="btn btn-secondary">
<span>Hugging Face Space</span>
</a>
</div>
<div class="readme-section">
<div class="readme-title">Documentation</div>
<div class="markdown-body">
{readme_html}
</div>
</div>
</div>
</body>
</html>"""
return web.Response(text=html_page, content_type="text/html")
app = web.Application()
app.add_routes(routes)
if __name__ == "__main__":
web.run_app(app, port=8080)