Browse Source

Add a validation script for preset settings files

CURA-3710
Lipu Fei 7 years ago
parent
commit
76703ce23c
1 changed files with 126 additions and 0 deletions
  1. 126 0
      tools/check_preset_settings.py

+ 126 - 0
tools/check_preset_settings.py

@@ -0,0 +1,126 @@
+import configparser
+import json
+import os
+import sys
+
+
+class PresetSettingsValidator:
+
+    def __init__(self, cura_dir: str):
+        self._cura_dir = os.path.abspath(cura_dir)
+        self._resource_dir = os.path.join(self._cura_dir, "resources")
+        self._definitions_dir = os.path.join(self._resource_dir, "definitions")
+        self._preset_settings_dir = os.path.join(self._resource_dir, "visibility_presets")
+
+        self._fdmprinter_def_path = os.path.join(self._definitions_dir, "fdmprinter.def.json")
+
+    def validate(self) -> bool:
+        """
+        Validates the preset settings files and returns True or False indicating whether there are invalid files.
+        """
+        if not os.path.isfile(self._fdmprinter_def_path):
+            raise FileNotFoundError("[%s] is not a file or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._fdmprinter_def_path, self._cura_dir))
+
+        if not os.path.isdir(self._preset_settings_dir):
+            raise FileNotFoundError("[%s] is not a directory or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._preset_settings_dir, self._cura_dir))
+
+        # parse the definition file
+        setting_tree_dict = self._parse_definition_file(self._fdmprinter_def_path)
+
+        has_invalid_files = False
+
+        # go through all the preset settings files
+        for root_dir, _, filenames in os.walk(self._preset_settings_dir):
+            for filename in filenames:
+                file_path = os.path.join(root_dir, filename)
+                print("Validating [%s] ..." % file_path)
+
+                incorrect_sections = []
+                incorrect_settings = {}
+
+                parser = configparser.ConfigParser(allow_no_value = True)
+                with open(file_path, "r", encoding = "utf-8") as f:
+                    parser.read_file(f)
+
+                for key in parser:
+                    # skip general
+                    if key in ("general", configparser.DEFAULTSECT):
+                        continue
+
+                    if key not in setting_tree_dict:
+                        incorrect_sections.append(key)
+                        continue
+
+                    for setting_key in parser[key]:
+                        if setting_key not in setting_tree_dict[key]:
+                            if setting_key not in incorrect_settings:
+                                incorrect_settings[setting_key] = {"seen_in": [],
+                                                                   "should_be_in": self._should_setting_be_in(setting_tree_dict, setting_key)}
+
+                            incorrect_settings[setting_key]["seen_in"].append(key)
+
+                # show results
+                print("==========================================")
+                if incorrect_settings or incorrect_settings:
+                    has_invalid_files = True
+                    print("[INVALID] [%s] is invalid, details below" % file_path)
+
+                    # show details
+                    for section_name in incorrect_sections:
+                        print(" -- section name [%s] is incorrect, please check fdmprinter.def.json." % section_name)
+                    for setting_name, details_dict in incorrect_settings.items():
+                        msg = " -- setting [%s] is found in sections [%s], " % (setting_name, ", ".join(details_dict["seen_in"]))
+                        if details_dict["should_be_in"] is not None:
+                            msg += "but should be in section [%s] only." % details_dict["should_be_in"]
+                        else:
+                            msg += "but it cannot be found in fdmprinter.def.json"
+                        print(msg)
+
+                else:
+                    print("[%s] is valid" % file_path)
+                print("==========================================")
+
+        return not has_invalid_files
+
+    def _parse_definition_file(self, file_path: str):
+        with open(file_path, "r", encoding = "utf-8") as f:
+            def_dict = json.load(f, encoding = "utf-8")
+
+        tree_dict = {}
+        for key, item in def_dict.get("settings", {}).items():
+            setting_list = []
+            self._generate_tree(setting_list, item.get("children", {}))
+            tree_dict[key] = setting_list
+
+        return tree_dict
+
+    def _generate_tree(self, setting_list: list, setting_dict: dict):
+        for key, item in setting_dict.items():
+            setting_list.append(key)
+            if "children" in item:
+                self._generate_tree(setting_list, item["children"])
+
+    def _should_setting_be_in(self, setting_dict: dict, setting_name: str) -> str:
+        """
+        Check which section the given setting belongs to. Returns None if the setting cannot be found.
+        """
+        section_name = None
+        for key, setting_list in setting_dict.items():
+            if setting_name in setting_list:
+                section_name = key
+                break
+        return section_name
+
+
+if __name__ == "__main__":
+    script_dir = os.path.dirname(os.path.realpath(__file__))
+    cura_dir = os.path.abspath(os.path.join(script_dir, ".."))
+
+    validator = PresetSettingsValidator(cura_dir)
+    is_everything_validate = validator.validate()
+
+    if not is_everything_validate:
+        print("Please")
+
+    ret_code = 0 if is_everything_validate else 1
+    sys.exit(ret_code)