Beispiel #1
0
 def get_collection_schema_from_interface_schema(self, schema):
     collection = {}
     for name in schema:
         if IDate.providedBy(schema[name]) or \
                                             IDatetime.providedBy(schema[name]):
             collection['field.'+name] = 'time'
         elif IDecimal.providedBy(schema[name]) or \
                             IFloat.providedBy(schema[name]) or \
                                            IInt.providedBy(schema[name]):
             collection['field.'+name] = 'number'
         elif IBool.providedBy(schema[name]):
             collection['field.'+name] = 'bool'
         elif ICollection.providedBy(schema[name]):
             if not ICollection.providedBy(schema[name].value_type) and not \
                         IDict.providedBy(schema[name].value_type):
                 collection['field.'+name] = 'array'
         elif IDict.providedBy(schema[name]):
             if IText.providedBy(schema[name].key_type) and \
                         IText.providedBy(schema[name].value_type):
                 collection['field.'+name] = 'array'
         # this is a pretty weak check for a IP address field.  We might want
         # to update this to look for a field validator based on the ipaddress package
         # or mark this field with a special interface indicating it is an 
         # IP address
         elif IDottedName.providedBy(schema[name]) and \
                         (schema[name].min_dots == schema[name].max_dots == 3):
             collection['field.'+name] = 'cidr'
         elif IText.providedBy(schema[name]) or \
                                     INativeString.providedBy(schema[name]):
             collection['field.'+name] = 'string'
     return collection
Beispiel #2
0
def valueToElement(field, value, name=None, force=False):
    """Create and return an element that describes the given value, which is
    assumed to be valid for the given field.

    If name is given, this will be used as the new element name. Otherwise,
    the field's __name__ attribute is consulted.

    If force is True, the value will always be written. Otherwise, it is only
    written if it is not equal to field.missing_value.
    """

    if name is None:
        name = field.__name__

    child = etree.Element(name)

    if value is not None and (force or value != field.missing_value):

        if IDict.providedBy(field):
            key_converter = IToUnicode(field.key_type)
            for k, v in value.items():
                list_element = valueToElement(field.value_type, v, 'element', force)
                list_element.attrib['key'] = key_converter.toUnicode(k)
                child.append(list_element)

        elif ICollection.providedBy(field):
            for v in value:
                list_element = valueToElement(field.value_type, v, 'element', force)
                child.append(list_element)

        else:
            converter = IToUnicode(field)
            child.text = converter.toUnicode(value)

    return child
Beispiel #3
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """
    value = default

    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = OrderedDict()
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)

            key_text = child.attrib.get('key', None)
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(unicode(key_text))

            value[k] = elementToValue(field.value_type, child)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)
            v = elementToValue(field.value_type, child)
            value.append(v)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            value = converter.fromUnicode(unicode(text))

        # handle i18n
        if isinstance(value, unicode) and parseinfo.i18n_domain is not None:
            translate_attr = ns('translate', I18N_NAMESPACE)
            domain_attr = ns('domain', I18N_NAMESPACE)
            msgid = element.attrib.get(translate_attr)
            domain = element.attrib.get(domain_attr, parseinfo.i18n_domain)
            if msgid:
                value = Message(msgid, domain=domain, default=value)
            elif translate_attr in element.attrib:
                value = Message(value, domain=domain)

    return value
Beispiel #4
0
def valueToElement(field, value, name=None, force=False):
    """Create and return an element that describes the given value, which is
    assumed to be valid for the given field.

    If name is given, this will be used as the new element name. Otherwise,
    the field's __name__ attribute is consulted.

    If force is True, the value will always be written. Otherwise, it is only
    written if it is not equal to field.missing_value.
    """

    if name is None:
        name = field.__name__

    child = etree.Element(name)

    if value is not None and (force or value != field.missing_value):

        if IDict.providedBy(field):
            key_converter = IToUnicode(field.key_type)
            for k, v in sorted(value.items()):
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                list_element.attrib['key'] = key_converter.toUnicode(k)
                child.append(list_element)

        elif ICollection.providedBy(field):
            if ISet.providedBy(field):
                # Serliazation should be consistent even if value was not really a set
                value = sorted(value)
            for v in value:
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                child.append(list_element)

        else:
            converter = IToUnicode(field)
            child.text = converter.toUnicode(value)

            # handle i18n
            if isinstance(value, Message):
                child.set(ns('domain', I18N_NAMESPACE), value.domain)
                if not value.default:
                    child.set(ns('translate', I18N_NAMESPACE), '')
                else:
                    child.set(ns('translate', I18N_NAMESPACE), child.text)
                    child.text = converter.toUnicode(value.default)

    return child
Beispiel #5
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """

    value = default

    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = {}
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue

            key_text = child.attrib.get('key', None)
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(unicode(key_text))

            value[k] = elementToValue(field.value_type, child)
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue
            v = elementToValue(field.value_type, child)
            value.append(v)
        value = fieldTypecast(field, value)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            value = converter.fromUnicode(unicode(text))

    return value
