示例#1
0
    def _getTeaserMedia(self, high, scale):
        """ teaser media utility method """
        obj = high.getObject()
        media = obj.getMedia()
        media_url = media_type = media_title = media_copy = media_note = ''
        if media:
            if IBlobWrapper.providedBy(media):
                media_url = obj.absolute_url() + '/image'
            else:
                media_url = media.absolute_url()

            if obj.absolute_url() in media_url:
                # image in image field
                media_type = 'Image'
                media_title = obj.getImageCaption()
                media_copy = obj.getImageCopyright()
                media_note = obj.getImageNote()
            else:
                # reference to an Image or FlashFile
                media_type = media.portal_type
                media_title = media.Title()
                media_copy = media.Rights()
                media_note = media.Description()

        adapter = queryMultiAdapter((obj, self.request),
                                    name=u'themes-object',
                                    default=None)
        themes = []
        if adapter is not None:
            themes = adapter.short_items()
        result = {
            'id': high['id'],
            'getUrl': high.get('getUrl', high.getURL()),
            'getNewsTitle': high['getNewsTitle'],
            'getTeaser': high['getTeaser'],
            'effective': high['effective'],
            'expires': high['expires'],
            'getVisibilityLevel': high['getVisibilityLevel'],
            'themes': themes,
        }

        if media is not None:
            result['media'] = {
                'absolute_url': media_url,
                'portal_type': media_type,
                'Title': media_title,
                'Rights': media_copy,
                'Description': media_note,
                'getScale': ''
            }
            if IBlobWrapper.providedBy(media):
                result['media']['getScale'] = obj.getField('image').tag(
                    obj, scale=scale)

        return result
示例#2
0
    def _getTeaserMedia(self, high, scale):
        """ teaser media utility method """
        obj = high.getObject()
        media = obj.getMedia()
        media_url = media_type = media_title = media_copy = media_note = ''
        if media:
            if IBlobWrapper.providedBy(media):
                media_url = obj.absolute_url() + '/image'
            else:
                media_url = media.absolute_url()

            if obj.absolute_url() in media_url:
                # image in image field
                media_type = 'Image'
                media_title = obj.getImageCaption()
                media_copy = obj.getImageCopyright()
                media_note = obj.getImageNote()
            else:
                # reference to an Image or FlashFile
                media_type = media.portal_type
                media_title = media.Title()
                media_copy = media.Rights()
                media_note = media.Description()

        adapter = queryMultiAdapter((obj, self.request), name=u'themes-object',
                                                                default=None)
        themes = []
        if adapter is not None:
            themes = adapter.short_items()
        result = {
            'id': high['id'],
            'getUrl': high.get('getUrl', high.getURL()),
            'getNewsTitle': high['getNewsTitle'],
            'getTeaser': high['getTeaser'],
            'effective': high['effective'],
            'expires': high['expires'],
            'getVisibilityLevel': high['getVisibilityLevel'],
            'themes': themes,
        }

        if media is not None:
            result['media'] = {
                    'absolute_url' : media_url,
                    'portal_type'  : media_type,
                    'Title'        : media_title,
                    'Rights'       : media_copy,
                    'Description'  : media_note,
                    'getScale'     : ''
                }
            if IBlobWrapper.providedBy(media):
                result['media']['getScale'] = obj.getField('image').tag(
                                                            obj, scale=scale)

        return result
def migrateToBlobs(context):
    from plone.app.blob.interfaces import IBlobWrapper
    portal = context.portal_url.getPortalObject()
    ctool  = getToolByName(portal, 'portal_catalog')
    items = ctool(object_provides=ILeadImageable.__identifier__) 
    cnt = len(items)
    logger.info('Migrating %d items' % cnt)
    for item in items:
        obj = item.getObject()
        field = obj.getField(IMAGE_FIELD_NAME)
        if (field is not None) and not IBlobWrapper.providedBy(field.getUnwrapped(obj)):
            # this is apparently old content. AttributeError is raised 
            # when old site is upgraded to BLOB aware one
            # Let's migrate
            logger.info('Migrating item %s' % '/'.join(obj.getPhysicalPath()))
            extender = LeadImageExtender(obj)
            if extender.fields:
                extfield = extender.fields[0]
                if extfield.getName() == IMAGE_FIELD_NAME:
                    # ok, retrieve the value
                    value = extfield.get(obj)
                    if hasattr(extfield, 'removeScales'):
                            extfield.removeScales(obj)
                    field.getMutator(obj)(value)
    logger.info('Migration finished')
