Ejemplo n.º 1
0
    def _validate_fields(self, raw_data):
        errors = []
        for name, field, schema in self.fields:
            if name not in raw_data:
                continue

            field = field.bind(self.obj or self.model)

            raw_value = raw_data.pop(name)

            if isinstance(raw_value, str):
                raw_value = raw_value.decode('utf8')

            # We don't want to accidentally swallow any adaptation TypeErrors from here:
            from_unicode = IFromUnicode(field)

            try:
                if raw_value in (None, u'', '') and field.required:
                    raise RequiredMissing(name)

                try:
                    value = from_unicode.fromUnicode(raw_value)
                except (ValueError, TypeError):
                    raise WrongType(name)
            # TODO: make this more descriptive as to which validation failed,
            # where was it defined etc.
            except zope.schema.ValidationError as exc:
                errors.append((name, exc))
            else:
                setattr(self.adapted_tmp_obj(self.tmp_obj, schema), name, value)
        return errors
Ejemplo n.º 2
0
    def fromUnicode(self, value):
        if self.context.value_type:
            value_converter = IFromUnicode(self.context.value_type)
            from_unicode = lambda x: value_converter.fromUnicode(x)
        else:
            from_unicode = lambda x: x

        if isinstance(value, basestring):
            value = [from_unicode(unicode(i.strip())) for i in value.strip(', ').split(',')]
        return self.context._type(value)
Ejemplo n.º 3
0
    def __call__(self, value):
        if isinstance(value, str):
            value = IFromUnicode(self.field).fromUnicode(value)

        # Mimic what z3c.form does in it's BaseDataConverter.
        if isinstance(value, str):
            value = value.strip()
            if value == "":
                value = self.field.missing_value

        self.field.validate(value)
        return value
Ejemplo n.º 4
0
    def updateWidgets(self):
        config = _load_config(self.request.get("form.widgets.config"))
        section = None
        for section_id in config.keys():
            tmp = config[section_id]
            if tmp.get("blueprint", "") in SOURCE_SECTIONS:
                section = tmp
                break
        if not section:
            raise Exception("Source section not found.")

        # Omit some fields depending on the selected source
        if section["blueprint"] == "collective.jsonmigrator.catalogsource":
            self.fields = self.fields.omit("remote_path", "remote_crawl_depth", "remote_skip_path")
        elif section["blueprint"] == "collective.jsonmigrator.remotesource":
            self.fields = self.fields.omit("catalog_path", "catalog_query")

        # Fill in default values from the transmogrifier config file
        for option, value in section.items():
            field = self.fields.get(option.replace("-", "_"))
            if field:
                field = field.field
                value = value.decode("utf8")
                if IFromUnicode.providedBy(field):
                    field.default = field.fromUnicode(value)
                elif IList.providedBy(field):
                    field.default = [field.value_type.fromUnicode(v) for v in value.split()]

        super(JSONMigratorRun, self).updateWidgets()
        self.widgets["config"].mode = interfaces.HIDDEN_MODE
Ejemplo n.º 5
0
def migrate_saved_data(ploneformgen, easyform):
    for data_adapter in ploneformgen.objectValues('FormSaveDataAdapter'):
        actions = get_actions(easyform)
        action = actions.get(data_adapter.getId())
        schema = get_schema(easyform)
        if ISaveData.providedBy(action):
            cols = data_adapter.getColumnNames()
            for idx, row in enumerate(data_adapter.getSavedFormInput()):
                if len(row) != len(cols):
                    logger.warning(
                        'Number of columns does not match. Skipping row %s in '
                        'data adapter %s/%s', idx,
                        '/'.join(easyform.getPhysicalPath()),
                        data_adapter.getId())
                    continue
                data = {}
                for key, value in zip(cols, row):
                    field = schema.get(key)
                    value = value.decode('utf8')
                    if IFromUnicode.providedBy(field):
                        value = field.fromUnicode(value)
                    elif IDatetime.providedBy(field) and value:
                        value = DateTime(value).asdatetime()
                    elif IDate.providedBy(field) and value:
                        value = DateTime(value).asdatetime().date()
                    elif ISet.providedBy(field):
                        try:
                            value = set(literal_eval(value))
                        except ValueError:
                            pass
                    elif INamedBlobFileField.providedBy(field):
                        value = None
                    data[key] = value
                action.addDataRow(data)
