feat: 新增 automation 自动化模块和配置管理
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
"""
|
||||
配置管理模块
|
||||
优先级:Web UI 设置 (data/config.json) > 环境变量 > 默认值
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'config.json')
|
||||
|
||||
# 默认配置
|
||||
DEFAULT_CONFIG = {
|
||||
'secsion': {
|
||||
'username': '',
|
||||
'password': ''
|
||||
},
|
||||
'scheduler': {
|
||||
'enabled': True,
|
||||
'hour': 1,
|
||||
'minute': 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def _ensure_config_dir():
|
||||
"""确保配置目录存在"""
|
||||
os.makedirs(os.path.dirname(CONFIG_FILE), exist_ok=True)
|
||||
|
||||
|
||||
def _load_config():
|
||||
"""从 config.json 加载配置"""
|
||||
try:
|
||||
if os.path.exists(CONFIG_FILE):
|
||||
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
logger.warning(f"读取配置文件失败: {e}")
|
||||
return {}
|
||||
|
||||
|
||||
def _save_config(config):
|
||||
"""保存配置到 config.json"""
|
||||
_ensure_config_dir()
|
||||
try:
|
||||
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
|
||||
json.dump(config, f, ensure_ascii=False, indent=2)
|
||||
logger.info("配置已保存")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"保存配置文件失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
class Config:
|
||||
"""配置管理器"""
|
||||
|
||||
@staticmethod
|
||||
def get_secsion_credentials():
|
||||
"""
|
||||
获取 secsion.com 登录凭据
|
||||
|
||||
优先级:config.json > 环境变量
|
||||
|
||||
Returns:
|
||||
tuple: (username, password) 或 None
|
||||
"""
|
||||
# 1. 从 config.json 读取
|
||||
config = _load_config()
|
||||
secsion = config.get('secsion', {})
|
||||
username = secsion.get('username', '').strip()
|
||||
password = secsion.get('password', '').strip()
|
||||
|
||||
if username and password:
|
||||
return (username, password)
|
||||
|
||||
# 2. 从环境变量读取
|
||||
env_username = os.environ.get('SECSION_USERNAME', '').strip()
|
||||
env_password = os.environ.get('SECSION_PASSWORD', '').strip()
|
||||
|
||||
if env_username and env_password:
|
||||
return (env_username, env_password)
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def save_secsion_credentials(username, password):
|
||||
"""保存 secsion.com 登录凭据"""
|
||||
config = _load_config()
|
||||
config.setdefault('secsion', {})
|
||||
config['secsion']['username'] = username
|
||||
config['secsion']['password'] = password
|
||||
return _save_config(config)
|
||||
|
||||
@staticmethod
|
||||
def get_schedule_config():
|
||||
"""
|
||||
获取定时任务配置
|
||||
|
||||
Returns:
|
||||
dict: {'enabled': bool, 'hour': int, 'minute': int}
|
||||
"""
|
||||
config = _load_config()
|
||||
schedule = config.get('scheduler', {})
|
||||
|
||||
# 回退到环境变量
|
||||
env_enabled = os.environ.get('SCHEDULER_ENABLED', '').lower()
|
||||
env_hour = os.environ.get('SCHEDULER_HOUR', '')
|
||||
env_minute = os.environ.get('SCHEDULER_MINUTE', '')
|
||||
|
||||
return {
|
||||
'enabled': schedule.get('enabled', env_enabled != 'false' if env_enabled else True),
|
||||
'hour': schedule.get('hour', int(env_hour) if env_hour else 1),
|
||||
'minute': schedule.get('minute', int(env_minute) if env_minute else 0)
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def save_schedule_config(enabled=True, hour=1, minute=0):
|
||||
"""保存定时任务配置"""
|
||||
config = _load_config()
|
||||
config.setdefault('scheduler', {})
|
||||
config['scheduler']['enabled'] = enabled
|
||||
config['scheduler']['hour'] = hour
|
||||
config['scheduler']['minute'] = minute
|
||||
return _save_config(config)
|
||||
|
||||
@staticmethod
|
||||
def get_shop_id():
|
||||
"""获取店铺 ID"""
|
||||
config = _load_config()
|
||||
secsion = config.get('secsion', {})
|
||||
shop_id = secsion.get('shop_id', '').strip()
|
||||
if shop_id:
|
||||
return shop_id
|
||||
return os.environ.get('SECSION_SHOP_ID', '').strip() or None
|
||||
|
||||
@staticmethod
|
||||
def save_shop_id(shop_id):
|
||||
"""保存店铺 ID"""
|
||||
config = _load_config()
|
||||
config.setdefault('secsion', {})
|
||||
config['secsion']['shop_id'] = shop_id
|
||||
return _save_config(config)
|
||||
|
||||
@staticmethod
|
||||
def get_all_config():
|
||||
"""获取所有配置(密码脱敏)"""
|
||||
config = _load_config()
|
||||
secsion = config.get('secsion', {})
|
||||
|
||||
return {
|
||||
'secsion': {
|
||||
'username': secsion.get('username', ''),
|
||||
'password': '******' if secsion.get('password') else '',
|
||||
'shop_id': secsion.get('shop_id', '')
|
||||
},
|
||||
'scheduler': config.get('scheduler', DEFAULT_CONFIG['scheduler'])
|
||||
}
|
||||
Reference in New Issue
Block a user