Пример #1
0
    def generate(self, force=False):
        ''' Generate the preview from the file attribute

        It tries to spare cpu cycles by generating the thumbnail only if the
        file is actually changed.
        For this reason a _video_size parameter on the video_thumb is set
        '''
        mtr = api.portal.get_tool('mimetypes_registry')
        if not shasattr(self.schema, 'file'):
            return

        video = self.schema.file

        try:
            mime_type_description = mtr.lookup(video.contentType)[0].id
        except:
            logger.exception('Cannot check mimetype')
            mime_type_description = ''

        if not mime_type_description == 'MPEG-4 video':
            self.schema.video_thumb = None
            return

        if not force:
            try:
                cached_size = self.schema.video_thumb._video_size
            except AttributeError:
                cached_size = None

            if cached_size == video.size:
                # Highly improbable that a new video with the same size
                # replaced the old one. We have nothing to do here
                return

        fd, tmpfile = tempfile.mkstemp()

        with openBlob(video) as f:
            cmd = 'ffmpegthumbnailer -s 0 -i {infile} -o {oufile}'.format(
                infile=f.name,
                oufile=tmpfile,
            )
            try:
                subprocess.call(cmd.split())
            except:
                self.schema.video_thumb = None
                logger.exception('Error running command %r', cmd)
                return

        thumb_name = video.filename.rpartition('.')[0] + u'.png'

        with open(tmpfile, 'rb') as thumb:
            nbi = NamedBlobImage(
                thumb.read(),
                filename=thumb_name,
            )
            nbi._video_size = video.size
            self.schema.video_thumb = nbi
Пример #2
0
 def createNewsitem(self, path, title=None):
     obj = self._createObject('News Item', path, title=title)
     named_image = NamedBlobImage(random_image(400, 200),
                                  filename=u'test.jpg',
                                  contentType='image/png')
     obj.image = named_image
     obj.reindexObject()
Пример #3
0
 def createImage(self, path, width=800, height=600, title=None):
     obj = self._createObject('Image', path, title=title)
     named_image = NamedBlobImage(random_image(width, height),
                                  filename=u'test.jpg',
                                  contentType='image/png')
     obj.image = named_image
     obj.reindexObject()
Пример #4
0
 def setUp(self):
     super(TestAvatarViews, self).setUp()
     avatar_file = open(
         os.path.join(os.path.dirname(__file__), TEST_AVATAR_FILENAME), 'r')
     self.profile1.portrait = NamedBlobImage(data=avatar_file.read(),
                                             filename=TEST_AVATAR_FILENAME)
     self.default_avatar = default_avatar(self.request.response)
Пример #5
0
    def populate_with_object(self, obj):
        """Tile can be populated with images and links; in this case we're not
        going to take care of any modification of the original object; we just
        copy the data to the tile and deal with it.
        """
        if obj.portal_type not in self.accepted_ct():
            return

        super(BannerTile, self).populate_with_object(obj)  # check permissions
        obj = aq_base(obj)  # avoid acquisition
        title = obj.Title()
        rights = obj.Rights() if hasattr(obj, 'Rights') else None

        # if image, store a copy of its data
        if obj.portal_type == 'Image':
            if hasattr(obj, 'getImage'):
                data = obj.getImage().data
            else:
                data = obj.image.data
            image = NamedBlobImage(data)
        else:
            image = None
        image_description = obj.Description() or obj.Title()
        remote_url = obj.getRemoteUrl() if obj.portal_type == 'Link' else None

        data_mgr = ITileDataManager(self)
        data_mgr.set({
            'title': title,
            'image': image,
            'image_description': image_description,
            'remote_url': remote_url,
            'rights': rights,
        })
Пример #6
0
    def get_image_data(self, obj):
        """Get image data from the object used to populate the tile.

        :param obj: object used to populate the tile
        :type obj: content type instance
        :returns: image
        :rtype: NamedBlobImage instance or None
        """
        image = None
        # if has image, store a copy of its data
        if self._has_image_field(obj) and self._field_is_visible('image'):
            scales = obj.restrictedTraverse('@@images')
            image = scales.scale('image', None)

        if image is not None and image != '':
            if isinstance(image.data, NamedBlobImage):
                # Dexterity
                image = image.data
            else:
                # Archetypes
                data = image.data
                if hasattr(data, 'data'):  # image data weirdness...
                    data = data.data
                image = NamedBlobImage(data)
        return image
Пример #7
0
 def fetch_data(self, field_obj, field_value, _obj, row_buffer):
     field_type = field_obj[1].__class__.__name__
     field_title = field_obj[1].title
     field_name = field_obj[0]
     if field_type in ('NamedBlobImage', 'NamedBlobFile'):
         request = urllib2.Request(url=field_value)
         try:
             response = urllib2.urlopen(request)
             filename = os.path.basename(response.url)
             if field_type == 'NamedBlobFile':
                 blob_file = NamedBlobFile(data=response.read(),
                                           filename=safe_unicode(filename))
             elif field_type == 'NamedBlobImage':
                 blob_file = NamedBlobImage(data=response.read(),
                                            filename=safe_unicode(filename))
             setattr(_obj, field_name, blob_file)
             return True
         except Exception:
             field_title = translate(_(field_title), context=self.request)
             error_doc = translate(
                 _("""The URL you have provided could not be reached."""),
                 context=self.request)
             msg = u'{0}: {1}; '.format(error_doc, field_title)
             row_buffer[2] += msg
             return False
Пример #8
0
    def populate_with_object(self, obj):
        """Tile can be populated with any content type with image
        or getImage attribute; in this case we're not
        going to take care of any modification of the original object; we just
        copy the data to the tile and deal with it.
        """
        if obj.portal_type not in self.accepted_ct():
            return

        super(BannerTile, self).populate_with_object(obj)  # check permissions

        if hasattr(obj, 'getRemoteUrl'):
            remote_url = obj.getRemoteUrl()
        else:
            # Get object URL
            # For Image and File objects (or any other in typesUseViewActionInListings)
            # we must add a /view to prevent the download of the file
            obj_url = obj.absolute_url_path()
            props = api.portal.get_tool('portal_properties')
            stp = props.site_properties
            view_action_types = stp.getProperty('typesUseViewActionInListings', ())

            if hasattr(obj, 'portal_type') and obj.portal_type in view_action_types:
                obj_url += '/view'

            remote_url = obj_url

        image = None
        # if has image, store a copy of its data
        if self._has_image_field(obj) and self._field_is_visible('image'):
            scales = obj.restrictedTraverse('@@images')
            image = scales.scale('image', None)

        if image is not None and image != '':
            if isinstance(image.data, NamedBlobImage):
                # Dexterity
                image = image.data
            else:
                # Archetypes
                image = NamedBlobImage(image.data)

        obj = aq_base(obj)  # avoid acquisition
        title = safe_unicode(obj.Title())

        data_mgr = ITileDataManager(self)
        data_mgr.set({
            'title': title,
            'image': image,
            'remote_url': remote_url,
        })
Пример #9
0
    def create_image(self, image, title):
        filedata = image.data.read()
        filename = image.data.filename

        blobimage = NamedBlobImage(data=filedata, filename=filename)
        obj = ploneapi.content.create(type='Image',
                                      title=title,
                                      image=blobimage,
                                      container=self.context)

        obj.indexObject()
        transaction.commit()

        return obj.UID()
Пример #10
0
def process(context):
    video = context.file

    if not video or video.filename == aws.FILENAME:
        return

    try:
        opened = openBlob(video._blob)
        bfilepath = opened.name
        opened.close()
    except IOError:
        logger.warn('error opening blob file')
        return

    # by default, assume all non-mp4 videos need to be converted
    # but in reality, all videos need converting, even mp4.
    # md5 is only what makes this possible
    convert_it = video.contentType.split('/')[-1] != 'mp4'
    if md5 is not None:
        old_hash = getattr(context, '_file_hash', None)
        current_hash = md5(bfilepath)
        if old_hash is None or old_hash != current_hash:
            convert_it = True

    if context.image and not convert_it:
        # already an mp4 and already has a screen grab
        return

    tmpdir = mkdtemp()
    tmpfilepath = os.path.join(tmpdir, video.filename)
    copyfile(bfilepath, tmpfilepath)

    if convert_it:
        output_filepath = os.path.join(tmpdir, 'output.mp4')
        try:
            avconv.convert(tmpfilepath, output_filepath)
        except:
            pass
        if os.path.exists(
                output_filepath) and os.path.getsize(output_filepath) > 0:
            if md5 is not None:
                try:
                    context._file_hash = md5(output_filepath)
                except:
                    pass
            context._p_jar.sync()
            fi = open(output_filepath)
            namedblob = NamedBlobFile(fi,
                                      filename=switchFileExt(
                                          video.filename, 'mp4'))
            context.file = namedblob
            fi.close()

    if not context.image:
        # try and grab one from video
        output_filepath = os.path.join(tmpdir, u'screengrab.png')
        try:
            avconv.grab_frame(tmpfilepath, output_filepath)
            if os.path.exists(output_filepath):
                fi = open(output_filepath)
                context.image = NamedBlobImage(fi, filename=u'screengrab.png')
                fi.close()
        except:
            logger.warn('error getting thumbnail from video')
    rmtree(tmpdir)