示例#4
0
    def convert(self, value):
        """
        Convert value to more JSON friendly format.
        """
        if isinstance(value, DateTime):
            # Zope DateTime
            # http://pypi.python.org/pypi/DateTime/3.0.2
            return value.ISO8601()
        elif isinstance(value, FormattableName):
            return dict(value.items())
        elif IBlobWrapper.providedBy(value):
            # TODO: equivalent handling of binary data as in isBinary special case
            return None
        elif hasattr(value, "isBinary") and value.isBinary():

            if not EXPORT_BINARY:
                return None

            # Archetypes FileField and ImageField payloads
            # are binary as OFS.Image.File object
            data = getattr(value.data, "data", None)
            if not data:
                return None
            return base64.b64encode(data)
        else:
            # Passthrough
            return value
示例#5
0
    def fieldSerialization(self, field, value):
        """
        Custom serialization for fields which provide field values that are
        incompatible with json / JSON-standard.
        @param field:   Field-Object from Schema
        @type field:    Field
        @param value:   Return-Value of the Raw-Accessor of the Field on the
        current context
        @type value:    string or stream
        @return:        JSON-optimized value
        @rtype:         string
        """

        if isinstance(field, DateTimeField) and value:
            value = str(value)

        elif HAS_BLOBS and IBlobWrapper.providedBy(value):
            file_ = value.getBlob().open()
            value = {'filename': value.getFilename(),
                     'data': base64.encodestring(file_.read()),
                     'type': 'blob'}
            file_.close()

        elif isinstance(field, FileField) and isinstance(value, File):
            tmp = StringIO.StringIO(value.data)
            tmp.seek(0)
            value = {'filename': value.filename,
                     'data': base64.encodestring(tmp.read())}

        elif isinstance(field, QueryField):
            query = field.getRaw(self.object)
            # Cast "ZPublisher.HTTPRequest.record" instance to dict
            value = [dict(item) for item in query]

        return value
def migrateToBlobs(context):
    from plone.app.blob.interfaces import IBlobWrapper
    portal = context.portal_url.getPortalObject()
    ctool = getToolByName(portal, 'portal_catalog')
    items = ctool(object_provides=ILeadImageable.__identifier__)
    cnt = len(items)
    logger.info('Migrating %d items' % cnt)
    for item in items:
        obj = item.getObject()
        field = obj.getField(IMAGE_FIELD_NAME)
        if (field is not None) and not IBlobWrapper.providedBy(field.getUnwrapped(obj)):
            # this is apparently old content. AttributeError is raised
            # when old site is upgraded to BLOB aware one
            # Let's migrate
            logger.info('Migrating item %s' % '/'.join(obj.getPhysicalPath()))
            extender = LeadImageExtender(obj)
            if extender.fields:
                extfield = extender.fields[0]
                if extfield.getName() == IMAGE_FIELD_NAME:
                    # ok, retrieve the value
                    value = extfield.get(obj)
                    if hasattr(extfield, 'removeScales'):
                            extfield.removeScales(obj)
                    field.getMutator(obj)(value)
    logger.info('Migration finished')
