def _get_home_page(): home_page = None get_website_user_home_page = dataent.get_hooks( 'get_website_user_home_page') if get_website_user_home_page: home_page = dataent.get_attr(get_website_user_home_page[-1])( dataent.session.user) if not home_page: role_home_page = dataent.get_hooks("role_home_page") if role_home_page: for role in dataent.get_roles(): if role in role_home_page: home_page = role_home_page[role][-1] break if not home_page: home_page = dataent.get_hooks("home_page") if home_page: home_page = home_page[-1] if not home_page: home_page = dataent.db.get_value("Website Settings", None, "home_page") or "login" home_page = home_page.strip('/') return home_page
def get_website_user_home_page(user): home_page_method = dataent.get_hooks('get_website_user_home_page') if home_page_method: home_page = dataent.get_attr(home_page_method[-1])(user) return '/' + home_page.strip('/') elif dataent.get_hooks('website_user_home_page'): return '/' + dataent.get_hooks('website_user_home_page')[-1].strip('/') else: return '/me'
def get_website_settings(): hooks = dataent.get_hooks() context = dataent._dict({ 'top_bar_items': get_items('top_bar_items'), 'footer_items': get_items('footer_items'), "post_login": [ {"label": _("My Account"), "url": "/me"}, # {"class": "divider"}, {"label": _("Logout"), "url": "/?cmd=web_logout"} ] }) settings = dataent.get_single("Website Settings") for k in ["banner_html", "brand_html", "copyright", "twitter_share_via", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup", "hide_footer_signup", "head_html", "title_prefix", "navbar_search"]: if hasattr(settings, k): context[k] = settings.get(k) if settings.address: context["footer_address"] = settings.address for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup"]: context[k] = int(context.get(k) or 0) if dataent.request: context.url = quote(str(get_request_site_address(full_address=True)), safe="/:") context.encoded_title = quote(encode(context.title or ""), str("")) for update_website_context in hooks.update_website_context or []: dataent.get_attr(update_website_context)(context) context.web_include_js = hooks.web_include_js or [] context.web_include_css = hooks.web_include_css or [] via_hooks = dataent.get_hooks("website_context") for key in via_hooks: context[key] = via_hooks[key] if key not in ("top_bar_items", "footer_items", "post_login") \ and isinstance(context[key], (list, tuple)): context[key] = context[key][-1] add_website_theme(context) if not context.get("favicon"): context["favicon"] = "/assets/dataent/images/favicon.png" if settings.favicon and settings.favicon != "attach_files:": context["favicon"] = settings.favicon return context
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 (dataent.get_hooks("app_include_js", app_name=app_name) or []) + (dataent.get_hooks("web_include_js", app_name=app_name) or []): messages.extend( get_messages_from_file(os.path.join(dataent.local.sites_path, file))) return messages
def get_site_info(): from dataent.utils.user import get_system_managers from dataent.core.doctype.user.user import STANDARD_USERS from dataent.email.queue import get_emails_sent_this_month # only get system users users = dataent.get_all('User', filters={ 'user_type': 'System User', 'name': ('not in', STANDARD_USERS) }, fields=[ 'name', 'enabled', 'last_login', 'last_active', 'language', 'time_zone' ]) system_managers = get_system_managers(only_name=True) for u in users: # tag system managers u.is_system_manager = 1 if u.name in system_managers else 0 u.full_name = get_fullname(u.name) u.email = u.name del u['name'] system_settings = dataent.db.get_singles_dict('System Settings') space_usage = dataent._dict((dataent.local.conf.limits or {}).get('space_usage', {})) kwargs = { "fields": ["user", "creation", "full_name"], "filters": { "Operation": "Login", "Status": "Success" }, "limit": "10" } site_info = { 'installed_apps': get_installed_apps_info(), 'users': users, 'country': system_settings.country, 'language': system_settings.language or 'english', 'time_zone': system_settings.time_zone, 'setup_complete': cint(system_settings.setup_complete), 'scheduler_enabled': system_settings.enable_scheduler, # usage 'emails_sent': get_emails_sent_this_month(), 'space_used': flt((space_usage.total or 0) / 1024.0, 2), 'database_size': space_usage.database_size, 'backup_size': space_usage.backup_size, 'files_size': space_usage.files_size, 'last_logins': dataent.get_all("Activity Log", **kwargs) } # from other apps for method_name in dataent.get_hooks('get_site_info'): site_info.update(dataent.get_attr(method_name)(site_info) or {}) # dumps -> loads to prevent datatype conflicts return json.loads(dataent.as_json(site_info))
def get_reply(self, query): self.query = query.lower() self.setup() self.pre_process() # basic replies if self.query.split()[0] in ("hello", "hi"): return _("Hello {0}").format(dataent.utils.get_fullname()) if self.query == "help": return help_text.format(dataent.utils.get_fullname()) # build using parsers replies = [] for parser in dataent.get_hooks('bot_parsers'): reply = None try: reply = dataent.get_attr(parser)(self, query).get_reply() except dataent.PermissionError: reply = _("Oops, you are not allowed to know that") if reply: replies.append(reply) if replies: return '\n\n'.join(replies) if not reply: return _("Don't know, ask 'help'")
def resolve_redirect(path): ''' Resolve redirects from hooks Example: website_redirect = [ # absolute location {"source": "/from", "target": "https://mysite/from"}, # relative location {"source": "/from", "target": "/main"}, # use regex {"source": r"/from/(.*)", "target": r"/main/\1"} # use r as a string prefix if you use regex groups or want to escape any string literal ] ''' redirects = dataent.get_hooks('website_redirects') if not redirects: return redirect_to = dataent.cache().hget('website_redirects', path) if redirect_to: dataent.flags.redirect_location = redirect_to raise dataent.Redirect for rule in redirects: pattern = rule['source'].strip('/ ') + '$' if re.match(pattern, path): redirect_to = re.sub(pattern, rule['target'], path) dataent.flags.redirect_location = redirect_to dataent.cache().hset('website_redirects', path, redirect_to) raise dataent.Redirect
def execute_cmd(cmd, from_async=False): """execute a request as python module""" for hook in dataent.get_hooks("override_whitelisted_methods", {}).get(cmd, []): # override using the first hook cmd = hook break try: method = get_attr(cmd) except Exception as e: if dataent.local.conf.developer_mode: raise e else: dataent.respond_as_web_page(title='Invalid Method', html='Method not found', indicator_color='red', http_status_code=404) return if from_async: method = method.queue is_whitelisted(method) return dataent.call(method, **dataent.form_dict)
def get_versions(): """Get versions of all installed apps. Example: { "dataent": { "title": "Dataent Framework", "version": "5.0.0" } }""" versions = {} for app in dataent.get_installed_apps(sort=True): app_hooks = dataent.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"] = dataent.get_attr(app + ".__version__") except AttributeError: versions[app]["version"] = '0.0.1' return versions
def restrict_roles_and_modules(self): '''Disable all restricted roles and set `restrict_to_domain` property in Module Def''' active_domains = dataent.get_active_domains() all_domains = list((dataent.get_hooks('domains') or {})) def remove_role(role): dataent.db.sql('delete from `tabHas Role` where role=%s', role) dataent.set_value('Role', role, 'disabled', 1) for domain in all_domains: data = dataent.get_domain_data(domain) if not dataent.db.get_value('Domain', domain): dataent.get_doc(dict(doctype='Domain', domain=domain)).insert() if 'modules' in data: for module in data.get('modules'): dataent.db.set_value('Module Def', module, 'restrict_to_domain', domain) if 'restricted_roles' in data: for role in data['restricted_roles']: if not dataent.db.get_value('Role', role): dataent.get_doc(dict(doctype='Role', role_name=role)).insert() dataent.db.set_value('Role', role, 'restrict_to_domain', domain) if domain not in active_domains: remove_role(role) if 'custom_fields' in data: if domain not in active_domains: inactive_domain = dataent.get_doc("Domain", domain) inactive_domain.setup_data() inactive_domain.remove_custom_field()
def get_jloader(): import dataent if not getattr(dataent.local, 'jloader', None): from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader if dataent.local.flags.in_setup_help: apps = ['dataent'] else: apps = dataent.get_hooks('template_apps') if not apps: apps = dataent.local.flags.web_pages_apps or dataent.get_installed_apps( sort=True) apps.reverse() if not "dataent" in apps: apps.append('dataent') dataent.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 dataent.local.jloader
def get_file_data_from_hash(content_hash, is_private=0): for name in dataent.db.sql_list( "select name from `tabFile` where content_hash=%s and is_private=%s", (content_hash, is_private)): b = dataent.get_doc('File', name) return {k: b.get(k) for k in dataent.get_hooks()['write_file_keys']} return False
def get_hook_method(hook_name, fallback=None): method = (dataent.get_hooks().get(hook_name)) if method: method = dataent.get_attr(method[0]) return method if fallback: return fallback
def get_scheduler_events(event): '''Get scheduler events from hooks and integrations''' scheduler_events = dataent.cache().get_value('scheduler_events') if not scheduler_events: scheduler_events = dataent.get_hooks("scheduler_events") dataent.cache().set_value('scheduler_events', scheduler_events) return scheduler_events.get(event) or []
def test_hooks(self): hooks = dataent.get_hooks() self.assertTrue(isinstance(hooks.get("app_name"), list)) self.assertTrue(isinstance(hooks.get("doc_events"), dict)) self.assertTrue(isinstance(hooks.get("doc_events").get("*"), dict)) self.assertTrue(isinstance(hooks.get("doc_events").get("*"), dict)) self.assertTrue( "dataent.desk.notifications.clear_doctype_notifications" in hooks.get("doc_events").get("*").get("on_update"))
def _get(): rules = dataent.get_hooks("website_route_rules") for d in dataent.get_all('DocType', 'name, route', dict(has_web_view=1)): if d.route: rules.append( dict(from_route='/' + d.route.strip('/'), to_route=d.name)) return rules
def _get(): installed_apps = dataent.get_installed_apps() doctypes = dataent.get_hooks("website_generators") doctypes += [ d.name for d in dataent.get_all('DocType', 'name, module', dict(has_web_view=1)) if dataent.local.module_app[dataent.scrub(d.module)] in installed_apps ] return doctypes
def update_and_get_user_progress(): ''' Return setup progress action states (called via `update_and_get_user_progress` hook) ''' states = {} for fn in dataent.get_hooks('update_and_get_user_progress'): states.update(dataent.get_attr(fn)()) return states
def get_user_progress_slides(): ''' Return user progress slides for the desktop (called via `get_user_progress_slides` hook) ''' slides = [] if cint(dataent.db.get_single_value('System Settings', 'setup_complete')): for fn in dataent.get_hooks('get_user_progress_slides'): slides += dataent.get_attr(fn)() return slides
def get_dict_from_hooks(fortype, name): translated_dict = {} hooks = dataent.get_hooks("get_translated_dict") for (hook_fortype, fortype_name) in hooks: if hook_fortype == fortype and fortype_name == name: for method in hooks[(hook_fortype, fortype_name)]: translated_dict.update(dataent.get_attr(method)()) return translated_dict
def main(app=None, module=None, doctype=None, verbose=False, tests=(), force=False, profile=False, junit_xml_output=None, ui_tests=False, doctype_list_path=None, skip_test_records=False, failfast=False): global unittest_runner if doctype_list_path: app, doctype_list_path = doctype_list_path.split(os.path.sep, 1) with open(dataent.get_app_path(app, doctype_list_path), 'r') as f: doctype = f.read().strip().splitlines() xmloutput_fh = None if junit_xml_output: xmloutput_fh = open(junit_xml_output, 'w') unittest_runner = xmlrunner_wrapper(xmloutput_fh) else: unittest_runner = unittest.TextTestRunner try: dataent.flags.print_messages = verbose dataent.flags.in_test = True if not dataent.db: dataent.connect() # if not dataent.conf.get("db_name").startswith("test_"): # raise Exception, 'db_name must start with "test_"' # workaround! since there is no separate test db dataent.clear_cache() dataent.utils.scheduler.disable_scheduler() set_test_email_config() if not dataent.flags.skip_before_tests: if verbose: print('Running "before_tests" hooks') for fn in dataent.get_hooks("before_tests", app_name=app): dataent.get_attr(fn)() if doctype: ret = run_tests_for_doctype(doctype, verbose, tests, force, profile) elif module: ret = run_tests_for_module(module, verbose, tests, profile) else: ret = run_all_tests(app, verbose, profile, ui_tests, failfast=failfast) dataent.db.commit() # workaround! since there is no separate test db dataent.clear_cache() return ret finally: if xmloutput_fh: xmloutput_fh.flush() xmloutput_fh.close()
def get_jenv_customization(customizable_type): import dataent if getattr(dataent.local, "site", None): for app in dataent.get_installed_apps(): for jenv_customizable, jenv_customizable_definition in dataent.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 get(): """get session boot info""" from dataent.desk.notifications import \ get_notification_info_for_boot, get_notifications from dataent.boot import get_bootinfo, get_unseen_notes from dataent.limits import get_limits, get_expiry_message bootinfo = None if not getattr(dataent.conf,'disable_session_cache', None): # check if cache exists bootinfo = dataent.cache().hget("bootinfo", dataent.session.user) if bootinfo: bootinfo['from_cache'] = 1 bootinfo["notification_info"].update(get_notifications()) bootinfo["user"]["recent"] = json.dumps(\ dataent.cache().hget("user_recent", dataent.session.user)) if not bootinfo: # if not create it bootinfo = get_bootinfo() bootinfo["notification_info"] = get_notification_info_for_boot() dataent.cache().hset("bootinfo", dataent.session.user, bootinfo) try: dataent.cache().ping() except redis.exceptions.ConnectionError: message = _("Redis cache server not running. Please contact Administrator / Tech support") if 'messages' in bootinfo: bootinfo['messages'].append(message) else: bootinfo['messages'] = [message] # check only when clear cache is done, and don't cache this if dataent.local.request: bootinfo["change_log"] = get_change_log() bootinfo["metadata_version"] = dataent.cache().get_value("metadata_version") if not bootinfo["metadata_version"]: bootinfo["metadata_version"] = dataent.reset_metadata_version() bootinfo.notes = get_unseen_notes() for hook in dataent.get_hooks("extend_bootinfo"): dataent.get_attr(hook)(bootinfo=bootinfo) bootinfo["lang"] = dataent.translate.get_user_lang() bootinfo["disable_async"] = dataent.conf.disable_async bootinfo["setup_complete"] = cint(dataent.db.get_single_value('System Settings', 'setup_complete')) # limits bootinfo.limits = get_limits() bootinfo.expiry_message = get_expiry_message() return bootinfo
def _get(): config = dataent._dict() hooks = dataent.get_hooks() if hooks: for notification_config in hooks.notification_config: nc = dataent.get_attr(notification_config)() for key in ("for_doctype", "for_module", "for_other", "targets"): config.setdefault(key, {}) config[key].update(nc.get(key, {})) return config
def sync_menu(self): '''Sync portal menu items''' dirty = False for item in dataent.get_hooks('standard_portal_menu_items'): if item.get('role') and not dataent.db.exists("Role", item.get('role')): dataent.get_doc({"doctype": "Role", "role_name": item.get('role'), "desk_access": 0}).insert() if self.add_item(item): dirty = True if dirty: self.save()
def get_permission_query_conditions(self): condition_methods = dataent.get_hooks("permission_query_conditions", {}).get(self.doctype, []) if condition_methods: conditions = [] for method in condition_methods: c = dataent.call(dataent.get_attr(method), self.user) if c: conditions.append(c) return " and ".join(conditions) if conditions else None
def build(path): if not dataent.db: dataent.connect() try: return build_page(path) except dataent.DoesNotExistError: hooks = dataent.get_hooks() if hooks.website_catch_all: path = hooks.website_catch_all[0] return build_page(path) else: raise
def get_messages_from_workflow(doctype=None, app_name=None): assert doctype or app_name, 'doctype or app_name should be provided' # translations for Workflows workflows = [] if doctype: workflows = dataent.get_all('Workflow', filters={'document_type': doctype}) else: fixtures = dataent.get_hooks('fixtures', app_name=app_name) or [] for fixture in fixtures: if isinstance(fixture, string_types) and fixture == 'Worflow': workflows = dataent.get_all('Workflow') break elif isinstance(fixture, dict) and fixture.get( 'dt', fixture.get('doctype')) == 'Workflow': workflows.extend( dataent.get_all('Workflow', filters=fixture.get('filters'))) messages = [] for w in workflows: states = dataent.db.sql( 'select distinct state from `tabWorkflow Document State` where parent=%s', (w['name'], ), as_dict=True) messages.extend([('Workflow: ' + w['name'], state['state']) for state in states if is_translatable(state['state'])]) states = dataent.db.sql( 'select distinct message from `tabWorkflow Document State` where parent=%s and message is not null', (w['name'], ), as_dict=True) messages.extend([("Workflow: " + w['name'], state['message']) for state in states if is_translatable(state['message'])]) actions = dataent.db.sql( 'select distinct action from `tabWorkflow Transition` where parent=%s', (w['name'], ), as_dict=True) messages.extend([("Workflow: " + w['name'], action['action']) \ for action in actions if is_translatable(action['action'])]) return messages
def get_setup_complete_hooks(args): stages = [] for method in dataent.get_hooks("setup_wizard_complete"): stages.append({ 'status': 'Executing method', 'fail_msg': 'Failed to execute method', 'tasks': [ { 'fn': dataent.get_attr(method), 'args': args, 'fail_msg': 'Failed to execute method' } ] }) return stages
def add_sidebar_data(context): from dataent.utils.user import get_fullname_and_avatar import dataent.www.list if context.show_sidebar and context.website_sidebar: context.sidebar_items = dataent.get_all( 'Website Sidebar Item', filters=dict(parent=context.website_sidebar), fields=['title', 'route', '`group`'], order_by='idx asc') if not context.sidebar_items: sidebar_items = dataent.cache().hget('portal_menu_items', dataent.session.user) if sidebar_items == None: sidebar_items = [] roles = dataent.get_roles() portal_settings = dataent.get_doc('Portal Settings', 'Portal Settings') def add_items(sidebar_items, items): for d in items: if d.get('enabled') and ((not d.get('role')) or d.get('role') in roles): sidebar_items.append( d.as_dict() if isinstance(d, Document) else d) if not portal_settings.hide_standard_menu: add_items(sidebar_items, portal_settings.get('menu')) if portal_settings.custom_menu: add_items(sidebar_items, portal_settings.get('custom_menu')) items_via_hooks = dataent.get_hooks('portal_menu_items') if items_via_hooks: for i in items_via_hooks: i['enabled'] = 1 add_items(sidebar_items, items_via_hooks) dataent.cache().hset('portal_menu_items', dataent.session.user, sidebar_items) context.sidebar_items = sidebar_items info = get_fullname_and_avatar(dataent.session.user) context["fullname"] = info.fullname context["user_image"] = info.avatar context["user"] = info.name