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/') @token_required def check_url(url): try: result = asyncio.run(crawl_missav( url )) return jsonify({ 'msg': '成功', 'code': 200, 'dat': result }), 200 except: 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/', 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 if __name__ == '__main__': # 检查环境变量是否设置 if not USERNAME or not PASSWORD: print("警告: 请设置环境变量 USER 和 PASSWORD") app.run(debug=True, host='0.0.0.0', port=5000)