def _generate_app(self, app, request, tree_roots, childs_of): # Thats the root node for the app tree menu nav = TreeRoot(app.split(".")[-1]) modnav = self._get_module(app, 'nav') if hasattr(modnav, 'BLACKLIST'): BLACKLIST = modnav.BLACKLIST else: BLACKLIST = [] if hasattr(modnav, 'ICON'): nav.icon = modnav.ICON if hasattr(modnav, 'NAME'): nav.name = modnav.NAME else: nav.name = self.titlecase(app) if hasattr(modnav, 'TYPE'): nav.type = modnav.TYPE if hasattr(modnav, 'HIDE'): nav.skip = modnav.HIDE if hasattr(modnav, 'URL'): nav.url = reverse(modnav.URL) if modnav: modname = "%s.nav" % app for c in dir(modnav): navc = getattr(modnav, c) try: subclass = issubclass(navc, TreeNode) except TypeError: continue if navc.__module__ == modname and subclass: obj = navc(request=request) if obj.skip is True: continue if not obj.append_to: self.register_option(obj, nav, replace=True) else: self._navs[obj.append_to + '.' + obj.gname] = obj tree_roots.register(nav) # We register it to the tree root if hasattr(modnav, 'init'): modnav.init(tree_roots, nav, request) appPool.hook_nav_init(nav.gname, tree_roots, nav, request) else: log.debug("App %s has no nav.py module, skipping", app) return modmodels = self._get_module(app, 'models') if modmodels: modname = '%s.models' % app for c in dir(modmodels): model = getattr(modmodels, c) try: if issubclass(model, models.Model): if model._meta.app_label == app: continue else: continue except TypeError, e: continue if c in BLACKLIST: log.debug( "Model %s from app %s blacklisted, skipping", c, app, ) continue if not ( model.__module__ in ( modname, 'freenasUI.' + modname, ) and model in self._modelforms ): log.debug("Model %s does not have a ModelForm", model) continue if model._admin.deletable is False: navopt = TreeNode( str(model._meta.object_name), name=model._meta.verbose_name, model=c, app_name=app, type='dialog') try: navopt.kwargs = { 'oid': model.objects.order_by("-id")[0].id, } navopt.view = 'freeadmin_%s_%s_edit' % ( model._meta.app_label, model._meta.module_name, ) except: navopt.view = 'freeadmin_%s_%s_add' % ( model._meta.app_label, model._meta.module_name, ) else: navopt = TreeNode(str(model._meta.object_name)) navopt.name = model._meta.verbose_name_plural navopt.model = c navopt.app_name = app navopt.order_child = False for key in model._admin.nav_extra.keys(): navopt.__setattr__( key, model._admin.nav_extra.get(key)) if model._admin.icon_model is not None: navopt.icon = model._admin.icon_model if model._admin.menu_child_of is not None: childs_of.append((navopt, model)) reg = True else: reg = self.register_option(navopt, nav) if reg and not navopt.type: qs = model.objects.filter( **model._admin.object_filters).order_by('-id') if qs.count() > 0: if model._admin.object_num > 0: qs = qs[:model._admin.object_num] for e in qs: subopt = TreeNode('Edit') subopt.type = 'editobject' subopt.view = 'freeadmin_%s_%s_edit' % ( model._meta.app_label, model._meta.module_name, ) if model._admin.icon_object is not None: subopt.icon = model._admin.icon_object subopt.model = c subopt.app_name = app subopt.kwargs = { 'oid': e.id, } if model._admin.edit_modelform: subopt.kwargs['mf'] = ( model._admin.edit_modelform ) subopt.gname = e.id try: subopt.name = unicode(e) except: subopt.name = 'Object' navopt.append_child(subopt) # Node to add an instance of model subopt = TreeNode('Add') subopt.name = _(u'Add %s') % model._meta.verbose_name subopt.view = 'freeadmin_%s_%s_add' % ( model._meta.app_label, model._meta.module_name, ) subopt.order = 500 subopt.type = 'dialog' if model._admin.icon_add is not None: subopt.icon = model._admin.icon_add subopt.model = c subopt.app_name = app self.register_option(subopt, navopt) # Node to view all instances of model subopt = TreeNode('View') subopt.name = _(u'View %s') % ( model._meta.verbose_name_plural, ) subopt.view = u'freeadmin_%s_%s_datagrid' % ( model._meta.app_label, model._meta.module_name, ) if model._admin.icon_view is not None: subopt.icon = model._admin.icon_view subopt.model = c subopt.app_name = app subopt.order = 501 subopt.type = 'viewmodel' self.register_option(subopt, navopt)
class NavTree(object): def __init__(self): self._modelforms = ModelFormsDict() self._navs = {} self._generated = False def isGenerated(self): return self._generated def _get_module(self, where, name): try: mod = __import__('%s.%s' % (where, name), globals(), locals(), [name], -1) return mod except ImportError: return None def register_option(self, opt, parent, replace=False, evaluate=True): """ This is used for Menu Item replacement Every option added to the tree register its name in a dict If the name was already registered before it can be replaced or not Returns:: bool: Item has been added to the tree or not """ exists = False for i in parent: if i.gname == opt.gname: exists = i if exists is not False and replace is True: parent.remove_child(exists) opt.attrFrom(exists) parent.append_child(opt) return True elif exists is False: parent.append_child(opt) return True return False def replace_navs(self, root): for gname, opt in self._navs.items(): for nav in root: find = nav.find_gname(gname) if find is not False: parent = find.parent parent.remove_child(find) opt.attrFrom(find) parent.append_child(opt) break def titlecase(self, s): return re.sub(r"[A-Za-z]+('[A-Za-z]+)?", lambda mo: mo.group(0)[0].upper() + mo.group(0)[1:], s) def prepare_modelforms(self): """ This piece of code lookup all ModelForm classes from forms.py and record models as a dict key """ self._modelforms.clear() for app in settings.INSTALLED_APPS: _models = {} modforms = self._get_module(app, 'forms') if modforms: modname = "%s.forms" % app for c in dir(modforms): form = getattr(modforms, c) try: subclass = issubclass(form, ModelForm) except TypeError: continue if form.__module__ == modname and subclass: if form._meta.model in _models: if isinstance(_models[form._meta.model], dict): _models[form._meta.model][form.__name__] = form else: tmp = _models[form._meta.model] _models[form._meta.model] = { tmp.__name__: tmp, form.__name__: form, } else: _models[form._meta.model] = form self._modelforms.update(_models) def generate(self, request=None): """ Tree Menu Auto Generate Every app listed at INSTALLED_APPS is scanned 1st - app_name.forms is imported. All its objects/classes are scanned looking for ModelForm classes 2nd - app_name.nav is imported. TreeNode classes are scanned for hard-coded menu entries or overwriting 3rd - app_name.models is imported. models.Model classes are scanned, if a related ModelForm is found several entries are Added to the Menu - Objects - Add (Model) - View (Model) """ self._generated = True self._navs.clear() tree_roots.clear() childs_of = [] for app in settings.INSTALLED_APPS: # If the app is listed at settings.BLACKLIST_NAV, skip it! if app in getattr(settings, 'BLACKLIST_NAV', []): continue try: self._generate_app(app, request, tree_roots, childs_of) except Exception, e: log.error("Failed to generate navtree for app %s: %s", app, e) log_traceback(log=log) nav = TreeRoot('display', name=_('Display System Processes'), action='displayprocs', icon='TopIcon') tree_roots.register(nav) nav = TreeRoot('shell', name=_('Shell'), icon='ShellIcon', action='shell') tree_roots.register(nav) nav = TreeRoot('reboot', name=_('Reboot'), action='reboot', icon='RebootIcon', type='scary_dialog', view='system_reboot_dialog') tree_roots.register(nav) nav = TreeRoot('shutdown', name=_('Shutdown'), icon='ShutdownIcon', type='scary_dialog', view='system_shutdown_dialog') tree_roots.register(nav) for opt, model in childs_of: for nav in tree_roots: exists = nav.find_gname(model._admin.menu_child_of) if exists is not False: exists.append_child(opt) break if exists is False: log.debug("Could not find %s to attach %r", model._admin.menu_child_of, opt) self.replace_navs(tree_roots)
def _generate_app(self, app, request, tree_roots, childs_of): # Thats the root node for the app tree menu nav = TreeRoot(app.split(".")[-1]) modnav = self._get_module(app, 'nav') if hasattr(modnav, 'BLACKLIST'): BLACKLIST = modnav.BLACKLIST else: BLACKLIST = [] if hasattr(modnav, 'ICON'): nav.icon = modnav.ICON if hasattr(modnav, 'NAME'): nav.name = modnav.NAME else: nav.name = self.titlecase(app) if modnav: modname = "%s.nav" % app for c in dir(modnav): navc = getattr(modnav, c) try: subclass = issubclass(navc, TreeNode) except TypeError: continue if navc.__module__ == modname and subclass: obj = navc(request=request) if obj.skip is True: continue if not obj.append_to: self.register_option(obj, nav, replace=True) else: self._navs[obj.append_to + '.' + obj.gname] = obj tree_roots.register(nav) # We register it to the tree root if hasattr(modnav, 'init'): modnav.init(tree_roots, nav) else: log.debug("App %s has no nav.py module, skipping", app) return modmodels = self._get_module(app, 'models') if modmodels: modname = '%s.models' % app for c in dir(modmodels): model = getattr(modmodels, c) try: if (issubclass(model, models.Model) and model._meta.app_label == app): continue except TypeError, e: continue if c in BLACKLIST: log.debug( "Model %s from app %s blacklisted, skipping", c, app, ) continue if not (model.__module__ in ( modname, 'freenasUI.' + modname, ) and model in self._modelforms): log.debug("Model %s does not have a ModelForm", model) continue if model._admin.deletable is False: navopt = TreeNode(str(model._meta.object_name), name=model._meta.verbose_name, model=c, app_name=app, type='dialog') try: navopt.kwargs = { 'oid': model.objects.order_by("-id")[0].id, } navopt.view = 'freeadmin_%s_%s_edit' % ( model._meta.app_label, model._meta.module_name, ) except: navopt.view = 'freeadmin_%s_%s_add' % ( model._meta.app_label, model._meta.module_name, ) else: navopt = TreeNode(str(model._meta.object_name)) navopt.name = model._meta.verbose_name_plural navopt.model = c navopt.app_name = app navopt.order_child = False for key in model._admin.nav_extra.keys(): navopt.__setattr__(key, model._admin.nav_extra.get(key)) if model._admin.icon_model is not None: navopt.icon = model._admin.icon_model if model._admin.menu_child_of is not None: childs_of.append((navopt, model)) reg = True else: reg = self.register_option(navopt, nav) if reg and not navopt.type: qs = model.objects.filter( **model._admin.object_filters).order_by('-id') if qs.count() > 0: if model._admin.object_num > 0: qs = qs[:model._admin.object_num] for e in qs: subopt = TreeNode('Edit') subopt.type = 'editobject' subopt.view = 'freeadmin_%s_%s_edit' % ( model._meta.app_label, model._meta.module_name, ) if model._admin.icon_object is not None: subopt.icon = model._admin.icon_object subopt.model = c subopt.app_name = app subopt.kwargs = { 'oid': e.id, } try: subopt.name = unicode(e) except: subopt.name = 'Object' navopt.append_child(subopt) # Node to add an instance of model subopt = TreeNode('Add') subopt.name = _(u'Add %s') % model._meta.verbose_name subopt.view = 'freeadmin_%s_%s_add' % ( model._meta.app_label, model._meta.module_name, ) subopt.order = 500 subopt.type = 'dialog' if model._admin.icon_add is not None: subopt.icon = model._admin.icon_add subopt.model = c subopt.app_name = app self.register_option(subopt, navopt) # Node to view all instances of model subopt = TreeNode('View') subopt.name = _(u'View %s') % ( model._meta.verbose_name_plural, ) subopt.view = u'freeadmin_%s_%s_datagrid' % ( model._meta.app_label, model._meta.module_name, ) if model._admin.icon_view is not None: subopt.icon = model._admin.icon_view subopt.model = c subopt.app_name = app subopt.order = 501 subopt.type = 'viewmodel' self.register_option(subopt, navopt)
def generate(self, request=None): """ Tree Menu Auto Generate Every app listed at INSTALLED_APPS is scanned 1st - app_name.forms is imported. All its objects/classes are scanned looking for ModelForm classes 2nd - app_name.nav is imported. TreeNode classes are scanned for hard-coded menu entries or overwriting 3rd - app_name.models is imported. models.Model classes are scanned, if a related ModelForm is found several entries are Added to the Menu - Objects - Add (Model) - View (Model) """ self._generated = True self._navs.clear() tree_roots.clear() childs_of = [] if hasattr(notifier, 'failover_status'): fstatus = notifier().failover_status() else: fstatus = 'SINGLE' for app in settings.INSTALLED_APPS: # If the app is listed at settings.BLACKLIST_NAV, skip it! if app in getattr(settings, 'BLACKLIST_NAV', []): continue try: self._generate_app(app, request, tree_roots, childs_of, fstatus) except Exception as e: log.error("Failed to generate navtree for app %s: %s", app, e) log_traceback(log=log) nav = TreeRoot( 'documentation', name=_('Guide'), icon=get_sw_name() + 'GuideIcon', action='opendocumentation', view='documentation_home', order=970, ) tree_roots.register(nav) nav = TreeRoot( 'display', name=_('Display System Processes'), action='displayprocs', icon='TopIcon', order=985, ) tree_roots.register(nav) if fstatus in ('MASTER', 'SINGLE'): nav = TreeRoot( 'initialwizard', name=_('Wizard'), icon='WizardIcon', action='wizard', order=980, ) tree_roots.register(nav) nav = TreeRoot( 'shell', name=_('Shell'), icon='ShellIcon', action='shell', order=990, ) tree_roots.register(nav) nav = TreeRoot( 'logout', name=_('Log Out'), icon='LogOutIcon', action='logout', order=995, ) tree_roots.register(nav) nav = TreeRoot( 'reboot', name=_('Reboot'), action='reboot', icon='RebootIcon', type='scary_dialog', view='system_reboot_dialog', order=999, ) tree_roots.register(nav) nav = TreeRoot( 'shutdown', name=_('Shutdown'), icon='ShutdownIcon', type='scary_dialog', view='system_shutdown_dialog', order=1000, ) tree_roots.register(nav) for opt, model in childs_of: for nav in tree_roots: exists = nav.find_gname(model._admin.menu_child_of) if exists is not False: exists.append_child(opt) break if exists is False: log.debug("Could not find %s to attach %r", model._admin.menu_child_of, opt) self.replace_navs(tree_roots) jails = [] # FIXME: use .filter for j in Jails.objects.all(): if (j.jail_type == WARDEN_TYPE_PLUGINJAIL and j.jail_status == WARDEN_STATUS_RUNNING): jails.append(j) self._get_plugins_nodes(request, jails)
class NavTree(object): def __init__(self): self._modelforms = ModelFormsDict() self._navs = {} self._generated = False def isGenerated(self): return self._generated def _get_module(self, where, name): try: mod = __import__('%s.%s' % (where, name), globals(), locals(), [name], -1) return mod except ImportError as ie: log.debug("Unable to import '%s' '%s': %s", where, name, ie) return None def register_option(self, opt, parent, replace=False, evaluate=True): """ This is used for Menu Item replacement Every option added to the tree register its name in a dict If the name was already registered before it can be replaced or not Returns:: bool: Item has been added to the tree or not """ exists = False for i in parent: if i.gname == opt.gname: exists = i if exists is not False and replace is True: parent.remove_child(exists) opt.attrFrom(exists) parent.append_child(opt) return True elif exists is False: parent.append_child(opt) return True return False def replace_navs(self, root): for gname, opt in self._navs.items(): for nav in root: find = nav.find_gname(gname) if find is not False: parent = find.parent parent.remove_child(find) opt.attrFrom(find) parent.append_child(opt) for child in find: opt.append_child(child) break """ If not node has been found to be replace then we can append the node instead of replace """ if find is not False or opt.replace_only is True: continue for nav in root: if '.' not in gname: continue parent = nav.find_gname(gname.rsplit('.', 1)[0]) if parent is not False: parent.append_child(opt) def titlecase(self, s): return re.sub(r"[A-Za-z]+('[A-Za-z]+)?", lambda mo: mo.group(0)[0].upper() + mo.group(0)[1:], s) def prepare_modelforms(self): """ This piece of code lookup all ModelForm classes from forms.py and record models as a dict key """ self._modelforms.clear() for app in settings.INSTALLED_APPS: _models = {} modforms = self._get_module(app, 'forms') if modforms: modname = "%s.forms" % app for c in dir(modforms): form = getattr(modforms, c) try: subclass = issubclass(form, ModelForm) except TypeError: continue if form.__module__ == modname and subclass: if form._meta.model in _models: if isinstance(_models[form._meta.model], dict): _models[form._meta.model][form.__name__] = form else: tmp = _models[form._meta.model] _models[form._meta.model] = { tmp.__name__: tmp, form.__name__: form, } else: _models[form._meta.model] = form self._modelforms.update(_models) def generate(self, request=None): """ Tree Menu Auto Generate Every app listed at INSTALLED_APPS is scanned 1st - app_name.forms is imported. All its objects/classes are scanned looking for ModelForm classes 2nd - app_name.nav is imported. TreeNode classes are scanned for hard-coded menu entries or overwriting 3rd - app_name.models is imported. models.Model classes are scanned, if a related ModelForm is found several entries are Added to the Menu - Objects - Add (Model) - View (Model) """ self._generated = True self._navs.clear() tree_roots.clear() childs_of = [] if hasattr(notifier, 'failover_status'): fstatus = notifier().failover_status() else: fstatus = 'SINGLE' for app in settings.INSTALLED_APPS: # If the app is listed at settings.BLACKLIST_NAV, skip it! if app in getattr(settings, 'BLACKLIST_NAV', []): continue try: self._generate_app(app, request, tree_roots, childs_of, fstatus) except Exception, e: log.error("Failed to generate navtree for app %s: %s", app, e) log_traceback(log=log) nav = TreeRoot( 'documentation', name=_('Guide'), icon=get_sw_name() + 'GuideIcon', action='opendocumentation', view='documentation_home', order=970, ) tree_roots.register(nav) nav = TreeRoot( 'display', name=_('Display System Processes'), action='displayprocs', icon='TopIcon', order=985, ) tree_roots.register(nav) if fstatus in ('MASTER', 'SINGLE'): nav = TreeRoot( 'initialwizard', name=_('Wizard'), icon='WizardIcon', action='wizard', order=980, ) tree_roots.register(nav) nav = TreeRoot( 'shell', name=_('Shell'), icon='ShellIcon', action='shell', order=990, ) tree_roots.register(nav) nav = TreeRoot( 'logout', name=_('Log Out'), icon='LogOutIcon', action='logout', order=995, ) tree_roots.register(nav) nav = TreeRoot( 'reboot', name=_('Reboot'), action='reboot', icon='RebootIcon', type='scary_dialog', view='system_reboot_dialog', order=999, ) tree_roots.register(nav) nav = TreeRoot( 'shutdown', name=_('Shutdown'), icon='ShutdownIcon', type='scary_dialog', view='system_shutdown_dialog', order=1000, ) tree_roots.register(nav) for opt, model in childs_of: for nav in tree_roots: exists = nav.find_gname(model._admin.menu_child_of) if exists is not False: exists.append_child(opt) break if exists is False: log.debug("Could not find %s to attach %r", model._admin.menu_child_of, opt) self.replace_navs(tree_roots) jails = [] # FIXME: use .filter for j in Jails.objects.all(): if (j.jail_type == WARDEN_TYPE_PLUGINJAIL and j.jail_status == WARDEN_STATUS_RUNNING): jails.append(j) self._get_plugins_nodes(request, jails)
def generate(self, request=None): """ Tree Menu Auto Generate Every app listed at INSTALLED_APPS is scanned 1st - app_name.forms is imported. All its objects/classes are scanned looking for ModelForm classes 2nd - app_name.nav is imported. TreeNode classes are scanned for hard-coded menu entries or overwriting 3rd - app_name.models is imported. models.Model classes are scanned, if a related ModelForm is found several entries are Added to the Menu - Objects - Add (Model) - View (Model) """ self._generated = True self._navs.clear() tree_roots.clear() childs_of = [] if hasattr(notifier, 'failover_status'): fstatus = notifier().failover_status() else: fstatus = 'SINGLE' for app in settings.INSTALLED_APPS: # If the app is listed at settings.BLACKLIST_NAV, skip it! if app in getattr(settings, 'BLACKLIST_NAV', []): continue try: self._generate_app(app, request, tree_roots, childs_of, fstatus) except Exception as e: log.error( "Failed to generate navtree for app %s: %s", app, e) log_traceback(log=log) nav = TreeRoot( 'documentation', name=_('Guide'), icon=get_sw_name() + 'GuideIcon', action='opendocumentation', view='documentation_home', order=970, ) tree_roots.register(nav) nav = TreeRoot( 'display', name=_('Display System Processes'), action='displayprocs', icon='TopIcon', order=985, ) tree_roots.register(nav) if fstatus in ('MASTER', 'SINGLE'): nav = TreeRoot( 'initialwizard', name=_('Wizard'), icon='WizardIcon', action='wizard', order=980, ) tree_roots.register(nav) nav = TreeRoot( 'shell', name=_('Shell'), icon='ShellIcon', action='shell', order=990, ) tree_roots.register(nav) nav = TreeRoot( 'logout', name=_('Log Out'), icon='LogOutIcon', action='logout', order=995, ) tree_roots.register(nav) nav = TreeRoot( 'reboot', name=_('Reboot'), action='reboot', icon='RebootIcon', type='scary_dialog', view='system_reboot_dialog', order=999, ) tree_roots.register(nav) nav = TreeRoot( 'shutdown', name=_('Shutdown'), icon='ShutdownIcon', type='scary_dialog', view='system_shutdown_dialog', order=1000, ) tree_roots.register(nav) for opt, model in childs_of: for nav in tree_roots: exists = nav.find_gname(model._admin.menu_child_of) if exists is not False: exists.append_child(opt) break if exists is False: log.debug( "Could not find %s to attach %r", model._admin.menu_child_of, opt) self.replace_navs(tree_roots) jails = [] # FIXME: use .filter for j in Jails.objects.all(): if ( j.jail_type == WARDEN_TYPE_PLUGINJAIL and j.jail_status == WARDEN_STATUS_RUNNING ): jails.append(j) self._get_plugins_nodes(request, jails)