2025-08-13 18:49:19 +08:00
|
|
|
|
from flask import Flask, request, Response
|
|
|
|
|
|
import logging
|
|
|
|
|
|
from config import config
|
|
|
|
|
|
from handlers.registry import HandlerRegistry
|
|
|
|
|
|
from utils.rss_generator import RSSGenerator
|
|
|
|
|
|
|
|
|
|
|
|
# 配置日志
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
def create_app(config_name='default'):
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
app.config.from_object(config[config_name])
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化处理器注册中心
|
|
|
|
|
|
handler_registry = HandlerRegistry()
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化RSS生成器
|
|
|
|
|
|
rss_generator = RSSGenerator(
|
|
|
|
|
|
title=app.config['RSS_TITLE'],
|
|
|
|
|
|
description=app.config['RSS_DESCRIPTION'],
|
|
|
|
|
|
link=app.config['RSS_LINK'],
|
|
|
|
|
|
language=app.config['RSS_LANGUAGE']
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/')
|
|
|
|
|
|
def index():
|
|
|
|
|
|
"""API文档页面"""
|
|
|
|
|
|
available_handlers = handler_registry.list_handlers()
|
|
|
|
|
|
docs = f"""
|
|
|
|
|
|
<h1>Crypto RSS Service</h1>
|
|
|
|
|
|
<h2>可用的RSS订阅源:</h2>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
for handler_name in available_handlers:
|
|
|
|
|
|
if handler_name == 'crypto':
|
|
|
|
|
|
docs += f"""
|
|
|
|
|
|
<li><a href="/rss/{handler_name}?pair=ETH-USDT">/rss/{handler_name}?pair=ETH-USDT</a> - ETH价格</li>
|
|
|
|
|
|
<li><a href="/rss/{handler_name}?pair=BTC-USDT">/rss/{handler_name}?pair=BTC-USDT</a> - BTC价格</li>
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
docs += """
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
<h2>使用说明:</h2>
|
|
|
|
|
|
<p>将RSS链接粘贴到您的墨水屏RSS阅读器中即可。</p>
|
|
|
|
|
|
"""
|
|
|
|
|
|
return docs
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/rss/<handler_name>')
|
|
|
|
|
|
def rss_feed(handler_name):
|
|
|
|
|
|
"""RSS订阅源端点"""
|
|
|
|
|
|
handler = handler_registry.get_handler(handler_name)
|
|
|
|
|
|
|
|
|
|
|
|
if not handler:
|
|
|
|
|
|
return Response("Handler not found", status=404)
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 获取查询参数
|
|
|
|
|
|
request_params = request.args.to_dict()
|
|
|
|
|
|
|
|
|
|
|
|
# 让处理器处理请求
|
|
|
|
|
|
items = handler.handle(**request_params)
|
|
|
|
|
|
|
2025-08-13 22:48:17 +08:00
|
|
|
|
if not items:
|
|
|
|
|
|
return Response("No data available", status=204)
|
|
|
|
|
|
|
|
|
|
|
|
if handler_name == 'crypto':
|
|
|
|
|
|
motdTitle = request_params.get('pair', app.config['DEFAULT_CRYPTO_PAIR'])
|
|
|
|
|
|
motdTitle = motdTitle.replace('-', '/').upper()
|
|
|
|
|
|
rss_xml = rss_generator.generate_rss(items, motdTitle=motdTitle)
|
|
|
|
|
|
else:
|
|
|
|
|
|
rss_xml = rss_generator.generate_rss(items)
|
2025-08-13 18:49:19 +08:00
|
|
|
|
|
|
|
|
|
|
return Response(rss_xml, mimetype='application/rss+xml')
|
2025-08-13 22:48:17 +08:00
|
|
|
|
|
2025-08-13 18:49:19 +08:00
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"生成RSS时出错: {e}")
|
|
|
|
|
|
error_items = [{
|
|
|
|
|
|
"title": "服务暂时不可用",
|
|
|
|
|
|
"description": f"生成RSS时出现错误: {str(e)}",
|
|
|
|
|
|
"link": app.config['RSS_LINK']
|
|
|
|
|
|
}]
|
|
|
|
|
|
rss_xml = rss_generator.generate_rss(error_items)
|
|
|
|
|
|
return Response(rss_xml, mimetype='application/rss+xml', status=500)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/health')
|
|
|
|
|
|
def health_check():
|
|
|
|
|
|
"""健康检查端点"""
|
|
|
|
|
|
return {"status": "healthy", "available_handlers": handler_registry.list_handlers()}
|
|
|
|
|
|
|
|
|
|
|
|
return app
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
app = create_app('development')
|
|
|
|
|
|
app.run(host='0.0.0.0', port=5000, debug=True)
|