feat: 新增平台

This commit is contained in:
2025-11-30 19:49:25 +08:00
parent c3e56a954d
commit fbd2c491b2
41 changed files with 4293 additions and 76 deletions

View File

@@ -1,4 +1,5 @@
from flask import Blueprint, render_template, redirect
from flask import Blueprint, render_template, redirect, request, Response
import requests
main_bp = Blueprint('main', __name__)
@@ -11,6 +12,12 @@ def index():
config[c.config_key] = c.config_value
return render_template('index.html', config=config)
@main_bp.route('/api-docs')
def api_docs():
"""API 文档页面"""
return render_template('api_docs.html')
@main_bp.route('/favicon.ico')
def favicon():
"""处理 favicon 请求"""
@@ -24,3 +31,106 @@ def favicon():
return redirect(logo_config.config_value)
# 返回空响应避免 404
return '', 204
@main_bp.route('/proxy/download')
def proxy_download():
"""代理下载视频/图片,绕过防盗链,支持 Range 请求"""
url = request.args.get('url')
if not url:
return 'Missing url parameter', 400
# 限制只能代理特定域名
allowed_domains = [
'weibocdn.com', 'sinaimg.cn', 'weibo.com',
'ppxvod.com', 'byteimg.com', 'pipix.com', '365yg.com', 'ixigua.com',
'kwimgs.com', 'kwaicdn.com', 'kuaishou.com', 'gifshow.com', 'yximgs.com',
'douyinvod.com', 'douyin.com', 'tiktokcdn.com', 'bytedance.com',
'bilivideo.com', 'bilibili.com', 'hdslb.com',
'zjcdn.com', 'douyinpic.com'
]
from urllib.parse import urlparse
parsed = urlparse(url)
domain = parsed.netloc.lower()
is_allowed = any(d in domain for d in allowed_domains)
if not is_allowed:
return f'Domain not allowed: {domain}', 403
# 根据域名设置不同的 Referer
referer_map = {
'weibo': 'https://weibo.com/',
'sina': 'https://weibo.com/',
'pipix': 'https://www.pipix.com/',
'365yg': 'https://www.pipix.com/',
'ixigua': 'https://www.ixigua.com/',
'kuaishou': 'https://www.kuaishou.com/',
'kwimgs': 'https://www.kuaishou.com/',
'kwaicdn': 'https://www.kuaishou.com/',
'yximgs': 'https://www.kuaishou.com/',
'douyin': 'https://www.douyin.com/',
'bytedance': 'https://www.douyin.com/',
'zjcdn': 'https://www.douyin.com/',
'douyinpic': 'https://www.douyin.com/',
'bilibili': 'https://www.bilibili.com/',
'hdslb': 'https://www.bilibili.com/',
}
referer = 'https://www.google.com/'
for key, ref in referer_map.items():
if key in domain:
referer = ref
break
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Referer': referer
}
# 转发 Range 请求头,支持视频进度条拖动
range_header = request.headers.get('Range')
if range_header:
headers['Range'] = range_header
resp = requests.get(url, headers=headers, stream=True, timeout=30)
# 获取文件类型
content_type = resp.headers.get('Content-Type', 'application/octet-stream')
# 设置下载文件名
if 'video' in content_type:
filename = f'video_{int(__import__("time").time())}.mp4'
elif 'image' in content_type:
filename = f'image_{int(__import__("time").time())}.jpg'
else:
filename = f'file_{int(__import__("time").time())}'
def generate():
for chunk in resp.iter_content(chunk_size=8192):
yield chunk
# 构建响应头
response_headers = {
'Content-Type': content_type,
'Accept-Ranges': 'bytes'
}
# 转发相关响应头
if resp.headers.get('Content-Length'):
response_headers['Content-Length'] = resp.headers.get('Content-Length')
if resp.headers.get('Content-Range'):
response_headers['Content-Range'] = resp.headers.get('Content-Range')
# 根据是否是 Range 请求返回不同状态码
status_code = resp.status_code
return Response(
generate(),
status=status_code,
headers=response_headers
)
except Exception as e:
return f'Download failed: {str(e)}', 500