Source code for testbot.config.setting

#!/usr/bin/env python
# -*- coding: utf-8 -*-


[docs]__author__ = "Nuanguang Gu(Sunny)"
[docs]__email__ = "nuanguang.gu@aliyun.com"
import os import json from abc import ABCMeta from functools import wraps from testbot.config import CONFIG_PATH
[docs]_DEFAULT_PATH = CONFIG_PATH
[docs]class SettingError(Exception): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
[docs]class SettingBase(metaclass=ABCMeta): """ 配置基类 """
[docs] file_name = None
[docs] setting_path = _DEFAULT_PATH
@classmethod
[docs] def _get_full_path(cls): """ 获取配置文件全路径 :return: 配置文件全路径 :rtype: str """ filename = cls.file_name if cls.file_name else cls.__name__ + ".json" return os.path.join(cls.setting_path, filename)
@classmethod
[docs] def save(cls): """ 保存配置文件 :return: None :rtype: NoneType """ if not os.path.exists(cls.setting_path): os.makedirs(cls.setting_path) with open(cls._get_full_path(), "w") as file: obj = dict() for key, value in cls.__dict__.items(): if key.startswith("_") or key == "setting_path" or key == "file_name": continue obj[key] = value json.dump(obj, file, indent=4)
@classmethod
[docs] def load(cls): """ 加载配置文件 :return: None :rtype: NoneType """ if os.path.exists(cls._get_full_path()): with open(cls._get_full_path()) as file: obj = json.load(file) for key, value in obj.items(): setattr(cls, key, value) else: cls.save()
[docs]def dynamic_setting(cls): """ 对SettingBase子类进行动态配置 :param cls: :type cls: :return: :rtype: """ @wraps(cls) def inner(*args, **kwargs): rv = cls(*args, **kwargs) for key, value in cls.__dict__.items(): if hasattr(value, "__base__") and value.__base__.__name__ == "SettingBase": setattr(rv, "setting", value) if hasattr(rv, "setting_path"): value.setting_path = rv.setting_path if hasattr(rv, "setting_file") and rv.setting_file is not None: value.file_name = rv.setting_file else: if value.file_name is None: value.file_name = f"{cls.__name__}_{value.__name__}.json" else: value.file_name = f"{cls.__name__}_{value.file_name}.json" value.load() return rv return inner
[docs]class TestSettingBase(SettingBase): """ 测试设置基类 """ def __init__(self, setting_path, filename): self.__class__.file_name = filename self.__class__.setting_path = setting_path
[docs]class StaticSettingManager(object): """ 静态配置管理类 """ def __init__(self): self.settings = dict() self._setting_path = _DEFAULT_PATH
[docs] def add_setting(self, setting_name: str, setting_class: object): """ 添加配置对象 :param setting_name: 配置名称 :type setting_name: str :param setting_class: 配置类 :type setting_class: object :return: :rtype: """ if hasattr(setting_class, "__base__"): if setting_class.__base__.__name__ != "SettingBase": raise SettingError("注册的配置必须是SettingBase的子类") else: raise SettingError("注册的配置必须是SettingBase的子类") self.settings[setting_name] = setting_class setting_class.setting_path = self._setting_path
[docs] def setting(self, setting_name: str, *args: tuple, **kwargs: dict): """ 配置文件的注册装饰器 :param setting_name: 配置名称 :type setting_name: str :param args: :type args: :param kwargs: :type kwargs: :return: :rtype: """ def wrapper(cls): self.add_setting(setting_name, cls) return cls return wrapper
@property
[docs] def setting_path(self) -> str: """ 设置路径 :return: 设置路径 :rtype: str """ return self._setting_path
@setting_path.setter def setting_path(self, value): self._setting_path = value for key, setting in self.settings.items(): setting.setting_path = value
[docs] def sync_path(self): """ 同步所有配置的路径 """ for key, setting in self.settings.items(): setting.setting_path = self._setting_path
[docs] def save_all(self): """ 保存所有配置 """ self.sync_path() for key, setting in self.settings.items(): setting.save()
[docs] def load_all(self): """ 读取所有配置 """ self.sync_path() for key, setting in self.settings.items(): setting.load()
[docs]static_setting = StaticSettingManager()