完成基础开发
This commit is contained in:
1
backend/api/__init__.py
Normal file
1
backend/api/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# API 蓝图模块
|
115
backend/api/clients.py
Normal file
115
backend/api/clients.py
Normal file
@ -0,0 +1,115 @@
|
||||
"""
|
||||
客户端管理 API 蓝图
|
||||
"""
|
||||
from flask import Blueprint, request, jsonify
|
||||
from services.client_service import ClientService
|
||||
|
||||
clients_bp = Blueprint('clients', __name__, url_prefix='/api/clients')
|
||||
client_service = ClientService()
|
||||
|
||||
|
||||
@clients_bp.route('', methods=['GET'])
|
||||
def get_clients():
|
||||
"""获取所有客户端列表"""
|
||||
try:
|
||||
clients = client_service.get_clients_with_connection()
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': clients
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@clients_bp.route('', methods=['POST'])
|
||||
def add_client():
|
||||
"""添加新客户端"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
|
||||
# 验证必需字段
|
||||
required_fields = ['name', 'host', 'port']
|
||||
for field in required_fields:
|
||||
if field not in data:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'缺少必需字段: {field}'
|
||||
}), 400
|
||||
|
||||
client = client_service.add_client(data)
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': client
|
||||
}), 201
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@clients_bp.route('/<client_id>', methods=['PUT'])
|
||||
def update_client(client_id):
|
||||
"""更新客户端配置"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
client = client_service.update_client(client_id, data)
|
||||
|
||||
if client:
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': client
|
||||
})
|
||||
else:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '客户端不存在'
|
||||
}), 404
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@clients_bp.route('/<client_id>', methods=['DELETE'])
|
||||
def delete_client(client_id):
|
||||
"""删除客户端"""
|
||||
try:
|
||||
success = client_service.delete_client(client_id)
|
||||
|
||||
if success:
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '客户端删除成功'
|
||||
})
|
||||
else:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '客户端不存在'
|
||||
}), 404
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@clients_bp.route('/<client_id>/test', methods=['POST'])
|
||||
def test_client_connection(client_id):
|
||||
"""测试客户端连接"""
|
||||
try:
|
||||
result = client_service.test_client_connection(client_id)
|
||||
return jsonify(result)
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
254
backend/api/torrents.py
Normal file
254
backend/api/torrents.py
Normal file
@ -0,0 +1,254 @@
|
||||
"""
|
||||
种子管理 API 蓝图
|
||||
"""
|
||||
from flask import Blueprint, request, jsonify
|
||||
from werkzeug.utils import secure_filename
|
||||
import os
|
||||
import tempfile
|
||||
from services.torrent_service import TorrentService
|
||||
|
||||
torrents_bp = Blueprint('torrents', __name__, url_prefix='/api/torrents')
|
||||
torrent_service = TorrentService()
|
||||
|
||||
|
||||
@torrents_bp.route('', methods=['GET'])
|
||||
def get_torrents():
|
||||
"""获取种子列表"""
|
||||
try:
|
||||
# 获取查询参数
|
||||
client_ids = request.args.getlist('client_ids')
|
||||
|
||||
data = torrent_service.get_all_torrents(client_ids if client_ids else None)
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': data
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@torrents_bp.route('/maindata', methods=['GET'])
|
||||
def get_maindata():
|
||||
"""获取主要数据(聚合接口)"""
|
||||
try:
|
||||
# 获取查询参数
|
||||
client_ids = request.args.getlist('client_ids')
|
||||
|
||||
data = torrent_service.get_all_torrents(client_ids if client_ids else None)
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': data
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@torrents_bp.route('/pause', methods=['POST'])
|
||||
def pause_torrents():
|
||||
"""暂停种子"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
torrent_hashes = data.get('hashes', [])
|
||||
client_id = data.get('client_id')
|
||||
|
||||
if not torrent_hashes:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请提供要暂停的种子哈希值'
|
||||
}), 400
|
||||
|
||||
result = torrent_service.pause_torrents(torrent_hashes, client_id)
|
||||
return jsonify(result)
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@torrents_bp.route('/resume', methods=['POST'])
|
||||
def resume_torrents():
|
||||
"""恢复种子"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
torrent_hashes = data.get('hashes', [])
|
||||
client_id = data.get('client_id')
|
||||
|
||||
if not torrent_hashes:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请提供要恢复的种子哈希值'
|
||||
}), 400
|
||||
|
||||
result = torrent_service.resume_torrents(torrent_hashes, client_id)
|
||||
return jsonify(result)
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@torrents_bp.route('/delete', methods=['POST'])
|
||||
def delete_torrents():
|
||||
"""删除种子"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
torrent_hashes = data.get('hashes', [])
|
||||
client_id = data.get('client_id')
|
||||
delete_files = data.get('delete_files', False)
|
||||
|
||||
if not torrent_hashes:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请提供要删除的种子哈希值'
|
||||
}), 400
|
||||
|
||||
result = torrent_service.delete_torrents(torrent_hashes, delete_files, client_id)
|
||||
return jsonify(result)
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@torrents_bp.route('/<torrent_hash>/details', methods=['GET'])
|
||||
def get_torrent_details(torrent_hash):
|
||||
"""获取种子详细信息"""
|
||||
try:
|
||||
client_id = request.args.get('client_id')
|
||||
|
||||
if not client_id:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请提供客户端ID'
|
||||
}), 400
|
||||
|
||||
details = torrent_service.get_torrent_details(torrent_hash, client_id)
|
||||
|
||||
if details:
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': details
|
||||
})
|
||||
else:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '种子不存在或无法获取详细信息'
|
||||
}), 404
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@torrents_bp.route('/add', methods=['POST'])
|
||||
def add_torrent():
|
||||
"""添加种子"""
|
||||
try:
|
||||
# 获取客户端ID
|
||||
client_id = request.form.get('client_id') or request.json.get('client_id') if request.is_json else None
|
||||
|
||||
if not client_id:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请指定客户端ID'
|
||||
}), 400
|
||||
|
||||
# 检查添加方式
|
||||
if 'torrent_file' in request.files:
|
||||
# 种子文件上传
|
||||
return _add_torrent_file(client_id)
|
||||
elif request.is_json:
|
||||
data = request.get_json()
|
||||
if 'magnet_link' in data:
|
||||
# 磁力链接
|
||||
return _add_magnet_link(client_id, data['magnet_link'], data.get('options', {}))
|
||||
elif 'torrent_url' in data:
|
||||
# 种子URL
|
||||
return _add_torrent_url(client_id, data['torrent_url'], data.get('options', {}))
|
||||
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请提供种子文件、磁力链接或种子URL'
|
||||
}), 400
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
def _add_torrent_file(client_id):
|
||||
"""添加种子文件"""
|
||||
file = request.files['torrent_file']
|
||||
if file.filename == '':
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请选择种子文件'
|
||||
}), 400
|
||||
|
||||
if not file.filename.lower().endswith('.torrent'):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '请上传.torrent文件'
|
||||
}), 400
|
||||
|
||||
# 获取可选参数
|
||||
options = {
|
||||
'category': request.form.get('category', ''),
|
||||
'tags': request.form.get('tags', ''),
|
||||
'save_path': request.form.get('save_path', ''),
|
||||
'paused': request.form.get('paused', 'false').lower() == 'true'
|
||||
}
|
||||
|
||||
# 保存临时文件
|
||||
filename = secure_filename(file.filename)
|
||||
with tempfile.NamedTemporaryFile(delete=False, suffix='.torrent') as temp_file:
|
||||
file.save(temp_file.name)
|
||||
|
||||
try:
|
||||
result = torrent_service.add_torrent_file(client_id, temp_file.name, options)
|
||||
return jsonify(result)
|
||||
finally:
|
||||
# 清理临时文件
|
||||
os.unlink(temp_file.name)
|
||||
|
||||
|
||||
def _add_magnet_link(client_id, magnet_link, options):
|
||||
"""添加磁力链接"""
|
||||
if not magnet_link.startswith('magnet:'):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '无效的磁力链接'
|
||||
}), 400
|
||||
|
||||
result = torrent_service.add_magnet_link(client_id, magnet_link, options)
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
def _add_torrent_url(client_id, torrent_url, options):
|
||||
"""添加种子URL"""
|
||||
if not torrent_url.startswith(('http://', 'https://')):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '无效的种子URL'
|
||||
}), 400
|
||||
|
||||
result = torrent_service.add_torrent_url(client_id, torrent_url, options)
|
||||
return jsonify(result)
|
Reference in New Issue
Block a user