Mercurial > libervia-backend
comparison src/bridge/bridge_constructor/bridge_contructor.py @ 374:193fd5995430
bridge-constructor: added dbus-xml constructor (used for Qt frontend)
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 28 Jul 2011 03:02:31 +0200 |
parents | 3ea41a199b36 |
children | 502489e17685 |
comparison
equal
deleted
inserted
replaced
373:a3aa4d046914 | 374:193fd5995430 |
---|---|
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','mediawiki'] | 38 MANAGED_PROTOCOLES=['dbus','mediawiki', 'dbus-xml'] |
39 DEFAULT_PROTOCOLE='dbus' | 39 DEFAULT_PROTOCOLE='dbus' |
40 FLAGS=['deprecated', 'async'] | 40 FLAGS=['deprecated', 'async'] |
41 | 41 |
42 ENV_OVERRIDE = "SAT_BRIDGE_CONST_" #Prefix used to override a constant | 42 ENV_OVERRIDE = "SAT_BRIDGE_CONST_" #Prefix used to override a constant |
43 | 43 |
47 from optparse import OptionParser | 47 from optparse import OptionParser |
48 from ConfigParser import SafeConfigParser as Parser | 48 from ConfigParser import SafeConfigParser as Parser |
49 from ConfigParser import NoOptionError | 49 from ConfigParser import NoOptionError |
50 import re | 50 import re |
51 from datetime import datetime | 51 from datetime import datetime |
52 from xml.dom import minidom | |
52 | 53 |
53 | 54 |
54 class ParseError(Exception): | 55 class ParseError(Exception): |
55 #Used when the signature parsing is going wrong (invalid signature ?) | 56 #Used when the signature parsing is going wrong (invalid signature ?) |
56 pass | 57 pass |
130 @param name: Name of the function to get | 131 @param name: Name of the function to get |
131 @return: string documentation, or None""" | 132 @return: string documentation, or None""" |
132 if self.bridge_template.has_option(name, "doc"): | 133 if self.bridge_template.has_option(name, "doc"): |
133 return self.bridge_template.get(name, "doc") | 134 return self.bridge_template.get(name, "doc") |
134 return None | 135 return None |
135 | 136 |
136 def getArguments(self, signature, name=None, default=None, unicode_protect=False): | 137 |
137 """Return arguments to user given a signature | 138 def argumentsParser(self, signature): |
138 @param signature: signature in the short form (using s,a,i,b etc) | 139 """Generator which return individual arguments signatures from a global signature""" |
139 @param name: dictionary of arguments name like given by getArguments | 140 start=0 |
140 @param default: dictionary of default values, like given by getDefault | |
141 @param unicode_protect: activate unicode protection on strings (return strings as unicode(str)) | |
142 @return: list of arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3")""" | |
143 i=0 | 141 i=0 |
144 idx=0 | 142 |
145 attr_string=[] | |
146 while i<len(signature): | 143 while i<len(signature): |
147 if signature[i] not in ['b','y','n','i','x','q','u','t','d','s','a']: | 144 if signature[i] not in ['b','y','n','i','x','q','u','t','d','s','a']: |
148 raise ParseError("Unmanaged attribute type [%c]" % signature[i]) | 145 raise ParseError("Unmanaged attribute type [%c]" % signature[i]) |
149 | |
150 attr_string.append(("unicode(%(name)s)%(default)s" if (unicode_protect and signature[i]=='s') else "%(name)s%(default)s") % { | |
151 'name':name[idx][0] if (name and name.has_key(idx)) else "arg_%i" % idx, | |
152 'default':"="+default[idx] if (default and default.has_key(idx)) else '' | |
153 }) #give arg_1, arg2, etc or name1, name2=default, etc. \ | |
154 #give unicode(arg_1), unicode(arg_2), etc. if unicode_protect is set and arg is a string | |
155 idx+=1 | |
156 | 146 |
157 if signature[i] == 'a': | 147 if signature[i] == 'a': |
158 i+=1 | 148 i+=1 |
159 if signature[i]!='{' and signature[i]!='(': #FIXME: must manage tuples out of arrays | 149 if signature[i]!='{' and signature[i]!='(': #FIXME: must manage tuples out of arrays |
160 i+=1 | 150 i+=1 |
151 yield signature[start:i] | |
152 start=i | |
161 continue #we have a simple type for the array | 153 continue #we have a simple type for the array |
162 opening_car = signature[i] | 154 opening_car = signature[i] |
163 assert(opening_car in ['{','(']) | 155 assert(opening_car in ['{','(']) |
164 closing_car = '}' if opening_car == '{' else ')' | 156 closing_car = '}' if opening_car == '{' else ')' |
165 opening_count = 1 | 157 opening_count = 1 |
172 if signature[i] == closing_car: | 164 if signature[i] == closing_car: |
173 opening_count-=1 | 165 opening_count-=1 |
174 if opening_count == 0: | 166 if opening_count == 0: |
175 break | 167 break |
176 i+=1 | 168 i+=1 |
169 yield signature[start:i] | |
170 start=i | |
171 | |
172 def getArguments(self, signature, name=None, default=None, unicode_protect=False): | |
173 """Return arguments to user given a signature | |
174 @param signature: signature in the short form (using s,a,i,b etc) | |
175 @param name: dictionary of arguments name like given by getArguments | |
176 @param default: dictionary of default values, like given by getDefault | |
177 @param unicode_protect: activate unicode protection on strings (return strings as unicode(str)) | |
178 @return: list of arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3")""" | |
179 idx=0 | |
180 attr_string=[] | |
181 | |
182 for arg in self.argumentsParser(signature): | |
183 attr_string.append(("unicode(%(name)s)%(default)s" if (unicode_protect and arg=='s') else "%(name)s%(default)s") % { | |
184 'name':name[idx][0] if (name and name.has_key(idx)) else "arg_%i" % idx, | |
185 'default':"="+default[idx] if (default and default.has_key(idx)) else '' | |
186 }) #give arg_1, arg2, etc or name1, name2=default, etc. \ | |
187 #give unicode(arg_1), unicode(arg_2), etc. if unicode_protect is set and arg is a string | |
188 idx+=1 | |
189 | |
177 return ", ".join(attr_string) | 190 return ", ".join(attr_string) |
178 | 191 |
179 def generateCoreSide(self): | 192 def generateCoreSide(self): |
180 """create the constructor in SàT core side (backend)""" | 193 """create the constructor in SàT core side (backend)""" |
181 raise NotImplementedError | 194 raise NotImplementedError |
460 sys.exit(1) | 473 sys.exit(1) |
461 | 474 |
462 #now we write to final file | 475 #now we write to final file |
463 self.finalWrite(self.frontend_dest, frontend_bridge) | 476 self.finalWrite(self.frontend_dest, frontend_bridge) |
464 | 477 |
478 class DbusXmlConstructor(Constructor): | |
479 """Constructor for DBus XML syntaxt (used by Qt frontend)""" | |
480 | |
481 def __init__(self, bridge_template, options): | |
482 Constructor.__init__(self, bridge_template, options) | |
483 | |
484 self.template="dbus_xml_template.xml" | |
485 self.core_dest="org.goffi.sat.xml" | |
486 | |
487 def generateCoreSide(self): | |
488 try: | |
489 doc = minidom.parse(self.template) | |
490 interface_elt = doc.getElementsByTagName('interface')[0] | |
491 except IOError: | |
492 print ("Can't access template") | |
493 sys.exit(1) | |
494 except IndexError: | |
495 print ("Template error") | |
496 sys.exit(1) | |
497 | |
498 sections = self.bridge_template.sections() | |
499 sections.sort() | |
500 for section in sections: | |
501 function = self.getValues(section) | |
502 print ("Adding %s %s" % (section, function["type"])) | |
503 new_elt = doc.createElement('method' if function["type"]=='method' else 'signal') | |
504 new_elt.setAttribute('name', section) | |
505 args_in_str = self.getArguments(function['sig_in']) | |
506 | |
507 idx=0 | |
508 args_doc = self.getArgumentsDoc(section) | |
509 for arg in self.argumentsParser(function['sig_in'] or ''): | |
510 arg_elt = doc.createElement('arg') | |
511 arg_elt.setAttribute('name', args_doc[idx][0] if args_doc.has_key(idx) else "arg_%i" % idx) | |
512 arg_elt.setAttribute('type', arg) | |
513 arg_elt.setAttribute('direction', 'in' if function["type"]=='method' else 'out') | |
514 new_elt.appendChild(arg_elt) | |
515 idx+=1 | |
516 | |
517 if function['sig_out']: | |
518 arg_elt = doc.createElement('arg') | |
519 arg_elt.setAttribute('type', function['sig_out']) | |
520 arg_elt.setAttribute('direction', 'out') | |
521 new_elt.appendChild(arg_elt) | |
522 | |
523 interface_elt.appendChild(new_elt) | |
524 | |
525 #now we write to final file | |
526 self.finalWrite(self.core_dest, [doc.toprettyxml()]) | |
465 | 527 |
466 class ConstructorError(Exception): | 528 class ConstructorError(Exception): |
467 pass | 529 pass |
468 | 530 |
469 class ConstructorFactory: | 531 class ConstructorFactory: |
470 def create(self, bridge_template, options): | 532 def create(self, bridge_template, options): |
471 if options.protocole=='dbus': | 533 if options.protocole=='dbus': |
472 return DbusConstructor(bridge_template, options) | 534 return DbusConstructor(bridge_template, options) |
473 elif options.protocole=='mediawiki': | 535 elif options.protocole=='mediawiki': |
474 return MediawikiConstructor(bridge_template, options) | 536 return MediawikiConstructor(bridge_template, options) |
537 elif options.protocole=='dbus-xml': | |
538 return DbusXmlConstructor(bridge_template, options) | |
475 | 539 |
476 raise ConstructorError('Unknown constructor type') | 540 raise ConstructorError('Unknown constructor type') |
477 | 541 |
478 class BridgeConstructor: | 542 class BridgeConstructor: |
479 def __init__(self): | 543 def __init__(self): |