Ejemplo n.º 6
0
    def updateWidgets(self):
        self.label = self.request.get('form.widgets.config')
        config = _load_config(self.request.get('form.widgets.config'))
        section = None
        for section_id in config.keys():
            tmp = config[section_id]
            if tmp.get('blueprint', '') in SOURCE_SECTIONS:
                section = tmp
                break
        if not section:
            raise Exception("Source section not found.")

        # Omit some fields depending on the selected source
        if section['blueprint'] == 'collective.jsonmigrator.catalogsource':
            self.fields = self.fields.omit('remote_path', 'remote_crawl_depth',
                                           'remote_skip_path')
        elif section['blueprint'] == 'collective.jsonmigrator.remotesource':
            self.fields = self.fields.omit('catalog_path', 'catalog_query')

        # Fill in default values from the transmogrifier config file
        for option, value in section.items():
            field = self.fields.get(option.replace('-', '_'))
            if field:
                field = field.field
                value = value.decode('utf8')
                if IFromUnicode.providedBy(field):
                    field.default = field.fromUnicode(value)
                elif IList.providedBy(field):
                    field.default = [
                        field.value_type.fromUnicode(v) for v in value.split()
                    ]

        super(JSONMigratorRun, self).updateWidgets()
        self.widgets['config'].mode = interfaces.HIDDEN_MODE
Ejemplo n.º 7
0
 def __call__(self,
              value,
              filestore,
              item,
              disable_constraints=False,
              logger=None):
     field = self.field
     if field is not None:
         try:
             if isinstance(value, str):
                 value = safe_unicode(value)
             if str(type(value)) == "<type 'unicode'>":
                 value = IFromUnicode(field).fromUnicode(value)
             self.field.validate(value)
         except Exception as e:
             if not disable_constraints:
                 raise e
             else:
                 if logger:
                     logger("%s is invalid in %s: %s" % (
                         self.field.__name__,
                         item["_path"],
                         e.__repr__(),
                     ))
     return value
Ejemplo n.º 8
0
 def test_unicode(self):
     field = IContent2['rich']
     self.assertTrue(IFromUnicode.providedBy(field))
     value = field.from_string("A plain text string")
     self.assertEqual(value.mimeType, 'text/plain')
     self.assertEqual(value.outputMimeType, 'text/x-uppercase')
     self.assertEqual(value.raw, 'A plain text string')
     self.assertEqual(value.raw_encoded, b'A plain text string')
Ejemplo n.º 9
0
    def __call__(self, value):
        if not isinstance(value, str):
            self.field.validate(value)
            return value

        value = IFromUnicode(self.field).fromUnicode(value)
        # IFromUnicode.fromUnicode() will validate, no need to do it twice
        return value
Ejemplo n.º 10
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
Ejemplo n.º 11
0
 def test_unicode(self):
     field = IContent2['rich']
     self.assertTrue(IFromUnicode.providedBy(field))
     value = field.from_string("A plain text string")
     self.assertEqual(value.mimeType, 'text/plain')
     self.assertEqual(value.outputMimeType, 'text/x-uppercase')
     self.assertEqual(value.raw, 'A plain text string')
     self.assertEqual(value.raw_encoded, b'A plain text string')
Ejemplo n.º 12
0
    def __call__(self, value):

        # Proper initialization of IContextSourceBinder
        # Check zope.schema IChoice field bind method.
        cloned_field = self.field.bind(self.context)

        if not isinstance(value, unicode):
            return value
        return IFromUnicode(cloned_field).fromUnicode(value)
Ejemplo n.º 13
0
 def __init__(self, field, widget):
     super().__init__(field, widget)
     if not IFromUnicode.providedBy(field):
         field_name = ''
         if field.__name__:
             field_name = '``%s`` ' % field.__name__
         raise TypeError(
             'Field %s of type ``%s`` must provide ``IFromUnicode``.' %
             (field_name, type(field).__name__))
