From: Simo Sorce Date: Wed, 15 Oct 2014 04:17:53 +0000 (-0400) Subject: Improve UI for enabling/disabling plugins config X-Git-Tag: v0.3.0~35 X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=commitdiff_plain;h=fb1c34e7aeac67a75c29a132ded87edeb557cdaf Improve UI for enabling/disabling plugins config Use the same templates for both info and login plugins Signed-off-by: Simo Sorce Reviewed-by: Patrick Uiterwijk --- diff --git a/ipsilon/admin/common.py b/ipsilon/admin/common.py index 7f723ac..827038e 100755 --- a/ipsilon/admin/common.py +++ b/ipsilon/admin/common.py @@ -20,6 +20,7 @@ import cherrypy from ipsilon.util.page import Page from ipsilon.util.page import admin_protect +from ipsilon.util.plugin import PluginObject class AdminPage(Page): @@ -34,10 +35,10 @@ class AdminPage(Page): self.auth_protect = True -class AdminPluginPage(AdminPage): +class AdminPluginConfig(AdminPage): def __init__(self, po, site, parent): - super(AdminPluginPage, self).__init__(site, form=True) + super(AdminPluginConfig, self).__init__(site, form=True) self._po = po self.title = '%s plugin' % po.name self.url = '%s/%s' % (parent.url, po.name) @@ -114,6 +115,158 @@ class AdminPluginPage(AdminPage): plugin=self._po) +class AdminPluginsOrder(AdminPage): + + def __init__(self, site, parent, facility): + super(AdminPluginsOrder, self).__init__(site, form=True) + self.parent = parent + self.facility = facility + self.url = '%s/order' % parent.url + self.menu = [parent] + + @admin_protect + def GET(self, *args, **kwargs): + return self.parent.root_with_msg() + + @admin_protect + def POST(self, *args, **kwargs): + message = "Nothing was modified." + message_type = "info" + by_name = {p.name: p for p in self._site[self.facility]['enabled']} + + if 'order' in kwargs: + order = kwargs['order'].split(',') + if len(order) != 0: + new_names = [] + new_plugins = [] + try: + for v in order: + val = v.strip() + if val not in by_name: + error = "Invalid plugin name: %s" % val + raise ValueError(error) + new_names.append(val) + new_plugins.append(by_name[val]) + if len(new_names) < len(by_name): + for val in by_name: + if val not in new_names: + new_names.append(val) + new_plugins.append(by_name[val]) + + self.parent.save_enabled_plugins(new_names) + self.parent.reorder_plugins(new_names) + + # When all is saved update also live config. The + # live config is a list of the actual plugin + # objects. + self._site[self.facility]['enabled'] = new_plugins + + message = "New configuration saved." + message_type = "success" + + except ValueError, e: + message = str(e) + message_type = "error" + + except Exception, e: # pylint: disable=broad-except + message = "Failed to save data!" + message_type = "error" + + return self.parent.root_with_msg(message=message, + message_type=message_type) + + +class AdminPlugins(AdminPage): + def __init__(self, name, site, parent, facility, ordered=True): + super(AdminPlugins, self).__init__(site) + self._master = parent + self.name = name + self.title = '%s plugins' % name + self.url = '%s/%s' % (parent.url, name) + self.facility = facility + self.template = 'admin/plugins.html' + self.order = None + parent.add_subtree(name, self) + + for plugin in self._site[facility]['available']: + cherrypy.log.error('Admin info plugin: %s' % plugin) + obj = self._site[facility]['available'][plugin] + page = AdminPluginConfig(obj, self._site, self) + if hasattr(obj, 'admin'): + obj.admin.mount(page) + self.add_subtree(plugin, page) + + if ordered: + self.order = AdminPluginsOrder(self._site, self, facility) + + def save_enabled_plugins(self, names): + po = PluginObject() + po.name = "global" + globalconf = dict() + globalconf['order'] = ','.join(names) + po.set_config(globalconf) + po.save_plugin_config(self.facility) + + def reorder_plugins(self, names): + return + + def root_with_msg(self, message=None, message_type=None): + plugins = self._site[self.facility] + enabled = [] + for p in plugins['enabled']: + enabled.append(p.name) + targs = {'title': self.title, + 'menu': self._master.menu, + 'message': message, + 'message_type': message_type, + 'available': plugins['available'], + 'enabled': enabled, + 'baseurl': self.url} + if self.order: + targs['order_name'] = '%s_order_form' % self.name + targs['order_action'] = self.order.url + + # pylint: disable=star-args + return self._template(self.template, **targs) + + def root(self, *args, **kwargs): + return self.root_with_msg() + + @admin_protect + def enable(self, plugin): + msg = None + plugins = self._site[self.facility] + if plugin not in plugins['available']: + msg = "Unknown plugin %s" % plugin + return self.root_with_msg(msg, "error") + obj = plugins['available'][plugin] + if obj not in plugins['enabled']: + obj.enable(self._site) + if self.order: + enabled = list(x.name for x in plugins['enabled']) + self.save_enabled_plugins(enabled) + msg = "Plugin %s enabled" % obj.name + return self.root_with_msg(msg, "success") + enable.public_function = True + + @admin_protect + def disable(self, plugin): + msg = None + plugins = self._site[self.facility] + if plugin not in plugins['available']: + msg = "Unknown plugin %s" % plugin + return self.root_with_msg(msg, "error") + obj = plugins['available'][plugin] + if obj in plugins['enabled']: + obj.disable(self._site) + if self.order: + enabled = list(x.name for x in plugins['enabled']) + self.save_enabled_plugins(enabled) + msg = "Plugin %s disabled" % obj.name + return self.root_with_msg(msg, "success") + disable.public_function = True + + class Admin(AdminPage): def __init__(self, site, mount): diff --git a/ipsilon/admin/info.py b/ipsilon/admin/info.py index d3f5284..bda117a 100755 --- a/ipsilon/admin/info.py +++ b/ipsilon/admin/info.py @@ -2,149 +2,11 @@ # # Copyright (C) 2014 Ipsilon Contributors see COPYING for license -import cherrypy -from ipsilon.util.page import admin_protect -from ipsilon.util.plugin import PluginObject -from ipsilon.admin.common import AdminPluginPage -from ipsilon.admin.common import AdminPage +from ipsilon.admin.common import AdminPlugins from ipsilon.info.common import FACILITY -def save_enabled_plugins(names): - po = PluginObject() - po.name = "global" - globalconf = dict() - globalconf['order'] = ','.join(names) - po.set_config(globalconf) - po.save_plugin_config(FACILITY) - - -class InfoPluginsOrder(AdminPage): - +class InfoPlugins(AdminPlugins): def __init__(self, site, parent): - super(InfoPluginsOrder, self).__init__(site, form=True) - self.url = '%s/order' % parent.url - self.menu = [parent] - - @admin_protect - def GET(self, *args, **kwargs): - opts = [p.name for p in self._site[FACILITY]['enabled']] - return self._template('admin/info_order.html', - title='info plugins order', - name='admin_info_order_form', - menu=self.menu, action=self.url, - options=opts) - - @admin_protect - def POST(self, *args, **kwargs): - message = "Nothing was modified." - message_type = "info" - plugins_by_name = {p.name: p for p in self._site[FACILITY]['enabled']} - - if 'order' in kwargs: - order = kwargs['order'].split(',') - if len(order) != 0: - new_names = [] - new_plugins = [] - try: - for v in order: - val = v.strip() - if val not in plugins_by_name: - error = "Invalid plugin name: %s" % val - raise ValueError(error) - new_names.append(val) - new_plugins.append(plugins_by_name[val]) - if len(new_names) < len(plugins_by_name): - for val in plugins_by_name: - if val not in new_names: - new_names.append(val) - new_plugins.append(plugins_by_name[val]) - - save_enabled_plugins(new_names) - - # When all is saved update also live config. The - # live config is a list of the actual plugin - # objects. - self._site[FACILITY]['enabled'] = new_plugins - - message = "New configuration saved." - message_type = "success" - - except ValueError, e: - message = str(e) - message_type = "error" - - except Exception, e: # pylint: disable=broad-except - message = "Failed to save data!" - message_type = "error" - - opts = [p.name for p in self._site[FACILITY]['enabled']] - return self._template('admin/info_order.html', - message=message, - message_type=message_type, - title='info plugins order', - name='admin_info_order_form', - menu=self.menu, action=self.url, - options=opts) - - -class InfoPlugins(AdminPage): - def __init__(self, site, parent): - super(InfoPlugins, self).__init__(site) - self._master = parent + super(InfoPlugins, self).__init__('info', site, parent, FACILITY) self.title = 'Info Plugins' - self.url = '%s/info' % parent.url - self.facility = FACILITY - parent.add_subtree('info', self) - - for plugin in self._site[FACILITY]['available']: - cherrypy.log.error('Admin info plugin: %s' % plugin) - obj = self._site[FACILITY]['available'][plugin] - self.__dict__[plugin] = AdminPluginPage(obj, self._site, self) - - self.order = InfoPluginsOrder(self._site, self) - - def root_with_msg(self, message=None, message_type=None): - info_plugins = self._site[FACILITY] - ordered = [] - for p in info_plugins['enabled']: - ordered.append(p.name) - return self._template('admin/info.html', title=self.title, - message=message, - message_type=message_type, - available=info_plugins['available'], - enabled=ordered, - menu=self._master.menu) - - def root(self, *args, **kwargs): - return self.root_with_msg() - - @admin_protect - def enable(self, plugin): - msg = None - plugins = self._site[FACILITY] - if plugin not in plugins['available']: - msg = "Unknown plugin %s" % plugin - return self.root_with_msg(msg, "error") - obj = plugins['available'][plugin] - if obj not in plugins['enabled']: - obj.enable(self._site) - save_enabled_plugins(list(x.name for x in plugins['enabled'])) - msg = "Plugin %s enabled" % obj.name - return self.root_with_msg(msg, "success") - enable.public_function = True - - @admin_protect - def disable(self, plugin): - msg = None - plugins = self._site[FACILITY] - if plugin not in plugins['available']: - msg = "Unknown plugin %s" % plugin - return self.root_with_msg(msg, "error") - obj = plugins['available'][plugin] - if obj in plugins['enabled']: - obj.disable(self._site) - save_enabled_plugins(list(x.name for x in plugins['enabled'])) - msg = "Plugin %s disabled" % obj.name - return self.root_with_msg(msg, "success") - disable.public_function = True diff --git a/ipsilon/admin/login.py b/ipsilon/admin/login.py index 4645917..c1a1c73 100755 --- a/ipsilon/admin/login.py +++ b/ipsilon/admin/login.py @@ -1,47 +1,17 @@ #!/usr/bin/python # -# Copyright (C) 2014 Simo Sorce -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Copyright (C) 2014 Ipsilon Contributors see COPYING for license -import cherrypy -from ipsilon.util.page import admin_protect -from ipsilon.util.plugin import PluginObject -from ipsilon.admin.common import AdminPluginPage -from ipsilon.admin.common import AdminPage +from ipsilon.admin.common import AdminPlugins from ipsilon.login.common import FACILITY -def save_enabled_plugins(names): - po = PluginObject() - po.name = "global" - globalconf = dict() - globalconf['order'] = ','.join(names) - po.set_config(globalconf) - po.save_plugin_config(FACILITY) - - -class LoginPluginsOrder(AdminPage): - +class LoginPlugins(AdminPlugins): def __init__(self, site, parent): - super(LoginPluginsOrder, self).__init__(site, form=True) - self.url = '%s/order' % parent.url - self.menu = [parent] + super(LoginPlugins, self).__init__('login', site, parent, FACILITY) + self.title = 'Login Plugins' - def _reorder_plugins(self, order): + def reorder_plugins(self, order): plugins = self._site[FACILITY]['available'] root = self._site[FACILITY]['root'] prev_obj = None @@ -52,127 +22,3 @@ class LoginPluginsOrder(AdminPage): prev_obj.next_login = plugins[name] prev_obj = plugins[name] prev_obj.next_login = None - - @admin_protect - def GET(self, *args, **kwargs): - opts = [p.name for p in self._site[FACILITY]['enabled']] - return self._template('admin/login_order.html', - title='login plugins order', - name='admin_login_order_form', - menu=self.menu, action=self.url, - options=opts) - - @admin_protect - def POST(self, *args, **kwargs): - message = "Nothing was modified." - message_type = "info" - plugins_by_name = {p.name: p for p in self._site[FACILITY]['enabled']} - - if 'order' in kwargs: - order = kwargs['order'].split(',') - if len(order) != 0: - new_names = [] - new_plugins = [] - try: - for v in order: - val = v.strip() - if val not in plugins_by_name: - error = "Invalid plugin name: %s" % val - raise ValueError(error) - new_names.append(val) - new_plugins.append(plugins_by_name[val]) - if len(new_names) < len(plugins_by_name): - for val in plugins_by_name: - if val not in new_names: - new_names.append(val) - new_plugins.append(plugins_by_name[val]) - - save_enabled_plugins(new_names) - self._reorder_plugins(new_names) - - # When all is saved update also live config. The - # live config is a list of the actual plugin - # objects. - self._site[FACILITY]['enabled'] = new_plugins - - message = "New configuration saved." - message_type = "success" - - except ValueError, e: - message = str(e) - message_type = "error" - - except Exception, e: # pylint: disable=broad-except - message = "Failed to save data!" - message_type = "error" - - opts = [p.name for p in self._site[FACILITY]['enabled']] - return self._template('admin/login_order.html', - message=message, - message_type=message_type, - title='login plugins order', - name='admin_login_order_form', - menu=self.menu, action=self.url, - options=opts) - - -class LoginPlugins(AdminPage): - def __init__(self, site, parent): - super(LoginPlugins, self).__init__(site) - self._master = parent - self.title = 'Login Plugins' - self.url = '%s/login' % parent.url - self.facility = FACILITY - parent.add_subtree('login', self) - - for plugin in self._site[FACILITY]['available']: - cherrypy.log.error('Admin login plugin: %s' % plugin) - obj = self._site[FACILITY]['available'][plugin] - self.__dict__[plugin] = AdminPluginPage(obj, self._site, self) - - self.order = LoginPluginsOrder(self._site, self) - - def root_with_msg(self, message=None, message_type=None): - login_plugins = self._site[FACILITY] - ordered = [] - for p in login_plugins['enabled']: - ordered.append(p.name) - return self._template('admin/login.html', title=self.title, - message=message, - message_type=message_type, - available=login_plugins['available'], - enabled=ordered, - menu=self._master.menu) - - def root(self, *args, **kwargs): - return self.root_with_msg() - - @admin_protect - def enable(self, plugin): - msg = None - plugins = self._site[FACILITY] - if plugin not in plugins['available']: - msg = "Unknown plugin %s" % plugin - return self.root_with_msg(msg, "error") - obj = plugins['available'][plugin] - if obj not in plugins['enabled']: - obj.enable(self._site) - save_enabled_plugins(list(x.name for x in plugins['enabled'])) - msg = "Plugin %s enabled" % obj.name - return self.root_with_msg(msg, "success") - enable.public_function = True - - @admin_protect - def disable(self, plugin): - msg = None - plugins = self._site[FACILITY] - if plugin not in plugins['available']: - msg = "Unknown plugin %s" % plugin - return self.root_with_msg(msg, "error") - obj = plugins['available'][plugin] - if obj in plugins['enabled']: - obj.disable(self._site) - save_enabled_plugins(list(x.name for x in plugins['enabled'])) - msg = "Plugin %s disabled" % obj.name - return self.root_with_msg(msg, "success") - disable.public_function = True diff --git a/ipsilon/admin/providers.py b/ipsilon/admin/providers.py index eea61e7..06e5f54 100755 --- a/ipsilon/admin/providers.py +++ b/ipsilon/admin/providers.py @@ -21,7 +21,7 @@ import cherrypy from ipsilon.util.page import admin_protect from ipsilon.providers.common import FACILITY -from ipsilon.admin.common import AdminPluginPage +from ipsilon.admin.common import AdminPluginConfig from ipsilon.admin.common import AdminPage @@ -37,7 +37,7 @@ class ProviderPlugins(AdminPage): for plugin in self._site[FACILITY]['available']: cherrypy.log.error('Admin provider plugin: %s' % plugin) obj = self._site[FACILITY]['available'][plugin] - page = AdminPluginPage(obj, self._site, self) + page = AdminPluginConfig(obj, self._site, self) if hasattr(obj, 'admin'): obj.admin.mount(page) self.add_subtree(plugin, page) diff --git a/templates/admin/info.html b/templates/admin/info.html deleted file mode 100644 index d51231f..0000000 --- a/templates/admin/info.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "master-admin.html" %} -{% block main %} -{% if user.is_admin %} -

