181 lines
4.5 KiB
Python
181 lines
4.5 KiB
Python
import asyncio
|
||
from flask import Flask, jsonify, request
|
||
import jwt
|
||
import datetime
|
||
import os
|
||
from functools import wraps
|
||
|
||
from download import M3U8Downloader
|
||
from function import crawl_missav
|
||
from urllib.parse import urlparse
|
||
|
||
app = Flask(__name__)
|
||
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'your-secret-key-here')
|
||
|
||
downloader = M3U8Downloader(max_workers=10, output_dir=r"download")
|
||
|
||
# 从环境变量获取用户名密码
|
||
USERNAME = os.getenv('USER')
|
||
PASSWORD = os.getenv('PASSWORD')
|
||
|
||
|
||
def token_required(f):
|
||
@wraps(f)
|
||
def decorated(*args, **kwargs):
|
||
token = request.headers.get(f'Authorization')
|
||
|
||
if not token:
|
||
return jsonify({
|
||
'msg': '请登录',
|
||
'code': 403,
|
||
}), 403
|
||
|
||
# 检查token格式
|
||
if token.startswith('Bearer '):
|
||
token = token[7:]
|
||
|
||
try:
|
||
# 解码token
|
||
data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
|
||
current_user = data['user']
|
||
except jwt.ExpiredSignatureError:
|
||
return jsonify({
|
||
'msg': '登录已过期,请重新登录',
|
||
'code': 403,
|
||
}), 403
|
||
except jwt.InvalidTokenError:
|
||
return jsonify({
|
||
'msg': '无效的token',
|
||
'code': 403,
|
||
}), 403
|
||
|
||
return f(*args, **kwargs)
|
||
|
||
return decorated
|
||
|
||
|
||
@app.route('/api/login', methods=['POST'])
|
||
def login():
|
||
data = request.get_json()
|
||
|
||
if not data:
|
||
return jsonify({
|
||
'msg': '请提供用户名和密码',
|
||
'code': 400,
|
||
}), 400
|
||
|
||
username = data.get('username')
|
||
password = data.get('password')
|
||
|
||
# 验证用户名密码
|
||
if username == USERNAME and password == PASSWORD:
|
||
# 生成token,1小时过期
|
||
token = jwt.encode({
|
||
'user': username,
|
||
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
|
||
}, app.config['SECRET_KEY'], algorithm='HS256')
|
||
|
||
return jsonify({
|
||
'msg': '登录成功',
|
||
'code': 200,
|
||
'data': {
|
||
'token': token,
|
||
'expires_in': 3600 # 1小时,单位秒
|
||
}
|
||
}), 200
|
||
else:
|
||
return jsonify({
|
||
'msg': '用户名或密码错误',
|
||
'code': 401,
|
||
}), 401
|
||
|
||
|
||
@app.route('/api/check/<path:url>')
|
||
@token_required
|
||
def check_url(url):
|
||
status = is_from_missav(url)
|
||
if (status):
|
||
result = asyncio.run(crawl_missav(
|
||
url
|
||
))
|
||
return jsonify({
|
||
'msg': '成功',
|
||
'code': 200,
|
||
'dat': result
|
||
}), 200
|
||
else:
|
||
return jsonify({
|
||
'msg': '不是来自missav的链接',
|
||
'code': 500
|
||
}), 200
|
||
|
||
|
||
@app.route('/api/download', methods=['POST'])
|
||
# @token_required
|
||
def download():
|
||
data = request.get_json()
|
||
|
||
if not data:
|
||
return jsonify({'error': 'No JSON data provided'}), 400
|
||
|
||
name = data.get('name')
|
||
url = data.get('url')
|
||
|
||
if not name or not url:
|
||
return jsonify({'error': 'Missing name or url parameter'}), 400
|
||
|
||
task_id = downloader.download(
|
||
output_filename=f"{name}.mp4",
|
||
m3u8_url=url
|
||
)
|
||
return jsonify({
|
||
'msg': '成功',
|
||
'code': 200,
|
||
'dat': task_id
|
||
}), 200
|
||
|
||
|
||
@app.route('/api/all-task', methods=['GET'])
|
||
# @token_required
|
||
def all_task():
|
||
all_tasks = downloader.get_all_tasks()
|
||
return jsonify({
|
||
'msg': '成功',
|
||
'code': 200,
|
||
'data': all_tasks
|
||
}), 200
|
||
|
||
|
||
@app.route('/api/progress/<path:task_id>', methods=['GET'])
|
||
@token_required
|
||
def progress(task_id):
|
||
progress_info = downloader.get_progress(task_id)
|
||
|
||
filename = progress_info['filename']
|
||
progress = progress_info['progress'] # 0~1的浮点数,如0.56表示56%
|
||
status = progress_info['status']
|
||
|
||
print(f"文件: {filename}, 进度: {progress:.2%}, 状态: {status}")
|
||
return jsonify({
|
||
'msg': '成功',
|
||
'code': 200,
|
||
'data': {'name': filename, 'progress': progress}
|
||
}), 200
|
||
|
||
|
||
def is_from_missav(url):
|
||
try:
|
||
parsed = urlparse(url)
|
||
hostname = parsed.netloc.lower()
|
||
return hostname == 'missav.ws' or hostname.endswith('.missav.ws')
|
||
except:
|
||
return False
|
||
|
||
|
||
if __name__ == '__main__':
|
||
# 检查环境变量是否设置
|
||
if not USERNAME or not PASSWORD:
|
||
print("警告: 请设置环境变量 USER 和 PASSWORD")
|
||
|
||
app.run(debug=True, host='0.0.0.0', port=5000)
|