Exemple #1
0
 def testBlobbableOFSImage(self):
     gif = getImage()
     obj = Image('foo', 'Foo', StringIO(gif))
     obj.filename = 'foo.gif'
     blobbable = IBlobbable(obj)
     target = Blob()
     blobbable.feed(target)
     self.assertEqual(target.open('r').read(), gif)
     self.assertEqual(blobbable.filename(), 'foo.gif')
     self.assertEqual(blobbable.mimetype(), 'image/gif')
 def publishTraverse(self, request, name):
     if name == 'image':
         site = portal.getSite()
         icon = self.context.getIcon()
         if icon.startswith('/'):
             icon = icon[1:]
         img = site.restrictedTraverse(icon)
         if "++resource++" in icon:
             img = Image('img', 'image', img.GET())
             img = img.__of__(self.context)
         return IconWrapper(img)
     return super(AceContentImagesTraverser, self).publishTraverse(request,
                                                                   name)
Exemple #3
0
 def manage_upload(self,file='',REQUEST=None):
   """ overrides Image.manage_upload to trigger Zoomify metadata generation 
       whenever file data is uploaded to Zope (covers add and edit methods) """
  
   self._v_imageFilename = file.filename
   Image.manage_upload(self, file=file, REQUEST=REQUEST)
   
   if REQUEST:
     message=""" The image has been saved, and Zoomify metadata is now being
                 generated on the server. It will take time for the process
                 to complete, and for the image data to be available for the
                 Zoomify viewer. """
                
     return self.aq_parent.manage_main(self,REQUEST,manage_tabs_message=message)
Exemple #4
0
 def test_OFSFileLastModified_Image(self):
     from OFS.Image import Image
     
     dummy = Image('dummy', 'Dummy', 'data')
     self.assertEquals(None, ILastModified(dummy)())
     
     timestamp = 987654321.0 # time stamp (in UTC)
     ts = TimeStamp(*time.gmtime(timestamp)[:6]) # corresponding TimeStamp
     
     # equivalent in local time, which is what the last-modified adapter
     # should return
     mod = datetime.datetime.fromtimestamp(timestamp, tzlocal())
     
     dummy._p_jar = FauxDataManager()
     dummy._p_serial = repr(ts)
     self.assertEquals(mod, ILastModified(dummy)())
Exemple #5
0
 def preview(self, height=None, width=None, alt=None,
             scale=0, xscale=0, yscale=0, css_class=None, title=None, **args):
   """ allow custom imageEdit form to work as expected by returning 
       Image.tag result for the preview image """
       
   result = ''
   if hasattr(self, 'TileGroup0') and hasattr(self.TileGroup0, '0-0-0.jpg'):
     result = Image.tag(self.TileGroup0['0-0-0.jpg'], height=height, width=width, 
                                                   alt=alt, scale=scale, 
                                                   xscale=xscale, yscale=yscale, 
                                                   css_class=css_class, 
                                                   title=title, **args)
   else:
     result = 'The image is not yet ready to be displayed.'
                                                 
   return result
Exemple #6
0
    def PUT_factory(self, name, typ, body):
        """
            Dispatcher for PUT requests to non-existent IDs.  Returns
            an object of the appropriate type (or None, if we don't
            know what to do).
        """
        major, minor = typ.split('/', 1)

        if major == 'image':
            return Image(id=name, title='', file='', content_type=typ)

        if major == 'text':

            if minor == 'x-python':
                return PythonScript(id=name)

            if minor in ('html', 'xml'):
                return ZopePageTemplate(name)

            return DTMLMethod(__name__=name)

        return None
def changeMemberPortrait(self, portrait, id=None):
    """update the portait of a member.

    We URL-quote the member id if needed.

    Note that this method might be called by an anonymous user who
    is getting registered.  This method will then be called from
    plone.app.users and this is fine.  When called from restricted
    python code or with a curl command by a hacker, the
    declareProtected line will kick in and prevent use of this
    method.
    """
    authenticated_id = self.getAuthenticatedMember().getId()
    if not id:
        id = authenticated_id
    safe_id = self._getSafeMemberId(id)

    # dexterity.membrane hand the current user id in unicode, but BTree can't
    # handle unicode keys in inner objects... *sigh*
    if isinstance(safe_id, unicode):
        safe_id = str(safe_id)

    valid_id = id == authenticated_id or id == authenticated_id + '_large'

    if authenticated_id and not valid_id:
        # Only Managers can change portraits of others.
        if not _checkPermission(ManageUsers, self):
            raise Unauthorized
    if portrait and portrait.filename:
        if not id.endswith('_large'):
            # Override default resizing
            scaled, mimetype = convertSquareImage(portrait)
        else:
            scaled, mimetype = adjust_large_image(portrait)

        portrait = Image(id=safe_id, file=scaled, title='')
        membertool = getToolByName(self, 'portal_memberdata')
        membertool._setPortrait(portrait, safe_id)
Exemple #8
0
def create_users(context):
    if context.readDataFile('loadcontent_various.txt') is None:
        return

    portal = context.getSite()
    pr = plone.api.portal.get_tool(name='portal_registration')
    pg = plone.api.portal.get_tool(name='portal_groups')
    pm = plone.api.portal.get_tool(name='portal_membership')
    pmd = plone.api.portal.get_tool(name='portal_memberdata')

    for user_data in TEST_USERS:
        username, password, group, portrait = (user_data.pop('username', None),
                                               user_data.pop('password', None),
                                               user_data.pop('group', None),
                                               user_data.pop('portrait', None))
        if username not in portal.acl_users.getUserIds():
            try:
                pr.addMember(username, password)
                if group:
                    pg.addPrincipalToGroup(username, group)
                user = pm.getMemberById(username)
                user.setMemberProperties(mapping=user_data)
                if portrait:
                    portrait_file = open(
                        os.path.join(os.path.dirname(__file__), 'data',
                                     portrait), 'rb')
                    pmd._setPortrait(
                        Image(id=username,
                              file=portrait_file,
                              title=user_data['fullname']), username)
                    portrait_file.close()
            except ValueError:
                logger.warn('The login name "%s" is not valid.' % username)
            except KeyError:
                logger.warn('The group "%s" is not valid.' % group)
    return 'Users created'
    def test_get_commenter_portrait(self):

        # Add a user with a member image
        self.membershipTool.addMember('jim', 'Jim', ['Member'], [])
        self.memberdata._setPortrait(
            Image(
                id='jim',
                file=dummy.File(),
                title='',
            ), 'jim')
        self.assertEqual(
            self.memberdata._getPortrait('jim').getId(),
            'jim',
        )
        self.assertEqual(
            self.memberdata._getPortrait('jim').meta_type,
            'Image',
        )

        # Add a conversation with a comment
        conversation = IConversation(self.portal.doc1)
        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        comment.Creator = 'Jim'
        comment.author_username = '******'
        conversation.addComment(comment)

        # Call get_commenter_portrait method of the viewlet
        self.viewlet.update()
        portrait_url = self.viewlet.get_commenter_portrait('jim')

        # Check if the correct member image URL is returned
        self.assertEqual(
            portrait_url,
            'http://nohost/plone/portal_memberdata/portraits/jim',
        )
Exemple #10
0
    def _createObjectByType(self, name, body, content_type):

        if name.endswith('.py'):

            ob = PythonScript(name)
            ob.write(body)

        elif name.endswith('.dtml'):

            ob = DTMLDocument('', __name__=name)
            ob.munge(body)

        elif content_type in ('text/html', 'text/xml'):

            ob = ZopePageTemplate(name, str(body), content_type=content_type)

        elif content_type[:6] == 'image/':

            ob = Image(name, '', body, content_type=content_type)

        else:
            ob = File(name, '', body, content_type=content_type)

        return ob
 def imageFromUpload(self, id, title, image_file):
     image = Image(id, title, image_file)
     return image
    def set(self, name, instance, value, **kwargs):
        """Set a value under the key 'name' for retrevial by/for
        instance."""

        # collect value info
        filename = getattr(value, 'filename', '')
        content_type = getattr(value, 'content_type', '')
        width = getattr(value, 'width', '')
        height = getattr(value, 'height', '')

        aws_utility = getUtility(IAWSFileClientUtility)
        if not aws_utility.active():
            if isinstance(value, AWSFile):
                # use default OFS.Image or OFS.File
                if width and height:
                    # we have image
                    value = Image(value.id(), '', str(value.data),
                                  content_type=content_type)
                else:
                    value = File(value.id(), '', str(value.data),
                                 content_type=content_type)
                setattr(value, 'filename', filename)
            AnnotationStorage.set(self, name, instance, value, **kwargs)
            return

        try:
            file_ = self.get(name, instance, **kwargs)
        except AttributeError:
            file_ = None

        if file_:
            if isinstance(file_, AWSFile):
                try:
                    self.update_source(file_, value.data, instance,
                                       filename, content_type, width, height)
                except (FileClientRemoveError, FileClientStoreError), e:
                    request = instance.REQUEST
                    IStatusMessage(request).addStatusMessage(
                        u"Couldn't update %s file to storage. %s" %
                        (safe_unicode(filename),
                         safe_unicode(e.message)), type='error')
                    if isinstance(value, AWSFile):
                        # use default OFS.Image or OFS.File
                        if width and height:
                            # we have image
                            value = Image(value.id(), '', str(value.data),
                                          content_type=content_type)
                        else:
                            value = File(value.id(), '', str(value.data),
                                         content_type=content_type)
                        setattr(value, 'filename', filename)
                    AnnotationStorage.set(self, name, instance,
                                          value, **kwargs)
                else:
                    # clean up data after update
                    setattr(file_, 'data', '')
            else:
                try:
                    file_ = self._do_migrate(file_, instance,
                                             data=value.data,
                                             filename=filename,
                                             content_type=content_type,
                                             width=width,
                                             height=height)
                except (FileClientRemoveError, FileClientStoreError):
                    request = instance.REQUEST
                    IStatusMessage(request).addStatusMessage(
                        u"Couldn't update %s file to storage. %s" %
                        (safe_unicode(filename),
                         safe_unicode(e.message)), type='error')
                    AnnotationStorage.set(self, name, instance,
                                          value, **kwargs)
                else:
                    AnnotationStorage.set(self, name, instance,
                                          file_, **kwargs)
Exemple #13
0
def demo(context):

    if context.readDataFile('plonesocial.suite_demo.txt') is None:
        return

    portal = site = context.getSite()
    avatar_path = os.path.join(context._profile_path, 'avatars')

    # create users
    users = []
    for file_name in os.listdir(avatar_path):
        userid = str(file_name.split('.')[0])
        users.append(userid)
        properties = dict(
            fullname=" ".join([x.capitalize() for x in userid.split("_")]),
            location=random.choice(("New York", "Chicago", "San Francisco",
                                    "Paris", "Amsterdam", "Zurich")),
            description=" ".join(loremipsum.get_sentences(2)))
        try:
            api.user.create(email='*****@*****.**' % userid,
                            username=userid,
                            password='******',
                            properties=properties)
        except ValueError:
            user = api.user.get(username=userid)
            user.setMemberProperties(properties)

        portrait = context.openDataFile(file_name, 'avatars')
        scaled, mimetype = scale_image(portrait)
        portrait = Image(id=userid, file=scaled, title='')
        memberdata = getToolByName(site, 'portal_memberdata')
        memberdata._setPortrait(portrait, userid)

    # setup social network
    graph = queryUtility(INetworkGraph)
    graph.clear()
    testusers = ['clare_presler', 'kurt_silvio']
    graph.set_follow(testusers[1], testusers[0])
    # give clare som extra followers
    for fan in ['christian_stoner', 'guy_hachey', 'jamie_jacko']:
        graph.set_follow(fan, testusers[0])
    # fully random followers
    for i in xrange(100):
        followee = random.choice(users)
        follower = random.choice(users)
        if followee in testusers or follower in testusers \
                or followee == follower:
            continue
        else:
            graph.set_follow(follower, followee)

    # setup publicly accessible folder and document
    portal.invokeFactory('Folder', 'public', title=u"Public Folder")
    public = portal['public']
    public.invokeFactory('Document', 'd1', title=u"Public Document")

    # create and fill a local IMicroblogContext workspace
    workspace_users = [
        'clare_presler', 'dollie_nocera', 'esmeralda_claassen',
        'pearlie_whitby'
    ]
    if 'workspace' not in portal:
        portal.invokeFactory('Folder', 'workspace', title=u"Secure Workspace")
        # enable local microblog
        directlyProvides(portal.workspace, IMicroblogContext)
        # in testing we don't have the 'normal' default workflow
        workflowTool = getToolByName(portal, 'portal_workflow')
        if workflowTool.getInfoFor(portal.workspace,
                                   'review_state') != 'private':
            workflowTool.doActionFor(portal.workspace, 'hide')
        # share workspace with some users
        for userid in workspace_users:
            api.user.grant_roles(username=userid,
                                 obj=portal.workspace,
                                 roles=['Contributor', 'Reader', 'Editor'])
        # update object_provides + workflow state + sharing indexes
        portal.workspace.reindexObject()

    # microblog random loremipsum
    # prepare microblog
    microblog = queryUtility(IMicroblogTool)
    microblog.clear()  # wipe all
    tags = ("hr", "marketing", "fail", "innovation", "learning", "easy",
            "newbiz", "conference", "help", "checkthisout")
    for i in xrange(100):
        # select random user
        userid = random.choice(users)
        # generate text
        text = " ".join(loremipsum.get_sentences(3))
        if random.choice((True, False)):
            text += " #%s" % random.choice(tags)
        if userid in workspace_users:
            # workspace
            text += ' #girlspace'
            status = StatusUpdate(text, context=portal.workspace)
        else:
            # global
            status = StatusUpdate(text)
        status.userid = userid
        status.creator = " ".join([x.capitalize() for x in userid.split("_")])
        # distribute most over last week
        if i < 90:
            offset_time = random.random() * 3600 * 24 * 7
            status.id -= int(offset_time * 1e6)
            status.date = DateTime(time.time() - offset_time)
        microblog.add(status)

    # microblog deterministic test content most recent
    # workspace
    t0 = ('Workspaces can have local microblogs and activitystreams. '
          'Local activitystreams show only local status updates. '
          'Microblog updates will show globally only for users who '
          'have the right permissions. This demo has a #girlspace workspace.')
    s0 = StatusUpdate(t0, context=portal.workspace)
    s0.userid = workspace_users[0]  # clare
    s0.creator = " ".join([x.capitalize() for x in s0.userid.split("_")])
    microblog.add(s0)
    # global
    t1 = ('The "My Network" section only shows updates '
          'of people you are following.')
    s1 = StatusUpdate(t1)
    s1.userid = testusers[0]  # clare
    s1.creator = " ".join([x.capitalize() for x in s1.userid.split("_")])
    microblog.add(s1)
    t2 = 'The "Explore" section shows all updates of all people.'
    s2 = StatusUpdate(t2)
    s2.userid = testusers[1]  # kurt
    s2.creator = " ".join([x.capitalize() for x in s2.userid.split("_")])
    microblog.add(s2)
    t3 = 'The #demo hashtag demonstrates that you can filter on topic'
    s3 = StatusUpdate(t3)
    s3.userid = s2.userid  # kurt
    s3.creator = s2.creator
    microblog.add(s3)

    # commit
    microblog.flush_queue()
    transaction.commit()
