combo/combo/plugins.py

98 lines
3.1 KiB
Python

# combo - content management system
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from functools import wraps
from django.apps import apps
from django.conf.urls import re_path
from django.http import Http404
from django.urls import include
from django.views.debug import technical_404_response
from .urls_utils import decorated_includes, staff_required
logger = logging.getLogger(__name__)
PLUGIN_GROUP_NAME = 'combo.plugin'
class PluginError(Exception):
pass
def get_plugin_includes(plugin, url_serie):
if not hasattr(plugin, url_serie):
return
urls = getattr(plugin, url_serie)()
if not hasattr(plugin, 'is_enabled'):
return re_path('^', include(urls))
def plugin_enabled(func):
@wraps(func)
def f(request, *args, **kwargs):
if not plugin.is_enabled():
return technical_404_response(request, Http404())
return func(request, *args, **kwargs)
return f
from .urls_utils import decorated_includes
return re_path('^', decorated_includes(plugin_enabled, include(urls)))
def register_plugins_urls(urlpatterns):
pre_urls = []
post_urls = []
for plugin in apps.get_app_configs():
urls = get_plugin_includes(plugin, 'get_before_urls')
if urls:
pre_urls.append(urls)
urls = get_plugin_includes(plugin, 'get_after_urls')
if urls:
post_urls.append(urls)
return pre_urls + urlpatterns + post_urls
def register_plugins_manager_urls(urlpatterns):
pre_urls = []
post_urls = []
for plugin in apps.get_app_configs():
urls = get_plugin_includes(plugin, 'get_before_manager_urls')
if urls:
pre_urls.append(urls)
urls = get_plugin_includes(plugin, 'get_after_manager_urls')
if urls:
post_urls.append(urls)
return (
[re_path('', decorated_includes(staff_required, include(pre_urls)))]
+ urlpatterns
+ [re_path('', decorated_includes(staff_required, include(post_urls)))]
)
def get_extra_manager_actions():
"""This iterates over all appconfigs and returns a list of dictionaries,
with href and text keys."""
actions = []
for plugin in apps.get_app_configs():
if hasattr(plugin, 'is_enabled') and not plugin.is_enabled():
continue
if hasattr(plugin, 'get_extra_manager_actions'):
actions.extend(plugin.get_extra_manager_actions())
return actions