def __init__(self, template): if isinstance(template, rdflib.Graph): self._graph = template else: try: self._graph = rdflib.Graph() self._graph.parse(data=template, format='n3') except: if isinstance(template, bytes): doc = etree.fromstring(template) elif isinstance(template, text_type): # Work around: ValueError: Unicode strings with encoding # declaration are not supported. doc = etree.fromstring(template.encode('utf-8')) root_element_qname = etree.QName(doc) if root_element_qname.namespace is None: raise TemplateParseException( "XML document does not contain a valid rdf namespace") if root_element_qname.namespace != RDF_NS: raise TemplateParseException("Invalid namespace: " + root_element_qname.namespace) if root_element_qname.localname != 'RDF': raise TemplateParseException("Invalid root element: " + root_element_qname.localname) self._graph = rdflib.Graph() self._graph.parse(data=template, format='xml')
def _parse_wiring_connection_info(self, wiring_element): connections = [] for connection in self._graph.objects(wiring_element, WIRE_M['hasConnection']): connection_info = { 'readonly': self._get_field(WIRE_M, 'readonly', connection, required=False).lower() == 'true', 'source': {}, 'target': {}, } for source in self._graph.objects(connection, WIRE_M['hasSource']): connection_info['source'] = { 'id': self._get_field(WIRE_M, 'sourceId', source), 'endpoint': self._get_field(WIRE_M, 'endpoint', source), 'type': self._get_field(WIRE, 'type', source), } break else: raise TemplateParseException(_('missing required field: source')) for target in self._graph.objects(connection, WIRE_M['hasTarget']): connection_info['target'] = { 'id': self._get_field(WIRE_M, 'targetId', target), 'endpoint': self._get_field(WIRE_M, 'endpoint', target), 'type': self._get_field(WIRE, 'type', target), } break else: raise TemplateParseException(_('missing required field: target')) connections.append(connection_info) self._info['wiring']['connections'] = connections
def __init__(self, template): self._info = {} self._translation_indexes = {} if isinstance(template, bytes): self._doc = etree.fromstring(template) elif isinstance(template, text_type): # Work around: ValueError: Unicode strings with encoding # declaration are not supported. self._doc = etree.fromstring(template.encode('utf-8')) else: self._doc = template root_element_qname = etree.QName(self._doc) xmlns = root_element_qname.namespace if xmlns is not None and xmlns != WIRECLOUD_TEMPLATE_NS: raise TemplateParseException("Invalid namespace: " + xmlns) if root_element_qname.localname != 'Template': raise TemplateParseException("Invalid root element: " + root_element_qname.localname) self._namespace = xmlns
def _parse_translation_catalogue(self): self._info['translations'] = {} self._info['default_lang'] = 'en' self._info['translation_index_usage'] = {} translations_elements = self._xpath(TRANSLATIONS_XPATH, self._doc) if len(translations_elements) == 0: return missing_translations = [] extra_translations = set() translations = translations_elements[0] self._info['default_lang'] = translations.get('default') for translation in self._xpath(TRANSLATION_XPATH, translations): current_catalogue = {} for msg in self._xpath(MSG_XPATH, translation): if msg.get('name') not in self._translation_indexes: extra_translations.add(msg.get('name')) current_catalogue[msg.get('name')] = msg.text self._info['translations'][translation.get( 'lang')] = current_catalogue if self._info['default_lang'] not in self._info['translations']: raise TemplateParseException( _("ERROR: There isn't a Translation element with the default language (%(default_lang)s) translations" ) % {'default_lang': self._info['default_lang']}) for index in self._translation_indexes: if index not in self._info['translations'][ self._info['default_lang']]: missing_translations.append(index) if len(missing_translations) > 0: msg = _( "ERROR: the following translation indexes need a default value: %(indexes)s." ) raise TemplateParseException( msg % {'indexes': ', '.join(missing_translations)}) if len(extra_translations) > 0: msg = _( "ERROR: the following translation indexes are not used: %(indexes)s." ) raise TemplateParseException( msg % {'indexes': ', '.join(extra_translations)}) self._info['translation_index_usage'] = self._translation_indexes
def _check_integer_fields(self, fields, place=None, required=False, default=0): if place is None: place = self._info for field in fields: if field not in place: if required: raise TemplateParseException('Missing required field: %s' % field) place[field] = default elif not isinstance(place[field], int): raise TemplateParseException('An integer value was expected for the %s field' % field)
def get_resource_info(self): if not is_valid_vendor(self._info['vendor']): raise TemplateParseException(_('The format of the vendor is invalid.')) if not is_valid_name(self._info['name']): raise TemplateParseException(_('The format of the name is invalid.')) if not is_valid_version(self._info['version']): raise TemplateParseException(_('The format of the version number is invalid. Format: X.X.X where X is an integer. Ex. "0.1", "1.11" NOTE: "1.01" should be changed to "1.0.1" or "1.1"')) return dict(self._info)
def _get_translation_field(self, namespace, element, subject, translation_name, required=True, **kwargs): translated = False base_value = None for field_element in self._graph.objects(subject, namespace[element]): if not isinstance(field_element, rdflib.Literal): msg = _('invalid content for field: %(field)s') raise TemplateParseException(msg % {'field': element}) if field_element.language: translated = True if field_element.language not in self._translations: self._translations[text_type(field_element.language)] = {} self._translations[text_type( field_element.language)][translation_name] = text_type( field_element) else: base_value = text_type(field_element) if base_value is not None and translated is True: if 'en' not in self._translations: self._translations['en'] = {} self._translations['en'][translation_name] = base_value if translated is True: self._add_translation_index(translation_name, **kwargs) return '__MSG_' + translation_name + '__' elif base_value is None and required: msg = _('missing required field: %(field)s') raise TemplateParseException(msg % {'field': element}) elif base_value is not None: return base_value else: return ''
def _check_contacts_fields(self, fields, place=None, required=False): if place is None: place = self._info for field in fields: if field not in place: if required: raise TemplateParseException('Missing required field: %s' % field) place[field] = [] elif isinstance(place[field], (str, list, tuple)): place[field] = parse_contacts_info(place[field]) else: raise TemplateParseException('%s field must be a list or string' % field)
def _check_boolean_fields(self, fields, place=None, required=False, default=False): if place is None: place = self._info if not isinstance(fields, (list, tuple)): fields = (fields,) for field in fields: if field not in place: if required: raise TemplateParseException('Missing required field: %s' % field) place[field] = default elif not isinstance(place[field], bool): raise TemplateParseException('A boolean value was expected for the %s field' % field)
def __init__(self, template): self._info = {} self._translation_indexes = {} if isinstance(template, bytes): self._doc = etree.fromstring(template) elif isinstance(template, text_type): # Work around: ValueError: Unicode strings with encoding # declaration are not supported. self._doc = etree.fromstring(template.encode('utf-8')) else: self._doc = template root_element_qname = etree.QName(self._doc) xmlns = root_element_qname.namespace if xmlns is None: raise ValueError("Missing document namespace") elif xmlns in OLD_TEMPLATE_NAMESPACES: raise ObsoleteFormatError() elif xmlns != WIRECLOUD_TEMPLATE_NS: raise ValueError("Invalid namespace: " + xmlns) if root_element_qname.localname not in ('widget', 'operator', 'mashup'): raise TemplateParseException("Invalid root element (%s)" % root_element_qname.localname) self._info['type'] = root_element_qname.localname
def _parse_wiring_connection_info(self, wiring_element): connections = [] for connection in self._xpath(CONNECTION_XPATH, wiring_element): if len(self._xpath(SOURCE_XPATH, connection)) > 0: source_element = self._xpath(SOURCE_XPATH, connection)[0] else: raise TemplateParseException( _('Missing required field: source')) if len(self._xpath(SOURCE_XPATH, connection)) > 0: target_element = self._xpath(TARGET_XPATH, connection)[0] else: raise TemplateParseException( _('Missing required field: target')) source_type = source_element.get('type') target_type = target_element.get('type') connection_info = { 'readonly': connection.get('readonly', 'false').lower() == 'true', 'source': { 'type': source_type[1:] if source_type in ['iwidget', 'ioperator'] else source_type, 'endpoint': source_element.get('endpoint'), 'id': source_element.get('id'), }, 'target': { 'type': target_type[1:] if target_type in ['iwidget', 'ioperator'] else target_type, 'endpoint': target_element.get('endpoint'), 'id': target_element.get('id'), } } connections.append(connection_info) self._info['wiring']['connections'] = connections
def get_xpath(self, query, element): elements = self._xpath(query, element) if len(elements) == 0: raise TemplateParseException('Missing %s element' % query.replace('t:', '')) else: return elements[0]
def _check_string_fields(self, fields, place=None, required=False, default='', null=False): if place is None: place = self._info if not isinstance(fields, (list, tuple)): fields = (fields,) for field in fields: if field not in place: if required: raise TemplateParseException('Missing required field: %s' % field) place[field] = default elif not isinstance(place[field], str): if null is True and place[field] is None: continue raise TemplateParseException('A string value was expected for the %s field' % field)
def _init(self): try: XMLSCHEMA.assertValid(self._doc) except Exception as e: raise TemplateParseException('%s' % e) self._component_description = self._xpath(RESOURCE_DESCRIPTION_XPATH, self._doc)[0] self._parse_basic_info()
def __init__(self, template, base=None): self.base = base if isinstance(template, text_type): self._info = json.loads(template) elif isinstance(template, bytes): self._info = json.loads(template.decode('utf8')) elif isinstance(template, dict): self._info = template else: raise TemplateParseException('Invalid input data') if 'type' not in self._info: raise TemplateParseException(_('Missing resource type.')) if self._info['type'] not in ('widget', 'operator', 'mashup'): raise TemplateParseException( _('Invalid resource type: %s') % self._info['type'])
def get_xpath(self, query, element, required=True): elements = self._xpath(query, element) if len(elements) == 0 and required: raise TemplateParseException('Missing %s element' % query.replace('t:', '')) elif len(elements) > 0: return elements[0] else: return None
def _get_field(self, xpath, element, required=True): elements = self._xpath(xpath, element) if len(elements) == 1 and elements[0].text and len(elements[0].text.strip()) > 0: return text_type(elements[0].text) elif not required: return '' else: msg = _('missing required field: %(field)s') raise TemplateParseException(msg % {'field': xpath})
def _check_contents_field(self, data, alternative=True): if isinstance(data, dict): self._check_string_fields(('src',), place=data, required=True) self._check_string_fields(('contenttype',), place=data, default='text/html') self._check_string_fields(('charset',), place=data, default='utf-8') if alternative is True: self._check_string_fields(('scope',), place=data, required=True) else: self._check_boolean_fields(('cacheable',), place=data, default=True) self._check_boolean_fields(('useplatformstyle',), place=data, default=False) else: raise TemplateParseException('contents info must be an object')
def _parse_wiring_connections(self, element, behaviour): behaviour['connections'] = [] for connection in self._graph.objects(element, WIRE_M['hasConnectionView']): connection_info = {} for source in self._graph.objects(connection, WIRE_M['hasSourceEndpoint']): connection_info['sourcename'] = self._join_endpoint_name( source) break else: raise TemplateParseException( _('missing required field: hasSourceEndpoint')) connection_info['sourcehandle'] = self._parse_position( connection, relation_name='hasSourceHandlePosition', default="auto") for target in self._graph.objects(connection, WIRE_M['hasTargetEndpoint']): connection_info['targetname'] = self._join_endpoint_name( target) break else: raise TemplateParseException( _('missing required field: hasTargetEndpoint')) connection_info['targethandle'] = self._parse_position( connection, relation_name='hasTargetHandlePosition', default="auto") behaviour['connections'].append(connection_info)
def __init__(self, template, base=None): self.base = base for parser in self.parsers: try: self._parser = parser(template) break except: pass if self._parser is None: raise TemplateParseException('No valid parser found') self._parser._init()
def _parse_requirements(self): self._info['requirements'] = [] requirements_elements = self._xpath(REQUIREMENTS_XPATH, self._resource_description) if len(requirements_elements) < 1: return for requirement in self._xpath(FEATURE_XPATH, requirements_elements[0]): if requirement.get('name', '').strip() == '': raise TemplateParseException('Missing required feature name') self._info['requirements'].append({ 'type': 'feature', 'name': requirement.get('name') })
def _get_field(self, namespace, element, subject, required=True, id_=False, default=''): fields = self._graph.objects(subject, namespace[element]) for field_element in fields: if not id_: result = text_type(field_element) break else: result = field_element break else: if required: msg = _('missing required field: %(field)s') raise TemplateParseException(msg % {'field': element}) else: result = default return result
def _init(self): self._info = {} self._translation_indexes = {} self._translations = {} # check if is a mashup, a widget or an operator for type_ in self._graph.subjects(RDF['type'], WIRE['Widget']): self._info['type'] = 'widget' break else: for t in self._graph.subjects(RDF['type'], WIRE['Operator']): self._info['type'] = 'operator' break else: for t in self._graph.subjects(RDF['type'], WIRE_M['Mashup']): self._info['type'] = 'mashup' break else: raise TemplateParseException('RDF document does not describe a widget, operator or mashup component') self._parse_basic_info()
def _parse_basic_info(self): self._info['translations'] = {} # ------------------------------------------ if self._info['type'] == 'widget': self._rootURI = next(self._graph.subjects(RDF['type'], WIRE['Widget'])) elif self._info['type'] == 'mashup': self._rootURI = next(self._graph.subjects(RDF['type'], WIRE_M['Mashup'])) elif self._info['type'] == 'operator': self._rootURI = next(self._graph.subjects(RDF['type'], WIRE['Operator'])) vendor = self._get_field(USDL, 'hasProvider', self._rootURI, id_=True) self._info['vendor'] = self._get_field(FOAF, 'name', vendor) if not is_valid_vendor(self._info['vendor']): raise TemplateParseException(_('The format of the vendor is invalid.')) self._info['name'] = self._get_field(DCTERMS, 'title', self._rootURI) if not is_valid_name(self._info['name']): raise TemplateParseException(_('The format of the name is invalid.')) self._info['version'] = self._get_field(USDL, 'versionInfo', self._rootURI) if not is_valid_version(self._info['version']): raise TemplateParseException(_('The format of the version number is invalid. Format: X.X.X where X is an integer. Ex. "0.1", "1.11" NOTE: "1.01" should be changed to "1.0.1" or "1.1"')) license = self._get_field(DCTERMS, 'license', self._rootURI, required=False, default=None, id_=True) if license is not None: self._info['licenseurl'] = text_type(license) self._info['license'] = self._get_field(RDFS, 'label', license, required=False) else: self._info['licenseurl'] = '' self._info['license'] = '' longdescription = self._get_field(DCTERMS, 'description', self._rootURI, id_=True, required=False) if longdescription != '' and isinstance(longdescription, rdflib.Literal): # Old and deprecated behaviour self._info['description'] = self._get_translation_field(DCTERMS, 'description', self._rootURI, 'description', required=False, type='resource', field='description') self._info['longdescription'] = '' else: self._info['longdescription'] = '%s' % longdescription self._info['description'] = self._get_translation_field(DCTERMS, 'abstract', self._rootURI, 'description', required=False, type='resource', field='description') self._info['authors'] = self._parse_people_field(DCTERMS, 'creator', self._rootURI) self._info['contributors'] = self._parse_people_field(DCTERMS, 'contributor', self._rootURI) self._info['image'] = self._get_field(WIRE, 'hasImageUri', self._rootURI, required=False) self._info['smartphoneimage'] = self._get_field(WIRE, 'hasiPhoneImageUri', self._rootURI, required=False) self._info['changelog'] = self._get_field(WIRE, 'hasChangeLog', self._rootURI, required=False) self._info['homepage'] = self._get_field(FOAF, 'homepage', self._rootURI, required=False) self._info['issuetracker'] = self._get_field(DOAP, 'bug-database', self._rootURI, required=False) self._info['doc'] = self._get_field(FOAF, 'page', self._rootURI, required=False) self._info['title'] = self._get_translation_field(WIRE, 'displayName', self._rootURI, 'title', required=False, type='resource', field='title') self._info['email'] = '' addr_element = self._get_field(VCARD, 'addr', self._rootURI, id_=True, default=None, required=False) if addr_element is not None: self._info['email'] = self._get_field(VCARD, 'email', addr_element, required=False) self._parse_requirements()
def _parse_widget_info(self): self._info['preferences'] = [] for preference in self._xpath(PREFERENCES_XPATH, self._doc): self._add_translation_index(preference.get('label'), type='vdef', variable=preference.get('name'), field='label') self._add_translation_index(preference.get('description', ''), type='vdef', variable=preference.get('name'), field='description') preference_info = { 'name': preference.get('name'), 'type': preference.get('type'), 'label': preference.get('label', ''), 'description': preference.get('description', ''), 'readonly': preference.get('readonly', 'false').lower() == 'true', 'default': preference.get('default', ''), 'value': preference.get('value'), 'secure': preference.get('secure', 'false').lower() == 'true', } if preference_info['type'] == 'list': preference_info['options'] = [] for option_index, option in enumerate( self._xpath(OPTION_XPATH, preference)): option_label = option.get('label', option.get('name')) self._add_translation_index( option_label, type='upo', variable=preference.get('name'), option=option_index) preference_info['options'].append({ 'label': option_label, 'value': option.get('value'), }) self._info['preferences'].append(preference_info) self._info['properties'] = [] for prop in self._xpath(PROPERTY_XPATH, self._doc): self._add_translation_index(prop.get('label'), type='vdef', variable=prop.get('name')) self._add_translation_index(prop.get('description', ''), type='vdef', variable=prop.get('name')) self._info['properties'].append({ 'name': prop.get('name'), 'type': prop.get('type'), 'label': prop.get('label'), 'description': prop.get('description', ''), 'default': prop.get('default', ''), 'secure': prop.get('secure', 'false').lower() == 'true', }) self._parse_wiring_info() xhtml_elements = self._xpath(CODE_XPATH, self._doc) if len(xhtml_elements) == 1 and xhtml_elements[0].get('href', '') != '': xhtml_element = xhtml_elements[0] else: msg = _('missing required attribute in Platform.Link: href') raise TemplateParseException(msg) self._info['contents'] = { 'src': xhtml_element.get('href'), 'contenttype': xhtml_element.get('content-type', 'text/html'), 'charset': xhtml_element.get('charset', 'utf-8'), 'useplatformstyle': xhtml_element.get('use-platform-style', 'false').lower() == 'true', 'cacheable': xhtml_element.get('cacheable', 'true').lower() == 'true' } self._info['altcontents'] = [] for altcontents_element in self._xpath(ALTCONTENT_XPATH, self._doc): self._info['altcontents'].append({ 'scope': altcontents_element.get('scope'), 'src': altcontents_element.get('href'), 'contenttype': altcontents_element.get('content-type', 'text/html'), 'charset': altcontents_element.get('charset', 'utf-8') }) rendering_element = self.get_xpath(PLATFORM_RENDERING_XPATH, self._doc) self._info['widget_width'] = rendering_element.get('width') self._info['widget_height'] = rendering_element.get('height')
def _parse_basic_info(self): self._info['vendor'] = self._get_field( VENDOR_XPATH, self._resource_description).strip() if not is_valid_vendor(self._info['vendor']): raise TemplateParseException( _('The format of the vendor is invalid.')) self._info['name'] = self._get_field( NAME_XPATH, self._resource_description).strip() if not is_valid_name(self._info['name']): raise TemplateParseException( _('The format of the name is invalid.')) self._info['version'] = self._get_field( VERSION_XPATH, self._resource_description).strip() if not is_valid_version(self._info['version']): raise TemplateParseException( _('ERROR: the format of the version number is invalid. Format: X.X.X where X is an integer. Ex. "0.1", "1.11" NOTE: "1.01" should be changed to "1.0.1" or "1.1"' )) self._info['title'] = self._get_field(DISPLAY_NAME_XPATH, self._resource_description, required=False) self._add_translation_index(self._info['title'], type='resource', field='title') self._info['description'] = self._get_field(DESCRIPTION_XPATH, self._resource_description, required=False) self._add_translation_index(self._info['description'], type='resource', field='description') self._info['longdescription'] = self._get_field( LONG_DESCRIPTION_XPATH, self._resource_description, required=False) self._info['authors'] = parse_contacts_info( self._get_field(AUTHOR_XPATH, self._resource_description, required=False)) self._info['contributors'] = parse_contacts_info( self._get_field(CONTRIBUTORS_XPATH, self._resource_description, required=False)) self._info['email'] = self._get_field(MAIL_XPATH, self._resource_description, required=False) self._info['image'] = self._get_field(IMAGE_URI_XPATH, self._resource_description, required=False) self._info['smartphoneimage'] = self._get_field( IPHONE_IMAGE_URI_XPATH, self._resource_description, required=False) self._info['homepage'] = self._get_field(HOMEPAGE_URI_XPATH, self._resource_description, required=False) self._info['doc'] = self._get_field(DOC_URI_XPATH, self._resource_description, required=False) self._info['license'] = self._get_field(LICENCE_XPATH, self._resource_description, required=False) self._info['licenseurl'] = self._get_field(LICENCE_URL_XPATH, self._resource_description, required=False) self._info['issuetracker'] = self._get_field( ISSUETRACKER_XPATH, self._resource_description, required=False) self._info['changelog'] = self._get_field(CHANGE_LOG_XPATH, self._resource_description, required=False) self._parse_requirements()
def _init(self): self._check_string_fields( ('title', 'description', 'longdescription', 'email', 'homepage', 'doc', 'changelog', 'image', 'smartphoneimage', 'license', 'licenseurl', 'issuetracker')) self._check_contacts_fields(('authors', 'contributors')) # Normalize/check preferences and properties (only for widgets and operators) if self._info['type'] != 'mashup': self._check_array_fields(('preferences', 'properties')) for preference in self._info['preferences']: self._check_string_fields(('name', 'type'), place=preference, required=True) self._check_string_fields(('label', 'description', 'default'), place=preference) self._check_boolean_fields(('readonly', 'secure'), place=preference, default=False) self._check_string_fields(('value', ), place=preference, null=True, default=None) for prop in self._info['properties']: self._check_string_fields(('name', 'type'), place=prop, required=True) self._check_string_fields(('label', 'description', 'default'), place=prop) self._check_boolean_fields(('secure', ), place=prop, default=False) if self._info['type'] == 'widget': self._check_array_fields(('altcontents', )) if self._info.get('contents', None) is None: raise TemplateParseException('Missing widget content info') if not isinstance(self._info['contents'], dict): raise TemplateParseException('Content info must be an object') self._check_contents_field(self._info['contents'], alternative=False) for altcontent in self._info['altcontents']: self._check_contents_field(altcontent) elif self._info['type'] == 'mashup': self._check_array_fields(('params', 'embedded')) for resource in self._info['embedded']: if isinstance(resource, dict): self._check_string_fields( ('vendor', 'name', 'version', 'src'), place=resource, required=True) else: raise TemplateParseException( 'embedded resource info must be an object') if 'wiring' not in self._info: self._info['wiring'] = get_wiring_skeleton() self._check_string_fields(('version', ), place=self._info['wiring'], default='1.0') if self._info['wiring']['version'] == '1.0': # TODO: update to the new wiring format inputs = self._info['wiring']['inputs'] outputs = self._info['wiring']['outputs'] self._info['wiring'] = parse_wiring_old_version( self._info['wiring']) self._info['wiring']['inputs'] = inputs self._info['wiring']['outputs'] = outputs # END TODO elif self._info['wiring']['version'] == '2.0': if 'visualdescription' not in self._info['wiring']: self._info['wiring']['visualdescription'] = {} self._check_array_fields( 'behaviours', place=self._info['wiring']['visualdescription'], required=False) self._check_behaviour_view_fields( self._info['wiring']['visualdescription']) for behaviour in self._info['wiring']['visualdescription'][ 'behaviours']: self._check_behaviour_view_fields(behaviour) if not 'wiring' in self._info: self._info['wiring'] = {} self._check_array_fields(('inputs', 'outputs'), place=self._info['wiring'], required=False) # Translations self._check_string_fields(('default_lang', ), default='en') self._info['translation_index_usage'] = {} if 'translations' not in self._info: self._info['translations'] = {} self._add_translation_index(self._info['title'], type='resource', field='title') self._add_translation_index(self._info['description'], type='resource', field='description') if self._info['type'] != 'mashup': for preference in self._info['preferences']: self._add_translation_index(preference['label'], type='vdef', variable=preference['name'], field='label') self._add_translation_index(preference['description'], type='vdef', variable=preference['name'], field='description') if preference['type'] == 'list': for option_index, option in enumerate( preference['options']): self._add_translation_index( option['label'], type='upo', variable=preference['name'], option=option_index) for prop in self._info['properties']: self._add_translation_index(prop['label'], type='vdef', variable=prop['name'], field='label') self._add_translation_index(prop['description'], type='vdef', variable=prop['name'], field='description') for input_endpoint in self._info['wiring']['inputs']: self._check_string_fields(('name', 'type'), required=True, place=input_endpoint) self._check_string_fields( ('label', 'description', 'actionlabel', 'friendcode'), place=input_endpoint) self._add_translation_index(input_endpoint['label'], type='inputendpoint', variable=input_endpoint['name'], field='label') self._add_translation_index(input_endpoint['description'], type='inputendpoint', variable=input_endpoint['name'], field='description') self._add_translation_index(input_endpoint['actionlabel'], type='inputendpoint', variable=input_endpoint['name'], field='actionlabel') for output_endpoint in self._info['wiring']['outputs']: self._check_string_fields(('name', 'type'), required=True, place=output_endpoint) self._check_string_fields( ('label', 'description', 'friendcode'), place=output_endpoint) self._add_translation_index(output_endpoint['label'], type='outputendpoint', variable=output_endpoint['name'], field='label') self._add_translation_index(output_endpoint['description'], type='outputendpoint', variable=output_endpoint['name'], field='description') # Requirements self._check_array_fields(('requirements', ))
def _parse_widget_info(self): # Preference info self._info['preferences'] = [] # Platform preferences must be sorted sorted_preferences = sorted(self._graph.objects(self._rootURI, WIRE['hasPlatformPreference']), key=lambda pref: possible_int(self._get_field(WIRE, 'index', pref, required=False))) for preference in sorted_preferences: var_name = self._get_field(DCTERMS, 'title', preference, required=True) preference_info = { 'name': var_name, 'type': self._get_field(WIRE, 'type', preference, required=False), 'label': self._get_translation_field(RDFS, 'label', preference, var_name + '_label', required=False, type='vdef', variable=var_name, field='label'), 'description': self._get_translation_field(DCTERMS, 'description', preference, var_name + '_description', required=False, type='vdef', variable=var_name, field='description'), 'readonly': self._get_field(WIRE, 'readonly', preference, required=False).lower() == 'true', 'default': self._get_field(WIRE, 'default', preference, required=False), 'value': self._get_field(WIRE, 'value', preference, required=False, default=None), 'secure': self._get_field(WIRE, 'secure', preference, required=False).lower() == 'true', } if preference_info['type'] == 'list': preference_info['options'] = [] sorted_options = sorted(self._graph.objects(preference, WIRE['hasOption']), key=lambda option: possible_int(self._get_field(WIRE, 'index', option, required=False))) for option_index, option in enumerate(sorted_options): preference_info['options'].append({ 'label': self._get_translation_field(DCTERMS, 'title', option, var_name + '_option' + str(option_index) + '_label', required=False, type='upo', variable=preference_info['name'], option=option_index), 'value': self._get_field(WIRE, 'value', option, required=False), }) self._info['preferences'].append(preference_info) # State properties info self._info['properties'] = [] sorted_properties = sorted(self._graph.objects(self._rootURI, WIRE['hasPlatformStateProperty']), key=lambda prop: possible_int(self._get_field(WIRE, 'index', prop, required=False))) for prop in sorted_properties: var_name = self._get_field(DCTERMS, 'title', prop, required=True) self._info['properties'].append({ 'name': var_name, 'type': self._get_field(WIRE, 'type', prop, required=False), 'label': self._get_translation_field(RDFS, 'label', prop, var_name + '_label', required=False, type='vdef', variable=var_name, field='label'), 'description': self._get_translation_field(DCTERMS, 'description', prop, var_name + '_description', required=False, type='vdef', variable=var_name, field='description'), 'default': self._get_field(WIRE, 'default', prop, required=False), 'secure': self._get_field(WIRE, 'secure', prop, required=False).lower() == 'true', }) self._parse_wiring_info() if self._info['type'] == 'widget': # It contains the widget code self._info['altcontents'] = [] sorted_contents = sorted(self._graph.objects(self._rootURI, USDL['utilizedResource']), key=lambda contents: possible_int(self._get_field(WIRE, 'index', contents, required=False))) for contents_node in sorted_contents: contents_info = { 'src': text_type(contents_node), } contents_info['scope'] = self._get_field(WIRE, 'contentsScope', contents_node, required=False) contents_info['contenttype'] = 'text/html' contents_info['charset'] = 'utf-8' contents_format = self._get_field(DCTERMS, 'format', contents_node, required=False) if contents_format.strip() != '': try: contenttype, parameters = parse_mime_type(contents_format) except: raise TemplateParseException('Invalid code content type: %s' % contents_format) contents_info['contenttype'] = contenttype if 'charset' in parameters: contents_info['charset'] = parameters['charset'].lower() del parameters['charset'] if len(parameters) > 0: raise TemplateParseException('Invalid code content type: %s' % contents_format) if contents_info['scope'] == '': del contents_info['scope'] contents_info['useplatformstyle'] = self._get_field(WIRE, 'usePlatformStyle', contents_node, required=False).lower() == 'true' contents_info['cacheable'] = self._get_field(WIRE, 'codeCacheable', contents_node, required=False, default='true').lower() == 'true' self._info['contents'] = contents_info else: self._info['altcontents'].append(contents_info) rendering_element = self._get_field(WIRE, 'hasPlatformRendering', self._rootURI, id_=True, required=False) self._info['widget_width'] = self._get_field(WIRE, 'renderingWidth', rendering_element, required=False) self._info['widget_height'] = self._get_field(WIRE, 'renderingHeight', rendering_element, required=False) elif self._info['type'] == 'operator': # The tamplate has 1-n javascript elements # Javascript files must be sorted sorted_js_files = sorted(self._graph.objects(self._rootURI, USDL['utilizedResource']), key=lambda js_file: possible_int(self._get_field(WIRE, 'index', js_file, required=True))) self._info['js_files'] = [] for js_element in sorted_js_files: self._info['js_files'].append(text_type(js_element)) if not len(self._info['js_files']) > 0: raise TemplateParseException(_('Missing required field: Javascript files'))