Пример #11
0
def _convertFormat(context):
    # reset these...
    context.video_file_ogv = None
    context.video_file_webm = None

    video = context.video_file
    context.video_converted = True
    try:
        opened = openBlob(video._blob)
        bfilepath = opened.name
        opened.close()
    except IOError:
        logger.warn('error opening blob file')
        return

    tmpdir = mkdtemp()
    tmpfilepath = os.path.join(tmpdir, video.filename)
    copyfile(bfilepath, tmpfilepath)

    try:
        metadata = avprobe.info(tmpfilepath)
    except:
        logger.warn('not a valid video format')
        return
    context.metadata = metadata

    conversion_types = {
        'mp4': 'video_file'
    }

    portal = getToolByName(context, 'portal_url').getPortalObject()
    settings = GlobalSettings(portal)
    for type_ in settings.additional_video_formats:
        format = getFormat(type_)
        if format:
            conversion_types[format.extension] = 'video_file_%s' % (
                format.extension
            )

    # sometimes force full video conversion
    force = settings.force

    for video_type, fieldname in conversion_types.items():
        if video_type == video.contentType.split('/')[-1] and not force:
            setattr(context, fieldname, video)
        else:
            output_filepath = os.path.join(tmpdir, 'output.' + video_type)
            try:
                avconv.convert(tmpfilepath, output_filepath, video_type, context)
            except:
                logger.warn('error converting to %s' % video_type)
                continue
            if os.path.exists(output_filepath):
                fi = open(output_filepath)
                namedblob = NamedBlobFile(
                    fi, filename=switchFileExt(video.filename,  video_type))
                setattr(context, fieldname, namedblob)
                fi.close()

    # try and grab one from video
    output_filepath = os.path.join(tmpdir, u'screengrab.png')
    try:
        avconv.grab_frame(tmpfilepath, output_filepath)
        if os.path.exists(output_filepath):
            with open(output_filepath, 'rb') as fi:
                data = fi.read()
            context.image = NamedBlobImage(data, filename=u'screengrab.png')
            fi.close()
    except:
        logger.warn('error getting thumbnail from video')
    rmtree(tmpdir)
Пример #12
0
def _convertFormat(context):
    # reset these...
    context.video_file_webm = None

    video = context.video_file
    context.video_converted = True
    try:
        opened = openBlob(video._blob)
        bfilepath = opened.name
        opened.close()
    except IOError:
        logger.warn('error opening blob file')
        return

    tmpdir = mkdtemp()
    tmpfilepath = os.path.join(tmpdir, video.filename)
    copyfile(bfilepath, tmpfilepath)

    try:
        metadata = avprobe.info(tmpfilepath)
    except:
        logger.warn('NOT a valid video format')
        return
    context.metadata = metadata
    logger.info('Valid video format')

    try:
        duration = _get_duration(tmpfilepath)
    except:
        logger.warn('cannot recover duration from file')
        return
    context.duration = duration

    conversion_types = {}

    portal = getToolByName(context, 'portal_url').getPortalObject()
    settings = GlobalSettings(portal)
    for type_ in settings.additional_video_formats:
        format = getFormat(type_)
        if format:
            conversion_types[format.type_] = '%s' % (format.quality)

    for video_type, quality in conversion_types.items():
        vt = video_type.split('_')[0]
        if video_type == video.contentType.split('/')[-1]:
            setattr(context, vt, video)
        else:
            output_filepath = os.path.join(tmpdir,
                                           'output_' + video_type + '.' + vt)
            try:
                avconv.convert(tmpfilepath, output_filepath, vt, quality,
                               context)
            except:
                logger.warn('error converting to %s' % vt)
                continue
            if os.path.exists(output_filepath):
                fi = open(output_filepath)
                namedblob = NamedBlobFile(fi,
                                          filename=switchFileExt(
                                              video.filename, vt))
                setattr(context, video_type, namedblob)
                fi.close()
            import transaction
            transaction.commit()

    # try and grab one from video
    output_filepath = os.path.join(tmpdir, u'screengrab.png')
    try:
        avconv.grab_frame(tmpfilepath, output_filepath)
        if os.path.exists(output_filepath):
            with open(output_filepath, 'rb') as fi:
                data = fi.read()
            context.image = NamedBlobImage(data, filename=u'screengrab.png')
            fi.close()
    except:
        logger.warn('error getting thumbnail from video')
    logger.warn('CONVERSIONS FINISHED')
    rmtree(tmpdir)
