calingen.interfaces.plugin_api
¶
Provides the API for plugins.
Module Contents¶
Classes¶
Mount point for plugins that provide means to compile layouts to documents. |
|
Mount point for plugins that provide events. |
|
Mount point for plugins that provide layouts. |
|
Core of the plugin api. |
Functions¶
|
Get the fully qualified Python path of a class (or instance). |
- class calingen.interfaces.plugin_api.CompilerProvider¶
Mount point for plugins that provide means to compile layouts to documents.
Plugins implementing this reference must provide the following attributes and methods:
title (
str
): The title of the provider.get_response() : A classmethod that accepts a
str
, which will be the rendered layout source as provided byLayoutProvider.render()
. The method must return a valid Django Response object.
- abstract classmethod get_response(source, *args, **kwargs)¶
Get the compiler’s HTTP response.
This is the compiler’s main interface to other components of the app.
It should be used to actually trigger the compilation of the provided source and then return a valid Django Response object.
- Parameters:
source (str) – The source as provided by
LayoutProvider.render()
.- Return type:
Notes
This method is called from
CompilerView's get() method
with an additional keyword argumentlayout_type
, exposing thelayout_type
attribute of the layout.
- classmethod list_available_plugins()¶
Return the available plugins.
- Returns:
The resulting
set
contains a 2-tuple for every plugin, including its qualified classname and its title attribute. The qualified classname is determined byfully_qualified_classname()
.- Return type:
- class calingen.interfaces.plugin_api.EventProvider¶
Mount point for plugins that provide events.
Plugins implementing this reference must provide the following attribute:
title (
str
): The title of the provider, provided as a class attribute.
Plugins implementing this reference can provide the following attributes and/or methods:
entries (
list
): A list ofcalingen.interfaces.data_exchange.CalendarEntry
instances.The default implementation of
resolve()
will work on thislist
. Alternativelyresolve()
may be re-implemented (see below).resolve(year) : A classmethod that accepts a year (
int
) as parameter and returns an instance ofcalingen.interfaces.data_exchange.CalendarEntryList
containing the Events of the requested year with their corresponding meta information as specified bycalingen.interfaces.data_exchange.CalendarEntry
.
- classmethod list_available_plugins()¶
Return the available plugins.
- Returns:
The resulting
set
contains a 2-tuple for every plugin, including its qualified classname and itstitle
attribute. The qualified classname is determined byfully_qualified_classname()
.- Return type:
Notes
Primary use case for this method is the usage in a Django view, specifically
ProfileForm
uses this method to provide the choices of its field. ThatForm
is then used in the app’s views, e.g.calingen.views.profile.ProfileUpdateView
.
- classmethod resolve(year)¶
Return a list of events.
- Parameters:
year (int) – The year to retrieve the list of events for.
- Returns:
Wraps the actual events, provided as
calingen.interfaces.data_exchange.CalendarEntry
into one single object.- Return type:
Notes
This is the default implementation of the
resolve()
method. It makes some assumptions about the internal structure of an actual implementation ofEventProvider
:A class variable
entries
provides alist
oftuple
instances with the following structure:(title, category, recurrence)
:title
:str
category
:str
, but it is recommended to rely on a predefined value fromcalingen.constants.EventCategory
recurrence
:dateutil.rrule.rrule
A class variable
title
(str
). This is already a required parameter of theEventProvider
implementation itsself and is used to populate thesource
attribute of the returnedCalenderEntry
instances.
- class calingen.interfaces.plugin_api.LayoutProvider¶
Mount point for plugins that provide layouts.
Plugins implementing this reference must provide the following attributes:
title (
str
): Thetitle
will be used to represent the plugin in the app’s views. It must be provided as a class attribute resolving to astr
. However, it is recommended to provide the following class attributes instead:By providing these attributes, the
title
can be provided automatically bytitle()
in a unified way throughout the application.layout_type (
str
): This required class attribute specifies the source language of the rendered result and is used incalingen.views.generation.CompilerView
to determine which compiler is to be used to actually compile the rendered source to its final product.The actual mapping of
layout_type
to compiler is done in the app-specific settingCALINGEN_COMPILER
.layout_type
may not be"default"
, as this is a special key used internally inCompilerView
and specifies the fallback compiler for the case that there is no dedicated compiler available for thelayout_type
of a layout.
Plugins implementing this reference can provide implementations of the following methods:
prepare_context(context) (
dict
): This method performs pre-processing of thecontext
. If an actual layout needs data in a different structure than provided bycalingen.views.generation.CompilerView
, this method may be re-implemented by the actual layout. Seeprepare_context()
for additional details.render(year, entries) (
str
): Actually renders the layout’s templates with the given context. This method may be re-implemented by actual layouts, though it is pretty generic as it is and should work for most use cases. It callsprepare_context()
for pre-processing of the context. It is recommended to rely onprepare_context()
in actual layout implementations.
- configuration_form¶
Layouts may provide a custom form to fetch configuration values.
The specified form should be a subclass of
calingen.forms.generation.LayoutConfigurationForm
and may implement custom validation / cleaning logic.
- classmethod list_available_plugins()¶
Return the available plugins.
- Returns:
The resulting
set
contains a 2-tuple for every plugin, including its qualified classname and its title attribute. The qualified classname is determined byfully_qualified_classname()
.- Return type:
Notes
Primary use case for this method is the usage in a Django view, specifically
ProfileForm
uses this method to provide the choices of its field. ThatForm
is then used in the app’s views, e.g.ProfileUpdateView
.
- classmethod prepare_context(context)¶
Pre-process the context before rendering.
- Parameters:
context (dict) – The context, as provided by
calingen.views.generation.CompilerView.get()
.- Returns:
The updated context.
- Return type:
Notes
This default implementation does nothing.
LayoutProvider
implementations may override this method to apply necessary modifications of thecontext
.
- classmethod render(context, *args, **kwargs)¶
Return the rendered source.
- Returns:
The rendered source.
- Return type:
Notes
This is a very basic implementation of the (required)
render()
method.
- title()¶
Return the plugin’s human-readable title.
- Returns:
The plugin’s title is constructed from class attributes.
- Return type:
Notes
The
title
is provided as aclassproperty
.If an actual layout implementation wishes to provide its title in a different way, it may provide a specific implementation of this method or provide a plain
title
class attribute, resolving to astr
(TODO: NEEDS VERIFICATION!).The
classproperty
decorator is provided by Django, so B902 is disabled on this.
- class calingen.interfaces.plugin_api.PluginMount(name, bases, attrs)¶
Bases:
type
Core of the plugin api.
Notes
Searching Google with any Django-related term usually results in at least five StackOverflow threads with similar issues. This failed for “django plugin system” (ok, there are SO threads, without providing any real solution).
However, there is a blog post by Marty Alchin, dating back to 2008 [1], describing some sort of weird Python sorcery. Digging deeper, while trying to understand the purpose and possible application of
metaclass
in this context, this SO thread [2] was found (easily one of the best SO threads on a general programming technique).Obviously, [1] was ported to Python3 syntax (getting rid of
__metaclass__
and apply it in the class definition of the actual mount point).References
- calingen.interfaces.plugin_api.fully_qualified_classname(class_or_instance)¶
Get the fully qualified Python path of a class (or instance).
- Parameters:
class_or_instance (any) – The class (or instance of a class) to work on
- Returns:
The fully qualified, dotted Python path of that class or instance.
- Return type: