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 = {}
         settings = {}
         for setting in result:
         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
         return settings
 
 

+ 52 - 64
flaskbb/management/views.py

@@ -26,7 +26,7 @@ from flaskbb.utils.requirements import (IsAtleastModerator, IsAdmin,
                                         IsAtleastSuperModerator)
                                         IsAtleastSuperModerator)
 from flaskbb.extensions import db, allows, celery
 from flaskbb.extensions import db, allows, celery
 from flaskbb.utils.helpers import (render_template, time_diff, time_utcnow,
 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.plugins.models import PluginRegistry, PluginStore
 from flaskbb.user.models import Guest, User, Group
 from flaskbb.user.models import Guest, User, Group
 from flaskbb.forum.models import Post, Topic, Forum, Category, Report
 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", methods=["GET", "POST"])
 @management.route("/settings/<path:slug>", methods=["GET", "POST"])
 @management.route("/settings/<path:slug>", methods=["GET", "POST"])
+@management.route("/settings/plugin/<path:plugin>", methods=["GET", "POST"])
 @allows.requires(IsAdmin)
 @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_groups = SettingsGroup.query.all()
+    all_plugins = PluginRegistry.query.all()
 
 
-    SettingsForm = Setting.get_form(active_group)
-
-    old_settings = Setting.get_settings(active_group)
     new_settings = {}
     new_settings = {}
-
-    form = SettingsForm()
-
     if form.validate_on_submit():
     if form.validate_on_submit():
-        for key, values in iteritems(old_settings):
+        for key, value in iteritems(old_settings):
             try:
             try:
                 # check if the value has changed
                 # check if the value has changed
-                if values['value'] == form[key].data:
+                if value == form[key].data:
                     continue
                     continue
                 else:
                 else:
                     new_settings[key] = form[key].data
                     new_settings[key] = form[key].data
             except KeyError:
             except KeyError:
                 pass
                 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")
         flash(_("Settings saved."), "success")
     else:
     else:
-        for key, values in iteritems(old_settings):
+        for key, value in iteritems(old_settings):
             try:
             try:
-                form[key].data = values['value']
+                form[key].data = value
             except (KeyError, ValueError):
             except (KeyError, ValueError):
                 pass
                 pass
 
 
     return render_template("management/settings.html", form=form,
     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
 # Users
@@ -703,34 +718,16 @@ def delete_category(category_id):
 @management.route("/plugins")
 @management.route("/plugins")
 @allows.requires(IsAdmin)
 @allows.requires(IsAdmin)
 def plugins():
 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)
     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)
 @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:
     if plugin.enabled:
         flash(_("Plugin %(plugin)s is already enabled.", plugin=plugin.name),
         flash(_("Plugin %(plugin)s is already enabled.", plugin=plugin.name),
@@ -745,14 +742,11 @@ def enable_plugin(pluginname):
     return redirect(url_for("management.plugins"))
     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)
 @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:
     if not plugin.enabled:
         flash(_("Plugin %(plugin)s is already disabled.", plugin=plugin.name),
         flash(_("Plugin %(plugin)s is already disabled.", plugin=plugin.name),
@@ -767,28 +761,22 @@ def disable_plugin(pluginname):
     return redirect(url_for("management.plugins"))
     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)
 @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()
     plugin.delete()
     flash(_("Plugin has been uninstalled."), "success")
     flash(_("Plugin has been uninstalled."), "success")
     return redirect(url_for("management.plugins"))
     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)
 @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)
     plugin.add_settings(plugin_module.SETTINGS)
     flash(_("Plugin has been installed."), "success")
     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 class="col-md-4 col-sm-4 col-xs-4 meta-item">{% trans %}Manage{% endtrans %}</div>
                     </div>
                     </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="row settings-row hover with-border-bottom">
                     <div class="col-md-4 col-sm-4 col-xs-4">
                     <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 %}
                     {% else %}
-                      {{ pluginname.title() }}
+                      {{ plugin_name.title() }}
                     {% endif %}
                     {% endif %}
                     </div>
                     </div>
                     <div class="col-md-4 col-sm-4 col-xs-4">
                     <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>
                     <div class="col-md-4 col-sm-4 col-xs-4">
                     <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() }}" />
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-success">{% trans %}Enable{% endtrans %}</button>
                             <button class="btn btn-success">{% trans %}Enable{% endtrans %}</button>
                         </form>
                         </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() }}" />
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-warning">{% trans %}Disable{% endtrans %}</button>
                             <button class="btn btn-warning">{% trans %}Disable{% endtrans %}</button>
                         </form>
                         </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() }}" />
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-info">{% trans %}Install{% endtrans %}</button>
                             <button class="btn btn-info">{% trans %}Install{% endtrans %}</button>
                         </form>
                         </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() }}" />
                             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
                             <button class="btn btn-danger">{% trans %}Uninstall{% endtrans %}</button>
                             <button class="btn btn-danger">{% trans %}Uninstall{% endtrans %}</button>
                         </form>
                         </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>
                     </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") %}
 {% extends theme("management/management_layout.html") %}
 
 
@@ -6,7 +6,7 @@
 <ol class="breadcrumb flaskbb-breadcrumb">
 <ol class="breadcrumb flaskbb-breadcrumb">
     <li><a href="{{ url_for('forum.index') }}">{% trans %}Forum{% endtrans %}</a></li>
     <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><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>
 </ol>
 {% endblock %}
 {% endblock %}
 
 
@@ -17,13 +17,22 @@
 <div class="col-md-3 settings-col">
 <div class="col-md-3 settings-col">
     <div class="nav-sidebar">
     <div class="nav-sidebar">
         <ul class="nav">
         <ul class="nav">
+        <li class="nav-header">FlaskBB Settings</li>
         {% for group in all_groups %}
         {% 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>
                 <li class="active"><a href="{{ url_for('management.settings', slug=group.key) }}">{{ group.name }}</a></li>
             {% else %}
             {% else %}
                 <li><a href="{{ url_for('management.settings', slug=group.key) }}">{{ group.name }}</a></li>
                 <li><a href="{{ url_for('management.settings', slug=group.key) }}">{{ group.name }}</a></li>
             {% endif %}
             {% endif %}
         {% endfor %}
         {% 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>
         </ul>
     </div>
     </div>
 </div><!--/.col-md-3 -->
 </div><!--/.col-md-3 -->
@@ -31,7 +40,7 @@
 <div class="col-md-9 settings-col with-left-border">
 <div class="col-md-9 settings-col with-left-border">
     <div class="panel settings-panel">
     <div class="panel settings-panel">
         <div class="panel-heading settings-head">
         <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>
         <div class="panel-body settings-body">
         <div class="panel-body settings-body">
             <div class="settings-content">
             <div class="settings-content">

+ 12 - 1
flaskbb/utils/helpers.py

@@ -23,7 +23,7 @@ from PIL import ImageFile
 
 
 import requests
 import requests
 import unidecode
 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 jinja2 import Markup
 from babel.core import get_locale_identifier
 from babel.core import get_locale_identifier
 from babel.dates import format_timedelta as babel_format_timedelta
 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
         metadata[key.replace('-', '_').lower()] = value
 
 
     return metadata
     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