Exemple #14
0
 def _toFieldValue(self, input):
     value=super(ImageWidget, self)._toFieldValue(input)
     if value is not self.context.missing_value:
         value=Image('image','image', value)
     return value
    def test_exportXML(self):
        from OFS.Folder import Folder
        from OFS.Image import Image
        from OFS.XMLExportImport import exportXML

        connection, app = self._makeJarAndRoot()
        data = open(imagedata, 'rb')

        sub = Folder('sub')
        app._setObject('sub', sub)
        img = Image('image', '', data, 'image/gif')
        sub._setObject('image', img)
        img._setProperty('prop1', 3.14159265359, 'float')
        img._setProperty('prop2', 1, 'int')
        img._setProperty('prop3', 2L**31-1, 'long')
        img._setProperty('prop4', 'xxx', 'string')
        img._setProperty('prop5', ['xxx', 'zzz'], 'lines')
        img._setProperty('prop6', u'xxx', 'unicode')
        img._setProperty('prop7', [u'xxx', u'zzz'], 'ulines')
        img._setProperty('prop8', '<&>', 'string')
        img._setProperty('prop9', u'<&>', 'unicode')
        img._setProperty('prop10', '<]]>', 'string')
        img._setProperty('prop11', u'<]]>', 'unicode')
        img._setProperty('prop12', u'£', 'unicode')
        transaction.savepoint(optimistic=True)
        oid = sub._p_oid

        handle, path = tempfile.mkstemp(suffix='.xml')
        try:
            ostream = os.fdopen(handle,'wb')
            data = exportXML(connection, oid, ostream)
            ostream.close()
        finally:
            os.remove(path)
  def includeImageList(self, data):
    """Include Images in ODF archive

    - data: zipped archive content
    """
    builder = OOoBuilder(data)
    content = builder.extract('content.xml')
    xml_doc = etree.XML(content)
    image_tag_list = xml_doc.xpath('//*[name() = "draw:image"]')
    SVG_NAMESPACE = 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'
    XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink'
    ratio_px_cm = 2.54 / 100.
    # Flag to enable modification of OOoBuilder
    odt_content_modified = False
    for image_tag in image_tag_list:
      frame = image_tag.getparent()
      #Try to get image file from ZODB
      href_attribute_list = image_tag.xpath('.//@*[name() = "xlink:href"]')
      url = href_attribute_list[0]
      parse_result = urlparse(unquote(url))
      # urlparse return a 6-tuple: scheme, netloc, path, params, query, fragment
      netloc = parse_result[1]
      path = parse_result[2]
      if path and netloc in ('', None):
        # it makes sense to include only relative to current site images not remote ones which can be taken by OOo
        # OOo corrupt relative Links inside HTML content during odt conversion
        # <img src="REF.TO.IMAGE" ... /> become <draw:image xlink:href="../REF.TO.IMAGE" ... />
        # So remove "../" added by OOo
        path = CLEAN_RELATIVE_PATH.sub('', path)
        # in some cases like Web Page content "/../" can be contained in image URL which will break
        # restrictedTraverse calls, our best guess is to remove it
        path = path.replace('/../', '')
        # remove occurencies of '//' or '///' in path (happens with web pages) and leave
        # a traversable relative URL
        path = '/'.join([x for x in path.split('/') if x.strip()!=''])
        # retrieve http parameters and use them to convert image
        query_parameter_string = parse_result[4]
        image_parameter_dict = dict(parse_qsl(query_parameter_string))
        try:
          image = self.context.restrictedTraverse(path)
        except (AttributeError, KeyError):
          #Image not found, this image is probably not hosted by ZODB. Do nothing
          image = None
        if image is not None:
          odt_content_modified = True
          content_type = image.getContentType()
          format = image_parameter_dict.pop('format', None)
          # convert API accepts only a certail range of arguments
          for key, value in image_parameter_dict.items():
            if key not in ('format', 'display', 'quality', 'resolution',):
              image_parameter_dict.pop(key)
          if getattr(image, 'convert', None) is not None:
            # The document support conversion so perform conversion
            # according given parameters
            mime, image_data = image.convert(format, **image_parameter_dict)
            # wrapp converted data into OFSImage in order to compute metadatas
            # on converted result
            image = OFSImage(image.getId(), image.getTitle(), image_data)

          # image should be OFSImage
          data = str(image.data)
          width = image.width
          height = image.height
          if height:
            frame.attrib.update({'{%s}height' % SVG_NAMESPACE: '%.3fcm' % (height * ratio_px_cm)})
          if width:
            frame.attrib.update({'{%s}width' % SVG_NAMESPACE: '%.3fcm' % (width * ratio_px_cm)})
          if not format:
            mimetype_list = self.context.getPortalObject().mimetypes_registry.lookup(content_type)
            # guess a format with help of mimetypes_registry
            for mimetype_object in mimetype_list:
              if mimetype_object.extensions:
                format = mimetype_object.extensions[0]
                break
              elif mimetype_object.globs:
                format = mimetype_object.globs[0].strip('*.')
                break
          new_path = builder.addImage(data, format=format)
          image_tag.attrib.update({'{%s}href' % XLINK_NAMESPACE: new_path})
    if odt_content_modified:
      builder.replace('content.xml', etree.tostring(xml_doc, encoding='utf-8',
                                                    xml_declaration=True,
                                                    pretty_print=False))
    return builder.render()
Exemple #17
0
            # logo not uploaded, return without doing anything
            return

        skins = getToolByName(self.context, 'portal_skins')
        target = self.context
        if 'custom' in skins:
            target = skins['custom']

        if LOGO_ID in target:
            img = target[LOGO_ID]
            if isinstance(img, Image):
                # this is an OFS image, or subclass, we should have the
                # update_data method
                try:
                    img.update_data(new_logo)
                    return
                except TypeError, e:
                    # there is a problem with the logo data, it's unicode
                    raise e
                except AttributeError, e:
                    # no update_data method.  make a new one and replace this
                    # one
                    pass
            else:
                # let's override it, it isn't an expected type.
                pass

        img = Image(LOGO_ID, 'Custom Site Logo', new_logo)
        target._setObject(LOGO_ID, img)
        return
Exemple #18
0
 def __call__(self, portrait, safe_id):
     if portrait and portrait.filename:
         scaled, mimetype = scale_image(portrait)
         portrait = Image(id=safe_id, file=scaled, title='')
         membertool = api.portal.get_tool(name='portal_memberdata')
         membertool._setPortrait(portrait, safe_id)
Exemple #19
0
    def includeImageList(self, data):
        """Include Images in ODF archive

    - data: zipped archive content
    """
        builder = OOoBuilder(data)
        content = builder.extract('content.xml')
        xml_doc = etree.XML(content)
        image_tag_list = xml_doc.xpath('//*[name() = "draw:image"]')
        SVG_NAMESPACE = 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'
        XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink'
        ratio_px_cm = 2.54 / 100.
        # Flag to enable modification of OOoBuilder
        odt_content_modified = False
        for image_tag in image_tag_list:
            frame = image_tag.getparent()
            #Try to get image file from ZODB
            href_attribute_list = image_tag.xpath(
                './/@*[name() = "xlink:href"]')
            url = href_attribute_list[0]
            parse_result = urlparse(unquote(url))
            # urlparse return a 6-tuple: scheme, netloc, path, params, query, fragment
            netloc = parse_result[1]
            path = parse_result[2]
            if path and netloc in ('', None):
                # it makes sense to include only relative to current site images not remote ones which can be taken by OOo
                # OOo corrupt relative Links inside HTML content during odt conversion
                # <img src="REF.TO.IMAGE" ... /> become <draw:image xlink:href="../REF.TO.IMAGE" ... />
                # So remove "../" added by OOo
                path = CLEAN_RELATIVE_PATH.sub('', path)
                # in some cases like Web Page content "/../" can be contained in image URL which will break
                # restrictedTraverse calls, our best guess is to remove it
                path = path.replace('/../', '')
                # remove occurencies of '//' or '///' in path (happens with web pages) and leave
                # a traversable relative URL
                path = '/'.join(
                    [x for x in path.split('/') if x.strip() != ''])
                # retrieve http parameters and use them to convert image
                query_parameter_string = parse_result[4]
                image_parameter_dict = dict(parse_qsl(query_parameter_string))
                try:
                    image = self.context.restrictedTraverse(path)
                except (AttributeError, KeyError):
                    #Image not found, this image is probably not hosted by ZODB. Do nothing
                    image = None
                if image is not None:
                    odt_content_modified = True
                    content_type = image.getContentType()
                    format = image_parameter_dict.pop('format', None)
                    # convert API accepts only a certail range of arguments
                    for key, value in ensure_list(
                            image_parameter_dict.items()):
                        if key not in (
                                'format',
                                'display',
                                'quality',
                                'resolution',
                        ):
                            image_parameter_dict.pop(key)
                    if getattr(image, 'convert', None) is not None:
                        # The document support conversion so perform conversion
                        # according given parameters
                        mime, image_data = image.convert(
                            format, **image_parameter_dict)
                        # wrapp converted data into OFSImage in order to compute metadatas
                        # on converted result
                        image = OFSImage(image.getId(), image.getTitle(),
                                         image_data)

                    # image should be OFSImage
                    data = str(image.data)
                    width = image.width
                    height = image.height
                    if height:
                        frame.attrib.update({
                            '{%s}height' % SVG_NAMESPACE:
                            '%.3fcm' % (height * ratio_px_cm)
                        })
                    if width:
                        frame.attrib.update({
                            '{%s}width' % SVG_NAMESPACE:
                            '%.3fcm' % (width * ratio_px_cm)
                        })
                    if not format:
                        mimetype_list = self.context.getPortalObject(
                        ).mimetypes_registry.lookup(content_type)
                        # guess a format with help of mimetypes_registry
                        for mimetype_object in mimetype_list:
                            if mimetype_object.extensions:
                                format = mimetype_object.extensions[0]
                                break
                            elif mimetype_object.globs:
                                format = mimetype_object.globs[0].strip('*.')
                                break
                    new_path = builder.addImage(data, format=format)
                    image_tag.attrib.update(
                        {'{%s}href' % XLINK_NAMESPACE: new_path})
        if odt_content_modified:
            builder.replace(
                'content.xml',
                etree.tostring(xml_doc,
                               encoding='utf-8',
                               xml_declaration=True,
                               pretty_print=False))
        return builder.render()
