2025-11-11 21:39:12 +08:00
|
|
|
|
import os
|
|
|
|
|
|
from flask import Flask
|
|
|
|
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
|
|
|
|
from flask_login import LoginManager
|
|
|
|
|
|
from flask_migrate import Migrate
|
|
|
|
|
|
from config import config
|
2025-11-13 16:51:51 +08:00
|
|
|
|
from flask_wtf.csrf import CSRFProtect
|
2025-11-16 19:56:14 +08:00
|
|
|
|
from flask_cors import CORS
|
2025-11-15 23:57:05 +08:00
|
|
|
|
import logging
|
|
|
|
|
|
from logging.handlers import RotatingFileHandler
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
# 初始化扩展
|
|
|
|
|
|
db = SQLAlchemy()
|
|
|
|
|
|
login_manager = LoginManager()
|
|
|
|
|
|
migrate = Migrate()
|
2025-11-13 16:51:51 +08:00
|
|
|
|
csrf = CSRFProtect()
|
2025-11-16 19:56:14 +08:00
|
|
|
|
cors = CORS()
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
def create_app(config_name='default'):
|
|
|
|
|
|
"""应用工厂函数"""
|
|
|
|
|
|
# 设置模板和静态文件夹
|
|
|
|
|
|
app_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
template_folder = os.path.join(app_dir, 'web', 'templates')
|
|
|
|
|
|
static_folder = os.path.join(os.path.dirname(app_dir), 'static')
|
|
|
|
|
|
|
|
|
|
|
|
app = Flask(__name__,
|
|
|
|
|
|
template_folder=template_folder,
|
|
|
|
|
|
static_folder=static_folder)
|
|
|
|
|
|
|
|
|
|
|
|
# 尝试加载.env文件
|
|
|
|
|
|
try:
|
|
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
if load_dotenv():
|
|
|
|
|
|
print("成功加载.env文件")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("未找到或无法加载.env文件")
|
|
|
|
|
|
except ImportError:
|
|
|
|
|
|
print("python-dotenv未安装,跳过.env文件加载")
|
|
|
|
|
|
|
|
|
|
|
|
app.config.from_object(config[config_name])
|
|
|
|
|
|
config[config_name].init_app(app)
|
|
|
|
|
|
|
|
|
|
|
|
# 特别确保MAX_CONTENT_LENGTH配置正确应用
|
|
|
|
|
|
max_content_length = app.config.get('MAX_CONTENT_LENGTH', 16 * 1024 * 1024)
|
|
|
|
|
|
app.config['MAX_CONTENT_LENGTH'] = max_content_length
|
|
|
|
|
|
print(f"Setting MAX_CONTENT_LENGTH to: {max_content_length} bytes ({max_content_length / (1024*1024)} MB)")
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化扩展
|
|
|
|
|
|
db.init_app(app)
|
|
|
|
|
|
login_manager.init_app(app)
|
|
|
|
|
|
migrate.init_app(app, db)
|
2025-11-13 16:51:51 +08:00
|
|
|
|
csrf.init_app(app)
|
2025-11-16 19:56:14 +08:00
|
|
|
|
cors.init_app(app, resources={r"/api/*": {"origins": "*"}})
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
# 配置登录管理器
|
2025-11-19 22:49:24 +08:00
|
|
|
|
login_manager.login_view = 'web.login' # type: ignore
|
2025-11-11 21:39:12 +08:00
|
|
|
|
login_manager.login_message = '请先登录'
|
|
|
|
|
|
login_manager.login_message_category = 'info'
|
|
|
|
|
|
login_manager.id_attribute = 'get_id' # 使用 get_id 方法获取用户ID
|
2025-11-19 22:49:24 +08:00
|
|
|
|
login_manager.session_protection = 'strong' # 启用强会话保护
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
# 注册蓝图
|
|
|
|
|
|
from app.api import api_bp
|
|
|
|
|
|
app.register_blueprint(api_bp, url_prefix=f'/api/{app.config["API_VERSION"]}')
|
2025-11-13 16:51:51 +08:00
|
|
|
|
csrf.exempt(api_bp)
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
2025-11-19 22:49:24 +08:00
|
|
|
|
from app.web import web_bp, user_bp
|
2025-11-11 21:39:12 +08:00
|
|
|
|
app.register_blueprint(web_bp)
|
2025-11-19 22:49:24 +08:00
|
|
|
|
app.register_blueprint(user_bp)
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
# 注册错误处理器
|
|
|
|
|
|
from app.web.views import register_error_handlers
|
|
|
|
|
|
register_error_handlers(app)
|
|
|
|
|
|
|
2025-11-15 23:57:05 +08:00
|
|
|
|
# 配置日志
|
|
|
|
|
|
if not app.debug and not app.testing:
|
|
|
|
|
|
# 确保日志目录存在
|
|
|
|
|
|
if not os.path.exists('logs'):
|
|
|
|
|
|
os.mkdir('logs')
|
|
|
|
|
|
|
|
|
|
|
|
# 配置文件日志处理器
|
|
|
|
|
|
file_handler = RotatingFileHandler('logs/kamaxitong.log', maxBytes=10240, backupCount=10)
|
|
|
|
|
|
file_handler.setFormatter(logging.Formatter(
|
|
|
|
|
|
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
|
|
|
|
|
|
))
|
|
|
|
|
|
file_handler.setLevel(logging.INFO)
|
|
|
|
|
|
app.logger.addHandler(file_handler)
|
|
|
|
|
|
|
|
|
|
|
|
app.logger.setLevel(logging.INFO)
|
|
|
|
|
|
app.logger.info('KaMiXiTong startup')
|
|
|
|
|
|
|
2025-11-13 16:51:51 +08:00
|
|
|
|
return app
|