feat(stats): monthly traffic/IP/file count stats displayed on status page
This commit is contained in:
6
app.py
6
app.py
@@ -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():
|
||||
|
||||
25
database.py
25
database.py
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user