From dfd5d6982d936a76c80478ef7010d7af8b5b4529 Mon Sep 17 00:00:00 2001 From: sokumon Date: Tue, 9 Dec 2025 17:24:00 +0530 Subject: [PATCH] fix: create and use a file map to remove orphans --- frappe/model/sync.py | 55 +++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/frappe/model/sync.py b/frappe/model/sync.py index db77b9fb00..61c4d0f0f3 100644 --- a/frappe/model/sync.py +++ b/frappe/model/sync.py @@ -208,28 +208,53 @@ def remove_orphan_entities(): "Report": {"is_standard": "Yes"}, "Dashboard": {"is_standard": True}, } + entity_file_map = create_entity_file_map(entites) for entity in entites: print(f"Removing orphan {entity}s") all_enitities = frappe.get_all( entity, filters=entity_filter_map.get(entity), fields=["name", "module"] ) for i, w in enumerate(all_enitities): - if w.module: + try: + entity_file_map[entity][w.name] + except KeyError: try: - module_path = frappe.get_module_path(w.module) - if not check_if_record_exists( - type="module", path=module_path, entity_type=entity, name=w.name, module_name=w.module - ): - print(f"Deleting entity {entity} {w.name}") - frappe.delete_doc(entity, w.name, force=True, ignore_missing=True) - update_progress_bar(f"Deleting orphaned {entity}", i, len(all_enitities)) - print() + print(f"Deleting entity {entity} {w.name}") + frappe.delete_doc(entity, w.name, force=True, ignore_missing=True) + update_progress_bar(f"Deleting orphaned {entity}", i, len(all_enitities)) + print() except Exception as e: print(f"Error occurred while deleting entity: {entity} {w.name}") print(e) - # save the deleted icons - frappe.db.commit() # nosemgrep + # save the deleted icons + frappe.db.commit() # nosemgrep + + +def create_entity_file_map(entities): + import glob + + from frappe.modules.import_file import read_doc_from_file + + entity_file_map = {} + for entity in entities: + entity_file_map[entity] = {} + for app in frappe.get_installed_apps(): + app_path = frappe.get_app_path(app) + for entity in entities: + entity_folder = entity.lower() + if entity.lower() == "dashboard": + entity_folder = f"*_{entity_folder}" + entity_files = list(glob.glob(f"{app_path}/**/{entity_folder}/**/*.json", recursive=True)) + for file in entity_files: + entity_json = read_doc_from_file(file) + if isinstance(entity_json, dict): + entity_file_map[entity][entity_json.get("name")] = file + elif isinstance(entity_json, list): + if len(entity_json) > 0: + entity_file_map[entity][entity_json[0].get("name")] = file + + return entity_file_map def check_if_record_exists(type=None, path=None, entity_type=None, name=None, module_name=None): @@ -247,14 +272,6 @@ def check_if_record_exists(type=None, path=None, entity_type=None, name=None, mo if os.path.exists(entity_path): return True - # This will handle names with brackets Eg: Item Balance (Simple) - if "(" in name: - cleaned_name = re.sub(r"\s*\([^)]*\)", "", name) - scrubbed_cleaned = frappe.scrub(cleaned_name) - cleaned_path = build_path(scrubbed_cleaned) - if os.path.exists(cleaned_path): - return True - return False