Пример #13
0
def process(context):
    video = context.file
    if not video or video.filename == aws.FILENAME:
        return

    try:
        opened = openBlob(video._blob)
        bfilepath = opened.name
        opened.close()
    except IOError:
        logger.warn('error opening blob file')
        return

    # by default, assume all non-mp4 videos need to be converted
    # but in reality, all videos need converting, even mp4.
    # md5 is only what makes this possible
    convert_it = video.contentType.split('/')[-1] != 'mp4'
    if md5 is not None:
        old_hash = getattr(context, '_file_hash', None)
        current_hash = md5(bfilepath)
        if old_hash is None or old_hash != current_hash:
            convert_it = True

    if context.image and not convert_it:
        # already an mp4 and already has a screen grab
        return

    if convert_it and youtube.should_upload(context):
        try:
            youtube.upload(context, bfilepath, filename=video.filename)
            # saving hash tells us we do not need to convert anymore...
            context._file_hash = md5(bfilepath)
            convert_it = False
        except Exception:
            logger.error('Error uploading youtube video', exc_info=True)

    tmpdir = mkdtemp()
    tmpfilepath = os.path.join(tmpdir, video.filename)
    copyfile(bfilepath, tmpfilepath)

    if convert_it:
        output_filepath = os.path.join(tmpdir, 'output.mp4')
        try:
            avconv.convert(tmpfilepath, output_filepath)
        except Exception:
            logger.info('Could not convert video', exc_info=True)
        if (os.path.exists(output_filepath) and
                os.path.getsize(output_filepath) > 0):
            if md5 is not None:
                try:
                    context._file_hash = md5(output_filepath)
                except Exception:
                    logger.info('Could not get md5', exc_info=True)
            if not getCelery().conf.task_always_eager:
                context._p_jar.sync()
            fi = open(output_filepath)
            namedblob = NamedBlobFile(
                fi, filename=switchFileExt(video.filename, 'mp4'))
            context.file = namedblob
            fi.close()

    if not context.image:
        # try and grab one from video
        output_filepath = os.path.join(tmpdir, u'screengrab.png')
        try:
            avconv.grab_frame(tmpfilepath, output_filepath)
            if os.path.exists(output_filepath):
                fi = open(output_filepath)
                context.image = NamedBlobImage(fi, filename=u'screengrab.png')
                fi.close()
        except Exception:
            logger.warning(
                'error getting thumbnail from video', exc_info=True)
    rmtree(tmpdir)
