新增下载接口
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from flask import Flask, jsonify, request, redirect
|
||||
from flask import Flask, jsonify, request, redirect, send_file
|
||||
from datetime import datetime, date
|
||||
import ipaddress
|
||||
from zoneinfo import ZoneInfo, available_timezones
|
||||
@@ -113,6 +113,7 @@ a:hover{text-decoration:underline;}</style>
|
||||
<tr><td>时间接口</td><td><a href="/time/api">/time/api</a></td><td><a href="/time/help">/time/help</a></td></tr>
|
||||
<tr><td>谜语接口</td><td><a href="/riddle/api">/riddle/api</a></td><td><a href="/riddle/help">/riddle/help</a></td></tr>
|
||||
<tr><td>期刊接口</td><td><a href="/sci/api">/sci/api</a></td><td><a href="/sci/help">/sci/help</a></td></tr>
|
||||
<tr><td>下载接口</td><td><a href="/pan/api">/pan/api</a></td><td><a href="/pan/help">/pan/help</a></td></tr>
|
||||
</tbody></table></body></html>
|
||||
"""
|
||||
|
||||
@@ -583,6 +584,70 @@ def sci():
|
||||
return jsonify(resp)
|
||||
|
||||
|
||||
@app.route("/pan/help")
|
||||
def pan_help():
|
||||
return jsonify({
|
||||
"路径": "/pan/api",
|
||||
"功能": "下载文件",
|
||||
"参数": {
|
||||
"name=xxx": "必填,文件名",
|
||||
"download=true/false": "下载/预览",
|
||||
},
|
||||
"列表": ["anian-music.js"]
|
||||
})
|
||||
|
||||
@app.route("/pan/api")
|
||||
def pan_file_download():
|
||||
args_lower = {k.lower(): v for k, v in request.args.items()}
|
||||
allowed_keys = {"name", "download"}
|
||||
extra_params = set(args_lower.keys()) - allowed_keys
|
||||
if extra_params:
|
||||
return jsonify({
|
||||
"error": f"{extra_params}参数非法",
|
||||
"allowed_params": ["name=xxx", "download=true/false"],
|
||||
})
|
||||
file_name = args_lower.get("name", "").strip()
|
||||
download_param = args_lower.get("download", "").strip()
|
||||
if download_param and download_param.lower() not in {"true", "false"}:
|
||||
resp = {
|
||||
"error": f"download参数[{download_param}]不为true/false",
|
||||
"params": {"name": file_name, "download": download_param}
|
||||
}
|
||||
return jsonify(resp)
|
||||
force_download = download_param.lower() == "true"
|
||||
params = {"name": file_name, "download": download_param if download_param else "false(默认)"}
|
||||
if not file_name:
|
||||
resp = {
|
||||
"error": "name参数不能为空",
|
||||
"params": params
|
||||
}
|
||||
return jsonify(resp)
|
||||
pan_dir = Path(__file__).parent / "data" / "pan"
|
||||
target_file = pan_dir / file_name
|
||||
real_pan = pan_dir.resolve()
|
||||
real_target = target_file.resolve()
|
||||
if not str(real_target).startswith(str(real_pan)):
|
||||
resp = {
|
||||
"error": "文件名非法",
|
||||
"params": params
|
||||
}
|
||||
return jsonify(resp)
|
||||
if not target_file.is_file():
|
||||
resp = {
|
||||
"error": f"文件 {file_name} 不存在",
|
||||
"help": "请前往/pan/help查看文件列表",
|
||||
"params": params
|
||||
}
|
||||
return jsonify(resp)
|
||||
|
||||
# 在线预览/播放核心:as_attachment=False
|
||||
return send_file(
|
||||
target_file,
|
||||
as_attachment=force_download,
|
||||
download_name=file_name
|
||||
)
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def not_found(_error):
|
||||
return redirect("/"), 302
|
||||
|
||||
Reference in New Issue
Block a user