示例#7
0
    def convert(self, value):
        """
        Convert value to more JSON friendly format.
        """
        if isinstance(value, DateTime):
            # Zope DateTime
            # http://pypi.python.org/pypi/DateTime/3.0.2
            return value.ISO8601()
        elif isinstance(value, FormattableName):
            return dict(value.items())
        elif IBlobWrapper.providedBy(value):
            # TODO: equivalent handling of binary data as in isBinary special case
            return None
        elif hasattr(value, "isBinary") and value.isBinary():

            if not EXPORT_BINARY:
                return None

            # Archetypes FileField and ImageField payloads
            # are binary as OFS.Image.File object
            data = getattr(value.data, "data", None)
            if not data:
                return None
            return base64.b64encode(data)
        else:
            # Passthrough
            return value
    def _expand_binary_data(self, obj, data):
        max_size = es_config.max_blobsize
        is_archetype = False
        if HAS_ARCHETYPES and IBaseContent.providedBy(obj):
            is_archetype = True
            schema = obj.Schema()
        for fieldname in self._iterate_binary_fields(obj, data):
            if fieldname not in data:
                data[fieldname] = None
                continue
            if is_archetype:
                field = schema[fieldname]
                value = field.get(obj)
                if value is None:
                    data[fieldname] = None
                    continue
                data[fieldname + '_meta'] = data[fieldname]
                if IBlobWrapper.providedBy(value):
                    if max_size and value.get_size() > max_size:
                        data[fieldname] = None
                        del data[fieldname + '_meta']
                        msg = 'File too big for ElasticSearch Indexing: {0}'
                        logger.info(msg.format(obj.absolute_url(), ), )
                        continue

                    with value.getBlob().open() as fh:
                        data[fieldname] = base64.b64encode(fh.read())
                elif ITextField.providedBy(field):
                    data[fieldname] = base64.b64encode(
                        data[fieldname + '_meta']['data'].encode('utf8'))
            else:
                field = getattr(obj, fieldname, None)
                if field is None:
                    data[fieldname] = None
                    continue
                data[fieldname + '_meta'] = data[fieldname]
                if IBlobby.providedBy(field):
                    if max_size and field.getSize() > max_size:
                        data[fieldname] = None
                        del data[fieldname + '_meta']
                        msg = 'File too big for ElasticSearch Indexing: {0}'
                        logger.info(msg.format(obj.absolute_url(), ), )
                        continue
                    with field.open() as fh:
                        data[fieldname] = base64.b64encode(fh.read())
                elif IRichTextValue.providedBy(field):
                    data[fieldname] = base64.b64encode(
                        data[fieldname + '_meta']['data'].encode('utf8'), )
            if max_size and len(data[fieldname]) > max_size:
                data[fieldname] = None
                del data[fieldname + '_meta']
                logger.info(
                    'File too big for ElasticSearch Indexing: {0}'.format(
                        obj.absolute_url(), ), )
示例#9
0
def check_is_image(img):
    """ Check image class
    """
    try:
        # first try blob Images
        from plone.app.blob.interfaces import IBlobWrapper
        from plone.app.imaging.interfaces import IBaseObject
        checked = False
        if IBaseObject.providedBy(img) or IBlobWrapper.providedBy(img):
            checked = True
        if not checked:
            raise
    except:
        # try to see if it is an old OFS.image
        if not isinstance(img, Image):
            raise ValueError('This is not a plone Image.')
示例#10
0
def check_is_image(img):
    """ Check image class
    """
    try:
        # first try blob Images
        from plone.app.blob.interfaces import IBlobWrapper
        from plone.app.imaging.interfaces import IBaseObject
        checked = False
        if IBaseObject.providedBy(img) or IBlobWrapper.providedBy(img):
            checked = True
        if not checked:
            raise
    except:
        # try to see if it is an old OFS.image
        if not isinstance(img, Image):
            raise ValueError(
                'This is not a plone Image.')
    def __call__(self, text, file_path=None):
        matches = SRC_PATTERN.findall(text)
        for match in set(matches):
            match_path = match.strip('"').strip("'").replace(
                '../', '').replace('%20', ' ').lstrip('/').encode('utf-8')
            obj = self.context.unrestrictedTraverse(match_path, None)
            ext = match_path.rsplit('.', 1)
            ext = ext in ('png', 'jpg', 'gif', 'jpeg') and ext or 'jpg'
            if obj and isinstance(obj, ATImage):
                text = text.replace(match_path, match_path + '/image.%s' % ext)
            if hasattr(obj, 'getBlobWrapper'):
                if 'image' in obj.getBlobWrapper().getContentType():
                    text = text.replace(match_path,
                                        match_path + '/image.%s' % ext)
            if not obj:
                try:
                    path, filename = match_path.rsplit('/', 1)
                except ValueError:
                    continue
                fieldname = filename.split('_', 1)[0]
                obj = self.context.restrictedTraverse(
                    '/'.join((path, fieldname)), None)
                if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj):
                    text = text.replace(match_path, match_path + '/image.jpg')
                if not obj:
                    if '/@@images/' in match_path:
                        parent_path, image_name = match_path.split(
                            '/@@images/')
                        spl_img_name = image_name.split('/')
                        if len(spl_img_name) == 1:
                            # no scalename in path
                            fieldname = spl_img_name
                            new_path = '/'.join((parent_path, 'image.jpg'))
                        else:
                            # scalename in path
                            fieldname, scalename = spl_img_name
                            new_path = '/'.join((parent_path, '_'.join(
                                (fieldname, scalename))))
                        text = text.replace(match_path,
                                            new_path + '/image.jpg')

        return text
