config.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. '''
  2. Created on 17 avr. 2018
  3. @author: olivier.massot
  4. '''
  5. import collections
  6. from cerberus.validator import Validator
  7. import yaml
  8. from yaml.parser import ParserError
  9. from core import constants
  10. CONFIG = {}
  11. _SCHEMA = {
  12. 'repertoire_defaut': {'type': 'string', 'required': True},
  13. 'repertoire_sortie': {'type': 'string', 'required': True},
  14. 'donnees': {
  15. 'type': 'dict',
  16. 'schema': {
  17. 'dict': {'type': 'dict', 'required': True},
  18. 'dt': {'type': 'dict', 'required': True},
  19. 'commun': {'type': 'dict', 'required': True},
  20. },
  21. 'required': True
  22. },
  23. 'mail': {'type': 'dict',
  24. 'schema': {
  25. 'dict': {
  26. 'type': 'dict',
  27. 'schema': {
  28. 'dest': {'type': 'string', 'required': True},
  29. 'objet': {'type': 'string', 'required': True},
  30. 'texte': {'type': 'string', 'required': True},
  31. },
  32. 'required': True
  33. },
  34. 'dt': {
  35. 'type': 'dict',
  36. 'schema': {
  37. 'dest': {'type': 'string'},
  38. 'objet': {'type': 'string'},
  39. 'texte': {'type': 'string'},
  40. },
  41. 'required': True
  42. }
  43. },
  44. 'required': True
  45. },
  46. 'modifiables': {'type': 'list', 'required': True}
  47. }
  48. class MissingConfigFile(Exception):
  49. """ Fichier de configuration manquant """
  50. pass
  51. class InvalidConfigFile(Exception):
  52. """ Fichier de configuration invalide """
  53. pass
  54. def deepupdate(d, u):
  55. for k, v in u.items():
  56. if isinstance(v, collections.Mapping):
  57. d[k] = deepupdate(d.get(k, {}), v)
  58. else:
  59. d[k] = v
  60. return d
  61. def load():
  62. # charge le fichier de configuration de base
  63. try:
  64. with open(constants.CONFIG_FILE_PATH, "rb") as f:
  65. baseconf = yaml.load(f)
  66. except FileNotFoundError:
  67. raise MissingConfigFile("Le fichier de configuration '{}' est introuvable".format(constants.CONFIG_FILE_PATH))
  68. except ParserError as e:
  69. raise InvalidConfigFile("Le fichier de configuration '{}' comporte des erreurs ({})".format(constants.CONFIG_FILE_PATH, e))
  70. deepupdate(CONFIG, baseconf)
  71. # surcharge la config avec la config utilisateur
  72. try:
  73. with open(constants.USER_DATA_PATH, "rb") as f:
  74. userconf = yaml.load(f)
  75. except FileNotFoundError:
  76. pass
  77. except ParserError as e:
  78. raise InvalidConfigFile("Le fichier de configuration '{}' comporte des erreurs ({})".format(constants.USER_DATA_PATH, e))
  79. userconf = patch1(userconf)
  80. userconf = {key: value for key, value in userconf.items() if value}
  81. deepupdate(CONFIG, userconf)
  82. # contrôle le schema de la config
  83. validator = Validator(_SCHEMA, allow_unknown=True)
  84. if not validator.validate(CONFIG):
  85. raise InvalidConfigFile("Erreur dans les fichiers de configuration: {}".format(validator.errors))
  86. def get(*keys):
  87. dataset = dict(CONFIG)
  88. for key in keys:
  89. dataset = dataset[key]
  90. return dataset
  91. def patch1(userconf):
  92. """ corrige le fichier de données utilisateur entre la verison 1.0 et 1.1 """
  93. if not "donnees" in userconf:
  94. userconf = {"donnees": {"commun": userconf}}
  95. return userconf
  96. if __name__ == "__main__":
  97. load()
  98. print(CONFIG)