feat(file): 优化文件处理和缓存机制

- 重构文件处理逻辑,提高性能和可维护性
- 增加缓存机制,减少重复读取和处理
- 改进错误处理和日志记录
- 优化缩略图生成算法
- 添加性能监控和测试依赖
This commit is contained in:
2025-07-11 00:21:57 +08:00
parent d0f9e65ad1
commit 8c4e5885c7
15 changed files with 1034 additions and 94 deletions

View File

@@ -1,6 +1,6 @@
from flask import *
from flask import Blueprint
from flask import Blueprint, request, abort, make_response
import db.file , file, gc , app_conf
from utils.performance_monitor import timing_context
api_Img_bp = Blueprint("api_Img_bp", __name__)
@@ -11,21 +11,30 @@ fullSize = conf.getint("img", "fullSize")
@api_Img_bp.route("/api/img/<bookid>/<index>")
def img(bookid, index): # 图片接口
if request.cookies.get("islogin") is None:
return abort(403)
if len(db.file.searchByid(bookid)) == 0:
return abort(404)
# 设置响应类型为图片
data, filename = file.raedZip(bookid, index)
if isinstance(data, str):
abort(404)
if request.args.get("mini") == "yes":
data = file.thumbnail(data,miniSize,encode=imgencode)
else:
data = file.thumbnail(data,fullSize,encode=imgencode)
response = make_response(data) # 读取文件
del data
response.headers.set("Content-Type",f"image/{imgencode}")
response.headers.set("Content-Disposition", "inline", filename=filename)
gc.collect()
return response
with timing_context(f"api.img.{bookid}.{index}"):
if request.cookies.get("islogin") is None:
return abort(403)
if len(db.file.searchByid(bookid)) == 0:
return abort(404)
# 读取图片数据
data, filename = file.readZip(bookid, index)
if isinstance(data, str):
abort(404)
# 处理图片尺寸
if request.args.get("mini") == "yes":
data = file.thumbnail(data, miniSize, encode=imgencode)
else:
data = file.thumbnail(data, fullSize, encode=imgencode)
# 创建响应
response = make_response(data)
del data # 及时释放内存
response.headers.set("Content-Type", f"image/{imgencode}")
response.headers.set("Content-Disposition", "inline", filename=filename)
response.headers.set("Cache-Control", "public, max-age=3600") # 添加缓存头
gc.collect() # 强制垃圾回收
return response

View File

@@ -14,7 +14,7 @@ def overview(page): # 概览
if request.cookies.get("islogin") is None: # 验证登录状态
return redirect("/")
metaDataList = db.file.getMetadata(
(page - 1) * 20, page * 20, request.args.get("search")
(page - 1) * 20, page * 20, request.args.get("search", "")
)
for item in metaDataList:
item[2] = item[2][:-4] # 去除文件扩展名
@@ -89,7 +89,13 @@ def upload_file():
uploaded_file = request.files.getlist("files[]") # 获取上传的文件列表
print(uploaded_file)
for fileitem in uploaded_file:
if fileitem.filename != "":
fileitem.save(conf.get("file", "inputdir") + "/" + fileitem.filename)
file.auotLoadFile()
if fileitem.filename and fileitem.filename != "":
input_dir = conf.get("file", "inputdir")
if not input_dir:
return "Input directory is not configured.", 500
import os
if input_dir is None:
return "Input directory is not configured.", 500
fileitem.save(os.path.join(input_dir, fileitem.filename))
file.autoLoadFile()
return "success"

61
router/performance_api.py Normal file
View File

@@ -0,0 +1,61 @@
from flask import Blueprint, render_template, jsonify, request
from utils.performance_monitor import get_performance_monitor
from utils.cache_manager import get_cache_manager
performance_bp = Blueprint("performance_bp", __name__)
@performance_bp.route("/api/performance/stats")
def performance_stats():
"""获取性能统计信息"""
if request.cookies.get("islogin") is None:
return jsonify({"error": "Unauthorized"}), 403
monitor = get_performance_monitor()
cache_manager = get_cache_manager()
operation_name = request.args.get("operation")
stats = {
"performance": monitor.get_stats(operation_name),
"cache": cache_manager.get_stats(),
"recent_errors": monitor.get_recent_errors(5)
}
return jsonify(stats)
@performance_bp.route("/api/performance/clear")
def clear_performance_data():
"""清空性能监控数据"""
if request.cookies.get("islogin") is None:
return jsonify({"error": "Unauthorized"}), 403
monitor = get_performance_monitor()
monitor.clear_metrics()
return jsonify({"message": "Performance data cleared"})
@performance_bp.route("/api/cache/clear")
def clear_cache():
"""清空缓存"""
if request.cookies.get("islogin") is None:
return jsonify({"error": "Unauthorized"}), 403
cache_manager = get_cache_manager()
cache_manager.clear()
return jsonify({"message": "Cache cleared"})
@performance_bp.route("/api/cache/cleanup")
def cleanup_cache():
"""清理过期缓存"""
if request.cookies.get("islogin") is None:
return jsonify({"error": "Unauthorized"}), 403
cache_manager = get_cache_manager()
cache_manager.cleanup_expired()
return jsonify({"message": "Expired cache cleaned up"})