config_manager_b.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import json
  2. import os
  3. import copy
  4. def save_json_file(file_path, data):
  5. """Sauvegarde générique de données JSON."""
  6. try:
  7. os.makedirs(os.path.dirname(file_path), exist_ok=True)
  8. with open(file_path, 'w', encoding='utf-8') as f:
  9. json.dump(data, f, indent=4)
  10. return True, None
  11. except Exception as e:
  12. return False, str(e)
  13. def load_json_file(file_path):
  14. """Chargement générique de données JSON."""
  15. if not os.path.exists(file_path):
  16. return None, "File not found"
  17. try:
  18. with open(file_path, 'r', encoding='utf-8') as f:
  19. data = json.load(f)
  20. return data, None
  21. except Exception as e:
  22. return None, str(e)
  23. class ConfigManager:
  24. # Source de vérité unique pour les paramètres d'usine
  25. DEFAULT_CONFIG = {
  26. "machine_settings": {
  27. "theme": "Dark",
  28. "language": "English",
  29. "cmd_mode": "M67 (Analog)",
  30. "firing_mode": "M3/M5",
  31. "m67_e_num": "0",
  32. "ctrl_max": "1000",
  33. "gcode_extension": ".nc",
  34. "laser_latency": 0.0,
  35. "premove": 10.0,
  36. "hor_linestep": 0.1,
  37. "ver_linestep": 0.1,
  38. "enable_thumbnails": True,
  39. "custom_header": "",
  40. "custom_footer": ""
  41. },
  42. "stats": {
  43. "total_lines": 0,
  44. "total_gcodes": 0,
  45. "total_time_seconds": 0.0
  46. }
  47. }
  48. def __init__(self, config_path):
  49. self.config_path = config_path
  50. self.data = self._load_from_disk()
  51. self._apply_defaults()
  52. def _load_from_disk(self):
  53. """Charge le fichier JSON ou renvoie un dict vide si absent/corrompu"""
  54. if not os.path.exists(self.config_path):
  55. return {}
  56. try:
  57. with open(self.config_path, 'r', encoding='utf-8') as f:
  58. return json.load(f)
  59. except Exception:
  60. return {}
  61. def _apply_defaults(self):
  62. """Injecte les valeurs par défaut manquantes dans les données chargées"""
  63. for section, content in self.DEFAULT_CONFIG.items():
  64. if section not in self.data:
  65. self.data[section] = copy.deepcopy(content)
  66. else:
  67. for key, val in content.items():
  68. if key not in self.data[section]:
  69. self.data[section][key] = val
  70. def get_item(self, section, key, default=None):
  71. """LA MÉTHODE MANQUANTE : Récupère une valeur spécifique"""
  72. section_data = self.data.get(section, {})
  73. return section_data.get(key, default)
  74. def set_item(self, section, key, value):
  75. """
  76. Définit une valeur et la sauvegarde immédiatement.
  77. """
  78. if section not in self.data:
  79. self.data[section] = {}
  80. self.data[section][key] = value
  81. return self.save()
  82. def get_section(self, section_name):
  83. """Récupère une section entière (utile pour SettingsView)"""
  84. return self.data.get(section_name, {})
  85. def set_section(self, section_name, new_data):
  86. """Met à jour une section avant sauvegarde"""
  87. self.data[section_name] = new_data
  88. def save(self):
  89. """Sauvegarde l'état actuel sur le disque"""
  90. try:
  91. with open(self.config_path, 'w', encoding='utf-8') as f:
  92. json.dump(self.data, f, indent=4)
  93. return True
  94. except Exception as e:
  95. print(f"Erreur de sauvegarde : {e}")
  96. return False
  97. def reset_all(self):
  98. """Réinitialisation totale aux paramètres d'usine"""
  99. self.data = copy.deepcopy(self.DEFAULT_CONFIG)
  100. return self.save()