uodata add continue download
This commit is contained in:
77
app.py
77
app.py
@@ -1,5 +1,6 @@
|
|||||||
from waitress import serve
|
from waitress import serve
|
||||||
from flask import Flask, render_template, request, redirect, url_for, jsonify, session, send_from_directory, g
|
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
|
from datetime import datetime
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
@@ -12,6 +13,10 @@ import pandas as pd
|
|||||||
app = Flask(__name__, template_folder='templates')
|
app = Flask(__name__, template_folder='templates')
|
||||||
app.secret_key = os.urandom(24) # 设置会话密钥
|
app.secret_key = os.urandom(24) # 设置会话密钥
|
||||||
|
|
||||||
|
# 初始化Gzip压缩
|
||||||
|
compress = Compress()
|
||||||
|
compress.init_app(app)
|
||||||
|
|
||||||
# 配置日志
|
# 配置日志
|
||||||
if not os.path.exists(LOG_DIR):
|
if not os.path.exists(LOG_DIR):
|
||||||
os.makedirs(LOG_DIR)
|
os.makedirs(LOG_DIR)
|
||||||
@@ -156,10 +161,78 @@ def contact():
|
|||||||
def serve_log_file(filename):
|
def serve_log_file(filename):
|
||||||
return send_from_directory(LOG_DIR, filename)
|
return send_from_directory(LOG_DIR, filename)
|
||||||
|
|
||||||
# 服务下载目录中的文件
|
# 服务下载目录中的文件 - 优化版本
|
||||||
@app.route('/downloads/<path:filename>')
|
@app.route('/downloads/<path:filename>')
|
||||||
def serve_download_file(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)
|
@app.errorhandler(404)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 32 KiB |
BIN
static/images/不同操作系统下载图标 (15).png
Normal file
BIN
static/images/不同操作系统下载图标 (15).png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 564 KiB |
@@ -3,12 +3,12 @@
|
|||||||
{% block title %}{{ t('pricing') if t('pricing') else '收费' }}{% endblock %}
|
{% block title %}{{ t('pricing') if t('pricing') else '收费' }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="hero">
|
<!-- <section class="hero">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>{{ t('contact_us') if t('contact_us') else '联系我们' }}</h2>
|
<h2>{{ t('contact_us') if t('contact_us') else '联系我们' }}</h2>
|
||||||
<p>{{ t('contact_description') if t('contact_description') else '富泽国际,竭诚为您服务!' }}</p>
|
<p>{{ t('contact_description') if t('contact_description') else '富泽国际,竭诚为您服务!' }}</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section> -->
|
||||||
|
|
||||||
<section class="contact">
|
<section class="contact">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
{% block title %}{{ t('download') if t('download') else '下载' }}{% endblock %}
|
{% block title %}{{ t('download') if t('download') else '下载' }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="hero">
|
<!-- <section class="hero">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>{{ t('download_clients') if t('download_clients') else '客户端下载' }}</h2>
|
<h2>{{ t('download_clients') if t('download_clients') else '客户端下载' }}</h2>
|
||||||
<p>{{ t('download_description') if t('download_description') else '下载我们的客户端,体验更便捷的服务' }}</p>
|
<p>{{ t('download_description') if t('download_description') else '下载我们的客户端,体验更便捷的服务' }}</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section> -->
|
||||||
|
|
||||||
<section class="services">
|
<section class="services">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -86,8 +86,8 @@
|
|||||||
<script>
|
<script>
|
||||||
// 创建下载接口
|
// 创建下载接口
|
||||||
function downloadApk() {
|
function downloadApk() {
|
||||||
// 提供下载的文件
|
// 提供下载的文件 - 使用相对路径避免DNS解析延迟
|
||||||
const apkUrl = "https://www.fuzsec.com/downloads/hkfuze-online-release_4.60.0_2025-06-20.apk";
|
const apkUrl = "/downloads/hkfuze-online-release_4.60.0_2025-06-20.apk";
|
||||||
|
|
||||||
// 创建隐藏的下载链接并模拟点击
|
// 创建隐藏的下载链接并模拟点击
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
{% block title %}{{ t('pricing') if t('pricing') else '收费' }}{% endblock %}
|
{% block title %}{{ t('pricing') if t('pricing') else '收费' }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="hero">
|
<!-- <section class="hero">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>{{ t('pricing') if t('pricing') else '收费方案' }}</h2>
|
<h2>{{ t('pricing') if t('pricing') else '收费方案' }}</h2>
|
||||||
<p>{{ t('pricing_description') if t('pricing_description') else '透明合理的收费结构,助力您的投资成功' }}</p>
|
<p>{{ t('pricing_description') if t('pricing_description') else '透明合理的收费结构,助力您的投资成功' }}</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section> -->
|
||||||
|
|
||||||
<section class="commission-table">
|
<section class="commission-table">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|||||||
2331
新建文本文档.html
2331
新建文本文档.html
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user