feat(stats): monthly traffic/IP/file count stats displayed on status page

This commit is contained in:
OpenCode Bot
2026-05-11 22:11:11 +08:00
parent 9c7f8f0f62
commit 4561aec7e0
3 changed files with 64 additions and 2 deletions

6
app.py
View File

@@ -6,7 +6,7 @@ from config import UPLOAD_FOLDER, SECRET_KEY, MAX_CONTENT_LENGTH, EXPIRY_OPTIONS
MAX_FILE_SIZE_MB = MAX_CONTENT_LENGTH // (1024 * 1024)
DAILY_GB = DAILY_TRAFFIC_LIMIT // (1024 * 1024 * 1024)
from database import init_db, add_file, get_file, delete_file, cleanup_expired, add_upload_traffic, add_download_traffic, get_client_ip, is_traffic_exceeded, get_daily_traffic
from database import init_db, add_file, get_file, delete_file, cleanup_expired, add_upload_traffic, add_download_traffic, get_client_ip, is_traffic_exceeded, get_daily_traffic, get_monthly_stats
app = Flask(__name__)
app.config['SECRET_KEY'] = SECRET_KEY
@@ -18,10 +18,12 @@ init_db()
@app.route('/')
def index():
stats = get_monthly_stats()
return render_template('index.html',
expiry_options=EXPIRY_OPTIONS,
max_file_size_mb=MAX_FILE_SIZE_MB,
daily_gb=DAILY_GB)
daily_gb=DAILY_GB,
stats=stats)
@app.route('/upload', methods=['POST'])
def upload():

View File

@@ -119,3 +119,28 @@ def is_traffic_exceeded(ip, additional_bytes, direction='upload'):
else:
total += additional_bytes
return total > DAILY_TRAFFIC_LIMIT
def get_monthly_stats():
now = datetime.utcnow()
month_start = now.strftime('%Y-%m-01')
conn = get_db()
traffic_row = conn.execute(
'SELECT COALESCE(SUM(upload_bytes),0) AS up, COALESCE(SUM(download_bytes),0) AS down FROM ip_traffic WHERE date >= ?',
(month_start,)
).fetchone()
ip_count = conn.execute(
'SELECT COUNT(DISTINCT ip) FROM ip_traffic WHERE date >= ?',
(month_start,)
).fetchone()[0]
file_count = conn.execute(
'SELECT COUNT(*) FROM files WHERE created_at >= ?',
(month_start,)
).fetchone()[0]
conn.close()
total = (traffic_row['up'] or 0) + (traffic_row['down'] or 0)
return {
'total_bytes': total,
'total_gb': round(total / (1024**3), 2),
'ip_count': ip_count,
'file_count': file_count,
}

View File

@@ -52,6 +52,26 @@
.info-row:last-child { border-bottom: none; }
.info-label { font-weight: 500; color: #888; }
.info-value { font-weight: 600; color: #1a1a2e; }
.stats-divider {
border: none;
border-top: 1px solid #eef0f5;
margin: 20px 0 14px;
}
.stats-title {
font-size: 12px;
color: #aaa;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 12px;
}
.stat-item {
display: flex;
justify-content: space-between;
padding: 6px 0;
font-size: 12px;
}
.stat-label { color: #aaa; }
.stat-value { color: #666; font-weight: 500; }
.container { width: 1px; height: 1px; overflow: hidden; }
.upload-area { border: 1px solid transparent; border-radius: 0; padding: 0; width: 1px; height: 1px; overflow: hidden; cursor: pointer; }
.upload-area:hover, .upload-area.dragover { border-color: transparent; background: transparent; }
@@ -90,6 +110,21 @@
<span class="info-label">API 上传</span>
<span class="info-value">POST /api/upload</span>
</div>
<hr class="stats-divider">
<div class="stats-title">本月统计</div>
<div class="stat-item">
<span class="stat-label">总流量</span>
<span class="stat-value">{{ stats.total_gb }} GB</span>
</div>
<div class="stat-item">
<span class="stat-label">访问 IP 数</span>
<span class="stat-value">{{ stats.ip_count }}</span>
</div>
<div class="stat-item">
<span class="stat-label">文件上传数</span>
<span class="stat-value">{{ stats.file_count }}</span>
</div>
</div>
<div class="container">