示例#12
0
 def get_object(self, attrs=[]):
     skeleton = self.get_skeleton(attrs, just_keys=True)
     for k in skeleton.keys():
         if self.context[k] == None:
             skeleton[k] = None
         elif isinstance(self.context[k], BaseUnit):
             # -- it's worse than the x-ray shows --
             # brittle_bones, tisk tisk
             #
             # Archetypes' BaseUnit subclasses OFS's File, which has the
             # _properties attribute, but it loses its 'id' and
             # 'content_type' ???
             skeleton[k] = self.context[k].getRaw()
         elif isinstance(self.context[k], File):
             skeleton[k] = self._gather_file_data(k)
         elif has_blob_support and IBlobWrapper.providedBy(self.context[k]):
             skeleton[k] = self._gather_blob_data(k)
         else:
             skeleton[k] = self.context[k]
     return skeleton
示例#13
0
def migrate_lead_image_into_textblock(old_page, new_page):
    image = old_page.getImage()
    if not image or not image.get_size():
        # no lead image
        return

    assert IBlobWrapper.providedBy(image), \
        'Unexpectedly, the teaser image "{!r}" is not an IBlobWrapper.'.format(
            image)

    teaser_block = createContentInContainer(
        container=new_page,
        portal_type='ftw.simplelayout.TextBlock',
        title='Teaser'
    )

    fields = dict(reduce(list.__add__,
                         map(getFieldsInOrder, iterSchemata(teaser_block))))

    fields['show_title'].set(teaser_block, False)
    fields['image_alt_text'].set(
        teaser_block, old_page.getImageAltText().decode('utf-8'))
    fields['image_caption'].set(
        teaser_block, old_page.getImageCaption().decode('utf-8'))
    fields['open_image_in_overlay'].set(
        teaser_block, old_page.getImageClickable())

    new_image = fields['image']._type(
        data='',
        contentType=image.content_type,
        filename=image.filename.decode('utf-8'))
    new_image._blob = image.getBlob()
    fields['image'].set(teaser_block, new_image)

    # Since the teaser was stored on the *page*, the image layout of the
    # teaser is stored in the block-config of the page!
    # Therefore we must migrate the view from the page to the new
    # teaser block.
    migrate_sl_image_layout(old_page, teaser_block)
    alsoProvides(teaser_block, ISlotA)
    move_sl_block_into_slot(old_page, new_page, teaser_block, 'default')
示例#14
0
    def fieldSerialization(self, field, value):
        """
        Custom serialization for fields which provide field values that are
        incompatible with json / JSON-standard.
        @param field:   Field-Object from Schema
        @type field:    Field
        @param value:   Return-Value of the Raw-Accessor of the Field on the
        current context
        @type value:    string or stream
        @return:        JSON-optimized value
        @rtype:         string
        """

        if isinstance(field, DateTimeField) and value:
            value = str(value)

        elif HAS_BLOBS and IBlobWrapper.providedBy(value):
            file_ = value.getBlob().open()
            value = {
                'filename': value.getFilename(),
                'data': base64.encodestring(file_.read()),
                'type': 'blob'
            }
            file_.close()

        elif isinstance(field, FileField) and isinstance(value, File):
            tmp = StringIO.StringIO(value.data)
            tmp.seek(0)
            value = {
                'filename': value.filename,
                'data': base64.encodestring(tmp.read())
            }

        elif isinstance(field, QueryField):
            query = field.getRaw(self.object)
            # Cast "ZPublisher.HTTPRequest.record" instance to dict
            value = [dict(item) for item in query]

        return value
    def __call__(self, text, file_path=None):
        matches = SRC_PATTERN.findall(text)
        for match in set(matches):
            match_path = match.strip('"').strip("'").replace('../', '').replace('%20', ' ').lstrip('/').encode('utf-8')
            obj = self.context.unrestrictedTraverse(match_path, None)
            ext = match_path.rsplit('.', 1)[-1]
            if ext and ext.endswith('/view'):
                ext = ext[:-5]
            ext = ext in ('png', 'jpg', 'gif', 'jpeg') and ext or 'jpg'
            if obj and isinstance(obj, ATImage):
                text = text.replace(match_path, match_path + '/image.%s' % ext)
            if hasattr(obj, 'getBlobWrapper'):
                if 'image' in obj.getBlobWrapper().getContentType():
                    text = text.replace(match_path, match_path + '/image.%s' % ext)
            if not obj:
                try:
                    path, filename = match_path.rsplit('/', 1)
                except ValueError:
                    continue
                fieldname = filename.split('_', 1)[0]
                obj = self.context.restrictedTraverse('/'.join((path, fieldname)), None)
                if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj):
                    text = text.replace(match_path, match_path + '/image.jpg')
                if not obj:
                    if '/@@images/' in match_path:
                        parent_path, image_name = match_path.split('/@@images/')
                        spl_img_name = image_name.split('/')
                        if len(spl_img_name) == 1:
                            # no scalename in path
                            fieldname = spl_img_name
                            new_path = '/'.join((parent_path, 'image.jpg'))
                        else:
                            # scalename in path 
                            fieldname, scalename = spl_img_name
                            new_path = '/'.join((parent_path, '_'.join((fieldname, scalename))))
                        text = text.replace(match_path, new_path + '/image.jpg')

        return text
