157 lines
5.0 KiB
Python
157 lines
5.0 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
應用程式配置模組
|
|
|
|
Author: PANJIT IT Team
|
|
Created: 2024-01-28
|
|
Modified: 2024-01-28
|
|
"""
|
|
|
|
import os
|
|
import secrets
|
|
from pathlib import Path
|
|
from datetime import timedelta
|
|
from dotenv import load_dotenv
|
|
|
|
# 載入環境變數
|
|
load_dotenv()
|
|
|
|
class Config:
|
|
"""基礎配置類別"""
|
|
|
|
# 基本應用配置
|
|
SECRET_KEY = os.environ.get('SECRET_KEY') or secrets.token_hex(32)
|
|
APP_NAME = os.environ.get('APP_NAME', 'PANJIT Document Translator')
|
|
|
|
# 資料庫配置
|
|
DATABASE_URL = os.environ.get('DATABASE_URL')
|
|
if DATABASE_URL and DATABASE_URL.startswith("mysql://"):
|
|
DATABASE_URL = DATABASE_URL.replace("mysql://", "mysql+pymysql://", 1)
|
|
|
|
SQLALCHEMY_DATABASE_URI = DATABASE_URL
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
SQLALCHEMY_ENGINE_OPTIONS = {
|
|
'pool_pre_ping': True,
|
|
'pool_recycle': 3600,
|
|
'connect_args': {
|
|
'charset': os.environ.get('MYSQL_CHARSET', 'utf8mb4'),
|
|
'connect_timeout': 30,
|
|
'read_timeout': 30,
|
|
'write_timeout': 30,
|
|
}
|
|
}
|
|
|
|
# JWT 配置 - 改用 JWT 認證
|
|
JWT_SECRET_KEY = os.environ.get('JWT_SECRET_KEY') or SECRET_KEY
|
|
JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=8)
|
|
JWT_REFRESH_TOKEN_EXPIRES = timedelta(days=30)
|
|
JWT_ALGORITHM = 'HS256'
|
|
|
|
# Redis 配置
|
|
REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379/0')
|
|
|
|
# Celery 配置
|
|
CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', 'redis://localhost:6379/0')
|
|
CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND', 'redis://localhost:6379/0')
|
|
CELERY_TASK_SERIALIZER = 'json'
|
|
CELERY_RESULT_SERIALIZER = 'json'
|
|
CELERY_ACCEPT_CONTENT = ['json']
|
|
CELERY_TIMEZONE = 'Asia/Taipei'
|
|
CELERY_ENABLE_UTC = True
|
|
|
|
# LDAP 配置
|
|
LDAP_SERVER = os.environ.get('LDAP_SERVER')
|
|
LDAP_PORT = int(os.environ.get('LDAP_PORT', 389))
|
|
LDAP_USE_SSL = os.environ.get('LDAP_USE_SSL', 'false').lower() == 'true'
|
|
LDAP_BIND_USER_DN = os.environ.get('LDAP_BIND_USER_DN')
|
|
LDAP_BIND_USER_PASSWORD = os.environ.get('LDAP_BIND_USER_PASSWORD')
|
|
LDAP_SEARCH_BASE = os.environ.get('LDAP_SEARCH_BASE')
|
|
LDAP_USER_LOGIN_ATTR = os.environ.get('LDAP_USER_LOGIN_ATTR', 'userPrincipalName')
|
|
|
|
# SMTP 配置
|
|
SMTP_SERVER = os.environ.get('SMTP_SERVER')
|
|
SMTP_PORT = int(os.environ.get('SMTP_PORT', 587))
|
|
SMTP_USE_TLS = os.environ.get('SMTP_USE_TLS', 'false').lower() == 'true'
|
|
SMTP_USE_SSL = os.environ.get('SMTP_USE_SSL', 'false').lower() == 'true'
|
|
SMTP_AUTH_REQUIRED = os.environ.get('SMTP_AUTH_REQUIRED', 'false').lower() == 'true'
|
|
SMTP_SENDER_EMAIL = os.environ.get('SMTP_SENDER_EMAIL')
|
|
SMTP_SENDER_PASSWORD = os.environ.get('SMTP_SENDER_PASSWORD', '')
|
|
|
|
# 檔案上傳配置
|
|
UPLOAD_FOLDER = Path(os.environ.get('UPLOAD_FOLDER', 'uploads')).absolute()
|
|
MAX_CONTENT_LENGTH = int(os.environ.get('MAX_CONTENT_LENGTH', 26214400)) # 25MB
|
|
ALLOWED_EXTENSIONS = {'.docx', '.doc', '.pptx', '.xlsx', '.xls', '.pdf'}
|
|
FILE_RETENTION_DAYS = int(os.environ.get('FILE_RETENTION_DAYS', 7))
|
|
|
|
# Dify API 配置(從 api.txt 載入)
|
|
DIFY_API_BASE_URL = ''
|
|
DIFY_API_KEY = ''
|
|
|
|
# 日誌配置
|
|
LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')
|
|
LOG_FILE = Path(os.environ.get('LOG_FILE', 'logs/app.log')).absolute()
|
|
|
|
# 管理員配置
|
|
ADMIN_EMAIL = os.environ.get('ADMIN_EMAIL', 'ymirliu@panjit.com.tw')
|
|
|
|
@classmethod
|
|
def load_dify_config(cls):
|
|
"""從 api.txt 載入 Dify API 配置"""
|
|
api_file = Path('api.txt')
|
|
if api_file.exists():
|
|
try:
|
|
with open(api_file, 'r', encoding='utf-8') as f:
|
|
for line in f:
|
|
if line.startswith('base_url:'):
|
|
cls.DIFY_API_BASE_URL = line.split(':', 1)[1].strip()
|
|
elif line.startswith('api:'):
|
|
cls.DIFY_API_KEY = line.split(':', 1)[1].strip()
|
|
except Exception:
|
|
pass
|
|
|
|
@classmethod
|
|
def init_directories(cls):
|
|
"""初始化必要目錄"""
|
|
directories = [
|
|
cls.UPLOAD_FOLDER,
|
|
cls.LOG_FILE.parent,
|
|
]
|
|
|
|
for directory in directories:
|
|
directory.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
class DevelopmentConfig(Config):
|
|
"""開發環境配置"""
|
|
DEBUG = True
|
|
FLASK_ENV = 'development'
|
|
|
|
|
|
class ProductionConfig(Config):
|
|
"""生產環境配置"""
|
|
DEBUG = False
|
|
FLASK_ENV = 'production'
|
|
|
|
# 生產環境的額外配置
|
|
SQLALCHEMY_ENGINE_OPTIONS = {
|
|
**Config.SQLALCHEMY_ENGINE_OPTIONS,
|
|
'pool_size': 10,
|
|
'max_overflow': 20,
|
|
}
|
|
|
|
|
|
class TestingConfig(Config):
|
|
"""測試環境配置"""
|
|
TESTING = True
|
|
WTF_CSRF_ENABLED = False
|
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
|
|
|
|
|
|
# 配置映射
|
|
config = {
|
|
'development': DevelopmentConfig,
|
|
'production': ProductionConfig,
|
|
'testing': TestingConfig,
|
|
'default': DevelopmentConfig
|
|
} |