Ejemplo n.º 14
0
    def from_unicode(self, field, value):

        # XXX: Bool incorrectly omits to declare that it implements
        # IFromUnicode, even though it does.
        import zope.schema
        if IFromUnicode.providedBy(field) or isinstance(field, zope.schema.Bool):
            return field.fromUnicode(value)
        else:
            return self.field_typecast(field, value)
Ejemplo n.º 15
0
    def _toFieldValue(self, input):
        if self.convert_missing_value and input == self._missing:
            value = self.context.missing_value
        else:
            assert IFromUnicode.providedBy(self.context)

            try:
                value = self.context.fromUnicode(input)
            except ValueError, v:
                raise ConversionError(_("Invalid link"), v)
    def _toFieldValue(self, input):
        if self.convert_missing_value and input == self._missing:
            value = self.context.missing_value
        else:
            assert IFromUnicode.providedBy(self.context)

            try:
                value = self.context.fromUnicode(input)
            except ValueError, v:
                raise ConversionError(_("Invalid link"), v)
Ejemplo n.º 17
0
def extract_data(schema, raw_data, prefix):
    data = Data({})

    for name in schema.names():
        field = schema[name]
        raw_value = raw_data.get(prefix + name, field.default)

        value = IFromUnicode(field).fromUnicode(raw_value)
        data[name] = value  # convert(raw_value, field)

    return data
Ejemplo n.º 18
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
Ejemplo n.º 19
0
 def __call__(self, value, filestore, item, disable_constraints=False):
     field = self.field
     if field is not None:
         if isinstance(value, str):
             value = value.decode('utf-8')
         if isinstance(value, unicode):
             try:
                 value = IFromUnicode(field).fromUnicode(value)
             except ConstraintNotSatisfied:
                 if not disable_constraints:
                     raise ConstraintNotSatisfied(value)
             except TypeError, e:
                 # TODO: This TypeError may happen because zope.schema._field.Choice._validate
                 # tries to iterate over a vocabulary factory without calling it
                 if not disable_constraints:
                     raise e
         if not disable_constraints:
             self.field.validate(value)
Ejemplo n.º 20
0
def contentPermissionHandler(
    _context, permission, category, managepermission,
    for_=None, class_=None, provides=(), **kwargs):

    if permission == 'zope.Public':
        raise ConfigurationError('zope.Public permission is not allowed.')

    provides = list(provides)
    provides.append(category)

    PermissionClass = PermissionType(
        permission, category, managepermission, class_, provides)

    # set default values
    for iface in provides:
        verifyClass(iface, PermissionClass)

        for fname, field in schema.getFields(iface).items():
            if fname in kwargs:
                if not IFromUnicode.providedBy(field):
                    raise ConfigurationError("Can't convert value", fname)

                setattr(PermissionClass, fname, field.fromUnicode(kwargs[fname]))
            else:
                if field.required and not hasattr(PermissionClass, fname):
                    raise ConfigurationError("Required field is missing", fname)

                if not hasattr(PermissionClass, fname):
                    setattr(PermissionClass, fname, field.default)

    # set up permissions
    required = {}
    for iface in provides + [IContentPermission]:
        for iname in iface:
            required[iname] = managepermission

    defineChecker(PermissionClass, Checker(required))

    # register adapters
    adapter(_context, (PermissionClass,),
            category, (for_,), name=permission)
    adapter(_context, (PermissionClass,),
            IContentPermission, (for_,), name=permission)
Ejemplo n.º 21
0
 def from_unicode(self, field, value):
     import zope.schema
     if IFromUnicode.providedBy(field) or \
                 isinstance(field, zope.schema.Bool):
         if type(field) == zope.schema.Int and len(value) == 0:
             return None
         try:
             return field.fromUnicode(value)
         except ConstraintNotSatisfied:
             if type(field) == Choice and \
                     ISource.providedBy(field.source):
                 if value in self._already_raised:
                     return value
                 else:
                     self._already_raised.append(value)
                     raise MissingObjectException(value)
             raise
     else:
         return self.field_typecast(field, value)