示例#16
0
    def _render_obj(self, obj):
        """
        Render object to string.
        """
        if isinstance(obj, basestring):
            return obj
        ## 'plone.global_sections' viewlet uses request['URL'] highlight
        ## selected tab, so it must be overridden but only for a while
        initial_url = self.request['URL']
        try:
            obj_url = obj.absolute_url()
        except AttributeError:
            try:
                obj_url = obj.context.absolute_url()
            except AttributeError:
                obj_url = None

        if obj_url:
            self.request['URL'] = obj_url

        ## breadcrumb implementation in quills uses 'PARENTS', so it must
        ## be overriden but ony for a while
        initial_parents = self.request['PARENTS']
        if hasattr(obj, 'aq_chain'):
            self.request['PARENTS'] = obj.aq_chain

        try:
            if IResource.providedBy(obj):
                try:
                    f = open(obj.context.path)
                    result = f.read()
                    f.close()
                except IOError:
                    log.error("Couldn't open '%s' file with resource" % obj.context.path)
                    return None

                return result

            if isinstance(obj, (BrowserView, FSPageTemplate, PythonScript)):
                try:
                    return obj()
                except NotFound:
                    log.error("Resource '%s' not found" % repr(obj))
                    return None
            if isinstance(obj, (FSFile, FSImage)):
                return self._render_obj(obj._readFile(None))

            if isinstance(obj, FSDTMLMethod):
                return self._render_obj(obj.read())

            mt = None
            try:
                mt = obj.aq_base.meta_type
            except AttributeError:
                pass

            if mt in self.file_types or isinstance(obj, (ImageField, OFSImage, Pdata, File)):
                return self._render_obj(obj.data)

            if PLONE_RESOURCE_INSTALLED and isinstance(obj, FilesystemFile):
                if not obj.request:
                    obj.request = self.request
                    return obj().read()

            if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj):
                return obj.data

            if IBaseObject.providedBy(obj) or isinstance(obj, PloneSite):
                def_page_id = obj.getDefaultPage()
                if def_page_id:
                    def_page = obj[def_page_id]
                    return self._render_obj(def_page)

                view_name = obj.getLayout()
                view = queryMultiAdapter((obj, self.request), name=view_name)
                if view_name == 'language-switcher':
                    lang = self.request.get('LANGUAGE')
                    def_page = getattr(obj, lang, None)
                    if def_page:
                        return self._render_obj(def_page)
                if view:
                    try:
                        return view.context()
                    except (ContentProviderLookupError, TypeError):
                        pass

                view = obj.restrictedTraverse(view_name, None)
                if view:
                    try:
                        return view.context()
                    except (AttributeError, TypeError):
                        try:
                            return view()
                        except Exception, error:
                            log.warning("Unable to render view: '%s'! Error occurred: %s" % (view, error))
                            pass

                else:
                    try:
                        return obj()
                    except AttributeError:
                        pass

        finally:
            ## back to initial url
            if obj_url:
                self.request['URL'] = initial_url

            ## back to initial parents
            self.request['PARENTS'] = initial_parents

        log.warning("Not recognized object '%s'!" % repr(obj))
        return None
 def __call__(self, text, file_path=None):
     dom = getDom(text)
     if not dom:
         return text
     for link in dom.cssselect('a[href],img[src]'):
         link = LinkElement(link)
         url = link.val.rstrip('/')
         match_path = url.replace('%20', ' ').lstrip('/')
         if type(match_path) == unicode:
             match_path = match_path.encode('utf-8')
         obj = self.context.unrestrictedTraverse(match_path, None)
         ext = match_path.split('.')[-1].lower()
         ext = ext in ('png', 'jpg', 'gif', 'jpeg') and ext or 'jpg'
         if obj and isinstance(obj, ATImage) or (
             hasattr(obj, 'getBlobWrapper') and \
                 'image' in obj.getBlobWrapper().getContentType()):
             link.set(url + '/image.%s' % ext)
         elif obj and isinstance(obj, ArchetypesImage):
             # it's a scale, always use image.jpg extension
             link.set(url + '/image.jpg')
         if not obj:
             try:
                 path, filename = match_path.rsplit('/', 1)
             except ValueError:
                 continue
             fieldname = filename.split('_', 1)[0]
             obj = self.context.restrictedTraverse('/'.join((path, fieldname)), None)
             if not obj:
                 # not all fields are traversable
                 obj = self.context.restrictedTraverse(path, None)
                 if IImageScaling.providedBy(obj):
                     # we can't do anything with the @@images view yet here...
                     obj = None
                 if obj and hasattr(obj, 'getField'):
                     field = obj.getField(fieldname)
                     if field:
                         obj = field.get(obj)
             if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj):
                 link.set(url + '/image.jpg')
             if not obj:
                 if '/@@images/' in match_path:
                     parent_path, image_name = match_path.split('/@@images/')
                     spl_img_name = image_name.split('/')
                     if len(spl_img_name) == 1:
                         # no scalename in path
                         uid = spl_img_name[0]
                         if '-' in uid:
                             # seems to be actual uid for a custom scale here...
                             # it should written out as [uid].[ext]
                             new_path = '/'.join((parent_path, uid))
                         else:
                             # just use original if we can't figure this out...
                             new_path = '/'.join((parent_path, 'image.%s' % ext))
                     else:
                         # scalename in path
                         fieldname, scalename = spl_img_name
                         new_path = '/'.join((parent_path, '_'.join((fieldname, scalename))))
                         new_path = new_path + '/image.jpg'
                     new_path = '/' + new_path.lstrip('/')
                     link.set(new_path)
     return unicode(dom)
