From eebf7e1fff07cf4b11cbc8aa5d7835c76e457487 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 13 Oct 2022 15:55:40 +0530 Subject: [PATCH] chore: dead code removal (#18410) * chore!: Drop dead code related to configs/moduelview * chore!: Drop dead boilerplate * chore: drop desktop.py boilerplate * chore!: Remove report dump --- frappe/config/__init__.py | 9 - frappe/desk/moduleview.py | 615 ------------------------------------ frappe/desk/report_dump.py | 107 ------- frappe/tests/test_config.py | 2 - frappe/utils/boilerplate.py | 34 +- 5 files changed, 1 insertion(+), 766 deletions(-) delete mode 100644 frappe/desk/moduleview.py delete mode 100644 frappe/desk/report_dump.py diff --git a/frappe/config/__init__.py b/frappe/config/__init__.py index 947f61e9e0..02626aedf5 100644 --- a/frappe/config/__init__.py +++ b/frappe/config/__init__.py @@ -1,11 +1,5 @@ import frappe from frappe import _ -from frappe.desk.moduleview import ( - config_exists, - get_data, - get_module_link_items_from_list, - get_onboard_items, -) def get_modules_from_all_apps_for_user(user: str = None) -> list[dict]: @@ -25,9 +19,6 @@ def get_modules_from_all_apps_for_user(user: str = None) -> list[dict]: if module_name in empty_tables_by_module: module["onboard_present"] = 1 - # Set defaults links - module["links"] = get_onboard_items(module["app"], frappe.scrub(module_name))[:5] - return allowed_modules_list diff --git a/frappe/desk/moduleview.py b/frappe/desk/moduleview.py deleted file mode 100644 index 913b3406e3..0000000000 --- a/frappe/desk/moduleview.py +++ /dev/null @@ -1,615 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: MIT. See LICENSE - -import json - -import frappe -from frappe import _ -from frappe.boot import get_allowed_pages, get_allowed_reports -from frappe.cache_manager import ( - build_domain_restriced_doctype_cache, - build_domain_restriced_page_cache, - build_table_count_cache, -) -from frappe.desk.doctype.desktop_icon.desktop_icon import clear_desktop_icons_cache, set_hidden - - -@frappe.whitelist() -def get(module): - """Returns data (sections, list of reports, counts) to render module view in desk: - `/desk/#Module/[name]`.""" - data = get_data(module) - - out = {"data": data} - - return out - - -@frappe.whitelist() -def hide_module(module): - set_hidden(module, frappe.session.user, 1) - clear_desktop_icons_cache() - - -def get_table_with_counts(): - counts = frappe.cache().get_value("information_schema:counts") - if counts: - return counts - else: - return build_table_count_cache() - - -def get_data(module, build=True): - """Get module data for the module view `desk/#Module/[name]`""" - doctype_info = get_doctype_info(module) - data = build_config_from_file(module) - - if not data: - data = build_standard_config(module, doctype_info) - else: - add_custom_doctypes(data, doctype_info) - - add_section(data, _("Custom Reports"), "fa fa-list-alt", get_report_list(module)) - - data = combine_common_sections(data) - data = apply_permissions(data) - - # set_last_modified(data) - - if build: - exists_cache = get_table_with_counts() - - def doctype_contains_a_record(name): - exists = exists_cache.get(name) - if not exists: - if not frappe.db.get_value("DocType", name, "issingle"): - exists = frappe.db.count(name) - else: - exists = True - exists_cache[name] = exists - return exists - - for section in data: - for item in section["items"]: - # Onboarding - - # First disable based on exists of depends_on list - doctype = item.get("doctype") - dependencies = item.get("dependencies") or None - if not dependencies and doctype: - item["dependencies"] = [doctype] - - dependencies = item.get("dependencies") - if dependencies: - incomplete_dependencies = [d for d in dependencies if not doctype_contains_a_record(d)] - if len(incomplete_dependencies): - item["incomplete_dependencies"] = incomplete_dependencies - - if item.get("onboard"): - # Mark Spotlights for initial - if item.get("type") == "doctype": - name = item.get("name") - count = doctype_contains_a_record(name) - - item["count"] = count - - return data - - -def build_config_from_file(module): - """Build module info from `app/config/desktop.py` files.""" - data = [] - module = frappe.scrub(module) - - for app in frappe.get_installed_apps(): - try: - data += get_config(app, module) - except ImportError: - pass - - return filter_by_restrict_to_domain(data) - - -def filter_by_restrict_to_domain(data): - """filter Pages and DocType depending on the Active Module(s)""" - doctypes = ( - frappe.cache().get_value("domain_restricted_doctypes") or build_domain_restriced_doctype_cache() - ) - pages = frappe.cache().get_value("domain_restricted_pages") or build_domain_restriced_page_cache() - - for d in data: - _items = [] - for item in d.get("items", []): - - item_type = item.get("type") - item_name = item.get("name") - - if (item_name in pages) or (item_name in doctypes) or item_type == "report": - _items.append(item) - - d.update({"items": _items}) - - return data - - -def build_standard_config(module, doctype_info): - """Build standard module data from DocTypes.""" - if not frappe.db.get_value("Module Def", module): - frappe.throw(_("Module Not Found")) - - data = [] - - add_section( - data, - _("Documents"), - "fa fa-star", - [d for d in doctype_info if d.document_type in ("Document", "Transaction")], - ) - - add_section( - data, - _("Setup"), - "fa fa-cog", - [d for d in doctype_info if d.document_type in ("Master", "Setup", "")], - ) - - add_section(data, _("Standard Reports"), "fa fa-list", get_report_list(module, is_standard="Yes")) - - return data - - -def add_section(data, label, icon, items): - """Adds a section to the module data.""" - if not items: - return - data.append({"label": label, "icon": icon, "items": items}) - - -def add_custom_doctypes(data, doctype_info): - """Adds Custom DocTypes to modules setup via `config/desktop.py`.""" - add_section( - data, - _("Documents"), - "fa fa-star", - [d for d in doctype_info if (d.custom and d.document_type in ("Document", "Transaction"))], - ) - - add_section( - data, - _("Setup"), - "fa fa-cog", - [d for d in doctype_info if (d.custom and d.document_type in ("Setup", "Master", ""))], - ) - - -def get_doctype_info(module): - """Returns list of non child DocTypes for given module.""" - active_domains = frappe.get_active_domains() - - doctype_info = frappe.get_all( - "DocType", - filters={"module": module, "istable": 0}, - or_filters={"ifnull(restrict_to_domain, '')": "", "restrict_to_domain": ("in", active_domains)}, - fields=["'doctype' as type", "name", "description", "document_type", "custom", "issingle"], - order_by="custom asc, document_type desc, name asc", - ) - - for d in doctype_info: - d.document_type = d.document_type or "" - d.description = _(d.description or "") - - return doctype_info - - -def combine_common_sections(data): - """Combine sections declared in separate apps.""" - sections = [] - sections_dict = {} - for each in data: - if each["label"] not in sections_dict: - sections_dict[each["label"]] = each - sections.append(each) - else: - sections_dict[each["label"]]["items"] += each["items"] - - return sections - - -def apply_permissions(data): - default_country = frappe.db.get_default("country") - - user = frappe.get_user() - user.build_permissions() - - allowed_pages = get_allowed_pages() - allowed_reports = get_allowed_reports() - - new_data = [] - for section in data: - new_items = [] - - for item in section.get("items") or []: - item = frappe._dict(item) - - if item.country and item.country != default_country: - continue - - if ( - (item.type == "doctype" and item.name in user.can_read) - or (item.type == "page" and item.name in allowed_pages) - or (item.type == "report" and item.name in allowed_reports) - or item.type == "help" - ): - - new_items.append(item) - - if new_items: - new_section = section.copy() - new_section["items"] = new_items - new_data.append(new_section) - - return new_data - - -def get_disabled_reports(): - if not hasattr(frappe.local, "disabled_reports"): - frappe.local.disabled_reports = {r.name for r in frappe.get_all("Report", {"disabled": 1})} - return frappe.local.disabled_reports - - -def get_config(app, module): - """Load module info from `[app].config.[module]`.""" - config = frappe.get_module(f"{app}.config.{module}") - config = config.get_data() - - sections = [s for s in config if s.get("condition", True)] - - disabled_reports = get_disabled_reports() - for section in sections: - items = [] - for item in section["items"]: - if item["type"] == "report" and item["name"] in disabled_reports: - continue - # some module links might not have name - if not item.get("name"): - item["name"] = item.get("label") - if not item.get("label"): - item["label"] = _(item.get("name")) - items.append(item) - section["items"] = items - - return sections - - -def config_exists(app, module): - try: - frappe.get_module(f"{app}.config.{module}") - return True - except ImportError: - return False - - -def add_setup_section(config, app, module, label, icon): - """Add common sections to `/desk#Module/Setup`""" - try: - setup_section = get_setup_section(app, module, label, icon) - if setup_section: - config.append(setup_section) - except ImportError: - pass - - -def get_setup_section(app, module, label, icon): - """Get the setup section from each module (for global Setup page).""" - config = get_config(app, module) - for section in config: - if section.get("label") == _("Setup"): - return {"label": label, "icon": icon, "items": section["items"]} - - -def get_onboard_items(app, module): - try: - sections = get_config(app, module) - except ImportError: - return [] - - onboard_items = [] - fallback_items = [] - - if not sections: - doctype_info = get_doctype_info(module) - sections = build_standard_config(module, doctype_info) - - for section in sections: - for item in section["items"]: - if item.get("onboard", 0) == 1: - onboard_items.append(item) - - # in case onboard is not set - fallback_items.append(item) - - if len(onboard_items) > 5: - return onboard_items - - return onboard_items or fallback_items - - -@frappe.whitelist() -def get_links_for_module(app, module): - return [{"value": l.get("name"), "label": l.get("label")} for l in get_links(app, module)] - - -def get_links(app, module): - try: - sections = get_config(app, frappe.scrub(module)) - except ImportError: - return [] - - links = [] - for section in sections: - for item in section["items"]: - links.append(item) - return links - - -@frappe.whitelist() -def get_desktop_settings(): - from frappe.config import get_modules_from_all_apps_for_user - - all_modules = get_modules_from_all_apps_for_user() - home_settings = get_home_settings() - - modules_by_name = {} - for m in all_modules: - modules_by_name[m["module_name"]] = m - - module_categories = ["Modules", "Domains", "Places", "Administration"] - user_modules_by_category = {} - - user_saved_modules_by_category = home_settings.modules_by_category or {} - user_saved_links_by_module = home_settings.links_by_module or {} - - def apply_user_saved_links(module): - module = frappe._dict(module) - all_links = get_links(module.app, module.module_name) - module_links_by_name = {} - for link in all_links: - module_links_by_name[link["name"]] = link - - if module.module_name in user_saved_links_by_module: - user_links = frappe.parse_json(user_saved_links_by_module[module.module_name]) - module.links = [module_links_by_name[l] for l in user_links if l in module_links_by_name] - - return module - - for category in module_categories: - if category in user_saved_modules_by_category: - user_modules = user_saved_modules_by_category[category] - user_modules_by_category[category] = [ - apply_user_saved_links(modules_by_name[m]) for m in user_modules if modules_by_name.get(m) - ] - else: - user_modules_by_category[category] = [ - apply_user_saved_links(m) for m in all_modules if m.get("category") == category - ] - - # filter out hidden modules - if home_settings.hidden_modules: - for category in user_modules_by_category: - hidden_modules = home_settings.hidden_modules or [] - modules = user_modules_by_category[category] - user_modules_by_category[category] = [ - module for module in modules if module.module_name not in hidden_modules - ] - - return user_modules_by_category - - -@frappe.whitelist() -def update_hidden_modules(category_map): - category_map = frappe.parse_json(category_map) - home_settings = get_home_settings() - - saved_hidden_modules = home_settings.hidden_modules or [] - - for category in category_map: - config = frappe._dict(category_map[category]) - saved_hidden_modules += config.removed or [] - saved_hidden_modules = [d for d in saved_hidden_modules if d not in (config.added or [])] - - if home_settings.get("modules_by_category") and home_settings.modules_by_category.get(category): - module_placement = [ - d for d in (config.added or []) if d not in home_settings.modules_by_category[category] - ] - home_settings.modules_by_category[category] += module_placement - - home_settings.hidden_modules = saved_hidden_modules - set_home_settings(home_settings) - - return get_desktop_settings() - - -@frappe.whitelist() -def update_global_hidden_modules(modules): - modules = frappe.parse_json(modules) - frappe.only_for("System Manager") - - doc = frappe.get_doc("User", "Administrator") - doc.set("block_modules", []) - for module in modules: - doc.append("block_modules", {"module": module}) - - doc.save(ignore_permissions=True) - - return get_desktop_settings() - - -@frappe.whitelist() -def update_modules_order(module_category, modules): - modules = frappe.parse_json(modules) - home_settings = get_home_settings() - - home_settings.modules_by_category = home_settings.modules_by_category or {} - home_settings.modules_by_category[module_category] = modules - - set_home_settings(home_settings) - - -@frappe.whitelist() -def update_links_for_module(module_name, links): - links = frappe.parse_json(links) - home_settings = get_home_settings() - - home_settings.setdefault("links_by_module", {}) - home_settings["links_by_module"].setdefault(module_name, None) - home_settings["links_by_module"][module_name] = links - - set_home_settings(home_settings) - - return get_desktop_settings() - - -@frappe.whitelist() -def get_options_for_show_hide_cards(): - global_options = [] - - if "System Manager" in frappe.get_roles(): - global_options = get_options_for_global_modules() - - return {"user_options": get_options_for_user_blocked_modules(), "global_options": global_options} - - -@frappe.whitelist() -def get_options_for_global_modules(): - from frappe.config import get_modules_from_all_apps - - all_modules = get_modules_from_all_apps() - - blocked_modules = frappe.get_doc("User", "Administrator").get_blocked_modules() - - options = [] - for module in all_modules: - module = frappe._dict(module) - options.append( - { - "category": module.category, - "label": module.label, - "value": module.module_name, - "checked": module.module_name not in blocked_modules, - } - ) - - return options - - -@frappe.whitelist() -def get_options_for_user_blocked_modules(): - from frappe.config import get_modules_from_all_apps_for_user - - all_modules = get_modules_from_all_apps_for_user() - home_settings = get_home_settings() - - hidden_modules = home_settings.hidden_modules or [] - - options = [] - for module in all_modules: - module = frappe._dict(module) - options.append( - { - "category": module.category, - "label": module.label, - "value": module.module_name, - "checked": module.module_name not in hidden_modules, - } - ) - - return options - - -def set_home_settings(home_settings): - frappe.cache().hset("home_settings", frappe.session.user, home_settings) - frappe.db.set_value("User", frappe.session.user, "home_settings", json.dumps(home_settings)) - - -@frappe.whitelist() -def get_home_settings(): - def get_from_db(): - settings = frappe.db.get_value("User", frappe.session.user, "home_settings") - return frappe.parse_json(settings or "{}") - - home_settings = frappe.cache().hget("home_settings", frappe.session.user, get_from_db) - return home_settings - - -def get_module_link_items_from_list(app, module, list_of_link_names): - try: - sections = get_config(app, frappe.scrub(module)) - except ImportError: - return [] - - links = [] - for section in sections: - for item in section["items"]: - if item.get("label", "") in list_of_link_names: - links.append(item) - - return links - - -def set_last_modified(data): - for section in data: - for item in section["items"]: - if item["type"] == "doctype": - item["last_modified"] = get_last_modified(item["name"]) - - -def get_last_modified(doctype): - def _get(): - try: - last_modified = frappe.get_all( - doctype, fields=["max(modified)"], as_list=True, limit_page_length=1 - )[0][0] - except Exception as e: - if frappe.db.is_table_missing(e): - last_modified = None - else: - raise - - # hack: save as -1 so that it is cached - if last_modified is None: - last_modified = -1 - - return last_modified - - last_modified = frappe.cache().hget("last_modified", doctype, _get) - - if last_modified == -1: - last_modified = None - - return last_modified - - -def get_report_list(module, is_standard="No"): - """Returns list on new style reports for modules.""" - reports = frappe.get_list( - "Report", - fields=["name", "ref_doctype", "report_type"], - filters={"is_standard": is_standard, "disabled": 0, "module": module}, - order_by="name", - ) - - out = [] - for r in reports: - out.append( - { - "type": "report", - "doctype": r.ref_doctype, - "is_query_report": 1 - if r.report_type in ("Query Report", "Script Report", "Custom Report") - else 0, - "label": _(r.name), - "name": r.name, - } - ) - - return out diff --git a/frappe/desk/report_dump.py b/frappe/desk/report_dump.py deleted file mode 100644 index 6650d24757..0000000000 --- a/frappe/desk/report_dump.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: MIT. See LICENSE - - -import copy -import json - -import frappe - - -@frappe.whitelist() -def get_data(doctypes, last_modified): - data_map = {} - for dump_report_map in frappe.get_hooks().dump_report_map: - data_map.update(frappe.get_attr(dump_report_map)) - - out = {} - - doctypes = json.loads(doctypes) - last_modified = json.loads(last_modified) - - for d in doctypes: - args = copy.deepcopy(data_map[d]) - dt = d.find("[") != -1 and d[: d.find("[")] or d - out[dt] = {} - - if args.get("from"): - modified_table = "item." - else: - modified_table = "" - - conditions = order_by = "" - table = args.get("from") or ("`tab%s`" % dt) - - if d in last_modified: - if not args.get("conditions"): - args["conditions"] = [] - args["conditions"].append(modified_table + "modified > '" + last_modified[d] + "'") - out[dt]["modified_names"] = frappe.db.sql_list( - """select %sname from %s - where %smodified > %s""" - % (modified_table, table, modified_table, "%s"), - last_modified[d], - ) - - if args.get("force_index"): - conditions = " force index (%s) " % args["force_index"] - if args.get("conditions"): - conditions += " where " + " and ".join(args["conditions"]) - if args.get("order_by"): - order_by = " order by " + args["order_by"] - - out[dt]["data"] = [ - list(t) - for t in frappe.db.sql( - """select {} from {} {} {}""".format(",".join(args["columns"]), table, conditions, order_by) - ) - ] - - # last modified - modified_table = table - if "," in table: - modified_table = " ".join(table.split(",")[0].split(" ")[:-1]) - - tmp = frappe.db.sql( - """select `modified` - from %s order by modified desc limit 1""" - % modified_table - ) - out[dt]["last_modified"] = tmp and tmp[0][0] or "" - out[dt]["columns"] = list(map(lambda c: c.split(" as ")[-1], args["columns"])) - - if args.get("links"): - out[dt]["links"] = args["links"] - - for d in out: - unused_links = [] - # only compress full dumps (not partial) - if out[d].get("links") and (d not in last_modified): - for link_key in out[d]["links"]: - link = out[d]["links"][link_key] - if link[0] in out and (link[0] not in last_modified): - - # make a map of link ids - # to index - link_map = {} - doctype_data = out[link[0]] - - col_idx = doctype_data["columns"].index(link[1]) - for row_idx in range(len(doctype_data["data"])): - row = doctype_data["data"][row_idx] - link_map[row[col_idx]] = row_idx - - for row in out[d]["data"]: - columns = list(out[d]["columns"]) - if link_key in columns: - col_idx = columns.index(link_key) - # replace by id - if row[col_idx]: - row[col_idx] = link_map.get(row[col_idx]) - else: - unused_links.append(link_key) - - for link in unused_links: - del out[d]["links"][link] - - return out diff --git a/frappe/tests/test_config.py b/frappe/tests/test_config.py index d2b1196f52..c7b99dbed3 100644 --- a/frappe/tests/test_config.py +++ b/frappe/tests/test_config.py @@ -9,8 +9,6 @@ class TestConfig(FrappeTestCase): def test_get_modules(self): frappe_modules = frappe.get_all("Module Def", filters={"app_name": "frappe"}, pluck="name") all_modules_data = get_modules_from_all_apps_for_user() - first_module_entry = all_modules_data[0] all_modules = [x["module_name"] for x in all_modules_data] - self.assertIn("links", first_module_entry) self.assertIsInstance(all_modules_data, list) self.assertFalse([x for x in frappe_modules if x not in all_modules]) diff --git a/frappe/utils/boilerplate.py b/frappe/utils/boilerplate.py index f0f3173425..d472f96e56 100644 --- a/frappe/utils/boilerplate.py +++ b/frappe/utils/boilerplate.py @@ -136,12 +136,6 @@ def _create_app_boilerplate(dest, hooks, no_git=False): touch_file(os.path.join(dest, hooks.app_name, hooks.app_name, "patches.txt")) - with open(os.path.join(dest, hooks.app_name, hooks.app_name, "config", "desktop.py"), "w") as f: - f.write(frappe.as_unicode(desktop_template.format(**hooks))) - - with open(os.path.join(dest, hooks.app_name, hooks.app_name, "config", "docs.py"), "w") as f: - f.write(frappe.as_unicode(docs_template.format(**hooks))) - app_directory = os.path.join(dest, hooks.app_name) if hooks.create_github_workflow: @@ -381,18 +375,6 @@ app_license = "{app_license}" # ] """ -desktop_template = """from frappe import _ - -def get_data(): - return [ - {{ - "module_name": "{app_title}", - "type": "module", - "label": _("{app_title}") - }} - ] -""" - setup_template = """from setuptools import setup, find_packages with open("requirements.txt") as f: @@ -419,21 +401,7 @@ gitignore_template = """.DS_Store *.egg-info *.swp tags -{app_name}/docs/current -node_modules/""" - -docs_template = '''""" -Configuration for docs -""" - -# source_link = "https://github.com/[org_name]/{app_name}" -# headline = "App that does everything" -# sub_heading = "Yes, you got that right the first time, everything" - -def get_context(context): - context.brand_html = "{app_title}" -''' - +node_modules""" github_workflow_template = """ name: CI