Ejemplo n.º 22
0
 def from_unicode(self, field, value):
     import zope.schema
     if IFromUnicode.providedBy(field) or \
                 isinstance(field, zope.schema.Bool):
         if type(field) == zope.schema.Int and len(value) == 0:
             return None
         try:
             return field.fromUnicode(value)
         except ConstraintNotSatisfied:
             if type(field) == Choice and \
                     ISource.providedBy(field.source):
                 if value in self._already_raised:
                     return value
                 else:
                     self._already_raised.append(value)
                     raise MissingObjectException(value)
             raise
     else:
         return self.field_typecast(field, value)
Ejemplo n.º 23
0
 def __call__(self, value, filestore, item,
              disable_constraints=False, logger=None):
     field = self.field
     if field is not None:
         try:
             if isinstance(value, str):
                 value = value.decode('utf-8')
             if isinstance(value, unicode):
                 value = IFromUnicode(field).fromUnicode(value)
             self.field.validate(value)
         except Exception, e:
             if not disable_constraints:
                 raise e
             else:
                 if logger:
                     logger(
                         "%s is invalid in %s: %s" % (
                             self.field.__name__,
                             item['_path'],
                             e.__repr__())
                         )
Ejemplo n.º 24
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
Ejemplo n.º 25
0
    def create_content(self, *args, **kwargs):
        """Create content and return its UID"""
        # XXX: Because kwargs are only supported with robotframework >= 2.8.3,
        # we must parse them here to support robotframework < 2.8.3.
        for arg in [x for x in args if '=' in x]:
            name, value = arg.split('=', 1)
            kwargs[name] = value

        assert 'type' in kwargs, u"Keyword arguments must include 'type'."
        portal = getSite()
        if 'container' in kwargs:
            pc = getToolByName(portal, 'portal_catalog')
            uid_or_path = kwargs.pop('container')
            uid_results =\
                pc.unrestrictedSearchResults(UID=uid_or_path)
            path_results = \
                pc.unrestrictedSearchResults(
                    path={'query': uid_or_path.rstrip('/'), 'depth': 0})
            container =\
                (uid_results or path_results)[0]._unrestrictedGetObject()
        else:
            container = portal

        # Pre-fill Image-types with random content
        if kwargs.get('type') == 'Image' and not 'image' in kwargs:
            import random
            import StringIO
            from PIL import (
                Image,
                ImageDraw
            )
            img = Image.new('RGB', (random.randint(320, 640),
                                    random.randint(320, 640)))
            draw = ImageDraw.Draw(img)
            draw.rectangle(((0, 0), img.size), fill=(random.randint(0, 255),
                                                     random.randint(0, 255),
                                                     random.randint(0, 255)))
            del draw

            kwargs['image'] = StringIO.StringIO()
            img.save(kwargs['image'], 'PNG')
            kwargs['image'].seek(0)

        id_ = kwargs.pop('id', None)
        type_ = kwargs.pop('type')

        content = None
        if HAS_DEXTERITY:
            # The title attribute for Dexterity types needs to be unicode
            if 'title' in kwargs and isinstance(kwargs['title'], str):
                kwargs['title'] = kwargs['title'].decode('utf-8')
            from plone.dexterity.interfaces import IDexterityFTI
            from plone.dexterity.utils import createContentInContainer
            try:
                getUtility(IDexterityFTI, name=type_)
                content = createContentInContainer(container, type_, **kwargs)
                if id_ is not None and content.id != id_:
                    container.manage_renameObject(content.id, id_)
            except ComponentLookupError:
                pass

        if HAS_DEXTERITY and content:
            # For dexterity-types, we need a second pass to fill all fields
            # using their widgets to get e.g. RichText-values created
            # correctly.
            fti = getUtility(IDexterityFTI, name=type_)
            schema = fti.lookupSchema()
            fields = {}
            for name in schema:
                fields[name] = schema[name]
            for schema in getAdditionalSchemata(portal_type=type_):
                for name in schema:
                    fields[name] = schema[name]
            for name, field in fields.items():
                widget = queryMultiAdapter((field, getRequest()), IFieldWidget)
                if widget and name in kwargs:
                    if not IFromUnicode.providedBy(field):
                        value = kwargs[name]
                    elif isinstance(kwargs[name], unicode):
                        value = kwargs[name]
                    else:
                        value = unicode(str(kwargs[name]), 'utf-8',
                                        errors='ignore')
                    converter = IDataConverter(widget)
                    dm = queryMultiAdapter((content, field), IDataManager)
                    if dm:
                        dm.set(converter.toFieldValue(value))

        if content is None:
            if id_ is None:
                normalizer = queryUtility(IURLNormalizer)
                id_ = normalizer.normalize(kwargs['title'])

            # It must be Archetypes based content:
            content = container[container.invokeFactory(type_, id_, **kwargs)]
            content.processForm()

        return IUUID(content)