示例#18
0
    def prepare_field_value(self, new_object, field, value):
        recurse = partial(self.prepare_field_value, new_object, field)

        if isinstance(value, str):
            return recurse(value.decode('utf-8'))

        if isinstance(value, list):
            return map(recurse, value)

        if isinstance(value, tuple):
            return tuple(map(recurse, value))

        relation_fields = filter(IRelationChoice.providedBy,
                                 (field, getattr(field, 'value_type', None)))
        if relation_fields and isinstance(value, unicode):
            target = uuidToObject(value)
            return create_relation('/'.join(target.getPhysicalPath()))

        if IRichText.providedBy(field) \
           and not IRichTextValue.providedBy(value):
            return recurse(field.fromUnicode(value))

        if INamedField.providedBy(field) and value \
           and not isinstance(value, field._type):

            source_is_blobby = IBlobWrapper.providedBy(value)
            target_is_blobby = INamedBlobFileField.providedBy(field) or \
                               INamedBlobImageField.providedBy(field)

            if source_is_blobby and target_is_blobby:
                filename = value.filename
                if isinstance(filename, str):
                    filename = filename.decode('utf-8')

                new_value = field._type(
                    data='',  # empty blob, will be replaced
                    contentType=value.content_type,
                    filename=filename)
                if not hasattr(new_value, '_blob'):
                    raise ValueError(
                        ('Unsupported file value type {!r}'
                         ', missing _blob.').format(
                             new_value.__class__))

                # Simply copy the persistent blob object (with the file system
                # pointer) to the new value so that the file is not copied.
                # We assume that the old object is trashed and can therefore
                # adopt the blob file.
                new_value._blob = value.getBlob()
                return recurse(new_value)

            else:
                filename = value.filename
                if isinstance(filename, str):
                    filename = filename.decode('utf-8')

                data = value.data
                data = getattr(data, 'data', data)  # extract Pdata
                return recurse(field._type(
                    data=data,
                    contentType=value.content_type,
                    filename=filename))

        return value
