GSoC 2017 - About a week in

This week has been quite productive. I started laying the groundwork for the encrypted lists plugin by making changes from core_changes to different components of both Mailman Core, Mailman-Client and Postorius. I will describe the MRs and ideas behind them here.

Mailman Core#

Move pipelines to their own package and instantiate dynamically#

mailman!287

This MR makes Pipelines in Mailman Core work in the same dynamic way as Handlers,Rules,Chains and other similar Mailman’s components work.

Add plugin infrastructure#

mailman!288

This MR is the biggest one and certainly the most important one for the pgpmailman plugin and other potential Mailman plugins. It adds a notion of a plugin to Mailman Core. To explain what I mean by a plugin, it’s best to look at its example configuration:

[plugin.example]
path: example_plugin
class: example_plugin.plugin.ExamplePlugin
enable: yes
configuration: python:example_plugin.config.example

This configuration defines a plugin called example (section name). Which resides in the example_plugin package with the example_plugin.plugin.ExamplePlugin class implementing the IPlugin interface, which I will describe in a moment. This plugin is enabled and can use the path example_plugin.config.example.cfg to load it’s configuration.

Alright now what does this actually do / change / provide in Mailman Core?

  • The plugin’s path package is searched for pluggable components if the plugin is enabled and has a non-empty path value. A new function similar to find_components is introduced and used, find_pluggable_components. The components are searched for in subpackages named after what is being searched, common to Mailman Core:
    • example_plugin.rules -> IRule
    • example_plugin.chains -> IChain
    • example_plugin.commands -> IEmailCommand
    • example_plugin.handlers -> IHandler
    • example_plugin.styles -> IStyle
    • example_plugin.pipelines -> IPipeline (after mailman!287 lands)
  • The plugin’s class is instantiated if the plugin is enabled and has a non-empty class value (and implements the IPlugin interface). The IPlugin interface has several methods:
    • pre_hook() -> Is called after instantiation but before Mailman’s db initialization, really just moved the existing pre_hook configurable callable into a plugin infrastructure. Return value unused.
    • post_hook() -> Is called after pre_hook and after initialization of Mailman’s db and other dynamic components such as commands, rules, handlers… Return value unused.
    • rest_object() -> Is called whenever a REST client calls the /plugins/<plugin.name>/... route, to obtain an object which will respond to REST queries for the plugin rooted at aforementioned route. This method can return None to signify the plugin doesn’t want to expose any REST routes, in which case any calls by clients return 404. Otherwise the object should use the routing system used by Mailman’s REST api (@child(), on_get and so on).
    • Mailman also sets the name attribute on the plugin object after instantiation, before pre_hook to the plugin’s name in configuration.
  • The plugin can use the path in it’s configuration option to load it’s configuration if it needs a config file. The same path resoultion rules apply as for the archivers configuration.

Add description attribute to styles#

mailman!289

Mailing list styles currently have an attribute for name, which for the default styles is:

 legacy-announce
 legacy-default

Which is not particularly human-readable, well it is, but doesn’t look like something to be shown in a web ui such as Postorius. Mapping these style names to their descriptions in Postorius is possible, however since the styles are dynamically found and instantiated, it’s not something practically doable.

So this MR adds a description attribute to IStyle and adds the appropriate descriptions to the default styles. Also exposes said description to REST clients.

Mailman-Client#

Add bindings for specifying list style#

mailmanclient!28

This MR adds missing access to the lists/styles REST api endpoint and another argument style_name to the Mailman-Client’s create_list call, which is already recognized in Core and will create a new list with selected style. This will then be used by Postorius.

Add plugin bindings#

mailmanclient!34

This MR depends on mailman!288 as it really just exposes the new REST api added with plugins to Mailman-Client. Since this new api gives plugins control over all the requests to paths after their root, the api in Mailman-Client can not be as high-level and abstracted as it is for lists and other core features. It provides access to plugin’s configuration and a Plugin.call(path, data, method) similar to Connection.call.

Postorius#

Add list style selection to list creation view#

postorius!214

This MR depends on mailmanclient!28 and mailman!289. It adds another field to the list creation form, prompting the user to select a list style, with the default being pre-selected and list style descriptions being shown.