MissAV-Download/api.py
2025-11-07 11:15:09 +08:00

181 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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:
# 生成token1小时过期
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)