diff --git a/doc/development/api/plugins.rst b/doc/development/api/plugins.rst index 614846d760..a03e83b1d2 100644 --- a/doc/development/api/plugins.rst +++ b/doc/development/api/plugins.rst @@ -49,15 +49,19 @@ description string A more verbose description of what your visible boolean (optional) ``True`` by default, can hide a plugin so it cannot be normally activated. restricted boolean (optional) ``False`` by default, restricts a plugin such that it can only be enabled for an event by system administrators / superusers. +compatibility string Specifier for compatible pretix versions. ================== ==================== =========================================================== A working example would be:: - from django.apps import AppConfig + try: + from pretix.base.plugins import PluginConfig + except ImportError: + raise RuntimeError("Please use pretix 2.7 or above to run this plugin!") from django.utils.translation import ugettext_lazy as _ - class PaypalApp(AppConfig): + class PaypalApp(PluginConfig): name = 'pretix_paypal' verbose_name = _("PayPal") @@ -68,6 +72,7 @@ A working example would be:: visible = True restricted = False description = _("This plugin allows you to receive payments via PayPal") + compatibility = "pretix>=2.7.0" default_app_config = 'pretix_paypal.PaypalApp' diff --git a/src/pretix/base/plugins.py b/src/pretix/base/plugins.py index 9bf684afc3..6b57a70d19 100644 --- a/src/pretix/base/plugins.py +++ b/src/pretix/base/plugins.py @@ -1,8 +1,10 @@ +import sys from enum import Enum from typing import List -from django.apps import apps +from django.apps import AppConfig, apps from django.conf import settings +from django.core.exceptions import ImproperlyConfigured class PluginType(Enum): @@ -39,3 +41,22 @@ def get_all_plugins(event=None) -> List[type]: plugins, key=lambda m: (0 if m.module.startswith('pretix.') else 1, str(m.name).lower().replace('pretix ', '')) ) + + +class PluginConfig(AppConfig): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if not hasattr(self, 'PretixPluginMeta'): + raise ImproperlyConfigured("A pretix plugin config should have a PretixPluginMeta inner class.") + + if hasattr(self.PretixPluginMeta, 'compatibility'): + import pkg_resources + try: + pkg_resources.require(self.PretixPluginMeta.compatibility) + except pkg_resources.VersionConflict as e: + print("Incompatible plugins found!") + print("Plugin {} requires you to have {}, but you installed {}.".format( + self.name, e.req, e.dist + )) + sys.exit(1)