Info plugins

- {% if message %} -
-

{{ message }}

-
- {% endif %} - - {% for p in available %} -
-
{{ p }}
-
- {% if p in enabled %} - Disable - Configure - {% else %} - Enable - {% endif %} -
-
- {% endfor %} - -

Plugins order

-
{{ ', '.join(enabled) }}
-
- configure -
-{% endif %} -{% endblock %} diff --git a/templates/admin/info_order.html b/templates/admin/info_order.html deleted file mode 100644 index 5d929be..0000000 --- a/templates/admin/info_order.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "master-admin.html" %} -{% block main %} -

{{ title }}

- {% if message %} -
-

{{ message }}

-
- {% endif %} -
-
- -
- - -
- Plugins order - - - Back -
-
-{% endblock %} - diff --git a/templates/admin/login.html b/templates/admin/login.html deleted file mode 100644 index 9f51d02..0000000 --- a/templates/admin/login.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "master-admin.html" %} -{% block main %} -{% if user.is_admin %} -

Login plugins

- {% if message %} -
-

{{ message }}

-
- {% endif %} - - {% for p in available %} -
-
{{ p }}
-
- {% if p in enabled %} - Disable - Configure - {% else %} - Enable - {% endif %} -
-
- {% endfor %} - -

Plugins order

