config.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. from pathlib import Path
  2. from typing import Optional
  3. import yaml
  4. from pydantic import BaseModel, SecretStr
  5. from .models import *
  6. class Config(BaseModel):
  7. bot: Bot = Bot()
  8. forwarding: Forwarding = Forwarding()
  9. logging: Logging = Logging()
  10. @classmethod
  11. def load(cls, cfg_path: Optional[Path] = None):
  12. filepath = Path(cfg_path)
  13. filepath.parent.mkdir(parents = True, exist_ok = True)
  14. if not filepath.exists():
  15. config = cls()
  16. else:
  17. with filepath.open(encoding = "utf-8") as config_file:
  18. config = cls(**yaml.safe_load(config_file))
  19. object.__setattr__(config, "filepath", filepath)
  20. if not filepath.exists():
  21. config.save()
  22. return config
  23. def save(self, cfg_path: Optional[Path] = None):
  24. if not getattr(self, "filepath") and not cfg_path:
  25. raise FileNotFoundError(f"Cannot find config file: {getattr(self.filepath) or cfg_path}")
  26. if not getattr(self, "filepath") or (not isinstance(cfg_path, Path) and cfg_path is not None):
  27. self.filepath = Path(cfg_path)
  28. self.filepath.parent.mkdir(parents = True, exist_ok = True)
  29. with open(self.filepath, "w", encoding = "utf-8") as config_file:
  30. yaml.dump(self._serialize(self.model_dump()), config_file, width = float("inf"), sort_keys = False)
  31. @classmethod
  32. def _serialize(cls, obj):
  33. if isinstance(obj, SecretStr):
  34. return obj.get_secret_value()
  35. elif isinstance(obj, dict):
  36. return {key: cls._serialize(value) for key, value in obj.items()}
  37. elif isinstance(obj, list):
  38. return [cls._serialize(value) for value in obj]
  39. return obj