1 '''
2 Plugin base module
3 '''
4
5 import os
6 import sys
7 import re
8 import web
9 import codecs
10 import config
11 import ConfigParser
12 from action import Action
13 from dependency import Dependency, Version
14
15 DEP = re.compile(r'^(?P<pname>\w+)\s*\((?P<operator>\>=|\>|=|\<=|\<)(?P<major>.*)\.(?P<minor>.*)\.(?P<release>.*)\)\s*$')
16
17
19 '''
20 Plugin base class. Each plugin should inherit from this class.
21
22 Variables documentation:
23
24 urls: This variable is a tuple of pairs in the form "url-regexp, view" as in web.py
25 applications, but for this plugin only.
26 '''
27
28
29
30
32 self.name = 'nonamed'
33 self.human_name = 'nonamed'
34 self.author = 'anonymous'
35 self.description = 'nodescription'
36 self._version = 'noversion'
37 self.enabled = False
38 self.urls = []
39 self._dependencies = []
40 self.actions = {}
41
43 '''
44 Returns the depencies list.
45 '''
46 return self._dependencies
47
49 '''
50 Generates the dependencies given a string.
51 It's necesary for parsing the configuration file.
52 '''
53 deps = map(str.strip, depstr.split(','))
54 for dep in deps:
55 match = DEP.match(dep)
56 print dep
57 print match
58 pname, operator, major, minor, release = match.groups()
59 dep = Dependency(pname, operator, major, minor, release)
60 self._dependencies.append(dep)
61
62 depend = property(get_dependencies, set_dependencies)
63
65 '''
66 Returns the version.
67 '''
68 return self._version
69
71 '''
72 Generates the version given a string.
73 It's necesary for parsing the configuration file.
74 '''
75 major, minor, release = verstr.split('.')
76 self._version = Version(major, minor, release)
77
78 version = property(get_version, set_version)
79
81 '''
82 Returns if the plugin is enabled in exection time.
83 '''
84 return self.enabled
85
94
96 '''
97 Given a path, it generates the initial configuration of a plugin.
98 '''
99 parser = ConfigParser.ConfigParser()
100 parser.readfp(codecs.open(path, 'r', sys.getfilesystemencoding(), errors="ignore"))
101
102
103 for k, v in parser.items('plugin'):
104 setattr(self, k, v)
105
106
107 actions = [i for i in parser.sections() if i.startswith('action/')]
108 for a in actions:
109 action = Action(self)
110 for k, v in parser.items(a):
111 if k == "appear_in_main_panel":
112 v = parser.getboolean(a, k)
113
114 setattr(action, k, v)
115
116 self.actions[action.name] = action
117
119 '''
120 Returns the actions.
121 '''
122 return self.actions.values()
123
125 '''
126 Returns the actions which appears in the main panel
127 '''
128 return (a for a in self.actions.values() if a.appear_in_main_panel)
129
130
132 '''
133 This function initialize the plugin in such a way that it can used.
134 It will be called in two cases:
135 1. When the plugin is disabled and it's going to be enabled by the
136 admins of the aplication. In this case the install function will
137 also be called if the plugin has not previously been
138 installed.
139 2. Once the plugin is already enabled and installed the pluginmanager
140 will instanciate the plugin and then will call this enable
141 function. This is because the enable function will always before
142 the plugin can be used.
143
144 You can reimplement this function if you want to execute custom
145 actions when your plugin is going to be used.
146 '''
147 pass
148
150 '''
151 This function will be called when the plugin is enabled and it's
152 going to be disabled by the admins of the aplication. It is called only
153 by the pluginmanager. WARNING: Note that disable will NOT be called
154 when the application shutdowns. Use __del__ for that.
155
156 You can reimplement this function if you want to execute custom
157 actions when your plugin is going to be disabled.
158 '''
159 pass
160
162 '''
163 This function will be called when the plugin is enabled the first
164 time.
165
166 You can reimplement this function if you want to install some tables
167 in the data base, or to do something only once.
168 '''
169 pass
170
172 '''
173 This function will be called when the user wants to delete the plugin
174 from the system.
175
176 You can reimplement this function like a cleanup function. You MUST
177 erase all data that plugin generated when it's not goint to be used
178 ever. For example all tables in the data base or data generated in
179 install function.
180 '''
181 pass
182
184 '''
185 Request a GET or a POST petition to the plugin. Redirects a url to a view inside
186 the plugin and returns the data that the appropiate view returns. The "method"
187 argument can be either "GET" or "POST".
188
189 This function is ONLY called by PluginView. When a request of type
190 /plugin/<plugin_name>/<args> is received, PluginView deals with it and acts as a
191 proxy, calling to this _request function of the plugin called "plugin_name", with
192 args= "args".
193
194 Each plugin deals with GET and POST requests by configuring the self.url tuple of
195 pairs url-regexp, view, as webpy applications do.
196 '''
197
198 for i in xrange(0, len(self.urls), 2):
199 path = self.urls[i]
200 view = self.urls[i+1]
201 view_instance = view()
202 match = re.match(path, args)
203 if not match:
204 continue
205
206
207
208 if method == "GET":
209 return view_instance.GET(*match.groups(), **match.groupdict())
210 else:
211 return view_instance.POST(*match.groups(), **match.groupdict())
212
214 '''
215 This function has to return a form. This form contains the options
216 of the plugin that the user can change. If you want options
217 in your plugin you have to reimplement this function.
218 Also you will want to reimplement save_options function which is
219 called when the user submits.
220
221 In the other hand if you don't need any options you haven't to do
222 anything.
223 '''
224 return None
225
227 '''
228 This function is called when the user filles the form returned
229 by get_options, which is passed like argument.
230 It's useful to save the user preferences.
231 You can reimplement this function.
232 '''
233 pass
234
236 '''
237 When the user navigates the organizative units tree structure it will
238 a panel with plugins' actions. The navigator view will call this
239 function for each plugin. You can reimplement this function to
240 return the actions that you want the user see.
241
242 The ou argument is the Organizative Unit that the user is seing.
243 '''
244 return []
245
247 '''
248 The same that get_actions_for_ou but when the user is seing only
249 a computer.
250
251 The computer argument is the Computer that the user is seing.
252 '''
253 return []
254