|
import json |
|
from pathlib import Path |
|
from threading import RLock |
|
import os |
|
import copy |
|
|
|
|
|
class ConfigManager: |
|
_instance = None |
|
_lock = RLock() |
|
|
|
@classmethod |
|
def get_instance(cls): |
|
"""获取单例实例""" |
|
|
|
if cls._instance is None: |
|
with cls._lock: |
|
if cls._instance is None: |
|
cls._instance = cls() |
|
return cls._instance |
|
|
|
def __init__(self): |
|
|
|
if hasattr(self, "_initialized") and self._initialized: |
|
return |
|
self._initialized = True |
|
|
|
self._config_path = Path.home() / ".config" / "PDFMathTranslate" / "config.json" |
|
self._config_data = {} |
|
|
|
|
|
self._ensure_config_exists() |
|
|
|
def _ensure_config_exists(self, isInit=True): |
|
"""确保配置文件存在,如果不存在则创建默认配置""" |
|
|
|
|
|
if not self._config_path.exists(): |
|
if isInit: |
|
self._config_path.parent.mkdir(parents=True, exist_ok=True) |
|
self._config_data = {} |
|
self._save_config() |
|
else: |
|
raise ValueError(f"config file {self._config_path} not found!") |
|
else: |
|
self._load_config() |
|
|
|
def _load_config(self): |
|
"""从 config.json 中加载配置""" |
|
with self._lock: |
|
with self._config_path.open("r", encoding="utf-8") as f: |
|
self._config_data = json.load(f) |
|
|
|
def _save_config(self): |
|
"""保存配置到 config.json""" |
|
with self._lock: |
|
|
|
cleaned_data = self._remove_circular_references(self._config_data) |
|
with self._config_path.open("w", encoding="utf-8") as f: |
|
json.dump(cleaned_data, f, indent=4, ensure_ascii=False) |
|
|
|
def _remove_circular_references(self, obj, seen=None): |
|
"""递归移除循环引用""" |
|
if seen is None: |
|
seen = set() |
|
obj_id = id(obj) |
|
if obj_id in seen: |
|
return None |
|
seen.add(obj_id) |
|
|
|
if isinstance(obj, dict): |
|
return { |
|
k: self._remove_circular_references(v, seen) for k, v in obj.items() |
|
} |
|
elif isinstance(obj, list): |
|
return [self._remove_circular_references(i, seen) for i in obj] |
|
return obj |
|
|
|
@classmethod |
|
def custome_config(cls, file_path): |
|
"""使用自定义路径加载配置文件""" |
|
custom_path = Path(file_path) |
|
if not custom_path.exists(): |
|
raise ValueError(f"Config file {custom_path} not found!") |
|
|
|
with cls._lock: |
|
instance = cls() |
|
instance._config_path = custom_path |
|
|
|
instance._ensure_config_exists(isInit=False) |
|
cls._instance = instance |
|
|
|
@classmethod |
|
def get(cls, key, default=None): |
|
"""获取配置值""" |
|
instance = cls.get_instance() |
|
|
|
|
|
if key in instance._config_data: |
|
return instance._config_data[key] |
|
|
|
|
|
if key in os.environ: |
|
value = os.environ[key] |
|
instance._config_data[key] = value |
|
instance._save_config() |
|
return value |
|
|
|
|
|
if default is not None: |
|
instance._config_data[key] = default |
|
instance._save_config() |
|
return default |
|
|
|
|
|
|
|
return default |
|
|
|
@classmethod |
|
def set(cls, key, value): |
|
"""设置配置值并保存""" |
|
instance = cls.get_instance() |
|
with instance._lock: |
|
instance._config_data[key] = value |
|
instance._save_config() |
|
|
|
@classmethod |
|
def get_translator_by_name(cls, name): |
|
"""根据 name 获取对应的 translator 配置""" |
|
instance = cls.get_instance() |
|
translators = instance._config_data.get("translators", []) |
|
for translator in translators: |
|
if translator.get("name") == name: |
|
return translator["envs"] |
|
return None |
|
|
|
@classmethod |
|
def set_translator_by_name(cls, name, new_translator_envs): |
|
"""根据 name 设置或更新 translator 配置""" |
|
instance = cls.get_instance() |
|
with instance._lock: |
|
translators = instance._config_data.get("translators", []) |
|
for translator in translators: |
|
if translator.get("name") == name: |
|
translator["envs"] = copy.deepcopy(new_translator_envs) |
|
instance._save_config() |
|
return |
|
translators.append( |
|
{"name": name, "envs": copy.deepcopy(new_translator_envs)} |
|
) |
|
instance._config_data["translators"] = translators |
|
instance._save_config() |
|
|
|
@classmethod |
|
def get_env_by_translatername(cls, translater_name, name, default=None): |
|
"""根据 name 获取对应的 translator 配置""" |
|
instance = cls.get_instance() |
|
translators = instance._config_data.get("translators", []) |
|
for translator in translators: |
|
if translator.get("name") == translater_name.name: |
|
if translator["envs"][name]: |
|
return translator["envs"][name] |
|
else: |
|
with instance._lock: |
|
translator["envs"][name] = default |
|
instance._save_config() |
|
return default |
|
|
|
with instance._lock: |
|
translators = instance._config_data.get("translators", []) |
|
for translator in translators: |
|
if translator.get("name") == translater_name.name: |
|
translator["envs"][name] = default |
|
instance._save_config() |
|
return default |
|
translators.append( |
|
{ |
|
"name": translater_name.name, |
|
"envs": copy.deepcopy(translater_name.envs), |
|
} |
|
) |
|
instance._config_data["translators"] = translators |
|
instance._save_config() |
|
return default |
|
|
|
@classmethod |
|
def delete(cls, key): |
|
"""删除配置值并保存""" |
|
instance = cls.get_instance() |
|
with instance._lock: |
|
if key in instance._config_data: |
|
del instance._config_data[key] |
|
instance._save_config() |
|
|
|
@classmethod |
|
def clear(cls): |
|
"""删除配置值并保存""" |
|
instance = cls.get_instance() |
|
with instance._lock: |
|
instance._config_data = {} |
|
instance._save_config() |
|
|
|
@classmethod |
|
def all(cls): |
|
"""返回所有配置项""" |
|
instance = cls.get_instance() |
|
|
|
return instance._config_data |
|
|
|
@classmethod |
|
def remove(cls): |
|
instance = cls.get_instance() |
|
with instance._lock: |
|
os.remove(instance._config_path) |
|
|