diff --git a/app/admin.py b/app/admin.py index aa5f7ee7..b8214400 100644 --- a/app/admin.py +++ b/app/admin.py @@ -149,7 +149,9 @@ class PluginAdmin(admin.ModelAdmin): def plugin_disable(self, request, plugin_name, *args, **kwargs): try: - disable_plugin(plugin_name) + p = disable_plugin(plugin_name) + if p.requires_restart(): + messages.warning(request, _("Restart required. Please restart WebODM to fully disable %(plugin)s") % {'plugin': plugin_name}) except Exception as e: messages.warning(request, _("Cannot disable plugin %(plugin)s: %(message)s") % {'plugin': plugin_name, 'message': str(e)}) diff --git a/app/plugins/functions.py b/app/plugins/functions.py index d11c23ca..1ca0384d 100644 --- a/app/plugins/functions.py +++ b/app/plugins/functions.py @@ -328,7 +328,9 @@ def enable_plugin(plugin_name): return p def disable_plugin(plugin_name): + p = get_plugin_by_name(plugin_name, only_active=False) Plugin.objects.get(pk=plugin_name).disable() + return p def delete_plugin(plugin_name): Plugin.objects.get(pk=plugin_name).delete() diff --git a/app/static/app/js/components/ClipboardInput.jsx b/app/static/app/js/components/ClipboardInput.jsx index c9235ee8..c83efa97 100644 --- a/app/static/app/js/components/ClipboardInput.jsx +++ b/app/static/app/js/components/ClipboardInput.jsx @@ -30,6 +30,7 @@ class ClipboardInput extends React.Component{ { this.dom = domNode; }} + title={this.props.value || ""} onBlur={() => { this.setState({showCopied: false}); }} />
diff --git a/coreplugins/shortlinks/api.py b/coreplugins/shortlinks/api.py index db62fdd0..f35b6a7a 100644 --- a/coreplugins/shortlinks/api.py +++ b/coreplugins/shortlinks/api.py @@ -3,11 +3,16 @@ import math from rest_framework import status from rest_framework.response import Response from app.plugins.views import TaskView -from app.plugins import get_current_plugin +from app.plugins import get_current_plugin, signals as plugin_signals +from django.dispatch import receiver from app.plugins import GlobalDataStore from django.http import Http404 from django.shortcuts import redirect +import logging + +logger = logging.getLogger('app.logger') + ds = GlobalDataStore('shortlinks') def gen_short_string(num): @@ -55,4 +60,12 @@ def HandleShortLink(request, view_type, short_id): return redirect('/public/task/{}/{}/'.format(task_id, v)) else: - raise Http404() \ No newline at end of file + raise Http404() + +@receiver(plugin_signals.task_removed, dispatch_uid="shortlinks_on_task_removed") +def shortlinks_cleanup(sender, task_id, **kwargs): + short_id = ds.get_string(task_id) + if short_id: + logger.info("Cleaning up shortlinks datastore for task {}".format(str(task_id))) + ds.del_key(task_id) + ds.del_key(short_id) diff --git a/coreplugins/shortlinks/plugin.py b/coreplugins/shortlinks/plugin.py index 8e9bf862..54f8a60c 100644 --- a/coreplugins/shortlinks/plugin.py +++ b/coreplugins/shortlinks/plugin.py @@ -10,7 +10,7 @@ class Plugin(PluginBase): def include_js_files(self): return ['main.js'] - + def root_mount_points(self): return [ MountPoint(r'^s(?P[m3])(?P[a-z0-9]+)/?$', HandleShortLink) diff --git a/coreplugins/shortlinks/public/SLCheckbox.jsx b/coreplugins/shortlinks/public/SLCheckbox.jsx index 1cc78b0f..8c50e799 100644 --- a/coreplugins/shortlinks/public/SLCheckbox.jsx +++ b/coreplugins/shortlinks/public/SLCheckbox.jsx @@ -63,17 +63,13 @@ export default class SLCheckbox extends React.Component{ if (error) return (); - return (