1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
import os
from functools import partial
from pluginbase import PluginBase
# For easier usage calculate the path relative to here.
here = os.path.abspath(os.path.dirname(__file__))
get_path = partial(os.path.join, here)
# Setup a plugin base for "example.modules" and make sure to load
# all the default built-in plugins from the builtin_plugins folder.
plugin_base = PluginBase(package='example.plugins',
searchpath=[get_path('./builtin_plugins')])
class Application(object):
"""Represents a simple example application."""
def __init__(self, name):
# Each application has a name
self.name = name
# And a dictionary where it stores "formatters". These will be
# functions provided by plugins which format strings.
self.formatters = {}
# and a source which loads the plugins from the "app_name/plugins"
# folder. We also pass the application name as identifier. This
# is optional but by doing this out plugins have consistent
# internal module names which allows pickle to work.
self.source = plugin_base.make_plugin_source(
searchpath=[get_path('./%s/plugins' % name)],
identifier=self.name)
# Here we list all the plugins the source knows about, load them
# and the use the "setup" function provided by the plugin to
# initialize the plugin.
for plugin_name in self.source.list_plugins():
plugin = self.source.load_plugin(plugin_name)
plugin.setup(self)
def register_formatter(self, name, formatter):
"""A function a plugin can use to register a formatter."""
self.formatters[name] = formatter
def run_demo(app, source):
"""Shows all formatters in demo mode of an application."""
print('Formatters for %s:' % app.name)
print(' input: %s' % source)
for name, fmt in sorted(app.formatters.items()):
print(' %10s: %s' % (name, fmt(source)))
print('')
def main():
# This is the demo string we want to format.
source = 'This is a cool demo text to show this functionality.'
# Set up two applications. One loads plugins from ./app1/plugins
# and the second one from ./app2/plugins. Both will also load
# the default ./builtin_plugins.
app1 = Application('app1')
app2 = Application('app2')
# Run the demo for both
run_demo(app1, source)
run_demo(app2, source)
# And just to show how the import system works, we also showcase
# importing plugins regularly:
with app1.source:
from example.plugins import secret
print('Plugin module: %s' % secret)
if __name__ == '__main__':
main()
|