Beispiel #6
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """

    value = default

    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = {}
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue

            key_text = child.attrib.get('key', None)
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(unicode(key_text))

            value[k] = elementToValue(field.value_type, child)
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue
            v = elementToValue(field.value_type, child)
            value.append(v)
        value = fieldTypecast(field, value)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            value = converter.fromUnicode(unicode(text))

    return value
Beispiel #7
0
def valueToElement(field, value, name=None, force=False):
    """Create and return an element that describes the given value, which is
    assumed to be valid for the given field.

    If name is given, this will be used as the new element name. Otherwise,
    the field's __name__ attribute is consulted.

    If force is True, the value will always be written. Otherwise, it is only
    written if it is not equal to field.missing_value.
    """

    if name is None:
        name = field.__name__

    child = ElementTree.Element(name)

    if value is not None and (force or value != field.missing_value):

        if IDict.providedBy(field):
            key_converter = IToUnicode(field.key_type)
            for k, v in value.items():
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                list_element.attrib['key'] = key_converter.toUnicode(k)
                child.append(list_element)

        elif ICollection.providedBy(field):
            for v in value:
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                child.append(list_element)

        else:
            converter = IToUnicode(field)
            child.text = converter.toUnicode(value)

    return child
Beispiel #8
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """
    value = default
    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = OrderedDict()
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)

            key_text = child.attrib.get('key')
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(six.text_type(key_text))

            value[k] = elementToValue(field.value_type, child)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)
            v = elementToValue(field.value_type, child)
            value.append(v)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    elif IChoice.providedBy(field):
        vocabulary = None
        try:
            vcf = getUtility(IVocabularyFactory, field.vocabularyName)
            vocabulary = vcf(None)
        except:
            pass

        if vocabulary and hasattr(vocabulary, 'by_value'):
            try:
                field._type = type(list(vocabulary.by_value.keys())[0])
            except:
                pass

        value = fieldTypecast(field, element.text)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            if isinstance(text, six.binary_type):
                text = text.decode()
            else:
                text = six.text_type(text)
            value = converter.fromUnicode(text)

        # handle i18n
        if isinstance(value, six.string_types) and \
                parseinfo.i18n_domain is not None:
            translate_attr = ns('translate', I18N_NAMESPACE)
            domain_attr = ns('domain', I18N_NAMESPACE)
            msgid = element.attrib.get(translate_attr)
            domain = element.attrib.get(domain_attr, parseinfo.i18n_domain)
            if msgid:
                value = Message(msgid, domain=domain, default=value)
            elif translate_attr in element.attrib:
                value = Message(value, domain=domain)

    return value
Beispiel #9
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """
    value = default
    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = OrderedDict()
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)

            key_text = child.attrib.get('key')
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(six.text_type(key_text))

            value[k] = elementToValue(field.value_type, child)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)
            v = elementToValue(field.value_type, child)
            value.append(v)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    elif IChoice.providedBy(field):
        vocabulary = None
        try:
            vcf = getUtility(IVocabularyFactory, field.vocabularyName)
            vocabulary = vcf(None)
        except:
            pass

        if vocabulary and hasattr(vocabulary, 'by_value'):
            try:
                field._type = type(list(vocabulary.by_value.keys())[0])
            except:
                pass

        value = fieldTypecast(field, element.text)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            if isinstance(text, six.binary_type):
                text = text.decode()
            else:
                text = six.text_type(text)
            value = converter.fromUnicode(text)

        # handle i18n
        if isinstance(value, six.string_types) and \
                parseinfo.i18n_domain is not None:
            translate_attr = ns('translate', I18N_NAMESPACE)
            domain_attr = ns('domain', I18N_NAMESPACE)
            msgid = element.attrib.get(translate_attr)
            domain = element.attrib.get(domain_attr, parseinfo.i18n_domain)
            if msgid:
                value = Message(msgid, domain=domain, default=value)
            elif translate_attr in element.attrib:
                value = Message(value, domain=domain)

    return value