Treat extruder_clearance_max_radius as extruder_clearance_radius, and raise error if both options are present

This commit is contained in:
Noisyfox 2025-10-11 16:17:14 +08:00
parent 6ea106f754
commit 2fa386cbdb
31 changed files with 77 additions and 29 deletions

View file

@ -355,6 +355,57 @@ def check_obsolete_keys(profiles_dir, vendor_name):
return error_count
CONFLICT_KEYS = [
['extruder_clearance_radius', 'extruder_clearance_max_radius'],
]
def check_conflict_keys(profiles_dir, vendor_name):
"""
Check for keys that could not be specified at the same time,
due to option renaming & backward compatibility reasons.
For example, `extruder_clearance_max_radius` and `extruder_clearance_radius` cannot co-exist
otherwise slicer won't know which one to use.
Parameters:
profiles_dir (Path): Base profiles directory
vendor_name (str): Vendor name
Returns:
int: Number of errors found
int: Number of warnings found
"""
error_count = 0
warn_count = 0
vendor_path = profiles_dir / vendor_name
if not vendor_path.exists():
print_warning(f"No machine profiles found for vendor: {vendor_name}")
return 0, 1
for file_path in vendor_path.rglob("*.json"):
try:
with open(file_path, 'r', encoding='UTF-8') as fp:
# Use custom hook to detect duplicates.
data = json.load(fp, object_pairs_hook=no_duplicates_object_pairs_hook)
except ValueError as ve:
print_error(f"Duplicate key error in {file_path.relative_to(profiles_dir)}: {ve}")
error_count += 1
continue
except Exception as e:
print_error(f"Error processing {file_path.relative_to(profiles_dir)}: {e}")
error_count += 1
continue
for key_sets in CONFLICT_KEYS:
if sum([1 if k in data else 0 for k in key_sets]) > 1:
print_error(f"Conflict keys {key_sets} co-exist in {file_path.relative_to(profiles_dir)}")
error_count += 1
return error_count, warn_count
def main():
parser = argparse.ArgumentParser(
description="Check 3D printer profiles for common issues",
@ -393,6 +444,10 @@ def main():
errors_found += new_errors
warnings_found += new_warnings
new_errors, new_warnings = check_conflict_keys(profiles_dir, vendor_name)
errors_found += new_errors
warnings_found += new_warnings
errors_found += check_filament_id(vendor_name, vendor_path / "filament")
checked_vendor_count += 1
@ -416,6 +471,8 @@ def main():
else:
print_success("Files with warnings : 0")
print("=================================================")
if errors_found > 0 or warnings_found > 0 :
print_warning('Issue(s) found, try `orca_filament_lib.py --fix` to fix common issues automatically')
exit(-1 if errors_found > 0 else 0)

View file

@ -160,6 +160,9 @@ def clean_up_profile(vendor="", profile_type="", force=False):
for root, dirs, files in os.walk(profile_dir):
for file in files:
if file.lower().endswith('.json'):
if file == 'filaments_color_codes.json': # Ignore non-profile file
continue
full_path = os.path.join(root, file)
# Get relative path from base directory
@ -190,6 +193,19 @@ def clean_up_profile(vendor="", profile_type="", force=False):
print(f"Removed {field} field from {file}")
need_update = True
# Handle `extruder_clearance_radius`.
if 'extruder_clearance_radius' in _profile and 'extruder_clearance_max_radius' in _profile:
# BBS renamed `extruder_clearance_radius` to `extruder_clearance_max_radius`
# however some of their profiles have both options exists with different value, which
# could cause very bad consequence such as toolhead collision.
# Here we make sure only one of these options exist, and if both present, we keep
# the one with greater value.
need_update = True
if float(_profile['extruder_clearance_max_radius']) > float(_profile['extruder_clearance_radius']):
del _profile['extruder_clearance_radius']
else:
del _profile['extruder_clearance_max_radius']
if need_update or force:
# write back to file
f.seek(0)