Ejemplo n.º 26
0
    def create_content(self, *args, **kwargs):
        """Create content and return its UID"""
        disableCSRFProtection()
        # XXX: Because kwargs are only supported with robotframework >= 2.8.3,
        # we must parse them here to support robotframework < 2.8.3.
        for arg in [x for x in args if '=' in x]:
            name, value = arg.split('=', 1)
            kwargs[name] = value

        assert 'type' in kwargs, u"Keyword arguments must include 'type'."
        portal_type = kwargs.get('type')
        portal = getSite()
        if 'container' in kwargs:
            pc = getToolByName(portal, 'portal_catalog')
            uid_or_path = kwargs.pop('container')
            uid_results =\
                pc.unrestrictedSearchResults(UID=uid_or_path)
            path_results = \
                pc.unrestrictedSearchResults(
                    path={'query': uid_or_path.rstrip('/'), 'depth': 0})
            container =\
                (uid_results or path_results)[0]._unrestrictedGetObject()
        else:
            container = portal

        # if we create 'file' and 'image' kwargs entries, they should not be
        # used to create the content but be set afterwards
        create_kwargs = {}
        create_kwargs.update(kwargs)

        if HAS_DEXTERITY:
            if portal_type in ('File', ) and 'file' not in kwargs:
                pdf_file = os.path.join(os.path.dirname(__file__), 'content',
                                        u'file.pdf')
                value = NamedBlobFile(data=open(pdf_file, 'r').read(),
                                      contentType='application/pdf',
                                      filename=u'file.pdf')
                kwargs['file'] = value

        if portal_type in ('Image', 'News Item') and 'image' not in kwargs:
            prefill_image_types(portal, kwargs)

        id_ = kwargs.pop('id', None)
        type_ = kwargs.pop('type')

        content = None
        if HAS_DEXTERITY:
            # The title attribute for Dexterity types needs to be unicode
            if 'title' in kwargs and isinstance(kwargs['title'], str):
                kwargs['title'] = kwargs['title'].decode('utf-8')
            from plone.dexterity.interfaces import IDexterityFTI
            from plone.dexterity.utils import createContentInContainer
            try:
                getUtility(IDexterityFTI, name=type_)
                content = createContentInContainer(container, type_,
                                                   **create_kwargs)
                if id_ is not None and content.id != id_:
                    container.manage_renameObject(content.id, id_)
            except ComponentLookupError:
                pass

        if HAS_DEXTERITY and content:
            # For dexterity-types, we need a second pass to fill all fields
            # using their widgets to get e.g. RichText-values created
            # correctly.
            fti = getUtility(IDexterityFTI, name=type_)
            schema = fti.lookupSchema()
            fields = {}
            for name in schema:
                fields[name] = schema[name]
            for schema in getAdditionalSchemata(portal_type=type_):
                for name in schema:
                    fields[name] = schema[name]
            for name, field in fields.items():
                widget = queryMultiAdapter((field, getRequest()), IFieldWidget)
                if widget and name in kwargs:
                    if not IFromUnicode.providedBy(field):
                        value = kwargs[name]
                    elif isinstance(kwargs[name], unicode):
                        value = kwargs[name]
                    else:
                        value = unicode(str(kwargs[name]),
                                        'utf-8',
                                        errors='ignore')
                    converter = IDataConverter(widget)
                    dm = queryMultiAdapter((content, field), IDataManager)
                    if dm:
                        dm.set(converter.toFieldValue(value))

        if content is None:
            if id_ is None:
                normalizer = queryUtility(IURLNormalizer)
                id_ = normalizer.normalize(kwargs['title'])

            # It must be Archetypes based content:
            content = container[container.invokeFactory(type_, id_, **kwargs)]
            content.processForm()

        return IUUID(content)