Пример #14
0
    def addMail(self, mailString):
        """ Store mail as news item
            Returns created item
        """

        pw = self.context.portal_workflow

        (header, body) = splitMail(mailString)

        # if 'keepdate' is set, get date from mail,
        # XXX 'time' is unused
        if self.getValueFor('keepdate'):
            timetuple = rfc822.parsedate_tz(header.get('date'))
            time = DateTime(rfc822.mktime_tz(timetuple))
        # ... take our own date, clients are always lying!
        else:
            time = DateTime()

        (TextBody, ContentType, HtmlBody, Attachments) = unpackMail(mailString)

        # Test Zeitangabe hinter Subject
        today = date.today()
        mydate = today.strftime("%d.%m.%Y")

        # let's create the news item

        subject = mime_decode_header(header.get('subject', 'No Subject'))
        sender = mime_decode_header(header.get('from', 'No From'))
        title = "%s" % (subject)

        new_id = IUserPreferredURLNormalizer(self.request).normalize(title)
        id = self._findUniqueId(new_id)
        # ContentType is only set for the TextBody
        if ContentType:
            body = TextBody
        else:
            body = self.HtmlToText(HtmlBody)

        # XXX als vorlaeufige Loesung
        from zope.component import getMultiAdapter
        plone_view = getMultiAdapter((self.context, self.request),
                                     name='plone')
        desc = plone_view.cropText(body, 60)
        body = '\n'.join([wrap_line(line) for line in body.splitlines()])
        uni_aktuell_body = ("<p><strong>%s: %s</strong></p> "
                            "<p>&nbsp;</p><pre>%s</pre>" %
                            (mydate, sender, body))

        objid = self.context.invokeFactory(
            'News Item',
            id=id,
            title=title,
            text=RichTextValue(uni_aktuell_body),
            description=desc,
        )

        mailObject = getattr(self.context, objid)
        images = [
            att for att in Attachments
            if att['maintype'] == 'image' and att['filename']
        ]
        if images and hasattr(mailObject, 'image'):
            image = Attachments[0]
            mailObject.image = NamedBlobImage(
                filename=safe_unicode(image['filename']),
                data=image['filebody'],
            )
        try:
            pw.doActionFor(mailObject, 'publish')
        except Exception as e:
            log.exception(e)
        return mailObject
    #         notes += safe_unicode(str(row))
    #         # if key in ids:
    #         #     setattr(newart, ids[key], value)
    #         # elif key == 'note' and value:
    #         #     newart.text = RichTextValue(value, 'text/html', 'text/html')
    #         #     # print "Note",
    # if notes:
    #     re.compile(r'resolveuid/([0-9a-f]+)').sub(resolveUID, notes)
    #     notes = u"<table>%s</table>" % notes
    #     newart.text = RichTextValue(notes, 'text/html', 'text/html')

    setSite(target_site)
    notes = u"<dl>%s</dl>" % notes
    newart.text = RichTextValue(notes, 'text/html', 'text/html')
    awImageField = awImageItem.Schema().get('image')
    image = NamedBlobImage()
    image.data = scaleImage(awImageField, awImageItem)
    image.contentType = awImageItem.content_type
    filename = awImageItem.getFilename()
    if filename:
        image.filename = filename.decode('ASCII')
    else:
        filename = id
    newart.image = image
    target_folder[id] = newart
    print id,
    if u'resolve' in notes:
        print 'resolveuid'
    else:
        print
commit()
Пример #16
0
    def test_avatar_tag_with_portrait(self):
        self.login_as_portal_owner()
        profile = pi_api.userprofile.create(
            username='******',
            email='*****@*****.**',
            approve=True,
            properties={
                'fullname': 'Jane Doe',
            },
        )
        profile.portrait = NamedBlobImage(
            data='GIF89a;',
            filename=u'avatar.png')

        self.maxDiff = None
        tag_no_link = re.sub('[ \n]+', ' ', pi_api.userprofile.avatar_tag(
            username='******', link_to=None))
        self.assertEqual(
            tag_no_link,
            u' <span class="pat-avatar avatar" data-initials="{initials}" '
            'title="{fullname}" > '
            '<img src="{portal_url}/profiles/{userid}/@@avatar_profile.jpg" '
            'alt="Image of {fullname}" class="" '
            'i18n:attributes="alt"> '
            '</span>'
            ''.format(
                portal_url=self.portal.absolute_url(),
                userid=profile.username,
                fullname=profile.fullname,
                initials=profile.initials,
            ))

        tag_link_profile = re.sub('[ \n]+', ' ', pi_api.userprofile.avatar_tag(
            username='******', link_to='profile'))
        self.assertEqual(
            tag_link_profile,
            u' <a href="{portal_url}/profiles/{userid}" '
            'class="pat-avatar avatar" data-initials="{initials}" '
            'title="{fullname}" > '
            '<img src="{portal_url}/profiles/{userid}/@@avatar_profile.jpg" '
            'alt="Image of {fullname}" class="" '
            'i18n:attributes="alt"> '
            '</a>'
            ''.format(
                portal_url=self.portal.absolute_url(),
                userid=profile.username,
                fullname=profile.fullname,
                initials=profile.initials,
            ))

        tag_link_image = re.sub('[ \n]+', ' ', pi_api.userprofile.avatar_tag(
            username='******', link_to='image'))
        self.assertEqual(
            tag_link_image,
            u' <a href="{portal_url}/profiles/{userid}/@@avatar_profile.jpg" '
            'class="pat-avatar avatar pat-gallery user-info-avatar" '
            'data-initials="{initials}" title="{fullname}" > '
            '<img src="{portal_url}/profiles/{userid}/@@avatar_profile.jpg" '
            'alt="Image of {fullname}" class="" '
            'i18n:attributes="alt"> '
            '</a>'

            ''.format(
                portal_url=self.portal.absolute_url(),
                userid=profile.username,
                fullname=profile.fullname,
                initials=profile.initials,
            ))
