- Introduce app/ package with config, services (storage, notifications), API server, and crawler modules - Add BaseCrawler and BarronsCrawler; extract notifications and storage - Keep enhanced_crawler.py as back-compat entry delegating to app.runner - Add template crawler for future sites - Update README with new structure and usage - Extend .env.template with DATA_DIR/LOG_DIR options
57 lines
2.1 KiB
Python
57 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from flask import Flask, jsonify, request
|
|
|
|
from app.services import notifications as notif
|
|
|
|
|
|
def create_app(crawler) -> Flask:
|
|
app = Flask(__name__)
|
|
|
|
@app.get('/health')
|
|
def health():
|
|
return jsonify({"status": "healthy", "timestamp": datetime.now().isoformat()})
|
|
|
|
@app.get('/stats')
|
|
def stats():
|
|
if crawler:
|
|
return jsonify(crawler.stats)
|
|
return jsonify({"error": "Crawler not initialized"}), 500
|
|
|
|
@app.get('/check')
|
|
def manual_check():
|
|
if not crawler:
|
|
return jsonify({"error": "Crawler not initialized"}), 500
|
|
result = crawler.run_check() or []
|
|
return jsonify({"result": f"Found {len(result)} new picks"})
|
|
|
|
@app.get('/notify_test')
|
|
def notify_test():
|
|
if not crawler:
|
|
return jsonify({"error": "Crawler not initialized"}), 500
|
|
channel = (request.args.get('channel') or 'email').lower()
|
|
test_pick = [notif.build_test_pick()]
|
|
try:
|
|
if channel == 'email':
|
|
if not crawler.config.email:
|
|
return jsonify({"error": "Email config not set"}), 400
|
|
notif.send_email(test_pick, crawler.config.email)
|
|
elif channel == 'webhook':
|
|
if not crawler.config.webhook_url:
|
|
return jsonify({"error": "Webhook URL not set"}), 400
|
|
notif.send_webhook(test_pick, crawler.config.webhook_url)
|
|
elif channel == 'discord':
|
|
if not crawler.config.discord_webhook:
|
|
return jsonify({"error": "Discord webhook not set"}), 400
|
|
notif.send_discord(test_pick, crawler.config.discord_webhook)
|
|
else:
|
|
return jsonify({"error": f"Unsupported channel: {channel}"}), 400
|
|
return jsonify({"result": f"Test notification sent via {channel}"})
|
|
except Exception as e:
|
|
crawler.logger.error(f"測試通知發送失敗: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
return app
|
|
|