|
29 | 29 | ) |
30 | 30 | from fourc_webviewer.python_utils import ( |
31 | 31 | convert_string2number, |
| 32 | + dict_leaves_to_number_if_schema, |
32 | 33 | find_value_recursively, |
| 34 | + parse_validation_error_text, |
33 | 35 | smart_string2number_cast, |
34 | 36 | ) |
35 | 37 |
|
@@ -75,7 +77,7 @@ def __init__( |
75 | 77 | self._server_vars["temp_dir_object"] = tempfile.TemporaryDirectory() |
76 | 78 |
|
77 | 79 | # Register on_field_blur function, which is called when the user leaves a field |
78 | | - self.server.controller.on_field_blur = self.on_field_blur |
| 80 | + self.server.controller.on_leave_edit_field = self.on_leave_edit_field |
79 | 81 |
|
80 | 82 | # initialize state variables for the different modes and |
81 | 83 | # statuses of the client (e.g. view mode versus edit mode, |
@@ -1116,81 +1118,25 @@ def click_save_button(self, **kwargs): |
1116 | 1118 | else: |
1117 | 1119 | self.state.export_status = self.state.all_export_statuses["error"] |
1118 | 1120 |
|
1119 | | - def parse_validation_error_text(self, text): |
1120 | | - """Parse a ValidationError message string (with multiple "- Parameter |
1121 | | - in [...]" blocks) into a nested dict.""" |
1122 | | - error_dict = {} |
1123 | | - # Match "- Parameter in [...]" blocks up until the next one or end of string |
1124 | | - block_re = re.compile( |
1125 | | - r"- Parameter in (?P<path>(?:\[[^\]]+\])+)\n" |
1126 | | - r"(?P<body>.*?)(?=(?:- Parameter in )|\Z)", |
1127 | | - re.DOTALL, |
1128 | | - ) |
1129 | | - for m in block_re.finditer(text): |
1130 | | - path_str = m.group("path") |
1131 | | - body = m.group("body") |
1132 | | - |
1133 | | - # extract the Error: line |
1134 | | - err_m = re.search(r"Error:\s*(.+)", body) |
1135 | | - if not err_m: |
1136 | | - continue |
1137 | | - err_msg = err_m.group(1).strip() |
1138 | | - |
1139 | | - keys = re.findall(r'\["([^"]+)"\]', path_str) |
1140 | | - |
1141 | | - # walk/create nested dicts, then assign the message at the leaf |
1142 | | - cur = error_dict |
1143 | | - for key in keys[:-1]: |
1144 | | - cur = cur.setdefault(key, {}) |
1145 | | - cur[keys[-1]] = err_msg |
1146 | | - |
1147 | | - return error_dict |
1148 | | - |
1149 | 1121 | @change("general_sections") |
1150 | 1122 | def on_sections_change(self, general_sections, **kwargs): |
1151 | 1123 | """Reaction to change of state.general_sections.""" |
1152 | 1124 |
|
1153 | 1125 | self.sync_server_vars_from_state() |
1154 | 1126 | try: |
1155 | 1127 | fourcinput = FourCInput(self._server_vars["fourc_yaml_content"]) |
1156 | | - # print(CONFIG) |
1157 | | - |
1158 | | - def get_by_path(dct, path): |
1159 | | - """Retrieve the value at the nested path from dct. |
1160 | | -
|
1161 | | - Raises KeyError if any key is missing. |
1162 | | - """ |
1163 | | - # print(f"get_by_path: {path}") |
1164 | | - current = dct |
1165 | | - for key in path: |
1166 | | - current = current[key] |
1167 | | - return current |
1168 | | - |
1169 | | - def dict_leaves_to_number_if_schema(value, schema_path=[]): |
1170 | | - """Convert all leaves of a dict to numbers if possible.""" |
1171 | | - if isinstance(value, dict): |
1172 | | - for k, v in value.items(): |
1173 | | - value[k] = dict_leaves_to_number_if_schema( |
1174 | | - v, schema_path + ["properties", k] |
1175 | | - ) |
1176 | | - return value |
1177 | | - if isinstance(value, str) and get_by_path( |
1178 | | - CONFIG["json_schema"], schema_path + ["type"] |
1179 | | - ) in ["number", "integer"]: |
1180 | | - return smart_string2number_cast(value) |
1181 | | - return value |
1182 | 1128 |
|
1183 | 1129 | dict_leaves_to_number_if_schema(fourcinput._sections) |
1184 | 1130 |
|
1185 | 1131 | fourcinput.validate() |
1186 | 1132 | self.state.input_error_dict = {} |
1187 | 1133 | except ValidationError as exc: |
1188 | | - self.state.input_error_dict = self.parse_validation_error_text( |
| 1134 | + self.state.input_error_dict = parse_validation_error_text( |
1189 | 1135 | str(exc.args[0]) |
1190 | 1136 | ) # exc.args[0] is the error message |
1191 | 1137 | return False |
1192 | 1138 |
|
1193 | | - def on_field_blur(self): |
| 1139 | + def on_leave_edit_field(self): |
1194 | 1140 | """Reaction to user leaving the field.""" |
1195 | 1141 | # also gets called when a new file is loaded |
1196 | 1142 | # basically just sets the state based on server_vars |
|
0 commit comments