Ejemplo n.º 27
0
    def create_content(self, *args, **kwargs):
        """Create content and return its UID"""
        disableCSRFProtection()
        # XXX: Because kwargs are only supported with robotframework >= 2.8.3,
        # we must parse them here to support robotframework < 2.8.3.
        for arg in [x for x in args if '=' in x]:
            name, value = arg.split('=', 1)
            kwargs[name] = value

        assert 'type' in kwargs, u"Keyword arguments must include 'type'."
        portal_type = kwargs.get('type')
        portal = getSite()
        if 'container' in kwargs:
            pc = getToolByName(portal, 'portal_catalog')
            uid_or_path = kwargs.pop('container')
            uid_results =\
                pc.unrestrictedSearchResults(UID=uid_or_path)
            path_results = \
                pc.unrestrictedSearchResults(
                    path={'query': uid_or_path.rstrip('/'), 'depth': 0})
            container =\
                (uid_results or path_results)[0]._unrestrictedGetObject()
        else:
            container = portal

        # if we create 'file' and 'image' kwargs entries, they should not be
        # used to create the content but be set afterwards
        create_kwargs = {}
        create_kwargs.update(kwargs)

        if HAS_DEXTERITY:
            if portal_type in ('File', ) and 'file' not in kwargs:
                pdf_file = os.path.join(
                    os.path.dirname(__file__), 'content', u'file.pdf')
                value = NamedBlobFile(
                    data=open(pdf_file, 'r').read(),
                    contentType='application/pdf',
                    filename=u'file.pdf'
                )
                kwargs['file'] = value

        if portal_type in ('Image', 'News Item') and 'image' not in kwargs:
            prefill_image_types(portal, kwargs)

        id_ = kwargs.pop('id', None)
        type_ = kwargs.pop('type')

        content = None
        if HAS_DEXTERITY:
            # The title attribute for Dexterity types needs to be unicode
            if 'title' in kwargs and isinstance(kwargs['title'], str):
                kwargs['title'] = kwargs['title'].decode('utf-8')
            from plone.dexterity.interfaces import IDexterityFTI
            from plone.dexterity.utils import createContentInContainer
            try:
                getUtility(IDexterityFTI, name=type_)
                content = createContentInContainer(
                    container, type_, **create_kwargs)
                if id_ is not None and content.id != id_:
                    container.manage_renameObject(content.id, id_)
            except ComponentLookupError:
                pass

        if HAS_DEXTERITY and content:
            # For dexterity-types, we need a second pass to fill all fields
            # using their widgets to get e.g. RichText-values created
            # correctly.
            fti = getUtility(IDexterityFTI, name=type_)
            schema = fti.lookupSchema()
            fields = {}
            for name in schema:
                fields[name] = schema[name]
            for schema in getAdditionalSchemata(portal_type=type_):
                for name in schema:
                    fields[name] = schema[name]
            for name, field in fields.items():
                widget = queryMultiAdapter((field, getRequest()), IFieldWidget)
                if widget and name in kwargs:
                    if not IFromUnicode.providedBy(field):
                        value = kwargs[name]
                    elif isinstance(kwargs[name], unicode):
                        value = kwargs[name]
                    else:
                        value = unicode(str(kwargs[name]), 'utf-8',
                                        errors='ignore')
                    converter = IDataConverter(widget)
                    dm = queryMultiAdapter((content, field), IDataManager)
                    if dm:
                        dm.set(converter.toFieldValue(value))

        if content is None:
            if id_ is None:
                normalizer = queryUtility(IURLNormalizer)
                id_ = normalizer.normalize(kwargs['title'])

            # It must be Archetypes based content:
            content = container[container.invokeFactory(type_, id_, **kwargs)]
            content.processForm()

        return IUUID(content)
Ejemplo n.º 28
0
 def __call__(self, value):
     if not isinstance(value, unicode):
         return value
     return IFromUnicode(self.field).fromUnicode(value)
