def migrate(verbose=True, rebuild_website=False): '''Migrate all apps to the latest version, will: - run before migrate hooks - run patches - sync doctypes (schema) - sync fixtures - sync desktop icons - sync web pages (from /www) - sync web pages (from /www) - run after migrate hooks ''' touched_tables_file = frappe.get_site_path('touched_tables.json') if os.path.exists(touched_tables_file): os.remove(touched_tables_file) try: frappe.flags.touched_tables = set() frappe.flags.in_migrate = True clear_global_cache() #run before_migrate hooks for app in frappe.get_installed_apps(): for fn in frappe.get_hooks('before_migrate', app_name=app): frappe.get_attr(fn)() # run patches frappe.modules.patch_handler.run_all() # sync frappe.model.sync.sync_all(verbose=verbose) frappe.translate.clear_cache() sync_fixtures() sync_customizations() sync_desktop_icons() sync_languages() frappe.get_doc('Portal Settings', 'Portal Settings').sync_menu() # syncs statics render.clear_cache() # add static pages to global search router.sync_global_search() #run after_migrate hooks for app in frappe.get_installed_apps(): for fn in frappe.get_hooks('after_migrate', app_name=app): frappe.get_attr(fn)() frappe.db.commit() clear_notifications() frappe.publish_realtime("version-update") frappe.flags.in_migrate = False finally: with open(touched_tables_file, 'w') as f: json.dump(list(frappe.flags.touched_tables), f, sort_keys=True, indent=4) frappe.flags.touched_tables.clear()
def migrate(verbose=True, rebuild_website=False): '''Migrate all apps to the latest version, will: - run before migrate hooks - run patches - sync doctypes (schema) - sync fixtures - sync desktop icons - sync web pages (from /www) - sync web pages (from /www) - run after migrate hooks ''' frappe.flags.in_migrate = True clear_global_cache() #run before_migrate hooks for app in frappe.get_installed_apps(): for fn in frappe.get_hooks('before_migrate', app_name=app): frappe.get_attr(fn)() # run patches frappe.modules.patch_handler.run_all() # sync frappe.model.sync.sync_all(verbose=verbose) frappe.translate.clear_cache() sync_fixtures() sync_customizations() sync_desktop_icons() sync_languages() frappe.get_doc('Portal Settings', 'Portal Settings').sync_menu() # syncs statics render.clear_cache() # add static pages to global search router.sync_global_search() #run after_migrate hooks for app in frappe.get_installed_apps(): for fn in frappe.get_hooks('after_migrate', app_name=app): frappe.get_attr(fn)() frappe.db.commit() clear_notifications() frappe.publish_realtime("version-update") frappe.flags.in_migrate = False
def get_pages(): pages = frappe.cache().get_value("_website_pages") if not pages: pages = [] for app in frappe.get_installed_apps(): app_path = frappe.get_app_path(app) path = os.path.join(app_path, "templates", "pages") if os.path.exists(path): for fname in os.listdir(path): fname = frappe.utils.cstr(fname) page_name, extn = fname.rsplit(".", 1) if extn in ("html", "xml", "js", "css"): route_page_name = page_name if extn=="html" else fname # add website route route = frappe._dict() route.page_or_generator = "Page" route.template = os.path.relpath(os.path.join(path, fname), app_path) route.name = route.page_name = route_page_name route.public_read = 1 controller_path = os.path.join(path, page_name + ".py") if os.path.exists(controller_path): controller = app + "." + os.path.relpath(controller_path, app_path).replace(os.path.sep, ".")[:-3] route.controller = controller try: route.page_title = frappe.get_attr(controller + "." + "page_title") except AttributeError: pass pages.append(route) frappe.cache().set_value("_website_pages", pages) return pages
def before_tests(): if len(frappe.get_installed_apps()) > 1: # don't run before tests if any other app is installed return frappe.db.sql("delete from `tabCustom Field`") frappe.db.sql("delete from `tabEvent`") frappe.db.commit() frappe.clear_cache() # complete setup if missing from frappe.desk.page.setup_wizard.setup_wizard import setup_complete if not int(frappe.db.get_single_value('System Settings', 'setup_complete') or 0): setup_complete({ "language" :"english", "email" :"*****@*****.**", "full_name" :"Test User", "password" :"test", "country" :"United States", "timezone" :"America/New_York", "currency" :"USD" }) frappe.db.commit() frappe.clear_cache()
def list_apps(context): "List apps in site" site = get_site(context) frappe.init(site=site) frappe.connect() print("\n".join(frappe.get_installed_apps())) frappe.destroy()
def get_versions(): """Get versions of all installed apps. Example: { "frappe": { "title": "Frappe Framework", "version": "5.0.0" } }""" versions = {} for app in frappe.get_installed_apps(sort=True): app_hooks = frappe.get_hooks(app_name=app) versions[app] = { "title": app_hooks.get("app_title")[0], "description": app_hooks.get("app_description")[0], "branch": get_app_branch(app) } if versions[app]['branch'] != 'master': branch_version = app_hooks.get('{0}_version'.format(versions[app]['branch'])) if branch_version: versions[app]['branch_version'] = branch_version[0] + ' ({0})'.format(get_app_last_commit_ref(app)) try: versions[app]["version"] = frappe.get_attr(app + ".__version__") except AttributeError: versions[app]["version"] = '0.0.1' return versions
def get_bootinfo(): """build and return boot info""" frappe.set_user_lang(frappe.session.user) bootinfo = frappe._dict() hooks = frappe.get_hooks() doclist = [] # user get_user(bootinfo) # system info bootinfo['sysdefaults'] = frappe.defaults.get_defaults() bootinfo['server_date'] = frappe.utils.nowdate() if frappe.session['user'] != 'Guest': bootinfo['user_info'] = get_fullnames() bootinfo['sid'] = frappe.session['sid']; # home page bootinfo.modules = {} for app in frappe.get_installed_apps(): try: bootinfo.modules.update(frappe.get_attr(app + ".config.desktop.get_data")() or {}) except ImportError: pass except AttributeError: pass bootinfo.module_app = frappe.local.module_app bootinfo.hidden_modules = frappe.db.get_global("hidden_modules") bootinfo.doctype_icons = dict(frappe.db.sql("""select name, icon from tabDocType where ifnull(icon,'')!=''""")) bootinfo.single_types = frappe.db.sql_list("""select name from tabDocType where ifnull(issingle,0)=1""") add_home_page(bootinfo, doclist) bootinfo.page_info = get_allowed_pages() load_translations(bootinfo) add_timezone_info(bootinfo) load_conf_settings(bootinfo) load_print(bootinfo, doclist) doclist.extend(get_meta_bundle("Page")) bootinfo.home_folder = frappe.db.get_value("File", {"is_home_folder": 1}) # ipinfo if frappe.session['data'].get('ipinfo'): bootinfo['ipinfo'] = frappe.session['data']['ipinfo'] # add docs bootinfo['docs'] = doclist for method in hooks.boot_session or []: frappe.get_attr(method)(bootinfo) if bootinfo.lang: bootinfo.lang = unicode(bootinfo.lang) bootinfo['versions'] = {k: v['version'] for k, v in get_versions().items()} bootinfo.error_report_email = frappe.get_hooks("error_report_email") bootinfo.calendars = sorted(frappe.get_hooks("calendars")) return bootinfo
def get_jloader(): import frappe if not getattr(frappe.local, 'jloader', None): from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader if frappe.local.flags.in_setup_help: apps = ['frappe'] else: apps = frappe.get_hooks('template_apps') if not apps: apps = frappe.local.flags.web_pages_apps or frappe.get_installed_apps(sort=True) apps.reverse() if not "frappe" in apps: apps.append('frappe') frappe.local.jloader = ChoiceLoader( # search for something like app/templates/... [PrefixLoader(dict( (app, PackageLoader(app, ".")) for app in apps ))] # search for something like templates/... + [PackageLoader(app, ".") for app in apps] ) return frappe.local.jloader
def install_app(name, verbose=False, set_as_patched=True): frappe.flags.in_install_app = name frappe.clear_cache() app_hooks = frappe.get_hooks(app_name=name) installed_apps = frappe.get_installed_apps() if name not in frappe.get_all_apps(with_frappe=True): raise Exception("App not in apps.txt") if name in installed_apps: print "App Already Installed" frappe.msgprint(_("App Already Installed")) return if name != "frappe": frappe.only_for("System Manager") for before_install in app_hooks.before_install or []: frappe.get_attr(before_install)() if name != "frappe": add_module_defs(name) sync_for(name, force=True, sync_everything=True, verbose=verbose) add_to_installed_apps(name) if set_as_patched: set_all_patches_as_completed(name) for after_install in app_hooks.after_install or []: frappe.get_attr(after_install)() frappe.flags.in_install_app = False
def list_apps(context): "Reinstall site ie. wipe all data and start over" site = get_single_site(context) frappe.init(site=site) frappe.connect() print "\n".join(frappe.get_installed_apps()) frappe.destroy()
def get_app_list(): """Get list of all apps with properties, installed, category from hooks and `frappe/data/app_listing/` if an entry exists""" out = {} installed = frappe.get_installed_apps() for app in frappe.get_all_apps(True): app_hooks = frappe.get_hooks(app_name=app) if app not in installed and app_hooks.get('hide_in_installer'): continue out[app] = {} for key in ("app_name", "app_title", "app_description", "app_icon", "app_publisher", "app_version", "app_url", "app_color"): val = app_hooks.get(key) or [] out[app][key] = val[0] if len(val) else "" if app in installed: out[app]["installed"] = 1 for app_from_list in get_app_listing().values(): if app_from_list.app_name in out: out[app_from_list.app_name].update(app_from_list) else: if not frappe.conf.disallow_app_listing: out[app_from_list.app_name] = app_from_list return out
def add_to_installed_apps(app_name, rebuild_website=True): installed_apps = frappe.get_installed_apps() if not app_name in installed_apps: installed_apps.append(app_name) frappe.db.set_global("installed_apps", json.dumps(installed_apps)) frappe.db.commit() post_install(rebuild_website)
def create_payment_gateway_and_account(): """If ERPNext is installed, create Payment Gateway and Payment Gateway Account""" if "erpnext" not in frappe.get_installed_apps(): return create_payment_gateway() create_payment_gateway_account()
def run_all_tests(app=None, verbose=False, profile=False): import os apps = [app] if app else frappe.get_installed_apps() test_suite = unittest.TestSuite() for app in apps: for path, folders, files in os.walk(frappe.get_pymodule_path(app)): for dontwalk in ('locals', '.git', 'public'): if dontwalk in folders: folders.remove(dontwalk) # print path for filename in files: filename = cstr(filename) if filename.startswith("test_") and filename.endswith(".py"): # print filename[:-3] _add_test(app, path, filename, verbose, test_suite=test_suite) if profile: pr = cProfile.Profile() pr.enable() out = unittest.TextTestRunner(verbosity=1+(verbose and 1 or 0)).run(test_suite) if profile: pr.disable() s = StringIO.StringIO() ps = pstats.Stats(pr, stream=s).sort_stats('cumulative') ps.print_stats() print s.getvalue() return out
def get_page_context_from_doctypes(): routes = frappe.cache().get_value("website_generator_routes") if not routes: routes = {} for app in frappe.get_installed_apps(): for doctype in frappe.get_hooks("website_generators", app_name = app): condition = "" route_column_name = "page_name" controller = get_controller(doctype) meta = frappe.get_meta(doctype) if meta.get_field("parent_website_route"): route_column_name = """concat(ifnull(parent_website_route, ""), if(ifnull(parent_website_route, "")="", "", "/"), page_name)""" if controller.website.condition_field: condition ="where {0}=1".format(controller.website.condition_field) for r in frappe.db.sql("""select {0} as route, name, modified from `tab{1}` {2}""".format(route_column_name, doctype, condition), as_dict=True): routes[r.route] = {"doctype": doctype, "name": r.name, "modified": r.modified} frappe.cache().set_value("website_generator_routes", routes) return routes
def validate(self): # check if app name is valid or not if self.app_name not in frappe.get_installed_apps(): frappe.throw("{0} app name is either invalid or not install in the system<br>\ app name should be <b>{1}<b>".format(self.app_name, " or ".join(frappe.get_installed_apps()))) # app name is valid create api_config and write api_config.json api_config = { "app_name": self.app_name, "api_name": self.api_name, "allowed_versions": map(lambda row: row.api_version, self.versions) } file_name = "{}/api_config.json".format(frappe.utils.get_site_path()) with open(file_name, "w") as f: f.write(json.dumps(api_config, sort_keys=True, indent=4))
def remove_from_installed_apps(app_name): installed_apps = frappe.get_installed_apps() if app_name in installed_apps: installed_apps.remove(app_name) frappe.db.set_global("installed_apps", json.dumps(installed_apps)) frappe.db.commit() if frappe.flags.in_install: post_install()
def export_fixtures(): for app in frappe.get_installed_apps(): for fixture in frappe.get_hooks("fixtures", app_name=app): print "Exporting " + fixture if frappe.db.get_value("DocType", fixture, "issingle"): export_fixture(fixture, fixture, app) else: export_csv(fixture, frappe.get_app_path(app, "fixtures", frappe.scrub(fixture) + ".csv"))
def install_collector(): """Replace the default except hook in sys to enable the automation of ticket collector""" def collector(type, exception, traceback): collect(exception) if 'frappe_traceback_collector' in frappe.get_installed_apps(): sys.excepthook = collector print "Traceback collector running ..."
def execute(): installed = frappe.get_installed_apps() if "webnotes" in installed: installed.remove("webnotes") if "frappe" not in installed: installed = ["frappe"] + installed frappe.db.set_global("installed_apps", json.dumps(installed)) frappe.clear_cache()
def remove_app(name): """Remove installed app""" frappe.only_for("System Manager") if name in frappe.get_installed_apps(): enqueue('frappe.desk.page.applications.applications.start_remove', name=name) frappe.msgprint(_('Queued for backup and removing {0}').format(frappe.bold(name)))
def install_app(name, verbose=False, set_as_patched=True): frappe.flags.in_install = name frappe.flags.ignore_in_install = False frappe.clear_cache() app_hooks = frappe.get_hooks(app_name=name) installed_apps = frappe.get_installed_apps() # install pre-requisites if app_hooks.required_apps: for app in app_hooks.required_apps: install_app(app) frappe.flags.in_install = name frappe.clear_cache() if name not in frappe.get_all_apps(): raise Exception("App not in apps.txt") if name in installed_apps: frappe.msgprint(_("App {0} already installed").format(name)) return print("\nInstalling {0}...".format(name)) if name != "frappe": frappe.only_for("System Manager") for before_install in app_hooks.before_install or []: out = frappe.get_attr(before_install)() if out==False: return if name != "frappe": add_module_defs(name) sync_for(name, force=True, sync_everything=True, verbose=verbose, reset_permissions=True) sync_from_app(name) add_to_installed_apps(name) frappe.get_doc('Portal Settings', 'Portal Settings').sync_menu() if set_as_patched: set_all_patches_as_completed(name) for after_install in app_hooks.after_install or []: frappe.get_attr(after_install)() sync_fixtures(name) sync_customizations(name) for after_sync in app_hooks.after_sync or []: frappe.get_attr(after_sync)() # frappe.flags.in_install = False
def get_installed_apps_info(): out = [] for app in frappe.get_installed_apps(): out.append({ 'app_name': app, 'version': getattr(frappe.get_module(app), '__version__', 'Unknown') }) return out
def sync_all(force=0, verbose=False): block_user(True) for app in frappe.get_installed_apps(): sync_for(app, force, verbose=verbose) block_user(False) frappe.clear_cache()
def export_fixtures(): """Export fixtures as JSON to `[app]/fixtures`""" for app in frappe.get_installed_apps(): for fixture in frappe.get_hooks("fixtures", app_name=app): print "Exporting {0}".format(fixture) if not os.path.exists(frappe.get_app_path(app, "fixtures")): os.mkdir(frappe.get_app_path(app, "fixtures")) export_json(fixture, frappe.get_app_path(app, "fixtures", frappe.scrub(fixture) + ".json"))
def get_all_patches(): patches = [] for app in frappe.get_installed_apps(): # 3-to-4 fix if app == "webnotes": app = "frappe" patches.extend(frappe.get_file_items(frappe.get_pymodule_path(app, "patches.txt"))) return patches
def execute(): for dt in ("assessment", "announcement", "course", "fees"): frappe.reload_doc("schools", "doctype", dt) frappe.get_doc('Portal Settings').sync_menu() if 'schools' in frappe.get_installed_apps(): domainify.setup_domain('Education') else: domainify.setup_sidebar_items(domainify.get_domain('Manufacturing'))
def get_jenv_customization(customizable_type): import frappe if getattr(frappe.local, "site", None): for app in frappe.get_installed_apps(): for jenv_customizable, jenv_customizable_definition in frappe.get_hooks(app_name=app).get("jenv", {}).items(): if customizable_type == jenv_customizable: for data in jenv_customizable_definition: split_data = data.split(":") yield split_data[0], split_data[1]
def check_docs_to_rename(): if "erpnext" not in frappe.get_installed_apps(): return docs_to_rename = get_docs_to_rename() if docs_to_rename: print "To Rename" print json.dumps(docs_to_rename, indent=1, sort_keys=True) frappe.db.rollback()
def start(self, rebuild=False): self.synced = [] self.synced_paths = [] self.updated = 0 if rebuild: frappe.db.sql("delete from `tabWeb Page` where ifnull(template_path, '')!=''") for app in frappe.get_installed_apps(): self.sync_for_app(app) self.cleanup()
def get_pages(app=None): '''Get all pages. Called for docs / sitemap''' pages = {} frappe.local.flags.in_get_all_pages = True folders = frappe.local.flags.web_pages_folders or ('www', 'templates/pages') if app: apps = [app] else: apps = frappe.local.flags.web_pages_apps or frappe.get_installed_apps() for app in apps: app_path = frappe.get_app_path(app) for start in folders: path = os.path.join(app_path, start) pages.update(get_pages_from_path(path, app, app_path)) frappe.local.flags.in_get_all_pages = False return pages
def execute(): frappe.reload_doctype('Role') for dt in ("assessment", "course", "fees"): # 'Schools' module changed to the 'Education' # frappe.reload_doc("schools", "doctype", dt) frappe.reload_doc("education", "doctype", dt) for dt in ("domain", "has_domain", "domain_settings"): frappe.reload_doc("core", "doctype", dt) frappe.reload_doc('website', 'doctype', 'portal_menu_item') frappe.get_doc('Portal Settings').sync_menu() if 'schools' in frappe.get_installed_apps(): domain = frappe.get_doc('Domain', 'Education') domain.setup_domain() else: domain = frappe.get_doc('Domain', 'Manufacturing') domain.setup_data() domain.setup_sidebar_items()
def run_all_tests(app=None, verbose=False): import os apps = [app] if app else frappe.get_installed_apps() test_suite = unittest.TestSuite() for app in apps: for path, folders, files in os.walk(frappe.get_pymodule_path(app)): for dontwalk in ('locals', '.git', 'public'): if dontwalk in folders: folders.remove(dontwalk) # print path for filename in files: filename = cstr(filename) if filename.startswith("test_") and filename.endswith(".py"): # print filename[:-3] _add_test(path, filename, verbose, test_suite=test_suite) return unittest.TextTestRunner(verbosity=1 + (verbose and 1 or 0)).run(test_suite)
def execute(): from frappe.website.doctype.website_template.website_template import \ get_pages_and_generators, get_template_controller frappe.reload_doc("website", "doctype", "website_template") frappe.reload_doc("website", "doctype", "website_route") for app in frappe.get_installed_apps(): pages, generators = get_pages_and_generators(app) for g in generators: doctype = frappe.get_attr(get_template_controller(app, g["path"], g["fname"]) + ".doctype") module = frappe.db.get_value("DocType", doctype, "module") frappe.reload_doc(frappe.scrub(module), "doctype", frappe.scrub(doctype)) frappe.db.sql("""update `tabBlog Category` set `title`=`name` where ifnull(`title`, '')=''""") frappe.db.sql("""update `tabWebsite Route` set idx=null""") for doctype in ["Blog Category", "Blog Post", "Web Page", "Website Group"]: frappe.db.sql("""update `tab{}` set idx=null""".format(doctype)) from frappe.website.doctype.website_template.website_template import rebuild_website_template rebuild_website_template()
def copy_client_files(fluorine_temp_path): apps = frappe.get_installed_apps() #[::-1] for app in apps: pathname = frappe.get_app_path(app) startpath = os.path.join(pathname, "templates", "react") if pathname: for root, dirs, files in os.walk(startpath): relpath = os.path.relpath(root, startpath) #if not root.endswith("public") and not root.endswith("server") and not root.endswith("tests") and not root.endswith("private") and not root.endswith("temp"): #if not relpath.startswith(("public", "tests", "private", "temp", "server")): m = re.search(r"\b(public|tests|server|temp|private)\b", relpath) if not m: destpath = os.path.join(fluorine_temp_path, relpath) print "destpath {} relpath {} root {}".format( destpath, relpath, root) frappe.create_folder(destpath) for file in files: if file.endswith(".js"): copy_file(os.path.join(root, file), os.path.join(destpath, app + "_" + file))
def set_filters(jenv): import frappe from frappe.utils import global_date_format, cint, cstr, flt from frappe.website.utils import get_shade, abs_url from markdown2 import markdown jenv.filters["global_date_format"] = global_date_format jenv.filters["markdown"] = markdown jenv.filters["json"] = frappe.as_json jenv.filters["get_shade"] = get_shade jenv.filters["len"] = len jenv.filters["int"] = cint jenv.filters["str"] = cstr jenv.filters["flt"] = flt jenv.filters["abs_url"] = abs_url # load jenv_filters from hooks.py for app in frappe.get_installed_apps(): for jenv_filter in (frappe.get_hooks(app_name=app).jenv_filter or []): filter_name, filter_function = jenv_filter.split(":") jenv.filters[filter_name] = frappe.get_attr(filter_function)
def execute(): frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_settings') frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_tax_account') frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_log') frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_webhook_detail') if 'erpnext_shopify' in frappe.get_installed_apps(): remove_from_installed_apps('erpnext_shopify') frappe.db.sql( 'delete from `tabDesktop Icon` where app="erpnext_shopify" ') frappe.delete_doc("Module Def", 'erpnext_shopify') frappe.db.commit() frappe.db.sql("truncate `tabShopify Log`") setup_app_type() else: disable_shopify()
def inline_style_in_html(html): ''' Convert email.css and html to inline-styled html ''' from premailer import Premailer apps = frappe.get_installed_apps() # add frappe email css file css_files = ['assets/css/email.css'] if 'frappe' in apps: apps.remove('frappe') for app in apps: path = 'assets/{0}/css/email.css'.format(app) css_files.append(path) css_files = [css_file for css_file in css_files if os.path.exists(os.path.abspath(css_file))] p = Premailer(html=html, external_styles=css_files, strip_important=False) return p.transform()
def sync_fixtures(app=None): """Import, overwrite fixtures from `[app]/fixtures`""" if app: apps = [app] else: apps = frappe.get_installed_apps() frappe.flags.in_fixtures = True for app in apps: if os.path.exists(frappe.get_app_path(app, "fixtures")): fixture_files = sorted(os.listdir(frappe.get_app_path(app, "fixtures"))) for fname in fixture_files: if fname.endswith(".json") or fname.endswith(".csv"): import_doc(frappe.get_app_path(app, "fixtures", fname)) import_custom_scripts(app) frappe.flags.in_fixtures = False frappe.db.commit()
def setup(): complete_setup() make_customers_suppliers_contacts() show_item_groups_in_website() make_items() make_price_lists() make_users_and_employees() make_bank_account() # make_opening_stock() # make_opening_accounts() make_tax_accounts() make_tax_masters() make_shipping_rules() if "shopping_cart" in frappe.get_installed_apps(): enable_shopping_cart() frappe.db.set_default("lang", 'zh-cn') frappe.local.lang = 'zh-cn' frappe.clear_cache()
def startDeployment(**kwargs): ### # This method will prepare the necessary data and call the methods # which will deploy(upload) the json to the respective doctypes. ### try: skipAppList = ['frappe', 'erpnext', 'deployer'] print("Server is " + kwargs['server']) apps = frappe.get_installed_apps() exitCriteria = 0 for app in apps: if app in skipAppList: continue if os.path.exists(frappe.get_app_path(app, "fixtures")): fixture_file_list = sorted( os.listdir(frappe.get_app_path(app, "fixtures"))) file_list_lenght = len(fixture_file_list) checkList = [] while fixture_file_list: if file_list_lenght == len(fixture_file_list): checkList = fixture_file_list.copy() file_List_Lenght = len(fixture_file_list) fname = fixture_file_list.pop() if fname.endswith(".json"): wholeJsonData = getJsonData( frappe.get_app_path(app, "fixtures", fname)) for jsonData in wholeJsonData: if not uploadData(jsonData, fname, kwargs): fixture_file_list.insert(0, fname) file_list_lenght = len(fixture_file_list) break if checkList == fixture_file_list: raise Exception( "Unable to deploy the following doctypes " + str(fixture_file_list) + ". Reason: Some dependent doctypes could be missing." ) except Exception as err: print(err) frappe.logger().error(frappe.utils.get_traceback())
def run_all_tests(app=None, verbose=False, profile=False, ui_tests=False, failfast=False, junit_xml_output=False): import os apps = [app] if app else frappe.get_installed_apps() test_suite = unittest.TestSuite() for app in apps: for path, folders, files in os.walk(frappe.get_pymodule_path(app)): for dontwalk in ('locals', '.git', 'public'): if dontwalk in folders: folders.remove(dontwalk) # print path for filename in files: filename = cstr(filename) if filename.startswith("test_") and filename.endswith(".py")\ and filename != 'test_runner.py': # print filename[:-3] _add_test(app, path, filename, verbose, test_suite, ui_tests) if junit_xml_output: runner = unittest_runner(verbosity=1+(verbose and 1 or 0), failfast=failfast) else: runner = unittest_runner(resultclass=TimeLoggingTestResult, verbosity=1+(verbose and 1 or 0), failfast=failfast) if profile: pr = cProfile.Profile() pr.enable() out = runner.run(test_suite) if profile: pr.disable() s = StringIO() ps = pstats.Stats(pr, stream=s).sort_stats('cumulative') ps.print_stats() print(s.getvalue()) return out
def auto_deploy(context, app, migrate=False, restart=False, remote='upstream'): '''Pull and migrate sites that have new version''' from frappe.utils.gitutils import get_app_branch from frappe.utils import get_sites branch = get_app_branch(app) app_path = frappe.get_app_path(app) # fetch subprocess.check_output(['git', 'fetch', remote, branch], cwd=app_path) # get diff if subprocess.check_output( ['git', 'diff', '{0}..upstream/{0}'.format(branch)], cwd=app_path): print('Updates found for {0}'.format(app)) if app == 'frappe': # run bench update subprocess.check_output(['bench', 'update', '--no-backup'], cwd='..') else: updated = False subprocess.check_output( ['git', 'pull', '--rebase', 'upstream', branch], cwd=app_path) # find all sites with that app for site in get_sites(): frappe.init(site) if app in frappe.get_installed_apps(): print('Updating {0}'.format(site)) updated = True subprocess.check_output( ['bench', '--site', site, 'clear-cache'], cwd='..') if migrate: subprocess.check_output( ['bench', '--site', site, 'migrate'], cwd='..') frappe.destroy() if updated and restart: subprocess.check_output(['bench', 'restart'], cwd='..') else: print('No Updates')
def get_messages_from_include_files(app_name=None): """Returns messages from js files included at time of boot like desk.min.js for desk and web""" messages = [] for file in (frappe.get_hooks("app_include_js", app_name=app_name) or []) + (frappe.get_hooks("web_include_js", app_name=app_name) or []): messages.extend( get_messages_from_file(os.path.join(frappe.local.sites_path, file))) for app in ([app_name] if app_name else frappe.get_installed_apps()): if os.path.isfile(frappe.get_app_path(app, "public/build.json")): with open(frappe.get_app_path(app, "public/build.json"), 'r') as f: for f in json.loads(f.read()): if not f.startswith("concat:"): messages.extend( get_messages_from_file( os.path.join(frappe.local.sites_path, "assets/" + f))) return messages
def run_ui_tests(context, app=None, ci=False): "Run UI tests" import subprocess site = get_site(context) frappe.init(site=site) if app is None: app = ",".join(frappe.get_installed_apps()) cmd = [ './node_modules/.bin/nightwatch', '--config', './apps/frappe/frappe/nightwatch.js', '--app', app, '--site', site ] if ci: cmd.extend(['--env', 'ci_server']) bench_path = frappe.utils.get_bench_path() subprocess.call(cmd, cwd=bench_path)
def console(context): "Start ipython console for a site" site = get_site(context) frappe.init(site=site) frappe.connect() frappe.local.lang = frappe.db.get_default("lang") import IPython all_apps = frappe.get_installed_apps() failed_to_import = [] for app in all_apps: try: locals()[app] = __import__(app) except ModuleNotFoundError: failed_to_import.append(app) print("Apps in this namespace:\n{}".format(", ".join(all_apps))) if failed_to_import: print("\nFailed to import:\n{}".format(", ".join(failed_to_import))) IPython.embed(display_banner="", header="", colors="neutral")
def get_scss_paths(): """ Return a set of SCSS import paths from all apps that provide `website.scss`. If `$BENCH_PATH/apps/frappe/frappe/public/scss/website[.bundle].scss` exists, the returned set will contain 'frappe/public/scss/website[.bundle]'. """ import_path_list = [] bench_path = frappe.utils.get_bench_path() scss_files = [ 'public/scss/website.scss', 'public/scss/website.bundle.scss' ] for app in frappe.get_installed_apps(): for scss_file in scss_files: relative_path = join_path(app, scss_file) full_path = get_path('apps', app, relative_path, base=bench_path) if path_exists(full_path): import_path = splitext(relative_path)[0] import_path_list.append(import_path) return import_path_list
def get_page_info_from_template(path): '''Return page_info from path''' apps = frappe.get_installed_apps(frappe_last=True) if 'cart_extra' in apps: apps.remove('cart_extra') apps.insert(0, 'cart_extra') for app in apps: app_path = frappe.get_app_path(app) folders = get_start_folders() for start in folders: search_path = os.path.join(app_path, start, path) options = (search_path, search_path + '.html', search_path + '.md', search_path + '/index.html', search_path + '/index.md') for o in options: option = frappe.as_unicode(o) if os.path.exists(option) and not os.path.isdir(option): return get_page_info(option, app, start, app_path=app_path) return None
def get_jloader(): import frappe if not frappe.local.jloader: from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader apps = frappe.local.flags.web_pages_apps or frappe.get_installed_apps(sort=True) apps.reverse() if not "frappe" in apps: apps.append('frappe') frappe.local.jloader = ChoiceLoader( # search for something like app/templates/... [PrefixLoader(dict( (app, PackageLoader(app, ".")) for app in apps ))] # search for something like templates/... + [PackageLoader(app, ".") for app in apps] ) return frappe.local.jloader
def get_routes_to_index(): apps = frappe.get_installed_apps() routes_to_index = [] for app in apps: base = frappe.get_app_path(app, "www") path_to_index = frappe.get_app_path(app, "www") for dirpath, _, filenames in os.walk(path_to_index, topdown=True): for f in filenames: if f.endswith((".md", ".html")): filepath = os.path.join(dirpath, f) route = os.path.relpath(filepath, base) route = route.split(".")[0] if route.endswith("index"): route = route.rsplit("index", 1)[0] routes_to_index.append(route) return routes_to_index
def _reinstall(site, admin_password=None, mariadb_root_username=None, mariadb_root_password=None, yes=False, verbose=False): from frappe.installer import _new_site if not yes: click.confirm('This will wipe your database. Are you sure you want to reinstall?', abort=True) try: frappe.init(site=site) frappe.connect() frappe.clear_cache() installed = frappe.get_installed_apps() frappe.clear_cache() except Exception: installed = [] finally: if frappe.db: frappe.db.close() frappe.destroy() frappe.init(site=site) _new_site(frappe.conf.db_name, site, verbose=verbose, force=True, reinstall=True, install_apps=installed, mariadb_root_username=mariadb_root_username, mariadb_root_password=mariadb_root_password, admin_password=admin_password)
def load_monkey_patches(): """ Loads all modules present in monkey_patches to override some logic in Frappe / ERPNext. Returns if patches have already been loaded earlier. """ global patches_loaded if patches_loaded: return patches_loaded = True if app_name not in frappe.get_installed_apps(): return for module_name in os.listdir( frappe.get_app_path(app_name, "monkey_patches")): if not module_name.endswith(".py") or module_name == "__init__.py": continue importlib.import_module(app_name + ".monkey_patches." + module_name[:-3])
def update_global_search_doctypes(): global_search_doctypes = [] show_message(1, _("Fetching default Global Search documents.")) installed_apps = [app for app in frappe.get_installed_apps() if app] active_domains = [domain for domain in frappe.get_active_domains() if domain] active_domains.append("Default") for app in installed_apps: search_doctypes = frappe.get_hooks(hook="global_search_doctypes", app_name=app) if not search_doctypes: continue for domain in active_domains: if search_doctypes.get(domain): global_search_doctypes.extend(search_doctypes.get(domain)) doctype_list = set([dt.name for dt in frappe.get_all("DocType")]) allowed_in_global_search = [] for dt in global_search_doctypes: if dt.get("index") is not None: allowed_in_global_search.insert(dt.get("index"), dt.get("doctype")) continue allowed_in_global_search.append(dt.get("doctype")) show_message(2, _("Setting up Global Search documents.")) global_search_settings = frappe.get_single("Global Search Settings") global_search_settings.allowed_in_global_search = [] for dt in allowed_in_global_search: if dt not in doctype_list: continue global_search_settings.append("allowed_in_global_search", { "document_type": dt }) global_search_settings.save(ignore_permissions=True) show_message(3, "Global Search Documents have been reset.")
def _get(): global_search_doctypes = [] filters = {} if not with_child_tables: filters = {"istable": ["!=", 1], "issingle": ["!=", 1]} for d in frappe.get_all('DocType', fields=['name', 'module'], filters=filters): meta = frappe.get_meta(d.name) if len(meta.get_global_search_fields()) > 0: global_search_doctypes.append(d) installed_apps = frappe.get_installed_apps() module_app = frappe.local.module_app doctypes = [ d.name for d in global_search_doctypes if module_app.get(frappe.scrub(d.module)) and module_app[frappe.scrub(d.module)] in installed_apps ] return doctypes
def get_routes_to_index(): apps = frappe.get_installed_apps() routes_to_index = [] for app in apps: base = frappe.get_app_path(app, 'www') path_to_index = frappe.get_app_path(app, 'www') for dirpath, _, filenames in os.walk(path_to_index, topdown=True): for f in filenames: if f.endswith(('.md', '.html')): filepath = os.path.join(dirpath, f) route = os.path.relpath(filepath, base) route = route.split('.')[0] if route.endswith('index'): route = route.rsplit('index', 1)[0] routes_to_index.append(route) return routes_to_index
def set_redirect(iyzipay_express_payment): """ ERPNext related redirects. You need to set Iyzipay Payment.flags.redirect_to on status change. Called via IyzipayPayment.on_update """ if "erpnext" not in frappe.get_installed_apps(): return if not iyzipay_express_payment.flags.status_changed_to: return reference_doctype = iyzipay_express_payment.reference_doctype reference_docname = iyzipay_express_payment.reference_docname if not (reference_doctype and reference_docname): return reference_doc = frappe.get_doc(reference_doctype, reference_docname) shopping_cart_settings = frappe.get_doc("Shopping Cart Settings") if iyzipay_express_payment.flags.status_changed_to == "Authorized": reference_doc.run_method("set_as_paid") # if shopping cart enabled and in session if (shopping_cart_settings.enabled and hasattr(frappe.local, "session") and frappe.local.session.user != "Guest"): success_url = shopping_cart_settings.payment_success_url if success_url: iyzipay_express_payment.flags.redirect_to = ({ "Orders": "orders", "Invoices": "invoices", "My Account": "me" }).get(success_url, "me") else: iyzipay_express_payment.flags.redirect_to = get_url( "/orders/{0}".format(reference_doc.reference_name))
def execute(): frappe.reload_doc('desk', 'doctype', 'desktop_icon') frappe.db.sql('delete from `tabDesktop Icon`') modules_list = [] for app in frappe.get_installed_apps(): modules_list += sync_from_app(app) # sync hidden modules hidden_modules = frappe.db.get_global('hidden_modules') if hidden_modules: for m in json.loads(hidden_modules): try: desktop_icon = frappe.get_doc('Desktop Icon', {'module_name': m, 'standard': 1, 'app': app}) desktop_icon.db_set('hidden', 1) except frappe.DoesNotExistError: pass # sync user sort for user in frappe.get_all('User', filters={'user_type': 'System User'}): user_list = frappe.defaults.get_user_default('_user_desktop_items', user=user.name) if user_list: user_list = json.loads(user_list) for i, module_name in enumerate(user_list): try: desktop_icon = get_user_copy(module_name, user=user.name) desktop_icon.db_set('idx', i) except frappe.DoesNotExistError: pass # set remaining icons as hidden for module_name in list(set([m['module_name'] for m in modules_list]) - set(user_list)): try: desktop_icon = get_user_copy(module_name, user=user.name) desktop_icon.db_set('hidden', 1) except frappe.DoesNotExistError: pass
def get_pages(): pages = frappe.cache().get_value("_website_pages") if not pages: pages = [] for app in frappe.get_installed_apps(): app_path = frappe.get_app_path(app) path = os.path.join(app_path, "templates", "pages") if os.path.exists(path): for fname in os.listdir(path): fname = frappe.utils.cstr(fname) page_name, extn = fname.rsplit(".", 1) if extn in ("html", "xml", "js", "css"): route_page_name = page_name if extn == "html" else fname # add website route route = frappe._dict() route.page_or_generator = "Page" route.template = os.path.relpath( os.path.join(path, fname), app_path) route.name = route.page_name = route_page_name route.public_read = 1 controller_path = os.path.join(path, page_name + ".py") if os.path.exists(controller_path): controller = app + "." + os.path.relpath( controller_path, app_path).replace( os.path.sep, ".")[:-3] route.controller = controller try: route.page_title = frappe.get_attr( controller + "." + "page_title") except AttributeError: pass pages.append(route) frappe.cache().set_value("_website_pages", pages) return pages
def run_all_tests(app=None, verbose=False, profile=False): import os apps = [app] if app else frappe.get_installed_apps() test_suite = unittest.TestSuite() for app in apps: for path, folders, files in os.walk(frappe.get_pymodule_path(app)): for dontwalk in ('locals', '.git', 'public'): if dontwalk in folders: folders.remove(dontwalk) # print path for filename in files: filename = cstr(filename) if filename.startswith("test_") and filename.endswith(".py"): # print filename[:-3] _add_test(app, path, filename, verbose, test_suite=test_suite) if profile: pr = cProfile.Profile() pr.enable() out = unittest.TextTestRunner(verbosity=1 + (verbose and 1 or 0)).run(test_suite) if profile: pr.disable() s = StringIO.StringIO() ps = pstats.Stats(pr, stream=s).sort_stats('cumulative') ps.print_stats() print s.getvalue() return out
def install_app(name, verbose=False, set_as_patched=True): frappe.flags.in_install_app = name frappe.clear_cache() app_hooks = frappe.get_hooks(app_name=name) installed_apps = frappe.get_installed_apps() if name not in frappe.get_all_apps(with_frappe=True): raise Exception("App not in apps.txt") if name in installed_apps: print "App Already Installed" frappe.msgprint("App {0} already installed".format(name)) return if name != "frappe": frappe.only_for("System Manager") for before_install in app_hooks.before_install or []: frappe.get_attr(before_install)() if name != "frappe": add_module_defs(name) sync_for(name, force=True, sync_everything=True, verbose=verbose) add_to_installed_apps(name) if set_as_patched: set_all_patches_as_completed(name) for after_install in app_hooks.after_install or []: frappe.get_attr(after_install)() print "Installing Fixtures..." sync_fixtures(name) frappe.flags.in_install_app = False