feat: implement config service with JSON read/write and safe fallback
- DEFAULT_CONFIG defines output_format, output_quality, output_dir, last_garment_dir, last_print_dir - load_config(): merges file values with defaults; never raises on missing, damaged, or non-object JSON root - save_config(): creates config/ dir as needed; logs error on failure Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +1,58 @@
|
|||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
DEFAULT_CONFIG = {
|
||||||
|
"output_format": "PNG", # PNG or JPG
|
||||||
|
"output_quality": 95, # JPG quality 1-95
|
||||||
|
"output_dir": "", # empty = use app output/ dir
|
||||||
|
"last_garment_dir": "",
|
||||||
|
"last_print_dir": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
_CONFIG_FILENAME = "app_config.json"
|
||||||
|
|
||||||
|
|
||||||
def load_config():
|
def load_config():
|
||||||
return {}
|
"""Load app config from JSON. Returns defaults merged with file values.
|
||||||
|
|
||||||
|
Never raises: missing file → info log + defaults;
|
||||||
|
damaged file → warning log + defaults.
|
||||||
|
"""
|
||||||
|
from services.file_service import get_config_path
|
||||||
|
config_file = get_config_path(_CONFIG_FILENAME)
|
||||||
|
|
||||||
|
if not config_file.exists():
|
||||||
|
logger.info("Config file not found, using defaults: %s", config_file)
|
||||||
|
return dict(DEFAULT_CONFIG)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(str(config_file), encoding="utf-8") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
raise ValueError("Config root is not a JSON object")
|
||||||
|
merged = dict(DEFAULT_CONFIG)
|
||||||
|
merged.update(data)
|
||||||
|
logger.info("Config loaded from %s", config_file)
|
||||||
|
return merged
|
||||||
|
except (json.JSONDecodeError, ValueError) as exc:
|
||||||
|
logger.warning("Config file damaged (%s), using defaults: %s", exc, config_file)
|
||||||
|
return dict(DEFAULT_CONFIG)
|
||||||
|
except OSError as exc:
|
||||||
|
logger.warning("Config file unreadable (%s), using defaults: %s", exc, config_file)
|
||||||
|
return dict(DEFAULT_CONFIG)
|
||||||
|
|
||||||
|
|
||||||
|
def save_config(data):
|
||||||
|
"""Save config dict to JSON. Logs error on failure, does not raise."""
|
||||||
|
from services.file_service import get_config_path
|
||||||
|
config_file = get_config_path(_CONFIG_FILENAME)
|
||||||
|
|
||||||
|
try:
|
||||||
|
config_file.parent.mkdir(exist_ok=True)
|
||||||
|
with open(str(config_file), "w", encoding="utf-8") as f:
|
||||||
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||||
|
logger.info("Config saved to %s", config_file)
|
||||||
|
except OSError as exc:
|
||||||
|
logger.error("Failed to save config to %s: %s", config_file, exc)
|
||||||
|
|||||||
@@ -109,18 +109,18 @@
|
|||||||
|
|
||||||
任务:
|
任务:
|
||||||
|
|
||||||
- [ ] 先读取 `src/services/config_service.py` 现有内容
|
- [x] 先读取 `src/services/config_service.py` 现有内容
|
||||||
- [ ] 完善 `src/services/config_service.py`
|
- [x] 完善 `src/services/config_service.py`
|
||||||
- [ ] 定义默认配置
|
- [x] 定义默认配置
|
||||||
- [ ] 支持读取 JSON 配置
|
- [x] 支持读取 JSON 配置
|
||||||
- [ ] 支持保存 JSON 配置
|
- [x] 支持保存 JSON 配置
|
||||||
- [ ] 配置损坏时使用安全默认值并记录日志
|
- [x] 配置损坏时使用安全默认值并记录日志
|
||||||
|
|
||||||
验收:
|
验收:
|
||||||
|
|
||||||
- [ ] 缺少配置文件时程序可启动
|
- [x] 缺少配置文件时程序可启动
|
||||||
- [ ] 配置文件损坏时程序可启动并记录日志
|
- [x] 配置文件损坏时程序可启动并记录日志
|
||||||
- [ ] 不会无提示清空用户配置
|
- [x] 不会无提示清空用户配置
|
||||||
|
|
||||||
## 2. 核心数据模型
|
## 2. 核心数据模型
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user