Kamixitong/config.py
2025-11-22 16:48:45 +08:00

146 lines
6.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from datetime import timedelta
import logging
from logging.handlers import TimedRotatingFileHandler
class Config:
"""基础配置类"""
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key-change-in-production'
# 数据库配置 - 优先使用环境变量中的DATABASE_URL
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'sqlite:///instance/kamaxitong.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
# SQLAlchemy 2.0 兼容性设置和连接池优化
SQLALCHEMY_ENGINE_OPTIONS = {
"future": True,
"pool_pre_ping": True, # 连接前检查连接是否有效
"pool_size": int(os.environ.get('DB_POOL_SIZE', 10)), # 连接池大小
"max_overflow": int(os.environ.get('DB_MAX_OVERFLOW', 20)), # 最大溢出连接数
"pool_recycle": int(os.environ.get('DB_POOL_RECYCLE', 3600)), # 连接回收时间(秒)
"pool_timeout": int(os.environ.get('DB_POOL_TIMEOUT', 30)), # 获取连接超时时间(秒)
"echo": False, # 关闭SQL日志输出生产环境
}
# 系统基本配置
SITE_NAME = os.environ.get('SITE_NAME') or '软件授权管理系统'
ADMIN_EMAIL = os.environ.get('ADMIN_EMAIL') or ''
# 前端域名配置 - 支持多种环境变量
FRONTEND_DOMAIN = os.environ.get('FRONTEND_DOMAIN') or os.environ.get('DOMAIN_NAME') or os.environ.get('SERVER_NAME') or ''
# 确保域名不包含协议部分
if FRONTEND_DOMAIN.startswith(('http://', 'https://')):
FRONTEND_DOMAIN = FRONTEND_DOMAIN.split('://', 1)[1]
# 验证器配置
AUTH_SECRET_KEY = os.environ.get('AUTH_SECRET_KEY') or 'auth-validator-secret-key'
OFFLINE_CACHE_DAYS = int(os.environ.get('OFFLINE_CACHE_DAYS', 7)) # 离线缓存天数
MAX_FAILED_ATTEMPTS = int(os.environ.get('MAX_FAILED_ATTEMPTS', 5)) # 最大失败次数
LOCKOUT_MINUTES = int(os.environ.get('LOCKOUT_MINUTES', 10)) # 锁定时间(分钟)
MAX_UNBIND_TIMES = int(os.environ.get('MAX_UNBIND_TIMES', 3)) # 最大解绑次数
# 卡密配置
LICENSE_KEY_LENGTH = int(os.environ.get('LICENSE_KEY_LENGTH', 32)) # 卡密长度
LICENSE_KEY_PREFIX = os.environ.get('LICENSE_KEY_PREFIX', '') # 卡密前缀
TRIAL_PREFIX = os.environ.get('TRIAL_PREFIX') or 'TRIAL_' # 试用卡密前缀
# API配置
API_VERSION = os.environ.get('API_VERSION') or 'v1'
ITEMS_PER_PAGE = int(os.environ.get('ITEMS_PER_PAGE', 20))
# 文件上传配置 - 增加到500MB
MAX_CONTENT_LENGTH = int(os.environ.get('MAX_CONTENT_LENGTH', 500 * 1024 * 1024)) # 500MB
UPLOAD_FOLDER = os.environ.get('UPLOAD_FOLDER') or 'static/uploads'
# 会话配置 - 增强的会话管理
PERMANENT_SESSION_LIFETIME = timedelta(hours=int(os.environ.get('SESSION_LIFETIME_HOURS', 168))) # 默认延长到7天
# 添加更多会话相关配置
SESSION_COOKIE_SECURE = os.environ.get('SESSION_COOKIE_SECURE', 'False').lower() == 'true' # 在生产环境中设为True
SESSION_COOKIE_HTTPONLY = os.environ.get('SESSION_COOKIE_HTTPONLY', 'True').lower() == 'true'
SESSION_COOKIE_SAMESITE = os.environ.get('SESSION_COOKIE_SAMESITE', 'Lax') # 改为Lax以提高兼容性
# 记住我功能配置
REMEMBER_COOKIE_DURATION = timedelta(days=int(os.environ.get('REMEMBER_COOKIE_DURATION', 30))) # 记住我功能持续30天
REMEMBER_COOKIE_SECURE = os.environ.get('REMEMBER_COOKIE_SECURE', 'False').lower() == 'true' # 生产环境中设为True
REMEMBER_COOKIE_HTTPONLY = os.environ.get('REMEMBER_COOKIE_HTTPONLY', 'True').lower() == 'true'
REMEMBER_COOKIE_SAMESITE = os.environ.get('REMEMBER_COOKIE_SAMESITE', 'Lax')
# 日志配置
LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')
LOG_FILE = os.environ.get('LOG_FILE', 'logs/kamaxitong.log')
@staticmethod
def init_app(app):
"""初始化应用配置"""
# 确保日志目录存在
import os
if not os.path.exists('logs'):
os.mkdir('logs')
# 配置日志 - 使用时间轮转而不是大小轮转来避免Windows文件锁定问题
import logging
from logging.handlers import TimedRotatingFileHandler
# 使用时间轮转日志处理器,每天轮转一次
file_handler = TimedRotatingFileHandler('logs/kamaxitong.log', when='midnight', interval=1, backupCount=10, encoding='utf-8')
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')
class DevelopmentConfig(Config):
"""开发环境配置"""
DEBUG = True
SQLALCHEMY_ECHO = False # 关闭SQL日志输出以提高性能需要调试时可临时开启
class ProductionConfig(Config):
"""生产环境配置"""
DEBUG = False
SQLALCHEMY_ECHO = False
@staticmethod
def init_app(app):
Config.init_app(app)
# 生产环境日志配置
import logging
from logging.handlers import TimedRotatingFileHandler
if not app.debug:
# 确保日志目录存在
import os
if not os.path.exists('logs'):
os.mkdir('logs')
# 使用时间轮转日志处理器,每天轮转一次
file_handler = TimedRotatingFileHandler('logs/kamaxitong.log', when='midnight', interval=1, backupCount=10, encoding='utf-8')
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')
class TestingConfig(Config):
"""测试环境配置"""
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
WTF_CSRF_ENABLED = False
# 为内存数据库禁用连接池配置
SQLALCHEMY_ENGINE_OPTIONS = {
"future": True,
"echo": False,
}
# 配置字典
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'testing': TestingConfig,
'default': DevelopmentConfig
}