Browse Source

Use the same logic for modifying flaskbb and plugin settings

Peter Justin 7 years ago
parent
commit
734f0626df

+ 1 - 7
flaskbb/management/models.py

@@ -98,13 +98,7 @@ class Setting(db.Model, CRUDMixin):
 
         settings = {}
         for setting in result:
-            settings[setting.key] = {
-                'name': setting.name,
-                'description': setting.description,
-                'value': setting.value,
-                'value_type': setting.value_type,
-                'extra': setting.extra
-            }
+            settings[setting.key] = setting.value
 
         return settings
 

+ 52 - 64
flaskbb/management/views.py

@@ -26,7 +26,7 @@ from flaskbb.utils.requirements import (IsAtleastModerator, IsAdmin,
                                         IsAtleastSuperModerator)
 from flaskbb.extensions import db, allows, celery
 from flaskbb.utils.helpers import (render_template, time_diff, time_utcnow,
-                                   get_online_users)
+                                   get_online_users, validate_plugin)
 from flaskbb.plugins.models import PluginRegistry, PluginStore
 from flaskbb.user.models import Guest, User, Group
 from flaskbb.forum.models import Post, Topic, Forum, Category, Report
@@ -104,43 +104,58 @@ def overview():
 
 @management.route("/settings", methods=["GET", "POST"])
 @management.route("/settings/<path:slug>", methods=["GET", "POST"])
+@management.route("/settings/plugin/<path:plugin>", methods=["GET", "POST"])
 @allows.requires(IsAdmin)
-def settings(slug=None):
-    slug = slug if slug else "general"
-
-    # get the currently active group
-    active_group = SettingsGroup.query.filter_by(key=slug).first_or_404()
-    # get all groups - used to build the navigation
+def settings(slug=None, plugin=None):
+    slug = slug if slug and not plugin else "general"
+
+    active_settings = {}
+    active_group, active_plugin = None, None
+    if plugin is not None:
+        active_plugin = PluginRegistry.query.filter_by(name=plugin).first_or_404()
+        active_settings['key'] = active_plugin.name
+        active_settings['title'] = active_plugin.name.title()
+        form = active_plugin.get_settings_form()
+        old_settings = active_plugin.settings
+
+    elif slug is not None:
+        active_group = SettingsGroup.query.filter_by(key=slug).first_or_404()
+        active_settings['key'] = active_group.key
+        active_settings['title'] = active_group.name
+        form = Setting.get_form(active_group)()
+        old_settings = Setting.get_settings(active_group)
+    # get all groups and plugins - used to build the navigation
     all_groups = SettingsGroup.query.all()
+    all_plugins = PluginRegistry.query.all()
 
-    SettingsForm = Setting.get_form(active_group)
-
-    old_settings = Setting.get_settings(active_group)
     new_settings = {}
-
-    form = SettingsForm()
-
     if form.validate_on_submit():
-        for key, values in iteritems(old_settings):
+        for key, value in iteritems(old_settings):
             try:
                 # check if the value has changed
-                if values['value'] == form[key].data:
+                if value == form[key].data:
                     continue
                 else:
                     new_settings[key] = form[key].data
             except KeyError:
                 pass
-        Setting.update(settings=new_settings, app=current_app)
+        if active_group is not None:
+            Setting.update(settings=new_settings, app=current_app)
+        else:
+            active_plugin.settings.update(new_settings)
+            active_plugin.save()
         flash(_("Settings saved."), "success")
     else:
-        for key, values in iteritems(old_settings):
+        for key, value in iteritems(old_settings):
             try:
-                form[key].data = values['value']
+                form[key].data = value
             except (KeyError, ValueError):
                 pass
 
     return render_template("management/settings.html", form=form,
-                           all_groups=all_groups, active_group=active_group)
+                           all_groups=all_groups, all_plugins=all_plugins,
+                           active_settings=active_settings,
+                           active_group=active_group)
 
 
 # Users
@@ -703,34 +718,16 @@ def delete_category(category_id):
 @management.route("/plugins")
 @allows.requires(IsAdmin)
 def plugins():
-    from flaskbb.utils.helpers import parse_pkginfo
-    plugins_distinfo = current_app.pluggy.list_plugin_distinfo()
-
-    plugins = {}
-    # XXX: Mapping from PKG-INFO to something more readable?
-    for plugin in plugins_distinfo:
-        name = current_app.pluggy.get_name(plugin[0])
-        plugins[name] = parse_pkginfo(plugin[1].key)
-
-    return render_template("management/plugins.html", plugins=plugins)
-
-
-@management.route("/plugins/<path:pluginname>/settings")
-@allows.requires(IsAdmin)
-def plugin_settings():
-    plugins = current_app.pluggy.get_plugins()
+    plugins = current_app.pluggy.list_plugin_metadata()
+    print(plugins)
     return render_template("management/plugins.html", plugins=plugins)
 
 
-@management.route("/plugins/<path:pluginname>/enable", methods=["POST"])
+@management.route("/plugins/<path:name>/enable", methods=["POST"])
 @allows.requires(IsAdmin)
