Mercurial > libervia-backend
comparison src/bridge/bridge_constructor/bridge_contructor.py @ 273:3b5e856b3a32
Bridge: added mediawiki constructor in bridge constructor, usefull for documentation purpose
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 25 Jan 2011 01:37:02 +0100 |
parents | 0288f97334f2 |
children | a00e87d48213 |
comparison
equal
deleted
inserted
replaced
272:1d2e0dfe7114 | 273:3b5e856b3a32 |
---|---|
33 under certain conditions. | 33 under certain conditions. |
34 --- | 34 --- |
35 | 35 |
36 This script construct a SàT bridge using the given protocol | 36 This script construct a SàT bridge using the given protocol |
37 """ | 37 """ |
38 MANAGED_PROTOCOLES=['dbus'] | 38 MANAGED_PROTOCOLES=['dbus','mediawiki'] |
39 DEFAULT_PROTOCOLE='dbus' | 39 DEFAULT_PROTOCOLE='dbus' |
40 FLAGS=['deprecated'] | |
40 | 41 |
41 import sys | 42 import sys |
42 import os | 43 import os |
43 from os import path | 44 from os import path |
44 from optparse import OptionParser | 45 from optparse import OptionParser |
45 from ConfigParser import SafeConfigParser as Parser | 46 from ConfigParser import SafeConfigParser as Parser |
46 from ConfigParser import NoOptionError | 47 from ConfigParser import NoOptionError |
47 import re | 48 import re |
49 from datetime import datetime | |
48 | 50 |
49 | 51 |
50 class ParseError(Exception): | 52 class ParseError(Exception): |
51 #Used when the signature parsing is going wrong (invalid signature ?) | 53 #Used when the signature parsing is going wrong (invalid signature ?) |
52 pass | 54 pass |
76 @return: dict, each key is the integer param number (no key if no default value)""" | 78 @return: dict, each key is the integer param number (no key if no default value)""" |
77 default_dict={} | 79 default_dict={} |
78 def_re = re.compile(r"param_(\d+)_default") | 80 def_re = re.compile(r"param_(\d+)_default") |
79 | 81 |
80 for option in self.bridge_template.options(name): | 82 for option in self.bridge_template.options(name): |
81 if option == 'doc_return': | |
82 default_dict['return'] = self.bridge_template.get(name, option) | |
83 continue | |
84 match = def_re.match(option) | 83 match = def_re.match(option) |
85 if match: | 84 if match: |
86 try: | 85 try: |
87 idx = int(match.group(1)) | 86 idx = int(match.group(1)) |
88 except ValueError: | 87 except ValueError: |
89 raise ParseError("Invalid value [%s] for parameter number" % match.group(1)) | 88 raise ParseError("Invalid value [%s] for parameter number" % match.group(1)) |
90 default_dict[idx] = self.bridge_template.get(name, option) | 89 default_dict[idx] = self.bridge_template.get(name, option) |
91 | 90 |
92 return default_dict | 91 return default_dict |
93 | 92 |
93 def getFlags(self, name): | |
94 """Return list of flags set for this function | |
95 @param name: Name of the function to get | |
96 @return: List of flags (string)""" | |
97 flags=[] | |
98 for option in self.bridge_template.options(name): | |
99 if option in FLAGS: | |
100 flags.append(option) | |
101 return flags | |
102 | |
94 def getArgumentsDoc(self, name): | 103 def getArgumentsDoc(self, name): |
95 """Return documentation of arguments | 104 """Return documentation of arguments |
96 @param name: Name of the function to get | 105 @param name: Name of the function to get |
97 @return: dict, each key is the integer param number (no key if no argument doc), value is a tuple (name, doc)""" | 106 @return: dict, each key is the integer param number (no key if no argument doc), value is a tuple (name, doc)""" |
98 doc_dict={} | 107 doc_dict={} |
99 option_re = re.compile(r"doc_param_(\d+)") | 108 option_re = re.compile(r"doc_param_(\d+)") |
100 value_re = re.compile(r"^(\w+): (.*)$", re.MULTILINE | re.DOTALL) | 109 value_re = re.compile(r"^(\w+): (.*)$", re.MULTILINE | re.DOTALL) |
101 for option in self.bridge_template.options(name): | 110 for option in self.bridge_template.options(name): |
111 if option == 'doc_return': | |
112 doc_dict['return'] = self.bridge_template.get(name, option) | |
113 continue | |
102 match = option_re.match(option) | 114 match = option_re.match(option) |
103 if match: | 115 if match: |
104 try: | 116 try: |
105 idx = int(match.group(1)) | 117 idx = int(match.group(1)) |
106 except ValueError: | 118 except ValueError: |
108 value_match = value_re.match(self.bridge_template.get(name, option)) | 120 value_match = value_re.match(self.bridge_template.get(name, option)) |
109 if not value_match: | 121 if not value_match: |
110 raise ParseError("Invalid value for parameter doc [%i]" % idx) | 122 raise ParseError("Invalid value for parameter doc [%i]" % idx) |
111 doc_dict[idx]=(value_match.group(1),value_match.group(2)) | 123 doc_dict[idx]=(value_match.group(1),value_match.group(2)) |
112 return doc_dict | 124 return doc_dict |
125 | |
126 def getDoc(self, name): | |
127 """Return documentation of the method | |
128 @param name: Name of the function to get | |
129 @return: string documentation, or None""" | |
130 if self.bridge_template.has_option(name, "doc"): | |
131 return self.bridge_template.get(name, "doc") | |
132 return None | |
113 | 133 |
114 def getArguments(self, signature, name=None, default=None, unicode_protect=False): | 134 def getArguments(self, signature, name=None, default=None, unicode_protect=False): |
115 """Return arguments to user given a signature | 135 """Return arguments to user given a signature |
116 @param signature: signature in the short form (using s,a,i,b etc) | 136 @param signature: signature in the short form (using s,a,i,b etc) |
117 @param name: dictionary of arguments name like given by getArguments | 137 @param name: dictionary of arguments name like given by getArguments |
182 print ("Can't open destination file [%s]" % full_path) | 202 print ("Can't open destination file [%s]" % full_path) |
183 except OSError: | 203 except OSError: |
184 print("It's not possible to generate the file, check your permissions") | 204 print("It's not possible to generate the file, check your permissions") |
185 exit(1) | 205 exit(1) |
186 | 206 |
207 class MediawikiConstructor(Constructor): | |
208 | |
209 def __init__(self, bridge_template, options): | |
210 Constructor.__init__(self, bridge_template, options) | |
211 self.core_template="mediawiki_template.tpl" | |
212 self.core_dest="mediawiki.wiki" | |
213 | |
214 def _wikiParameter(self, name, sig_in): | |
215 """Format parameters with the wiki syntax | |
216 @param name: name of the function | |
217 @param sig_in: signature in | |
218 @return: string of the formated parameters""" | |
219 arg_doc = self.getArgumentsDoc(name) | |
220 arg_default = self.getDefault(name) | |
221 args_str = self.getArguments(sig_in) | |
222 args = args_str.split(', ') if args_str else [] #ugly but it works :) | |
223 wiki=[] | |
224 for i in range(len(args)): | |
225 if arg_doc.has_key(i): | |
226 name,doc=arg_doc[i] | |
227 doc='\n:'.join(doc.rstrip('\n').split('\n')) | |
228 wiki.append("; %s: %s" % (name, doc)) | |
229 else: | |
230 wiki.append("; arg_%d: " % i) | |
231 if arg_default.has_key(i): | |
232 wiki.append(":''DEFAULT: %s''" % arg_default[i]) | |
233 return "\n".join(wiki) | |
234 | |
235 def _wikiReturn(self, name): | |
236 """Format return doc with the wiki syntax | |
237 @param name: name of the function | |
238 """ | |
239 arg_doc = self.getArgumentsDoc(name) | |
240 wiki=[] | |
241 if arg_doc.has_key('return'): | |
242 wiki.append('\n|-\n! scope=row | return value\n|') | |
243 wiki.append('<br />\n'.join(arg_doc['return'].rstrip('\n').split('\n'))) | |
244 return "\n".join(wiki) | |
245 | |
246 def generateCoreSide(self): | |
247 signals_part = [] | |
248 methods_part = [] | |
249 sections = self.bridge_template.sections() | |
250 sections.sort() | |
251 for section in sections: | |
252 function = self.getValues(section) | |
253 print ("Adding %s %s" % (section, function["type"])) | |
254 default = self.getDefault(section) | |
255 deprecated_msg = """<br />'''<font color="#FF0000">/!\ WARNING /!\ : This method is deprecated, please don't use it !</font>'''""" | |
256 signature_signal = \ | |
257 """\ | |
258 ! scope=row | signature | |
259 | %s | |
260 |-\ | |
261 """ % function['sig_in'] | |
262 signature_method = \ | |
263 """\ | |
264 ! scope=row | signature in | |
265 | %s | |
266 |- | |
267 ! scope=row | signature out | |
268 | %s | |
269 |-\ | |
270 """ % (function['sig_in'], function['sig_out']) | |
271 completion = { | |
272 'signature':signature_signal if function['type']=="signal" else signature_method, | |
273 'sig_out':function['sig_out'] or '', | |
274 'category':function['category'], | |
275 'name':section, | |
276 'doc':self.getDoc(section) or "FIXME: No description available", | |
277 'deprecated':deprecated_msg if "deprecated" in self.getFlags(section) else "", | |
278 'parameters':self._wikiParameter(section, function['sig_in']), | |
279 'return':self._wikiReturn(section) if function['type'] == 'method' else '' | |
280 } | |
281 | |
282 dest = signals_part if function['type'] == "signal" else methods_part | |
283 dest.append("""\ | |
284 == %(name)s == | |
285 ''%(doc)s'' | |
286 %(deprecated)s | |
287 {| class="wikitable" style="text-align:left; width:80%%;" | |
288 ! scope=row | category | |
289 | %(category)s | |
290 |- | |
291 %(signature)s | |
292 ! scope=row | parameters | |
293 | | |
294 %(parameters)s%(return)s | |
295 |} | |
296 """ % completion) | |
297 | |
298 #at this point, signals_part, and methods_part should be filled, | |
299 #we just have to place them in the right part of the template | |
300 core_bridge = [] | |
301 try: | |
302 with open(self.core_template) as core_template: | |
303 for line in core_template: | |
304 if line.startswith('##SIGNALS_PART##'): | |
305 core_bridge.extend(signals_part) | |
306 elif line.startswith('##METHODS_PART##'): | |
307 core_bridge.extend(methods_part) | |
308 elif line.startswith('##TIMESTAMP##'): | |
309 core_bridge.append('Generated on %s' % datetime.now()) | |
310 else: | |
311 core_bridge.append(line.replace('\n','')) | |
312 except IOError: | |
313 print ("Can't open template file [%s]" % self.core_template) | |
314 sys.exit(1) | |
315 | |
316 #now we write to final file | |
317 self.finalWrite(self.core_dest, core_bridge) | |
318 | |
187 class DbusConstructor(Constructor): | 319 class DbusConstructor(Constructor): |
188 | 320 |
189 def __init__(self, bridge_template, options): | 321 def __init__(self, bridge_template, options): |
190 Constructor.__init__(self, bridge_template, options) | 322 Constructor.__init__(self, bridge_template, options) |
191 self.core_template="dbus_core_template.py" | 323 self.core_template="dbus_core_template.py" |
303 | 435 |
304 class ConstructorFactory: | 436 class ConstructorFactory: |
305 def create(self, bridge_template, options): | 437 def create(self, bridge_template, options): |
306 if options.protocole=='dbus': | 438 if options.protocole=='dbus': |
307 return DbusConstructor(bridge_template, options) | 439 return DbusConstructor(bridge_template, options) |
440 elif options.protocole=='mediawiki': | |
441 return MediawikiConstructor(bridge_template, options) | |
308 | 442 |
309 raise ConstructorError('Unknown constructor type') | 443 raise ConstructorError('Unknown constructor type') |
310 | 444 |
311 class BridgeConstructor: | 445 class BridgeConstructor: |
312 def __init__(self): | 446 def __init__(self): |