Ejemplo n.º 29
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
Ejemplo n.º 30
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
Ejemplo n.º 31
0
def get_attribute_values(request, record, attribute_map):
    values = {}
    vocabularies = get_vocabularies(request, attribute_map)

    for header, field in attribute_map.items():

        downloaded = download_field_from_url(field, record[header])
        if downloaded is not False:
            values[field.__name__] = downloaded
            continue

        if IDate.providedBy(field):
            if not record[header]:
                values[field.__name__] = None
            else:
                values[field.__name__] = parse_date(record[header])
            continue

        if IDatetime.providedBy(field):
            if not record[header]:
                values[field.__name__] = None
            else:
                values[field.__name__] = parse_datetime(record[header])
            continue

        if IURI.providedBy(field):
            if not record[header].strip():
                values[field.__name__] = None
                continue

        if IList.providedBy(field):
            if ITextLine.providedBy(field.value_type):
                values[field.__name__] = convert_to_list(record[header])
                continue

        if ISet.providedBy(field):
            if IChoice.providedBy(field.value_type):
                values[field.__name__] = set(convert_to_list(record[header]))
                continue

        if IChoice.providedBy(field):
            if not record[header].strip():
                values[field.__name__] = None
            else:
                vocabulary = vocabularies[header]
                if record[header].lower() not in vocabulary:
                    raise ContentImportError(
                        _(
                            u'The ${name} column contains the '
                            u'unknown value ${value}',
                            mapping=dict(name=header, value=record[header])
                        )
                    )

                values[field.__name__] = vocabulary[record[header].lower()]

            continue

        assert IFromUnicode.providedBy(field), """
            {} does not support fromUnicode
        """.format(field)

        try:
            values[field.__name__] = field.fromUnicode(record[header])

            if isinstance(values[field.__name__], basestring):
                values[field.__name__] = values[field.__name__].strip()
            if isinstance(field, Text):
                values[field.__name__] = values[field.__name__].replace(
                    '<br />', '\n'
                )

        except ValidationError, e:
            raise ContentImportError(e.doc(), colname=header)
        except ValueError, e:
            raise ContentImportError(e.message, colname=header)
Ejemplo n.º 32
0
    def __call__(self, value):
        if not isinstance(value, str) or not isinstance(value, bytes):
            return value
        return IFromUnicode(self.field).fromUnicode(value)


# @implementer(IFieldDeserializer)
# @adapter(IDatetime, IDexterityContent, IBrowserRequest)
# class DatetimeFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         try:
#             value = datetime(value).toZone(DateTime().localZone()).asdatetime(
#             ).replace(tzinfo=None)
#         except (SyntaxError, DateTimeError) as e:
#             raise ValueError(e.message)

#         self.field.validate(value)
#         return value

# @implementer(IFieldDeserializer)
# @adapter(ICollection, IDexterityContent, IBrowserRequest)
# class CollectionFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         if not isinstance(value, list):
#             value = [value]

#         if IField.providedBy(self.field.value_type):
#             deserializer = getMultiAdapter(
#                 (self.field.value_type, self.context, self.request),
#                 IFieldDeserializer)

#             for i, v in enumerate(value):
#                 value[i] = deserializer(v)

#         value = self.field._type(value)
#         self.field.validate(value)

#         return value

# @implementer(IFieldDeserializer)
# @adapter(IDict, IDexterityContent, IBrowserRequest)
# class DictFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         kdeserializer = lambda k: k
#         vdeserializer = lambda v: v
#         if IField.providedBy(self.field.key_type):
#             kdeserializer = getMultiAdapter(
#                 (self.field.key_type, self.context, self.request),
#                 IFieldDeserializer)
#         if IField.providedBy(self.field.value_type):
#             vdeserializer = getMultiAdapter(
#                 (self.field.value_type, self.context, self.request),
#                 IFieldDeserializer)

#         new_value = {}
#         for k, v in value.items():
#             new_value[kdeserializer(k)] = vdeserializer(v)

#         self.field.validate(new_value)
#         return new_value

# @implementer(IFieldDeserializer)
# @adapter(ITime, IDexterityContent, IBrowserRequest)
# class TimeFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         try:
#             # Create an ISO 8601 datetime string and parse it with Zope's
#             # DateTime module and then convert it to a timezone naive time
#             # in local time
#             value = DateTime(u'2000-01-01T' + value).toZone(DateTime(
#             ).localZone()).asdatetime().replace(tzinfo=None).time()
#         except (SyntaxError, DateTimeError):
#             raise ValueError(u'Invalid time: {}'.format(value))