示例#19
0
    def prepare_field_value(self, new_object, field, value):
        recurse = partial(self.prepare_field_value, new_object, field)

        if isinstance(value, str):
            return recurse(value.decode('utf-8'))

        if isinstance(value, list):
            return map(recurse, value)

        if isinstance(value, tuple):
            return tuple(map(recurse, value))

        relation_fields = filter(IRelation.providedBy,
                                 (field, getattr(field, 'value_type', None)))
        if relation_fields and isinstance(value, unicode):
            target = uuidToObject(value)
            return create_relation('/'.join(target.getPhysicalPath()))

        if IRichText.providedBy(field) \
           and not IRichTextValue.providedBy(value):
            return recurse(field.fromUnicode(value))

        if INamedField.providedBy(field) and value is not None \
           and not isinstance(value, field._type):

            if value == '':
                return None

            if hasattr(value, 'get_size') and value.get_size() == 0:
                return None

            source_is_blobby = IBlobWrapper.providedBy(value)
            target_is_blobby = INamedBlobFileField.providedBy(field) or \
                               INamedBlobImageField.providedBy(field)

            if source_is_blobby and target_is_blobby:
                filename = value.filename
                if isinstance(filename, str):
                    filename = filename.decode('utf-8')

                new_value = field._type(
                    data='',  # empty blob, will be replaced
                    contentType=value.content_type,
                    filename=filename)
                if not hasattr(new_value, '_blob'):
                    raise ValueError(
                        ('Unsupported file value type {!r}'
                         ', missing _blob.').format(
                             new_value.__class__))

                # Simply copy the persistent blob object (with the file system
                # pointer) to the new value so that the file is not copied.
                # We assume that the old object is trashed and can therefore
                # adopt the blob file.
                new_value._blob = value.getBlob()
                return recurse(new_value)

            else:
                filename = value.filename
                if isinstance(filename, str):
                    filename = filename.decode('utf-8')

                data = value.data
                data = getattr(data, 'data', data)  # extract Pdata
                return recurse(field._type(
                    data=data,
                    contentType=value.content_type,
                    filename=filename))

        return value
示例#20
0
    def _render_obj(self, obj, new_req=None):
        """
        Render object to string.
        """
        if isinstance(obj, basestring):
            return obj
        if new_req is None:
            new_req = self.request

        try:
            if IResource.providedBy(obj):
                try:
                    f = open(obj.context.path)
                    result = f.read()
                    f.close()
                except AttributeError:
                    result = obj.context.data
                except IOError:
                    log.error("Couldn't open '%s' file with resource" % (obj.context.path))
                    return None

                return result

            if isinstance(obj, (BrowserView, FSPageTemplate, PythonScript)):
                try:
                    return obj()
                except NotFound:
                    log.error("Resource '%s' not found" % repr(obj))
                    return None
            if isinstance(obj, (FSFile, FSImage)):
                return self._render_obj(obj._readFile(None))

            if isinstance(obj, FSDTMLMethod):
                return self._render_obj(obj.read())

            mt = None
            try:
                mt = obj.aq_base.meta_type
            except AttributeError:
                pass

            if mt in self.file_types or isinstance(obj, (ImageField, OFSImage, Pdata, File)):
                return self._render_obj(obj.data)

            if PLONE_RESOURCE_INSTALLED and isinstance(obj, FilesystemFile):
                if not obj.request:
                    obj.request = new_req
                    return obj().read()

            if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj):
                return obj.data

            if IBaseObject.providedBy(obj) or isinstance(obj, PloneSite):
                def_page_id = obj.getDefaultPage()
                if def_page_id:
                    def_page = obj[def_page_id]
                    return self._render_obj(def_page)

                view_name = obj.getLayout()
                view = queryMultiAdapter((obj, new_req), name=view_name)
                if view_name == "language-switcher":
                    lang = new_req.get("LANGUAGE")
                    def_page = getattr(obj, lang, None)
                    if def_page:
                        return self._render_obj(def_page)
                if view:
                    try:
                        return view.context()
                    except (ContentProviderLookupError, TypeError):
                        pass

                view = obj.restrictedTraverse(view_name, None)
                if view:
                    try:
                        return view.context()
                    except (AttributeError, TypeError):
                        try:
                            return view()
                        except Exception, error:
                            log.warning("Unable to render view: '%s'! Error occurred: %s" % (view, error))
                else:
                    try:
                        return obj()
                    except AttributeError:
                        pass

        finally:
            pass

        log.warning("Not recognized object '%s'!" % repr(obj))
        return None
