Exemplo n.º 1
0
    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')
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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 ''
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
    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
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
    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]
Exemplo n.º 13
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)
Exemplo n.º 14
0
    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()
Exemplo n.º 15
0
    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'])
Exemplo n.º 16
0
    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
Exemplo n.º 17
0
    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})
Exemplo n.º 18
0
    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')
Exemplo n.º 19
0
    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)
Exemplo n.º 20
0
    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()
Exemplo n.º 21
0
    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')
            })
Exemplo n.º 22
0
    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
Exemplo n.º 23
0
    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()
Exemplo n.º 24
0
    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()
Exemplo n.º 25
0
    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')
Exemplo n.º 26
0
    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()
Exemplo n.º 27
0
    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', ))
Exemplo n.º 28
0
    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'))