ADR-017 Phase 3f-1 system sprint;新增無 prefix system_public_bp,保留公開 URL 與 backup CSRF;ABC detail 併入 sales_bp。
177 lines
5.1 KiB
Python
177 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
爬蟲管理 API 路由
|
|
提供網頁介面來管理爬蟲的啟用/停用狀態
|
|
"""
|
|
from flask import Blueprint, jsonify, request, render_template, redirect, url_for
|
|
from services.crawler_config_loader import (
|
|
load_crawler_config,
|
|
update_crawler_status,
|
|
get_crawler_info,
|
|
get_enabled_crawlers,
|
|
get_paused_crawlers
|
|
)
|
|
import json
|
|
import os
|
|
from datetime import datetime
|
|
|
|
# 創建 Blueprint
|
|
crawler_bp = Blueprint('crawler_management', __name__)
|
|
|
|
CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'data', 'crawler_config.json')
|
|
|
|
@crawler_bp.route('/crawler_management')
|
|
def crawler_management_page():
|
|
"""爬蟲管理頁面 - 重定向到整合後的 settings 頁面"""
|
|
return redirect(url_for('system_public.settings'))
|
|
|
|
@crawler_bp.route('/api/crawlers', methods=['GET'])
|
|
def get_crawlers():
|
|
"""API: 取得所有爬蟲配置"""
|
|
try:
|
|
config = load_crawler_config()
|
|
return jsonify({
|
|
"status": "success",
|
|
"data": config.get('crawlers', {})
|
|
})
|
|
except Exception as e:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": str(e)
|
|
}), 500
|
|
|
|
@crawler_bp.route('/api/crawlers/<crawler_key>', methods=['GET'])
|
|
def get_crawler(crawler_key):
|
|
"""API: 取得單一爬蟲資訊"""
|
|
try:
|
|
info = get_crawler_info(crawler_key)
|
|
if info is None:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": f"爬蟲 {crawler_key} 不存在"
|
|
}), 404
|
|
|
|
return jsonify({
|
|
"status": "success",
|
|
"data": info
|
|
})
|
|
except Exception as e:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": str(e)
|
|
}), 500
|
|
|
|
@crawler_bp.route('/api/crawlers/<crawler_key>/toggle', methods=['POST'])
|
|
def toggle_crawler(crawler_key):
|
|
"""API: 切換爬蟲啟用/停用狀態"""
|
|
try:
|
|
data = request.get_json() or {}
|
|
enabled = data.get('enabled')
|
|
reason = data.get('reason', '')
|
|
|
|
if enabled is None:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": "缺少 enabled 參數"
|
|
}), 400
|
|
|
|
# 更新配置
|
|
success = update_crawler_status(crawler_key, enabled, reason)
|
|
|
|
if not success:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": "更新失敗"
|
|
}), 500
|
|
|
|
# 取得更新後的資訊
|
|
info = get_crawler_info(crawler_key)
|
|
|
|
return jsonify({
|
|
"status": "success",
|
|
"message": f"爬蟲 {info.get('name', crawler_key)} 已{'啟用' if enabled else '停用'}",
|
|
"data": info
|
|
})
|
|
|
|
except Exception as e:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": str(e)
|
|
}), 500
|
|
|
|
@crawler_bp.route('/api/crawlers/<crawler_key>/schedule', methods=['PUT'])
|
|
def update_crawler_schedule(crawler_key):
|
|
"""API: 更新爬蟲執行頻率"""
|
|
try:
|
|
data = request.get_json() or {}
|
|
schedule_hours = data.get('schedule_hours')
|
|
|
|
if schedule_hours is None:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": "缺少 schedule_hours 參數"
|
|
}), 400
|
|
|
|
try:
|
|
schedule_hours = int(schedule_hours)
|
|
if schedule_hours < 1 or schedule_hours > 24:
|
|
raise ValueError("執行頻率必須在 1-24 小時之間")
|
|
except ValueError as e:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": str(e)
|
|
}), 400
|
|
|
|
# 載入配置
|
|
config = load_crawler_config()
|
|
|
|
if crawler_key not in config.get('crawlers', {}):
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": f"爬蟲 {crawler_key} 不存在"
|
|
}), 404
|
|
|
|
# 更新執行頻率
|
|
config['crawlers'][crawler_key]['schedule_hours'] = schedule_hours
|
|
config['metadata']['last_updated'] = datetime.now().isoformat()
|
|
|
|
# 寫回配置文件
|
|
with open(CONFIG_PATH, 'w', encoding='utf-8') as f:
|
|
json.dump(config, f, ensure_ascii=False, indent=2)
|
|
|
|
return jsonify({
|
|
"status": "success",
|
|
"message": f"執行頻率已更新為每 {schedule_hours} 小時",
|
|
"data": config['crawlers'][crawler_key]
|
|
})
|
|
|
|
except Exception as e:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": str(e)
|
|
}), 500
|
|
|
|
@crawler_bp.route('/api/crawlers/status', methods=['GET'])
|
|
def get_crawlers_status():
|
|
"""API: 取得爬蟲狀態總覽"""
|
|
try:
|
|
enabled = get_enabled_crawlers()
|
|
paused = get_paused_crawlers()
|
|
|
|
return jsonify({
|
|
"status": "success",
|
|
"data": {
|
|
"enabled_count": len(enabled),
|
|
"paused_count": len(paused),
|
|
"enabled_crawlers": list(enabled.keys()),
|
|
"paused_crawlers": list(paused.keys())
|
|
}
|
|
})
|
|
|
|
except Exception as e:
|
|
return jsonify({
|
|
"status": "error",
|
|
"message": str(e)
|
|
}), 500
|