Exemple #20
0
class ConfManager(
        _multilangmanager.MultiLanguageManager,
        _metacmdmanager.MetacmdManager,
        _filtermanager.FilterManager,
):
    zope.interface.implements(IZMSMetamodelProvider.IZMSMetamodelProvider,
                              IZMSFormatProvider.IZMSFormatProvider)

    # Create a SecurityInfo for this class. We will use this
    # in the rest of our class definition to make security
    # assertions.
    security = ClassSecurityInfo()

    # Management Interface.
    # ---------------------
    addZMSCustomForm = ConfDict.template('addzmscustomform')
    addZMSLinkElementForm = ConfDict.template('addzmslinkelementform')
    addZMSSqlDbForm = ConfDict.template('addzmssqldbform')
    manage_customize = HTMLFile('dtml/ZMS/manage_customize', globals())
    manage_customizeLanguagesForm = HTMLFile(
        'dtml/ZMS/manage_customizelanguagesform', globals())
    manage_customizeMetacmdForm = HTMLFile('dtml/metacmd/manage_customizeform',
                                           globals())
    manage_customizeFilterForm = HTMLFile(
        'dtml/ZMS/manage_customizefilterform', globals())
    manage_customizeDesignForm = HTMLFile(
        'dtml/ZMS/manage_customizedesignform', globals())
    manage_editorForm = HTMLFile('dtml/ZMS/manage_editorform', globals())

    # --------------------------------------------------------------------------
    #  ConfManager.importConfPackage:
    # --------------------------------------------------------------------------
    def importConfPackage(self, file, REQUEST, createIfNotExists=0):
        if type(file) is str:
            if file.startswith('http://'):
                file = StringIO(self.http_import(file))
            else:
                file = open(_fileutil.getOSPath(file), 'rb')
        files = _fileutil.getZipArchive(file)
        for f in files:
            if not f.get('isdir'):
                self.importConf(f, REQUEST, createIfNotExists)
        self.synchronizeObjAttrs()

    # --------------------------------------------------------------------------
    #  ConfManager.getConfXmlFile:
    # --------------------------------------------------------------------------
    def getConfXmlFile(self, file):
        if type(file) is dict:
            filename = file['filename']
            xmlfile = StringIO(file['data'])
        elif type(file) is str and file.startswith('http://'):
            filename = _fileutil.extractFilename(file)
            xmlfile = StringIO(self.http_import(file))
        else:
            filename = _fileutil.extractFilename(file)
            xmlfile = open(_fileutil.getOSPath(file), 'rb')
        return filename, xmlfile

    # --------------------------------------------------------------------------
    #  ConfManager.importConf:
    # --------------------------------------------------------------------------
    def importConf(self, file, REQUEST, createIfNotExists=0):
        message = ''
        filename, xmlfile = self.getConfXmlFile(file)
        zms_system = 1
        if filename.find('.charfmt.') > 0:
            self.format_manager.importCharformatXml(xmlfile, REQUEST,
                                                    zms_system,
                                                    createIfNotExists)
        elif filename.find('.filter.') > 0:
            _filtermanager.importXml(self, xmlfile, REQUEST, zms_system,
                                     createIfNotExists)
        elif filename.find('.metadict.') > 0:
            self.metaobj_manager.importMetadictXml(xmlfile, REQUEST,
                                                   zms_system,
                                                   createIfNotExists)
        elif filename.find('.metaobj.') > 0:
            self.metaobj_manager.importMetaobjXml(xmlfile, REQUEST, zms_system,
                                                  createIfNotExists)
        elif filename.find('.metacmd.') > 0:
            _metacmdmanager.importXml(self, xmlfile, REQUEST, zms_system,
                                      createIfNotExists)
        elif filename.find('.langdict.') > 0:
            _multilangmanager.importXml(self, xmlfile, REQUEST, zms_system,
                                        createIfNotExists)
        elif filename.find('.textfmt.') > 0:
            self.format_manager.importTextformatXml(xmlfile, REQUEST,
                                                    zms_system,
                                                    createIfNotExists)
        xmlfile.close()
        return message

    # --------------------------------------------------------------------------
    #  ConfManager.getConfFiles:
    #
    #  Returns configuration-files from $ZMS_HOME/import-Folder
    # --------------------------------------------------------------------------
    def getConfFiles(self, pattern=None, REQUEST=None, RESPONSE=None):
        """
      ConfManager.getConfFiles
      """
        filenames = {}
        filepaths = [
            self.Control_Panel.getINSTANCE_HOME() + '/etc/zms/import/',
            package_home(globals()) + '/import/',
        ]
        try:
            conf = open(filepaths[0] + 'configure.zcml', 'r')
            _globals.writeBlock(
                self,
                "[getConfFiles]: Read from " + filepaths[0] + "configure.zcml")
        except:
            conf = open(filepaths[1] + 'configure.zcml', 'r')
            _globals.writeBlock(
                self,
                "[getConfFiles]: Read from " + filepaths[0] + "configure.zcml")
        conf_xml = self.xmlParse(conf)
        for source in self.xmlNodeSet(conf_xml, 'source'):
            location = source['attrs']['location']
            if location.startswith('http://'):
                try:
                    remote_conf = self.http_import(location + 'configure.zcml')
                    remote_conf_xml = self.xmlParse(remote_conf)
                    for remote_file in self.xmlNodeSet(remote_conf_xml,
                                                       'file'):
                        filename = remote_file['attrs']['id']
                        if filename not in filenames.keys():
                            filenames[
                                location +
                                filename] = filename + ' (' + remote_file[
                                    'attrs']['title'] + ')'
                except:
                    _globals.writeError(
                        self,
                        "[getConfFiles]: can't get conf-files from remote URL=%s"
                        % location)
            else:
                for filepath in filepaths:
                    if os.path.exists(filepath):
                        for filename in os.listdir(filepath + location):
                            path = filepath + filename
                            mode = os.stat(path)[stat.ST_MODE]
                            if not stat.S_ISDIR(mode):
                                if filename not in filenames:
                                    filenames[path] = filename
        conf.close()
        # Filter.
        if pattern is not None:
            for k in filenames.keys():
                if k.find(pattern) < 0:
                    del filenames[k]
                else:
                    v = filenames[k]
                    i = v.find(' ')
                    if i < 0:
                        i = len(v)
                    v = v[:v.find(pattern)] + v[i:]
                    filenames[k] = v
        # Return.
        if REQUEST is not None and \
           RESPONSE is not None:
            RESPONSE = REQUEST.RESPONSE
            content_type = 'text/xml; charset=utf-8'
            filename = 'getConfFiles.xml'
            RESPONSE.setHeader('Content-Type', content_type)
            RESPONSE.setHeader('Content-Disposition',
                               'inline;filename="%s"' % filename)
            RESPONSE.setHeader('Cache-Control', 'no-cache')
            RESPONSE.setHeader('Pragma', 'no-cache')
            return self.getXmlHeader() + self.toXmlString(filenames)
        else:
            return filenames

    """
    ############################################################################
    ###
    ###   Configuration-Properties Getters
    ###
    ############################################################################
    """

    # --------------------------------------------------------------------------
    #  ConfManager.getSequence:
    #
    #  Returns sequence.
    # --------------------------------------------------------------------------
    def getSequence(self):
        id = 'acl_sequence'
        exists = id in self.objectIds(['Sequence'])
        portalMaster = self.getPortalMaster()
        if portalMaster is not None:
            startvalue = 0
            if exists:
                ob = getattr(self, id)
                startvalue = ob.value
                self.manage_delObjects(ids=[id])
            ob = portalMaster.getSequence()
            if ob.value < startvalue:
                ob.value = startvalue
        else:
            if not exists:
                sequence = _sequence.Sequence()
                self._setObject(sequence.id, sequence)
            ob = getattr(self, id)
        return ob

    # --------------------------------------------------------------------------
    #  ConfManager.getMediaDb:
    #
    #  Returns mediadb.
    # --------------------------------------------------------------------------
    def getMediaDb(self):
        for ob in self.getDocumentElement().objectValues(['MediaDb']):
            return ob
        return None

    # --------------------------------------------------------------------------
    #  ConfManager.getResourceFolders:
    #
    #  Returns list of resource-folders.
    # --------------------------------------------------------------------------
    def getResourceFolders(self):
        obs = []
        ids = self.getConfProperty('ZMS.resourceFolders',
                                   'instance,common').split(',')
        if '*' in ids:
            ids.extend(
                map(
                    lambda x: x.id,
                    filter(lambda x: x.id not in ids,
                           self.getHome().objectValues(['Folder']))))
        for id in ids:
            if id == '*':
                obs.append(self.getHome())
            else:
                container = getattr(self, id, None)
                if container is not None and len(
                        container.objectValues(['ZMS'])) == 0:
                    obs.append(container)
        return obs

    # --------------------------------------------------------------------------
    #  ConfManager.getStylesheet:
    #
    #  Returns stylesheet.
    # --------------------------------------------------------------------------
    def getStylesheet(self, id=None):
        stylesheets = self.getStylesheets()
        if id is None:
            return stylesheets[0]
        else:
            for css in stylesheets:
                if absattr(css.id) == id:
                    return css

    # --------------------------------------------------------------------------
    #  ConfManager.getStylesheets:
    #
    #  Returns list of stylesheets.
    # --------------------------------------------------------------------------
    def getStylesheets(self):
        ids = []
        obs = []
        for container in self.getResourceFolders():
            for folder in [getattr(container, 'css', None), container]:
                if folder is not None:
                    for ob in folder.objectValues(
                        ['DTML Method', 'DTML Document', 'File']):
                        id = absattr(ob.id)
                        path = ob.getPhysicalPath()
                        if len(filter(lambda x: x.endswith('css'),
                                      path)) > 0 and id not in ids:
                            ids.append(id)
                            if id == self.getConfProperty(
                                    'ZMS.stylesheet', 'style.css'):
                                obs.insert(0, ob)
                            else:
                                obs.append(ob)
        return obs

    """
    ############################################################################
    ###
    ###   Configuration-Tab Options
    ###
    ############################################################################
    """

    # --------------------------------------------------------------------------
    #  ConfManager.customize_manage_options:
    # --------------------------------------------------------------------------
    customize_manage_options__roles__ = None

    def customize_manage_options(self):
        l = []
        l.append({'label': 'TAB_SYSTEM', 'action': 'manage_customize'})
        l.append({
            'label': 'TAB_LANGUAGES',
            'action': 'manage_customizeLanguagesForm'
        })
        for ob in self.objectValues():
            if IZMSConfigurationProvider in list(
                    zope.interface.providedBy(ob)):
                for d in ob.manage_sub_options():
                    l.append(
                        self.operator_setitem(d.copy(), 'action',
                                              ob.id + '/' + d['action']))
        l.append({
            'label': 'TAB_METACMD',
            'action': 'manage_customizeMetacmdForm'
        })
        l.append({
            'label': 'TAB_FILTER',
            'action': 'manage_customizeFilterForm'
        })
        l.append({
            'label': 'TAB_DESIGN',
            'action': 'manage_customizeDesignForm'
        })
        return l

    ############################################################################
    ###
    ###   Configuration-Properties
    ###
    ############################################################################
    """
    Returns configuration-manager.
    """

    def getConfManager(self):
        return self

    """
    Returns property from configuration.
    @rtype: C{dict}
    """

    def getConfProperties(self):
        return getattr(self, '__attr_conf_dict__', {})

    """
    Removes property from configuration.
    
    @param key: The key.
    @type key: C{string}
    @return None
    """
    security.declareProtected('ZMS Administrator', 'delConfProperty')

    def delConfProperty(self, key):
        self.setConfProperty(key, None)

    """
    Returns property from configuration.
    
    @param key: The key.
    @type key: C{string}
    @param default: The default-value.
    @type default: C{any}
    @rtype: C{any}
    """

    def getConfProperty(self, key, default=None, REQUEST=None):
        """ ConfManager.getConfProperty """
        if REQUEST is not None:
            authorized = REQUEST['AUTHENTICATED_USER'].has_role(
                'Authenticated')
            if not authorized:
                raise zExceptions.Unauthorized
        if OFS.misc_.misc_.zms['confdict'].has_key(key):
            default = OFS.misc_.misc_.zms['confdict'].get(key)
        return self.getConfProperties().get(key, default)

    """
    Sets property into configuration.
    
    @param key: The key.
    @type key: C{string}
    @param value: The value.
    @type value: C{any}
    @return None
    """
    security.declareProtected('ZMS Administrator', 'setConfProperty')

    def setConfProperty(self, key, value):
        d = self.getConfProperties()
        if value is None:
            if d.has_key(key):
                del d[key]
        else:
            d[key] = value
        self.__attr_conf_dict__ = d
        self.__attr_conf_dict__ = self.__attr_conf_dict__.copy()

    """
    ############################################################################
    ###
    ###   Configuration-System
    ###
    ############################################################################
    """

    ############################################################################
    #  ConfManager.manage_customizeSystem:
    #
    #  Customize system properties.
    ############################################################################
    def manage_customizeSystem(self, btn, key, lang, REQUEST, RESPONSE=None):
        """ ConfManager.manage_customizeSystem """

        message = ''
        params = []

        ##### Import ####
        if key == 'Import':
            if btn == 'Import':
                f = REQUEST['file']
                createIfNotExists = 1
                if f:
                    filename = f.filename
                    self.importConfPackage(f, REQUEST, createIfNotExists)
                else:
                    filename = REQUEST['init']
                    self.importConfPackage(filename, REQUEST,
                                           createIfNotExists)
                message = self.getZMILangStr('MSG_IMPORTED') % ('<i>%s</i>' %
                                                                filename)

        ##### History ####
        elif key == 'History':
            old_active = self.getConfProperty('ZMS.Version.active', 0)
            new_active = REQUEST.get('active', 0)
            old_nodes = self.getConfProperty('ZMS.Version.nodes', ['{$}'])
            new_nodes = self.string_list(REQUEST.get('nodes', ''))
            self.setConfProperty('ZMS.Version.active', new_active)
            self.setConfProperty('ZMS.Version.nodes', new_nodes)
            nodes = []
            if old_active == 1 and new_active == 0:
                nodes = old_nodes
            if old_active == 1 and new_active == 1:
                nodes = self.difference_list(
                    old_nodes,
                    self.getConfProperty('ZMS.Version.nodes', ['{$}']))
            for node in nodes:
                ob = self.getLinkObj(node)
                if ob is not None:
                    message += '[%s: %i]' % (node, ob.packHistory())
            message = self.getZMILangStr('MSG_CHANGED') + message

        ##### Clients ####
        elif key == 'Clients':
            if btn == 'Change':
                s = REQUEST.get('portal_master', '').strip()
                if s != self.getHome().id:
                    self.setConfProperty('Portal.Master', s)
                l = []
                for s in REQUEST.get('portal_clients', '').split('\n'):
                    s = s.strip()
                    if s in self.getHome().objectIds(['Folder']):
                        l.append(s)
                self.setConfProperty('Portal.Clients', l)
                message = self.getZMILangStr('MSG_CHANGED')

        ##### MediaDb ####
        elif key == 'MediaDb':
            if btn == 'Create':
                location = REQUEST['mediadb_location'].strip()
                _mediadb.manage_addMediaDb(self, location)
                message = self.getZMILangStr('MSG_CHANGED')
            elif btn == 'Pack':
                message = _mediadb.manage_packMediaDb(self)
            elif btn == 'Remove':
                message = _mediadb.manage_delMediaDb(self)

        ##### Custom ####
        elif key == 'Custom':
            k = REQUEST.get('conf_key', '')
            if btn == 'Change':
                v = REQUEST.get('conf_value', '')
                self.setConfProperty(k, v)
                if REQUEST.get('portal_clients'):
                    for portalClient in self.getPortalClients():
                        portalClient.setConfProperty(k, v)
                params.append('conf_key')
                message = self.getZMILangStr('MSG_CHANGED')
            elif btn == 'Delete':
                self.delConfProperty(k)
                if REQUEST.get('portal_clients'):
                    for portalClient in self.getPortalClients():
                        portalClient.delConfProperty(k)
                message = self.getZMILangStr('MSG_DELETED') % int(1)

        ##### InstalledProducts ####
        elif key == 'InstalledProducts':
            if btn == 'Change':
                self.setConfProperty('InstalledProducts.pil.thumbnail.max',
                                     REQUEST.get('pil_thumbnail_max', 100))
                self.setConfProperty(
                    'InstalledProducts.pil.hires.thumbnail.max',
                    REQUEST.get('pil_hires_thumbnail_max', 600))
                message = self.getZMILangStr('MSG_CHANGED')

        ##### Manager ####
        elif key == 'Manager':
            if btn == 'Add':
                meta_type = REQUEST.get('meta_type', '')
                if meta_type == 'Sequence':
                    obj = _sequence.Sequence()
                    self._setObject(obj.id, obj)
                    message = 'Added ' + meta_type
                elif meta_type == 'ZMSLog':
                    obj = zmslog.ZMSLog()
                    self._setObject(obj.id, obj)
                    message = 'Added ' + meta_type
                elif meta_type in [
                        'ZMSWorkflowProvider', 'ZMSWorkflowProviderAcquired'
                ]:
                    obj = ConfDict.get_constructor(meta_type)()
                    self._setObject(obj.id, obj)
                    message = 'Added ' + meta_type
            elif btn == 'Remove':
                ids = REQUEST.get('ids', [])
                if ids:
                    message = 'Removed ' + ', '.join(ids)
                    self.manage_delObjects(ids=ids)

        # Return with message.
        if RESPONSE:
            d = {'lang': lang, 'manage_tabs_message': message}
            for param in params:
                d[param] = REQUEST.get(param, '')
            return RESPONSE.redirect(
                self.url_append_params('manage_customize', d) + '#%s' % key)

        return message

    """
    ############################################################################
    ###
    ###   Configuration-Design
    ###
    ############################################################################
    """

    ############################################################################
    #  ConfManager.manage_customizeDesign:
    #
    #  Customize design properties.
    ############################################################################
    def manage_customizeDesign(self, btn, lang, REQUEST, RESPONSE):
        """ ConfManager.manage_customizeDesign """
        message = ''
        cssId = REQUEST.get('cssId', '')

        # Ex-/Import.
        # -----------
        if btn in [
                self.getZMILangStr('BTN_EXPORT'),
                self.getZMILangStr('BTN_IMPORT')
        ]:
            #-- Theme.
            home = self.getHome()
            home_id = home.id
            temp_folder = self.temp_folder
            # Init exclude-ids.
            excl_ids = []
            # Add clients-folders to exclude-ids.
            for folder in home.objectValues(['Folder']):
                if len(folder.objectValues(['ZMS'])) > 0:
                    excl_ids.append(absattr(folder.id))
            # Add content-object artefacts to exclude-ids.
            for metaObjId in self.getMetaobjIds():
                for metaObjAttrId in self.getMetaobjAttrIds(metaObjId):
                    metaObjAttr = self.getMetaobjAttr(metaObjId, metaObjAttrId)
                    if metaObjAttr[
                            'type'] in self.metaobj_manager.valid_zopetypes:
                        excl_ids.append(metaObjAttrId)
            # Filter ids.
            ids = filter(lambda x: x not in excl_ids,
                         home.objectIds(self.metaobj_manager.valid_zopetypes))
            if btn == self.getZMILangStr('BTN_EXPORT'):
                if home_id in temp_folder.objectIds():
                    temp_folder.manage_delObjects(ids=[home_id])
                temp_folder.manage_addFolder(id=home_id,
                                             title=home.title_or_id())
                folder = getattr(temp_folder, home_id)
                home.manage_copyObjects(ids, REQUEST)
                folder.manage_pasteObjects(cb_copy_data=None, REQUEST=REQUEST)
                return RESPONSE.redirect(
                    self.url_append_params(
                        '%s/manage_exportObject' % temp_folder.absolute_url(),
                        {
                            'id': home_id,
                            'download:int': 1
                        }))
            if btn == self.getZMILangStr('BTN_IMPORT'):
                v = REQUEST['theme']
                temp_filename = _fileutil.extractFilename(v.filename)
                temp_id = temp_filename[:temp_filename.rfind('.')]
                filepath = INSTANCE_HOME + '/import/' + temp_filename
                _fileutil.exportObj(v, filepath)
                if temp_id in temp_folder.objectIds():
                    temp_folder.manage_delObjects(ids=[temp_id])
                temp_folder.manage_importObject(temp_filename)
                folder = getattr(temp_folder, temp_id)
                home.manage_delObjects(ids=ids)
                folder.manage_copyObjects(folder.objectIds(), REQUEST)
                home.manage_pasteObjects(cb_copy_data=None, REQUEST=REQUEST)
                _fileutil.remove(filepath)
                temp_folder.manage_delObjects(ids=[temp_id])

        # Save.
        # -----
        if btn == self.getZMILangStr('BTN_SAVE'):
            #-- Stylesheet.
            if REQUEST.has_key('cssId'):
                if REQUEST.get('default'):
                    self.setConfProperty('ZMS.stylesheet',
                                         REQUEST.get('cssId'))
                css = self.getStylesheet(REQUEST.get('cssId'))
                data = REQUEST.get('stylesheet')
                title = css.title
                css.manage_edit(data, title)
                message = self.getZMILangStr('MSG_CHANGED')
            #-- Sitemap.
            if REQUEST.has_key('attr_layoutsitemap'):
                if len(REQUEST['attr_layoutsitemap']) > 0:
                    self.attr_layoutsitemap = int(
                        REQUEST['attr_layoutsitemap'])
                elif hasattr(self, 'attr_layoutsitemap'):
                    delattr(self, 'attr_layoutsitemap')
                message = self.getZMILangStr('MSG_CHANGED')

        # Upload.
        # -------
        elif btn == self.getZMILangStr('BTN_UPLOAD'):
            #-- ZMI Logo.
            self.zmi_logo = Image(id='logo', title='', file='')
            self.zmi_logo.manage_upload(REQUEST['file'], REQUEST)
            message = self.getZMILangStr('MSG_CHANGED')

        # Return with message.
        message = urllib.quote(message)
        return RESPONSE.redirect(
            'manage_customizeDesignForm?lang=%s&manage_tabs_message=%s&cssId=%s'
            % (lang, message, cssId))

    ############################################################################
    ###
    ###   Interface IZMSWorkflowProvider: delegate to workflow_manager
    ###
    ############################################################################

    def getWfActivities(self):
        workflow_manager = getattr(self, 'workflow_manager', None)
        if workflow_manager is None:
            return []
        return workflow_manager.getActivities()

    def getWfActivitiesIds(self):
        workflow_manager = getattr(self, 'workflow_manager', None)
        if workflow_manager is None:
            return []
        return workflow_manager.getActivityIds()

    def getWfActivity(self, id):
        workflow_manager = getattr(self, 'workflow_manager', None)
        if workflow_manager is None:
            return None
        return workflow_manager.getActivity(id)

    def getWfTransitions(self):
        workflow_manager = getattr(self, 'workflow_manager', None)
        if workflow_manager is None:
            return []
        return workflow_manager.getTransitions()

    def getWfTransition(self, id):
        workflow_manager = getattr(self, 'workflow_manager', None)
        if workflow_manager is None:
            return None
        return workflow_manager.getTransition(id)

    ############################################################################
    ###
    ###   Interface IZMSMetamodelProvider: delegate
    ###
    ############################################################################

    def getMetaobjManager(self):
        return self.metaobj_manager

    def getMetaobjId(self, name):
        return self.getMetaobjManager().getMetaobjId(name)

    def getMetaobjIds(self, sort=1, excl_ids=[]):
        return self.getMetaobjManager().getMetaobjIds(sort, excl_ids)

    def getMetaobj(self, id):
        return self.getMetaobjManager().getMetaobj(id)

    def getMetaobjAttrIds(self, meta_id, types=[]):
        return self.getMetaobjManager().getMetaobjAttrIds(meta_id, types)

    def getMetaobjAttrs(self, meta_id, types=[]):
        return self.getMetaobjManager().getMetaobjAttrs(meta_id)

    def getMetaobjAttr(self, id, attr_id, syncTypes=['resource']):
        return self.getMetaobjManager().getMetaobjAttr(id, attr_id, syncTypes)

    def getMetaobjAttrIdentifierId(self, meta_id):
        return self.getMetaobjManager().getMetaobjAttrIdentifierId(meta_id)

    def notifyMetaobjAttrAboutValue(self, meta_id, key, value):
        return self.getMetaobjManager().notifyMetaobjAttrAboutValue(
            meta_id, key, value)

    ############################################################################
    ###
    ###   Interface IZMSFormatProvider: delegate
    ###
    ############################################################################

    def getFormatManager(self):
        return self.format_manager

    def getTextFormatDefault(self):
        return self.getFormatManager().getTextFormatDefault()

    def getTextFormat(self, id, REQUEST):
        return self.getFormatManager().getTextFormat(id, REQUEST)

    def getTextFormats(self, REQUEST):
        return self.getFormatManager().getTextFormats(REQUEST)

    def getCharFormats(self):
        return self.getFormatManager().getCharFormats()

    ############################################################################
    ###
    ###   Interface IZMSLocale: delegate
    ###
    ############################################################################

    def getLocale(self):
        return self

    """
 def testDeletePortrait(self):
     self.memberdata._setPortrait(
         Image(id=default_user, file=dummy.File(), title=''),
         default_user)
     self.memberdata._deletePortrait(default_user)
     self.assertEqual(self.memberdata._getPortrait(default_user), None)
Exemple #22
0
    def manage_customizeDesign(self, btn, lang, REQUEST, RESPONSE):
        """ ConfManager.manage_customizeDesign """
        message = ''
        cssId = REQUEST.get('cssId', '')

        # Ex-/Import.
        # -----------
        if btn in [
                self.getZMILangStr('BTN_EXPORT'),
                self.getZMILangStr('BTN_IMPORT')
        ]:
            #-- Theme.
            home = self.getHome()
            home_id = home.id
            temp_folder = self.temp_folder
            # Init exclude-ids.
            excl_ids = []
            # Add clients-folders to exclude-ids.
            for folder in home.objectValues(['Folder']):
                if len(folder.objectValues(['ZMS'])) > 0:
                    excl_ids.append(absattr(folder.id))
            # Add content-object artefacts to exclude-ids.
            for metaObjId in self.getMetaobjIds():
                for metaObjAttrId in self.getMetaobjAttrIds(metaObjId):
                    metaObjAttr = self.getMetaobjAttr(metaObjId, metaObjAttrId)
                    if metaObjAttr[
                            'type'] in self.metaobj_manager.valid_zopetypes:
                        excl_ids.append(metaObjAttrId)
            # Filter ids.
            ids = filter(lambda x: x not in excl_ids,
                         home.objectIds(self.metaobj_manager.valid_zopetypes))
            if btn == self.getZMILangStr('BTN_EXPORT'):
                if home_id in temp_folder.objectIds():
                    temp_folder.manage_delObjects(ids=[home_id])
                temp_folder.manage_addFolder(id=home_id,
                                             title=home.title_or_id())
                folder = getattr(temp_folder, home_id)
                home.manage_copyObjects(ids, REQUEST)
                folder.manage_pasteObjects(cb_copy_data=None, REQUEST=REQUEST)
                return RESPONSE.redirect(
                    self.url_append_params(
                        '%s/manage_exportObject' % temp_folder.absolute_url(),
                        {
                            'id': home_id,
                            'download:int': 1
                        }))
            if btn == self.getZMILangStr('BTN_IMPORT'):
                v = REQUEST['theme']
                temp_filename = _fileutil.extractFilename(v.filename)
                temp_id = temp_filename[:temp_filename.rfind('.')]
                filepath = INSTANCE_HOME + '/import/' + temp_filename
                _fileutil.exportObj(v, filepath)
                if temp_id in temp_folder.objectIds():
                    temp_folder.manage_delObjects(ids=[temp_id])
                temp_folder.manage_importObject(temp_filename)
                folder = getattr(temp_folder, temp_id)
                home.manage_delObjects(ids=ids)
                folder.manage_copyObjects(folder.objectIds(), REQUEST)
                home.manage_pasteObjects(cb_copy_data=None, REQUEST=REQUEST)
                _fileutil.remove(filepath)
                temp_folder.manage_delObjects(ids=[temp_id])

        # Save.
        # -----
        if btn == self.getZMILangStr('BTN_SAVE'):
            #-- Stylesheet.
            if REQUEST.has_key('cssId'):
                if REQUEST.get('default'):
                    self.setConfProperty('ZMS.stylesheet',
                                         REQUEST.get('cssId'))
                css = self.getStylesheet(REQUEST.get('cssId'))
                data = REQUEST.get('stylesheet')
                title = css.title
                css.manage_edit(data, title)
                message = self.getZMILangStr('MSG_CHANGED')
            #-- Sitemap.
            if REQUEST.has_key('attr_layoutsitemap'):
                if len(REQUEST['attr_layoutsitemap']) > 0:
                    self.attr_layoutsitemap = int(
                        REQUEST['attr_layoutsitemap'])
                elif hasattr(self, 'attr_layoutsitemap'):
                    delattr(self, 'attr_layoutsitemap')
                message = self.getZMILangStr('MSG_CHANGED')

        # Upload.
        # -------
        elif btn == self.getZMILangStr('BTN_UPLOAD'):
            #-- ZMI Logo.
            self.zmi_logo = Image(id='logo', title='', file='')
            self.zmi_logo.manage_upload(REQUEST['file'], REQUEST)
            message = self.getZMILangStr('MSG_CHANGED')

        # Return with message.
        message = urllib.quote(message)
        return RESPONSE.redirect(
            'manage_customizeDesignForm?lang=%s&manage_tabs_message=%s&cssId=%s'
            % (lang, message, cssId))
Exemple #23
0
    def includeImageList(self, data):
        """Include Images in ODF archive

    - data: zipped archive content
    """
        builder = OOoBuilder(data)
        content = builder.extract("content.xml")
        xml_doc = etree.XML(content)
        image_tag_list = xml_doc.xpath('//*[name() = "draw:image"]')
        SVG_NAMESPACE = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
        XLINK_NAMESPACE = "http://www.w3.org/1999/xlink"
        ratio_px_cm = 2.54 / 100.0
        # Flag to enable modification of OOoBuilder
        odt_content_modified = False
        for image_tag in image_tag_list:
            frame = image_tag.getparent()
            # Try to get image file from ZODB
            href_attribute_list = image_tag.xpath('.//@*[name() = "xlink:href"]')
            url = href_attribute_list[0]
            parse_result = urlparse(unquote(url))
            # urlparse return a 6-tuple: scheme, netloc, path, params, query, fragment
            path = parse_result[2]
            if path:
                # OOo corrupt relative Links inside HTML content during odt conversion
                # <img src="REF.TO.IMAGE" ... /> become <draw:image xlink:href="../REF.TO.IMAGE" ... />
                # So remove "../" added by OOo
                path = CLEAN_RELATIVE_PATH.sub("", path)
                # in some cases like Web Page content "/../" can be contained in image URL which will break
                # restrictedTraverse calls, our best guess is to remove it
                path = path.replace("/../", "")
                # retrieve http parameters and use them to convert image
                query_parameter_string = parse_result[4]
                image_parameter_dict = dict(parse_qsl(query_parameter_string))
                try:
                    image = self.context.restrictedTraverse(path)
                except (AttributeError, KeyError):
                    # Image not found, this image is probably not hosted by ZODB. Do nothing
                    image = None
                if image is not None:
                    odt_content_modified = True
                    content_type = image.getContentType()
                    format = image_parameter_dict.pop("format", None)
                    if getattr(image, "convert", None) is not None:
                        # The document support conversion so perform conversion
                        # according given parameters
                        mime, image_data = image.convert(format, **image_parameter_dict)
                        # wrapp converted data into OFSImage in order to compute metadatas
                        # on converted result
                        image = OFSImage(image.getId(), image.getTitle(), image_data)

                    # image should be OFSImage
                    data = str(image.data)
                    width = image.width
                    height = image.height
                    if height:
                        frame.attrib.update({"{%s}height" % SVG_NAMESPACE: "%.3fcm" % (height * ratio_px_cm)})
                    if width:
                        frame.attrib.update({"{%s}width" % SVG_NAMESPACE: "%.3fcm" % (width * ratio_px_cm)})
                    if not format:
                        mimetype_list = self.context.getPortalObject().mimetypes_registry.lookup(content_type)
                        # guess a format with help of mimetypes_registry
                        for mimetype_object in mimetype_list:
                            if mimetype_object.extensions:
                                format = mimetype_object.extensions[0]
                                break
                            elif mimetype_object.globs:
                                format = mimetype_object.globs[0].strip("*.")
                                break
                    new_path = builder.addImage(data, format=format)
                    image_tag.attrib.update({"{%s}href" % XLINK_NAMESPACE: new_path})
        if odt_content_modified:
            builder.replace(
                "content.xml", etree.tostring(xml_doc, encoding="utf-8", xml_declaration=True, pretty_print=False)
            )
        return builder.render()
Exemple #24
0
def load_image(filename):
    id = os.path.basename(filename)
    ob = Image(id, '', '')
    ob.update_data(file(filename, 'rb').read())
    return ob
    def test_exportXML(self):
        from OFS.Folder import Folder
        from OFS.Image import Image
        from OFS.XMLExportImport import exportXML

        connection, app = self._makeJarAndRoot()
        data = open(imagedata, 'rb')

        sub = Folder('sub')
        app._setObject('sub', sub)
        img = Image('image', '', data, 'image/gif')
        sub._setObject('image', img)
        img._setProperty('prop1', 3.14159265359, 'float')
        img._setProperty('prop2', 1, 'int')
        img._setProperty('prop3', 2L**31-1, 'long')
        img._setProperty('prop4', 'xxx', 'string')
        img._setProperty('prop5', ['xxx', 'zzz'], 'lines')
        img._setProperty('prop6', u'xxx', 'unicode')
        img._setProperty('prop7', [u'xxx', u'zzz'], 'ulines')
        img._setProperty('prop8', '<&>', 'string')
        img._setProperty('prop9', u'<&>', 'unicode')
        img._setProperty('prop10', '<]]>', 'string')
        img._setProperty('prop11', u'<]]>', 'unicode')
        img._setProperty('prop12', u'£', 'unicode')
        transaction.savepoint(optimistic=True)
        oid = sub._p_oid

        handle, path = tempfile.mkstemp(suffix='.xml')
        try:
            ostream = os.fdopen(handle,'wb')
            data = exportXML(connection, oid, ostream)
            ostream.close()
        finally:
            os.remove(path)
class UserPropertySheetTests( unittest.TestCase
                            , IPropertySheet_conformance
                            ):

    _SCHEMA = ( ( 's', 'string'  )
              , ( 'i', 'int'     )
              , ( 'f', 'float'   )
              , ( 'n', 'long'    )
              , ( 'd', 'date'    )
              , ( 'l', 'lines'   )
              , ( 't', 'lines'   )
              , ( 'b', 'boolean' )
              , ( 'img', 'image' )
              )

    _STRING_VALUE = 'string'
    _INT_VALUE = 42
    _FLOAT_VALUE = 9.8
    _LONG_VALUE = sys.maxint + 1
    _DATE_VALUE = DateTime()
    _LIST_VALUE = [ 'a', 'b', 'c' ]
    _TUPLE_VALUE = ( 'd', 'e', 'f' )
    _BOOL_VALUE = True
    _IMG_VALUE = Image('image', 'Test Image', img_file)

    def _getTargetClass( self ):

        from Products.PluggableAuthService.UserPropertySheet \
            import UserPropertySheet

        return UserPropertySheet

    def _makeOne( self, *args, **kw ):

        return self._getTargetClass()( *args, **kw )

    def test_ctor_id_noschema_novalues( self ):

        ups = self._makeOne( 'empty' )

        self.assertEqual( ups.getId(), 'empty' )

        self.failIf( ups.hasProperty( 'empty' ) )
        self.failIf( ups.hasProperty( 'foo' ) )
        self.failIf( ups.hasProperty( 'bar' ) )

        self.assertEqual( ups.getProperty( 'foo' ), None )
        self.assertEqual( ups.getPropertyType( 'foo' ), None )

        self.assertEqual( len( ups.propertyMap() ), 0 )
        self.assertEqual( len( ups.propertyIds() ), 0 )
        self.assertEqual( len( ups.propertyValues() ), 0 )
        self.assertEqual( len( ups.propertyItems() ), 0 )
        self.assertEqual( len( ups.propertyIds() ), 0 )

    def _checkStockSchema( self, ups, values_are_none=False ):

        self.failIf( ups.hasProperty( 'x' ) )
        self.failUnless( ups.hasProperty( 's' ) )
        self.failUnless( ups.hasProperty( 'i' ) )
        self.failUnless( ups.hasProperty( 'f' ) )
        self.failUnless( ups.hasProperty( 'n' ) )
        self.failUnless( ups.hasProperty( 'd' ) )
        self.failUnless( ups.hasProperty( 'l' ) )
        self.failUnless( ups.hasProperty( 't' ) )
        self.failUnless( ups.hasProperty( 'b' ) )
        self.failUnless( ups.hasProperty( 'img' ) )

        self.assertEqual( ups.getPropertyType( 's' ), 'string' )
        self.assertEqual( ups.propertyInfo( 's' )[ 'type' ], 'string' )
        if values_are_none:
            self.assertEqual( ups.getProperty( 's' ), None )
        else:
            self.assertEqual( ups.getProperty( 's' ), self._STRING_VALUE )

        self.assertEqual( ups.getPropertyType( 'i' ), 'int' )
        self.assertEqual( ups.propertyInfo( 'i' )[ 'type' ], 'int' )
        if values_are_none:
            self.assertEqual( ups.getProperty( 'i' ), None )
        else:
            self.assertEqual( ups.getProperty( 'i' ), self._INT_VALUE )

        self.assertEqual( ups.getPropertyType( 'f' ), 'float' )
        self.assertEqual( ups.propertyInfo( 'f' )[ 'type' ], 'float' )
        if values_are_none:
            self.assertEqual( ups.getProperty( 'f' ), None )
        else:
            self.assertEqual( ups.getProperty( 'f' ), self._FLOAT_VALUE )

        self.assertEqual( ups.getPropertyType( 'n' ), 'long' )
        self.assertEqual( ups.propertyInfo( 'n' )[ 'type' ], 'long' )
        if values_are_none:
            self.assertEqual( ups.getProperty( 'n' ), None )
        else:
            self.assertEqual( ups.getProperty( 'n' ), self._LONG_VALUE )

        self.assertEqual( ups.getPropertyType( 'd' ), 'date' )
        self.assertEqual( ups.propertyInfo( 'd' )[ 'type' ], 'date' )
        if values_are_none:
            self.assertEqual( ups.getProperty( 'd' ), None )
        else:
            self.assertEqual( ups.getProperty( 'd' ), self._DATE_VALUE )

        self.assertEqual( ups.getPropertyType( 'b' ), 'boolean' )
        self.assertEqual( ups.propertyInfo( 'b' )[ 'type' ], 'boolean' )
        if values_are_none:
            self.assertEqual( ups.getProperty( 'b' ), None )
        else:
            self.assertEqual( ups.getProperty( 'b' ), self._BOOL_VALUE )

        self.assertEqual( ups.getPropertyType( 'l' ), 'lines' )
        self.assertEqual( ups.propertyInfo( 'l' )[ 'type' ], 'lines' )

        if values_are_none:
            self.assertEqual( ups.getProperty( 'l' ), None )
        else:
            got = ups.getProperty( 'l' )
            self.assertEqual( type( got ), type( () ) )
            self.assertEqual( len( got ), len( self._LIST_VALUE ) )

            for i in range( len( self._LIST_VALUE ) ):
                self.assertEqual( got[i], self._LIST_VALUE[i] )

        self.assertEqual( ups.getPropertyType( 't' ), 'lines' )
        self.assertEqual( ups.propertyInfo( 't' )[ 'type' ], 'lines' )

        if values_are_none:
            self.assertEqual( ups.getProperty( 't' ), None )
        else:
            got = ups.getProperty( 't' )
            self.assertEqual( type( got ), type( () ) )
            self.assertEqual( len( got ), len( self._TUPLE_VALUE ) )

            for i in range( len( self._TUPLE_VALUE ) ):
                self.assertEqual( got[i], self._TUPLE_VALUE[i] )

        self.assertEqual( ups.getPropertyType( 'img' ), 'image' )
        self.assertEqual( ups.propertyInfo( 'img' )[ 'type' ], 'image' )

        if values_are_none:
            self.assertEqual( ups.getProperty( 'img' ), None )
        else:
            got = ups.getProperty( 'img' )
            self.assertEqual( type( got ), Image )
            self.assertEqual( got.size, self._IMG_VALUE.size )
            self.assertEqual( got, self._IMG_VALUE )


        pmap = ups.propertyMap()
        self.assertEqual( len( pmap ), len( self._SCHEMA ) )

        for i in range( len( pmap ) ):
            info = pmap[i]
            spec = [ x for x in self._SCHEMA if x[0] == info['id' ] ][0]
            self.assertEqual( info[ 'id' ], spec[0] )
            self.assertEqual( info[ 'type' ], spec[1] )
            self.assertEqual( info[ 'mode' ], '' )  # readonly, no delete


    def test_ctor__guessSchema( self ):

        ups = self._makeOne( 'guessed'
                           , s=self._STRING_VALUE
                           , i=self._INT_VALUE
                           , f=self._FLOAT_VALUE
                           , n=self._LONG_VALUE
                           , d=self._DATE_VALUE
                           , l=self._LIST_VALUE
                           , t=self._TUPLE_VALUE
                           , b=self._BOOL_VALUE
                           , img=self._IMG_VALUE
                           )

        self._checkStockSchema( ups )


    def test_ctor_w_schema(self):

        ups = self._makeOne( 'w_schema'
                           , self._SCHEMA
                           , s=self._STRING_VALUE
                           , i=self._INT_VALUE
                           , f=self._FLOAT_VALUE
                           , n=self._LONG_VALUE
                           , d=self._DATE_VALUE
                           , l=self._LIST_VALUE
                           , t=self._TUPLE_VALUE
                           , b=self._BOOL_VALUE
                           , img=self._IMG_VALUE
                           )

        self._checkStockSchema( ups )


    def test_ctor_w_schema_no_values(self):

        ups = self._makeOne( 'w_schema'
                           , self._SCHEMA
                           )

        self._checkStockSchema( ups, values_are_none=True )
Exemple #27
0
 def __call__(self, portrait, safe_id):
     if portrait and portrait.filename:
         scaled, mimetype = scale_image(portrait)
         portrait = Image(id=safe_id, file=scaled, title='')
         membertool = getToolByName(self.context, 'portal_memberdata')
         membertool._setPortrait(portrait, safe_id)
Exemple #28
0
 def _createZODBClone(self):
     return Image(self.getId(), '', self._readFile(1))
Exemple #29
0
    def render(self):
        try:
            from plone.protect.interfaces import IDisableCSRFProtection
            alsoProvides(self.request, IDisableCSRFProtection)
        except:
            pass
        portal = api.portal.get()
        soup_users_portrait = get_soup('users_portrait', portal)
        plugins = portal.acl_users.plugins.listPlugins(IPropertiesPlugin)
        # We use the most preferent plugin
        # If the most preferent plugin is:
        #    mutable_properties --> users who have entered into communities
        #    ldap --> users in LDAP
        pplugin = plugins[0][1]
        all_user_properties = pplugin.enumerateUsers()

        for user in all_user_properties:
            user_obj = api.user.get(user['id'])

            if user_obj:
                id = user['id']
                maxclient, settings = getUtility(IMAXClient)()
                foto = maxclient.people[id].avatar
                imageUrl = foto.uri + '/large'

                portrait = urllib.urlretrieve(imageUrl)

                scaled, mimetype = convertSquareImage(portrait[0])
                portrait = Image(id=id, file=scaled, title=id)

                # membertool = api.portal.get_tool(name='portal_memberdata')
                # membertool._setPortrait(portrait, str(id))
                # import transaction
                # transaction.commit()
                member_info = get_safe_member_by_id(id)
                if member_info.get('fullname', False) \
                   and member_info.get('fullname', False) != id \
                   and isinstance(portrait, Image) and portrait.size != 3566 and portrait.size != 6186:
                    portrait_user = True
                    # 3566 is the size of defaultUser.png I don't know how get image
                    # title. This behavior is reproduced in profile portlet. Ahora tambien 6186
                else:
                    portrait_user = False

                exist = [
                    r for r in soup_users_portrait.query(Eq('id_username', id))
                ]
                if exist:
                    user_record = exist[0]
                    # Just in case that a user became a legit one and previous was a nonlegit
                    user_record.attrs['id_username'] = id
                    user_record.attrs['portrait'] = portrait_user
                else:
                    record = Record()
                    record_id = soup_users_portrait.add(record)
                    user_record = soup_users_portrait.get(record_id)
                    user_record.attrs['id_username'] = id
                    user_record.attrs['portrait'] = portrait_user
                soup_users_portrait.reindex(records=[user_record])
            else:
                logger.info(
                    'No user found in user repository (LDAP) {}'.format(
                        user['id']))

            logger.info('Updated portrait user for {}'.format(user['id']))

        logger.info('Finish rebuild_user_portrait portal {}'.format(portal))
        return 'Done'