config.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import pathlib
  2. import json
  3. import json.decoder
  4. from .exception import config_exception
  5. from .app_resources import app_resources
  6. class config:
  7. def __init__(self, defaults: dict) -> None:
  8. self.__defaults = defaults.copy()
  9. self.__config = defaults.copy()
  10. def _get(self, name: str) -> str | int | float | dict | list:
  11. if not name in self.__config:
  12. raise TypeError("Can not found " + name + " in config.")
  13. return self.__config[name]
  14. def __get_default(self, name: str) -> str | int | float | dict | list:
  15. return self.__defaults[name]
  16. @property
  17. def defaults(self) -> dict:
  18. return self.__defaults.copy()
  19. def exists(self, name: str) -> bool:
  20. return name in self.__defaults
  21. def load(self, config: dict) -> object:
  22. for key in config:
  23. if not self.exists(key):
  24. content = "When parsing config file found key " + key + " "
  25. content = content + "which is not recognized. Correct it."
  26. raise config_exception(content)
  27. if type(config[key]) is not type(self.__get_default(key)):
  28. required_type = type(self.__get_default).__name__
  29. detected_type = type(config[key]).__name__
  30. content = "When processing \"" + key + "\" key in config "
  31. content = content + "detected types mismatch. It would be an "
  32. content = content + required_type + ", but it is an "
  33. content = content + detected_type + "."
  34. raise config_exception(content)
  35. self.__config[key] = config[key]
  36. return self
  37. def __str__(self) -> str:
  38. dump = "Config dump: \n"
  39. for count in self.defaults.keys():
  40. key = "Key \"" + count + "\": "
  41. key = key + "\"" + self._get(count) + "\", "
  42. key = key + "default = \"" + self.__get_default(count) + "\""
  43. dump = dump + key + "\n"
  44. return dump
  45. class config_generator:
  46. def __init__(self, target: type) -> None:
  47. if target is config:
  48. raise TypeError("Config is skeleton class for configs.")
  49. self.__config = target().defaults
  50. def modify(self, key: str, value: str | int | float) -> object:
  51. if not key in self.__config:
  52. raise config_exception("Key \"" + key + "\" not exists.")
  53. self.__config[key] = value
  54. return self
  55. def save(self, where: pathlib.Path) -> None:
  56. json_config = json.dumps(self.__config)
  57. if where.exists():
  58. content = "Can not create config file \"" + str(where) + "\" "
  59. content = content + "because it already exists in filesystem."
  60. raise config_exception(content)
  61. with where.open("w") as handler:
  62. handler.write(json_config)
  63. class config_loader:
  64. def __init__(self, target: type) -> None:
  65. if target is config:
  66. raise TypeError("Config is skeleton class for configs.")
  67. self.__type = target
  68. self.__target = None
  69. @property
  70. def result(self) -> config:
  71. if self.__target is None:
  72. raise RuntimeError("Config is not loaded yet.")
  73. return self.__target
  74. @property
  75. def resources(self) -> app_resources:
  76. return app_resources(self.result)
  77. def load(self, where: pathlib.Path) -> object:
  78. if not where.is_file():
  79. content = "Can not found required config file \""
  80. content = content + str(where.absolute()) + "\"."
  81. raise config_exception(content)
  82. preparing = self.__type()
  83. with where.open() as config:
  84. try:
  85. config_object = json.loads(config.read())
  86. preparing.load(config_object)
  87. self.__target = preparing
  88. except json.decoder.JSONDecodeError as code_error:
  89. content = "Can not load config file, syntax error: "
  90. content = content + str(code_error) + "."
  91. raise config_error(content)
  92. return self