Files
Document_Translator/app/config.py
2025-09-03 09:05:51 +08:00

157 lines
5.1 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.

#!/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 = False # 改為 False讓 Celery 使用本地時區
# 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
}