uodata add continue download

This commit is contained in:
2025-09-03 14:04:55 +08:00
parent 61f65331f4
commit 3562e38605
7 changed files with 85 additions and 2343 deletions

77
app.py
View File

@@ -1,5 +1,6 @@
from waitress import serve
from flask import Flask, render_template, request, redirect, url_for, jsonify, session, send_from_directory, g
from flask_compress import Compress
from datetime import datetime
import os
import logging
@@ -12,6 +13,10 @@ import pandas as pd
app = Flask(__name__, template_folder='templates')
app.secret_key = os.urandom(24) # 设置会话密钥
# 初始化Gzip压缩
compress = Compress()
compress.init_app(app)
# 配置日志
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
@@ -156,10 +161,78 @@ def contact():
def serve_log_file(filename):
return send_from_directory(LOG_DIR, filename)
# 服务下载目录中的文件
# 服务下载目录中的文件 - 优化版本
@app.route('/downloads/<path:filename>')
def serve_download_file(filename):
return send_from_directory('downloads', filename)
import os
from flask import request, Response
from werkzeug.datastructures import Range
from werkzeug.exceptions import RequestedRangeNotSatisfiable
file_path = os.path.join('downloads', filename)
# 检查文件是否存在
if not os.path.isfile(file_path):
return jsonify({"status": "error", "message": "文件未找到"}), 404
# 获取文件大小和最后修改时间
file_size = os.path.getsize(file_path)
last_modified = os.path.getmtime(file_path)
# 处理Range请求断点续传
range_header = request.headers.get('Range')
if range_header:
try:
range_obj = Range.parse_range_header(range_header, file_size)
if range_obj.ranges:
# 支持单个范围请求
start, end = range_obj.ranges[0]
length = end - start + 1 if end is not None else file_size - start
def generate():
with open(file_path, 'rb') as f:
f.seek(start)
remaining = length
while remaining > 0:
chunk_size = min(8192, remaining)
chunk = f.read(chunk_size)
if not chunk:
break
yield chunk
remaining -= len(chunk)
response = Response(
generate(),
206, # Partial Content
mimetype='application/vnd.android.package-archive',
direct_passthrough=True
)
response.headers['Content-Range'] = f'bytes {start}-{start + length - 1}/{file_size}'
response.headers['Content-Length'] = str(length)
response.headers['Accept-Ranges'] = 'bytes'
# 设置缓存头 - 1小时缓存
response.headers['Cache-Control'] = 'public, max-age=3600'
response.headers['Last-Modified'] = last_modified
return response
except (ValueError, RequestedRangeNotSatisfiable):
# 如果Range请求无效返回完整文件
pass
# 普通文件下载无Range请求或Range请求无效
response = send_from_directory('downloads', filename)
# 设置缓存头 - 1小时缓存
response.headers['Cache-Control'] = 'public, max-age=3600'
response.headers['Last-Modified'] = last_modified
response.headers['Accept-Ranges'] = 'bytes'
# 对于APK文件设置正确的MIME类型
if filename.lower().endswith('.apk'):
response.headers['Content-Type'] = 'application/vnd.android.package-archive'
return response
# 全局错误处理
@app.errorhandler(404)