#         self.field.validate(value)
#         return value

# @implementer(IFieldDeserializer)
# @adapter(ITimedelta, IDexterityContent, IBrowserRequest)
# class TimedeltaFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         try:
#             value = timedelta(seconds=value)
#         except TypeError as e:
#             raise ValueError(e.message)

#         self.field.validate(value)
#         return value

# @implementer(IFieldDeserializer)
# @adapter(INamedField, IDexterityContent, IBrowserRequest)
# class NamedFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         content_type = 'application/octet-stream'
#         filename = None
#         if isinstance(value, dict):
#             content_type = value.get(u'content-type', content_type).encode(
#                 'utf8')
#             filename = value.get(u'filename', filename)
#             if u'encoding' in value:
#                 data = value.get('data', '').decode(value[u'encoding'])
#             else:
#                 data = value.get('data', '')
#         else:
#             data = value

#         value = self.field._type(
#             data=data, contentType=content_type, filename=filename)
#         self.field.validate(value)
#         return value

# @implementer(IFieldDeserializer)
# @adapter(IRichText, IDexterityContent, IBrowserRequest)
# class RichTextFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         content_type = self.field.default_mime_type
#         encoding = 'utf8'
#         if isinstance(value, dict):
#             content_type = value.get(u'content-type', content_type)
#             encoding = value.get(u'encoding', encoding)
#             data = value.get(u'data', u'')
#         else:
#             data = value

#         value = RichTextValue(
#             raw=data,
#             mimeType=content_type,
#             outputMimeType=self.field.output_mime_type,
#             encoding=encoding,
#         )
#         self.field.validate(value)
#         return value

# @implementer(IFieldDeserializer)
# @adapter(IRelationChoice, IDexterityContent, IBrowserRequest)
# class RelationChoiceFieldDeserializer(DefaultFieldDeserializer):

#     def __call__(self, value):
#         obj = None

#         if isinstance(value, int):
#             # Resolve by intid
#             intids = queryUtility(IIntIds)
#             obj = intids.queryObject(value)
#         elif isinstance(value, basestring):
#             portal = getMultiAdapter((self.context, self.request),
#                                      name='plone_portal_state').portal()
#             portal_url = portal.absolute_url()
#             if value.startswith(portal_url):
#                 # Resolve by URL
#                 obj = portal.restrictedTraverse(
#                     value[len(portal_url) + 1:].encode('utf8'), None)
#             elif value.startswith('/'):
#                 # Resolve by path
#                 obj = portal.restrictedTraverse(
#                     value.encode('utf8').lstrip('/'), None)
#             else:
#                 # Resolve by UID
#                 catalog = getToolByName(self.context, 'portal_catalog')
#                 brain = catalog(UID=value)
#                 if brain:
#                     obj = brain[0].getObject()

#         self.field.validate(obj)
#         return obj
Ejemplo n.º 33
0
                iface = _context.resolve(tp)
            except Exception, err:
                pass

        if iface is not None:
            provides.append(iface)

    kwargs['type'] = type
    kwargs['name'] = name
    kwargs['permission'] = permission

    # convert kwargs
    for iface in provides:
        for fname, field in schema.getFields(iface).items():
            if fname in kwargs:
                if not IFromUnicode.providedBy(field):
                    raise ConfigurationError("Can't convert value", fname)

                setattr(new_class, fname, field.fromUnicode(kwargs[fname]))
            else:
                if field.required and not hasattr(new_class, fname):
                    raise ConfigurationError("Required field is missing", fname)

                if not hasattr(new_class, fname):
                    setattr(new_class, fname, field.default)

    # add IPagelet to provides
    if name:
        inProvides = False
        for iface in provides:
            if IPagelet.isOrExtends(iface) and not IPageletType.providedBy(iface):
Ejemplo n.º 34
0
 def convert(k, v):
     return (IFromUnicode(self.context.key_type).fromUnicode(unicode(k)),
             IFromUnicode(self.context.value_type).fromUnicode(unicode(v)))