Spaces:
Running
Running
File size: 13,434 Bytes
1aa43d1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HuggingFace 保活管理器</title>
<meta name="description" content="管理和保活您的HuggingFace Spaces,防止因长时间不访问而休眠">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="app-container">
<!-- 头部 -->
<header class="header">
<div class="header-content">
<div class="logo">
<div class="logo-icon">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 17L12 22L22 17" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 12L12 17L22 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class="logo-text">
<h1>HF 保活管理器</h1>
<p>HuggingFace Space Keepalive Manager</p>
</div>
</div>
<div class="status-badge">
<span class="status-dot"></span>
<span>运行中</span>
</div>
</div>
</header>
<!-- 主内容区 -->
<main class="main-content">
<!-- 状态卡片 -->
<section class="status-section">
<div class="status-card">
<div class="status-icon urls-icon">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class="status-info">
<span class="status-value" id="url-count">{{ urls|length }}</span>
<span class="status-label">保活URL</span>
</div>
</div>
<div class="status-card">
<div class="status-icon interval-icon">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
<polyline points="12,6 12,12 16,14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class="status-info">
<span class="status-value">{{ interval }}小时</span>
<span class="status-label">保活间隔</span>
</div>
</div>
<div class="status-card">
<div class="status-icon next-run-icon">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 12h14M12 5l7 7-7 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class="status-info">
<span class="status-value next-run-time" id="next-run">{{ next_run }}</span>
<span class="status-label">下次执行</span>
</div>
</div>
</section>
<!-- 添加URL表单 -->
<section class="add-url-section glass-card">
<h2>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
<line x1="12" y1="8" x2="12" y2="16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<line x1="8" y1="12" x2="16" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
添加保活URL
</h2>
<form id="add-url-form" class="add-form">
<div class="form-row">
<div class="form-group">
<label for="url-input">URL地址</label>
<input type="url" id="url-input" placeholder="https://your-space.hf.space" required>
</div>
<div class="form-group name-group">
<label for="name-input">名称 (可选)</label>
<input type="text" id="name-input" placeholder="我的空间">
</div>
<button type="submit" class="btn btn-primary">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<line x1="12" y1="5" x2="12" y2="19" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<line x1="5" y1="12" x2="19" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
添加
</button>
</div>
</form>
</section>
<!-- URL列表 -->
<section class="urls-section glass-card">
<div class="section-header">
<h2>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
保活列表
</h2>
<button id="ping-all-btn" class="btn btn-secondary">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23 4v6h-6M1 20v-6h6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
立即全部保活
</button>
</div>
<div id="urls-list" class="urls-list">
{% if urls %}
{% for url in urls %}
<div class="url-item" data-index="{{ loop.index0 }}">
<div class="url-info">
<span class="url-name">{{ url.name }}</span>
<a href="{{ url.url }}" target="_blank" class="url-link">{{ url.url }}</a>
<span class="url-added">添加于: {{ url.added_at }}</span>
</div>
<div class="url-actions">
<button class="btn btn-icon ping-btn" title="测试连接" data-index="{{ loop.index0 }}">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<polyline points="22,4 12,14.01 9,11.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<button class="btn btn-icon btn-danger delete-btn" title="删除" data-index="{{ loop.index0 }}">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<polyline points="3,6 5,6 21,6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
</div>
{% endfor %}
{% else %}
<div class="empty-state">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<p>还没有添加任何保活URL</p>
<span>在上方输入框中添加需要保活的HuggingFace Space URL</span>
</div>
{% endif %}
</div>
</section>
<!-- 日志区域 -->
<section class="logs-section glass-card">
<div class="section-header">
<h2>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<polyline points="14,2 14,8 20,8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="16" y1="13" x2="8" y2="13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="16" y1="17" x2="8" y2="17" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<polyline points="10,9 9,9 8,9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
运行日志
</h2>
<button id="clear-logs-btn" class="btn btn-secondary btn-small">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<polyline points="3,6 5,6 21,6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
清空日志
</button>
</div>
<div id="logs-container" class="logs-container">
{% for log in logs %}
<div class="log-item log-{{ log.status }}">
<span class="log-time">{{ log.timestamp }}</span>
<span class="log-url">{{ log.url }}</span>
<span class="log-message">{{ log.message }}</span>
</div>
{% else %}
<div class="empty-logs">
<p>暂无日志记录</p>
</div>
{% endfor %}
</div>
</section>
</main>
<!-- 页脚 -->
<footer class="footer">
<p>HuggingFace Space 保活管理器 © 2024</p>
<p class="footer-tip">💡 提示:保持此页面每日访问,即可确保所有配置的Space正常运行</p>
</footer>
</div>
<!-- Toast 通知 -->
<div id="toast-container"></div>
<script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>
|