81 lines
2.4 KiB
Python
81 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
PerToolBox Server - 热度统计路由
|
|
Copyright (C) 2024 Sea Network Technology Studio
|
|
Author: Canglan <admin@sea-studio.top>
|
|
License: AGPL v3
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from fastapi import APIRouter, HTTPException, Request
|
|
from ...utils.redis_client import redis_client
|
|
from ...models import ToolStatsTotal
|
|
from ...dependencies import DbDependency
|
|
from ...middleware.rate_limit import rate_limit
|
|
|
|
router = APIRouter(prefix="/api/v1", tags=["stats"])
|
|
|
|
TOOL_NAMES = [
|
|
"todos", "notes", "password", "qrcode",
|
|
"crypto_hash", "crypto_base64", "crypto_url", "crypto_aes", "json"
|
|
]
|
|
|
|
@router.post("/tool/usage")
|
|
@rate_limit(requests=20, period=60)
|
|
async def record_usage(
|
|
request: Request, # 添加 request 参数
|
|
tool_name: str,
|
|
db: DbDependency
|
|
):
|
|
"""记录页面访问次数(热度)"""
|
|
if tool_name not in TOOL_NAMES:
|
|
raise HTTPException(status_code=400, detail="无效的工具名")
|
|
|
|
today = datetime.now().strftime("%Y-%m-%d")
|
|
today_key = f"tool:stats:today:{tool_name}:{today}"
|
|
total_key = f"tool:stats:total:{tool_name}"
|
|
|
|
today_count = redis_client.incr(today_key)
|
|
redis_client.expire(today_key, 48 * 3600)
|
|
total_count = redis_client.incr(total_key)
|
|
|
|
stats = db.query(ToolStatsTotal).filter(ToolStatsTotal.tool_name == tool_name).first()
|
|
if stats:
|
|
stats.total_count = total_count
|
|
else:
|
|
stats = ToolStatsTotal(tool_name=tool_name, total_count=total_count)
|
|
db.add(stats)
|
|
db.commit()
|
|
|
|
return {"success": True}
|
|
|
|
@router.get("/tool/stats")
|
|
@rate_limit(requests=100, period=60)
|
|
async def get_stats(
|
|
request: Request, # 添加 request 参数
|
|
db: DbDependency
|
|
):
|
|
"""获取所有工具的今日/总访问次数"""
|
|
today = datetime.now().strftime("%Y-%m-%d")
|
|
result = {}
|
|
|
|
for tool_name in TOOL_NAMES:
|
|
today_key = f"tool:stats:today:{tool_name}:{today}"
|
|
total_key = f"tool:stats:total:{tool_name}"
|
|
|
|
today_count = redis_client.get(today_key)
|
|
total_count = redis_client.get(total_key)
|
|
|
|
if total_count is None:
|
|
stats = db.query(ToolStatsTotal).filter(ToolStatsTotal.tool_name == tool_name).first()
|
|
total_count = stats.total_count if stats else 0
|
|
else:
|
|
total_count = int(total_count)
|
|
|
|
result[tool_name] = {
|
|
"today": int(today_count) if today_count else 0,
|
|
"total": total_count
|
|
}
|
|
|
|
return result |