示例#21
0
def sync_contacts(context, ldap_records, set_owner=False):
    """Synchronize the given ldap results """

    # Statistics
    created = 0
    modified = 0
    skipped = 0
    failed = 0
    deleted = 0

    dn_contact_id_mapping = {}

    ct = getToolByName(context, 'portal_catalog')
    mapper = get_ldap_attribute_mapper()
    dummy_contact = createContent('ftw.contacts.Contact')
    dummy_contact_folder = createContent('ftw.contacts.ContactFolder')

    # 1st pass: create or update profiles
    for dn, entry in ldap_records:

        if not dn:
            continue

        dn = dn.decode('unicode_escape').encode('iso8859-1').decode('utf-8')

        # Only entries with a contact id
        contact_id = entry.get(mapper.id(), [None, ])[0]
        if not contact_id:
            skipped += 1
            logger.debug("Skipping entry '%s'. No contact id." % dn)
            continue
        # Get the normalzied name for the contact with the given id. This has
        # to be done on a dummy folder because existing content would influence
        # the resulting id.
        contact_id = INameChooser(dummy_contact_folder).chooseName(
            contact_id, dummy_contact)

        dn_contact_id_mapping[dn] = contact_id

        contact = context.unrestrictedTraverse(contact_id, None)
        changed = False
        is_new_object = False

        # Check if we really got the wanted object.
        if not IContact.providedBy(contact):
            contact = None

        # Create contact
        if contact is None:
            try:
                contact = createContent('ftw.contacts.Contact')
                contact.id = contact_id
                addContentToContainer(context, contact)

                is_new_object = True
            # invalid id
            except BadRequest:
                failed += 1
                logger.warn("Could not create contact '%s' (invalid id)."
                            % contact_id)
                continue

        # Update/set field values
        IContactSchema(contact).ldap_dn = dn
        field_mapping = dict(getFields(IContactSchema))
        for ldap_name, field_name in mapper.mapping().items():
            field = field_mapping.get(field_name, None)
            if field is None:
                raise NotImplementedError()

            value = entry.get(ldap_name, [''])[0]

            current_value = field.get(contact)
            if IBlobWrapper.providedBy(current_value):
                current_value = current_value.data

            if current_value != value:
                # Handle images
                if INamedImageField.providedBy(field) and value:
                    infile = StringIO(value)
                    filename = '%s.jpg' % contact_id
                    value = File(filename, filename, infile, 'image/jpeg')
                    value.filename = filename

                field.set(contact, value)
                changed = True

        # Update/set fields with custom updaters
        custom_updaters = getAdapters((contact, entry),
                                      provided=ILDAPCustomUpdater)
        for name, updater in custom_updaters:
            changed = updater.update()

        if is_new_object:
            if set_owner:
                # Grant owner role to contact
                contact.__ac_local_roles__ = None
                contact.manage_setLocalRoles(contact_id, ['Owner'])
                contact.reindexObjectSecurity()

            notify(ObjectCreatedEvent(contact))

            aq_contact = context.get(contact_id)
            ct.catalog_object(aq_contact, '/'.join(aq_contact.getPhysicalPath()))

            created += 1
            logger.debug("Created new contact '%s (%s)'." % (contact_id, dn))

        elif changed:
            contact.reindexObject()
            notify(ObjectModifiedEvent(contact))
            modified += 1
            logger.debug("Modified contact '%s' (%s)." % (contact_id, dn))

    total = len(ldap_records)
    unchanged = total - skipped - modified - created - failed

    # 2nd pass: set references
    # TODO

    # 3rd pass: delete contacts which have an ldap_id but are not in LDAP.
    all_contacts = ct.unrestrictedSearchResults(
        portal_type='ftw.contacts.Contact',
        path=dict(query='/'.join(context.getPhysicalPath()), depth=1))
    to_be_deleted = {}
    for contact in all_contacts:
        obj = contact.getObject()
        ldap_dn = IContactSchema(obj).ldap_dn
        if ldap_dn and ldap_dn not in dn_contact_id_mapping:
            parent_path = '/'.join(obj.getPhysicalPath()[:-1])
            id_ = obj.getPhysicalPath()[-1]
            if parent_path not in to_be_deleted:
                to_be_deleted[parent_path] = []
            to_be_deleted[parent_path].append(id_)
            logger.debug("Deleting contact '%s'" % id_)

    # Disable link integrity check while deleting contacts
    ptool = getToolByName(context, 'portal_properties')
    props = getattr(ptool, 'site_properties')
    old_check = props.getProperty('enable_link_integrity_checks', False)
    props.enable_link_integrity_checks = False

    for parent_path, ids in to_be_deleted.items():
        parent = context.unrestrictedTraverse(parent_path)
        deleted += len(ids)
        parent.manage_delObjects(ids)

    # Reenable previous link integrity setting
    props.enable_link_integrity_checks = old_check

    return dict(
        created=created,
        modified=modified,
        unchanged=unchanged,
        total=total,
        skipped=skipped,
        failed=failed,
        deleted=deleted,
    )