-
{{ ', '.join(enabled) }}
-
- configure -
-{% endif %} -{% endblock %} diff --git a/templates/admin/login_order.html b/templates/admin/login_order.html deleted file mode 100644 index b14c4d9..0000000 --- a/templates/admin/login_order.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "master-admin.html" %} -{% block main %} -

{{ title }}

- {% if message %} -
-

{{ message }}

-
- {% endif %} -
-
- -
- - -
- Plugins order - - - Back -
-
-{% endblock %} - diff --git a/templates/admin/plugins.html b/templates/admin/plugins.html new file mode 100644 index 0000000..7bbe544 --- /dev/null +++ b/templates/admin/plugins.html @@ -0,0 +1,108 @@ +{% extends "master-admin.html" %} +{% block main %} +{% if user.is_admin %} + +
+
+

{{ title }}

+
+ +
+ + + {% for p in enabled %} + + {% endfor %} + + {% for p in available if not p in enabled %} + + {% endfor %} + + +
+
+
+ {{ p }} +
+
+
+
+ Disable +
+
+ {%- if available[p].get_config_desc() %} + Configure + {% endif %} +
+
+
+
+ {%- if not (loop.first and loop.last) %} +
+ {%- set outer_loop = loop %} + {%- for move in ['↑', '↓'] %} + {%- if move == '↑' %} + {%- if outer_loop.first %} + {%- set state='disabled' %} + {%- else %} + {%- set state='btn-default' %} + {%- set idx0=outer_loop.index0-1 %} + {%- set idx1=outer_loop.index0 %} + {%- endif %} + {%- else %} + {%- if outer_loop.last %} + {%- set state='disabled' %} + {%- else %} + {%- set state='btn-default' %} + {%- set idx0=outer_loop.index0 %} + {%- set idx1=outer_loop.index0+1 %} + {%- endif %} + {%- endif %} + + {%- endfor %} +
+ {%- endif %} +
+
+
+
+
+ {{ p }} +
+
+
+
+ Enable +
+
+ {%- if available[p].get_config_desc() %} + Configure + {% endif %} +
+
+
+
+
+
+
+
+ +{% endif %} +{% endblock %}