Пример #17
0
    def render(self):
        # Get the api key from registry
        settings = get_settings()

        # workaround for http://bugs.python.org/issue5285,
        # map unicode to strings
        janrain_api_key = str(settings.janrain_api_key)

        if not janrain_api_key:
            return 'No Janrain API key configured'

        # Get the token
        token = self.request.form.get('token', None)
        if not token:
            return 'No token passed in request'

        # Get the user profile from Janrain
        auth_info_url = '%s/auth_info?apiKey=%s&token=%s' % (
            JANRAIN_API_BASE_URL,
            janrain_api_key,
            token,
        )

        if settings.janrain_use_extended_profile:
            auth_info_url = auth_info_url + '&extended=true'

        resp = urllib2.urlopen(auth_info_url)
        auth_info = simplejson.loads(resp.read())

        # This is for Plone's built in member management instead of membrane
        # See if a user already exists for the profile's email
        # email = auth_info['profile']['email']
        # member = None
        # if email:
        #     member = mtool.getMemberById(email)

        # See if user already exists using dexterity.membrane
        profile = auth_info.get('profile', {})

        email = profile.get('verifiedEmail', None)

        # NB: Do NOT accept the 'email' attribute as an alternative
        # to 'verifiedEmail'.  The 'email' attribute can be entered by
        # users and therefore would be a security hole.

        if not email:
            raise AttributeError(
                'No email provided from social profile, unable to create '
                'account')

        email = email.lower()

        res = get_brains_for_email(self.context, email, self.request)
        if not res:
            # create new Person if no existing Person was found
            # with the same email
            name = profile.get('name', {})
            address = profile.get('address', {})
            if not address:
                addresses = profile.get('addresses', [])
                if addresses:
                    address = addresses[0]

            data = {
                'first_name': name.get('givenName', None),
                'last_name': name.get('familyName', None),
                'email': email,
                'street_address': address.get('streetAddress', None),
                'city': address.get('locality', None),
                'state': address.get('region', None),
                'zip': address.get('postalCode', None),
                'country': address.get('country', None),
                # 'gender': profile.get('gender', None),
                'social_signin': True,
            }

            # Create the user
            people_container = getattr(getSite(), 'people')
            person = createContentInContainer(
                people_container,
                'collective.salesforce.fundraising.person',
                checkConstraints=False,
                **data)

            # Authenticate the user
            mtool = getToolByName(self.context, 'portal_membership')
            acl = getToolByName(self.context, 'acl_users')
            newSecurityManager(None, acl.getUser(email))
            mtool.loginUser()

        # or use the existing Person if found
        else:
            # Authenticate the user
            mtool = getToolByName(self.context, 'portal_membership')
            acl = getToolByName(self.context, 'acl_users')
            newSecurityManager(None, acl.getUser(email))
            mtool.loginUser()

            person = res[0].getObject()

            if not person.social_signin:
                person.social_signin = True

        # Set the photo
        photo = profile.get('photo', None)
        if not photo:
            photos = profile.get('photos', [])
            if photos:
                photo = photos[0]
        if photo and (not person.portrait or not person.portrait.size):
            img_data = urllib2.urlopen(photo).read()
            person.portrait = NamedBlobImage(img_data)

        # See if came_from was passed
        came_from = self.request.form.get('came_from', None)
        # fix odd bug where came_from is a list of two values
        if came_from and isinstance(came_from, (list, tuple)):
            came_from = came_from[0]
        if came_from:
            return self.request.response.redirect(came_from)

        # merge in with standard plone login process.
        login_next = self.context.restrictedTraverse('login_next')
        login_next()