-def enable_plugin(pluginname):
-    plugin_module = current_app.pluggy.get_plugin(pluginname)
-    if plugin_module is None:
-        flash(_("Plugin %(plugin)s not found.", plugin=pluginname), "error")
-        return redirect(url_for("management.plugins"))
-
-    plugin = PluginRegistry.query.filter_by(name=pluginname).first_or_404()
+def enable_plugin(name):
+    validate_plugin(name)
+    plugin = PluginRegistry.query.filter_by(name=name).first_or_404()
 
     if plugin.enabled:
         flash(_("Plugin %(plugin)s is already enabled.", plugin=plugin.name),
@@ -745,14 +742,11 @@ def enable_plugin(pluginname):
     return redirect(url_for("management.plugins"))
 
 
-@management.route("/plugins/<path:pluginname>/disable", methods=["POST"])
+@management.route("/plugins/<path:name>/disable", methods=["POST"])
 @allows.requires(IsAdmin)
-def disable_plugin(pluginname):
-    plugin_module = current_app.pluggy.get_plugin(pluginname)
-    if plugin_module is None:
-        flash(_("Plugin %(plugin)s not found.", plugin=pluginname), "danger")
-        return redirect(url_for("management.plugins"))
-    plugin = PluginRegistry.query.filter_by(name=pluginname).first_or_404()
+def disable_plugin(name):
+    validate_plugin(name)
+    plugin = PluginRegistry.query.filter_by(name=name).first_or_404()
 
     if not plugin.enabled:
         flash(_("Plugin %(plugin)s is already disabled.", plugin=plugin.name),
@@ -767,28 +761,22 @@ def disable_plugin(pluginname):
     return redirect(url_for("management.plugins"))
 
 
-@management.route("/plugins/<path:pluginname>/uninstall", methods=["POST"])
+@management.route("/plugins/<path:name>/uninstall", methods=["POST"])
 @allows.requires(IsAdmin)
-def uninstall_plugin(pluginname):
-    plugin_module = current_app.pluggy.get_plugin(pluginname)
-    if plugin_module is None:
-        flash(_("Plugin %(plugin)s not found.", plugin=pluginname), "danger")
-        return redirect(url_for("management.plugins"))
-    plugin = PluginRegistry.query.filter_by(name=pluginname).first_or_404()
+def uninstall_plugin(name):
+    validate_plugin(name)
+    plugin = PluginRegistry.query.filter_by(name=name).first_or_404()
 
     plugin.delete()
     flash(_("Plugin has been uninstalled."), "success")
     return redirect(url_for("management.plugins"))
 
 
-@management.route("/plugins/<path:pluginname>/install", methods=["POST"])
+@management.route("/plugins/<path:name>/install", methods=["POST"])
 @allows.requires(IsAdmin)
-def install_plugin(pluginname):
-    plugin_module = current_app.pluggy.get_plugin(pluginname)
-    if plugin_module is None:
-        flash(_("Plugin %(plugin)s not found.", plugin=pluginname), "danger")
-        return redirect(url_for("management.plugins"))
-    plugin = PluginRegistry.query.filter_by(name=pluginname).first_or_404()
+def install_plugin(name):
+    plugin_module = validate_plugin(name)
+    plugin = PluginRegistry.query.filter_by(name=name).first_or_404()
 
     plugin.add_settings(plugin_module.SETTINGS)
     flash(_("Plugin has been installed."), "success")

+ 12 - 12
flaskbb/templates/management/plugins.html

@@ -27,40 +27,40 @@
                         <div class="col-md-4 col-sm-4 col-xs-4 meta-item">{% trans %}Manage{% endtrans %}</div>
                     </div>
                 </div>
-                {% for pluginname, plugininfo in plugins.items() %}
+                {% for plugin_name, plugin_info in plugins.items() %}
                 <div class="row settings-row hover with-border-bottom">
                     <div class="col-md-4 col-sm-4 col-xs-4">
-                    {% if plugininfo['Home-page'] %}
-                      <a href="{{ plugininfo['Home-page'] }}">{{ pluginname.title() }}</a>
+                    {% if plugin_info.get('home_page') %}
+                      <a href="{{ plugin_info.get('home_page') }}">{{ plugin_name.title() }}</a>
                     {% else %}
-                      {{ pluginname.title() }}
+                      {{ plugin_name.title() }}
                     {% endif %}
                     </div>
                     <div class="col-md-4 col-sm-4 col-xs-4">
-                        <div class="plugin-version">{% trans %}Version{% endtrans %}: {{ plugininfo['Version'] }}</div>
-                        <div class="plugin-description">{{ plugininfo['Description'] }}</div>
-                        <div class="plugin-author">{% trans %}by{% endtrans %} {{ plugininfo['Author'] }}</div>
+                        <div class="plugin-version">{% trans %}Version{% endtrans %}: {{ plugin_info.get('version') }}</div>
+                        <div class="plugin-description">{{ plugin_info.get('summary') }}</div>
+                        <div class="plugin-author">{% trans %}by{% endtrans %} {{ plugin_info.get('author') }}</div>
                     </div>
                     <div class="col-md-4 col-sm-4 col-xs-4">
-                        <form class="inline-form" method="post" action="{{ url_for('management.enable_plugin', pluginname=pluginname) }}">
+                        <form class="inline-form" method="post" action="{{ url_for('management.enable_plugin', name=plugin_name) }}">
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-success">{% trans %}Enable{% endtrans %}</button>
                         </form>
-                        <form class="inline-form" method="post" action="{{ url_for('management.disable_plugin', pluginname=pluginname) }}">
+                        <form class="inline-form" method="post" action="{{ url_for('management.disable_plugin', name=plugin_name) }}">
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-warning">{% trans %}Disable{% endtrans %}</button>
                         </form>
 
-                        <form class="inline-form" method="post" action="{{ url_for('management.install_plugin', pluginname=pluginname) }}">
+                        <form class="inline-form" method="post" action="{{ url_for('management.install_plugin', name=plugin_name) }}">
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-info">{% trans %}Install{% endtrans %}</button>
                         </form>
 
-                        <form class="inline-form" method="post" action="{{ url_for('management.uninstall_plugin', pluginname=pluginname) }}">
+                        <form class="inline-form" method="post" action="{{ url_for('management.uninstall_plugin', name=plugin_name) }}">
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-danger">{% trans %}Uninstall{% endtrans %}</button>
                         </form>
-                        <a class="btn btn-info" href="{{ url_for('management.plugin_settings', pluginname=pluginname) }}">Settings</a>
+                        <a class="btn btn-info" href="{{ url_for('management.settings', plugin=plugin_name) }}">Settings</a>
                     </div>
                     </div>
                 </div>

+ 13 - 4
flaskbb/templates/management/settings.html

@@ -1,4 +1,4 @@
-{% set page_title = active_group.name %}
+{% set page_title = active_settings.get('title') %}
 
 {% extends theme("management/management_layout.html") %}
 
@@ -6,7 +6,7 @@
 <ol class="breadcrumb flaskbb-breadcrumb">
     <li><a href="{{ url_for('forum.index') }}">{% trans %}Forum{% endtrans %}</a></li>
     <li><a href="{{ url_for('management.overview') }}">{% trans %}Management{% endtrans %}</a></li>
-    <li class="active">{{ active_group.name }}</li>
+    <li class="active">{{ active_settings.get('title') }}</li>
 </ol>
 {% endblock %}
 
@@ -17,13 +17,22 @@
 <div class="col-md-3 settings-col">
     <div class="nav-sidebar">
         <ul class="nav">
+        <li class="nav-header">FlaskBB Settings</li>
         {% for group in all_groups %}
-            {% if group.key == active_group.key %}
+            {% if group.key == active_settings.get('key') %}
                 <li class="active"><a href="{{ url_for('management.settings', slug=group.key) }}">{{ group.name }}</a></li>
             {% else %}
                 <li><a href="{{ url_for('management.settings', slug=group.key) }}">{{ group.name }}</a></li>
             {% endif %}
         {% endfor %}
+        <li class="nav-header">Plugin Settings</li>
+        {% for plugin in all_plugins %}
+            {% if plugin.name == active_settings.get('key') %}
+                <li class="active"><a href="{{ url_for('management.settings', plugin=plugin.name) }}">{{ plugin.name.title() }}</a></li>
+            {% else %}
+                <li><a href="{{ url_for('management.settings', plugin=plugin.name) }}">{{ plugin.name.title() }}</a></li>
+            {% endif %}
+        {% endfor %}
         </ul>
     </div>
 </div><!--/.col-md-3 -->
@@ -31,7 +40,7 @@
 <div class="col-md-9 settings-col with-left-border">
     <div class="panel settings-panel">
         <div class="panel-heading settings-head">
-            <span class="fa fa-cogs"></span> {{ active_group.name }}
+            <span class="fa fa-cogs"></span> {{ active_settings.get('title') }}
         </div>
         <div class="panel-body settings-body">
             <div class="settings-content">

+ 12 - 1
flaskbb/utils/helpers.py

@@ -23,7 +23,7 @@ from PIL import ImageFile
 
 import requests
 import unidecode
-from flask import session, url_for, flash, redirect, request
+from flask import current_app, session, url_for, flash, redirect, request
 from jinja2 import Markup
 from babel.core import get_locale_identifier
 from babel.dates import format_timedelta as babel_format_timedelta
@@ -638,3 +638,14 @@ def parse_pkg_metadata(dist_name):
         metadata[key.replace('-', '_').lower()] = value
 
     return metadata
+
+
+def validate_plugin(name):  # better name?
+    """Tries to look up the plugin by name. Upon failure it will flash
+    a message and abort. Returns the plugin module on success.
+    """
+    plugin_module = current_app.pluggy.get_plugin(name)
+    if plugin_module is None:
+        flash(_("Plugin %(plugin)s not found.", plugin=name), "error")
+        return redirect(url_for("management.plugins"))
+    return plugin_module