Ejemplo n.º 1
0
    def setUp(self):
        self.portal = self.layer['portal']
        self.request = self.layer['request']
        alsoProvides(self.request, IDefaultBrowserLayer)
        alsoProvides(self.request, IPloneAppMultilingualInstalled)

        fti = DexterityFTI('Feedback')
        fti.behaviors = (
            'plone.app.dexterity.behaviors.metadata.IBasic',
            'plone.app.content.interfaces.INameFromTitle',
            'plone.app.multilingual.dx.interfaces.IDexterityTranslatable',
        )
        fti.model_source = u"""\
<model xmlns="http://namespaces.plone.org/supermodel/schema"
       xmlns:lingua="http://namespaces.plone.org/supermodel/lingua">
  <schema>
    <field name="mandatory_feedback" type="zope.schema.Text"
           lingua:independent="true">
      <description />
      <required>True</required>
      <title>Mandatory feedback</title>
    </field>
  </schema>
</model>"""
        portal_types = getToolByName(self.portal, 'portal_types')
        portal_types._setObject('Feedback', fti)

        self.document = createContentInContainer(
            self.portal['en'],
            'Feedback',
            checkConstraints=False,
            title=u'Test feedback',
            mandatory_feedback=u'This is a test')

        # Call 'create_translation' to annotate request
        self.request.form['language'] = 'ca'
        self.redirect = getMultiAdapter((self.document, self.request),
                                        name="create_translation")
        self.redirect()

        # Look up the ++addtranslation++ with annotated request in place
        self.view = self.portal['ca'].restrictedTraverse('++addtranslation++' +
                                                         IUUID(self.document))
        self.view.update()
        self.field = self.view.form_instance.fields['mandatory_feedback'].field
        self.widget = self.view.form_instance.widgets['mandatory_feedback']
Ejemplo n.º 2
0
    def default_template_is_in_allowed_templates(data):
        """ Validate ad-hoc agenda item templates
        """
        default_template = data.ad_hoc_template
        allowed_templates = data.allowed_ad_hoc_agenda_item_templates

        if default_template is None:
            return

        if not allowed_templates:
            return

        if IUUID(default_template) not in allowed_templates:
            raise Invalid(
                _(u'error_default_template_is_in_allowed_templates',
                  default=u'The default ad-hoc agenda item template has to be '
                  u'amongst the allowed ones for this committee.'))
Ejemplo n.º 3
0
    def _remove_grouping_values(self, grouping, values, obj):
        """ Remove $uid from the list of uids stored under the grouping values
            (provided by $values) in the groupings datastructure.

            If $uid is the only one in the list, then remove the
            list (and its key) entirely.
        """
        uid = IUUID(obj)
        groupings = self.get_groupings()
        if grouping not in groupings:
            return
        for value in groupings[grouping].keys():
            if value not in values and uid in groupings[grouping][value]:
                if len(groupings[grouping][value]) == 1:
                    del groupings[grouping][value]
                else:
                    groupings[grouping][value].remove(uid)
Ejemplo n.º 4
0
 def get_options(self):
     site = get_top_site_from_url(self.context, self.request)
     base_url = site.absolute_url()
     base_vocabulary = '%s/@@getVocabulary?name=' % base_url
     site_path = site.getPhysicalPath()
     context_path = self.context.getPhysicalPath()
     columns = self.get_columns()
     options = {
         'vocabularyUrl':
         '%splone.app.vocabularies.Catalog' % (base_vocabulary),
         'urlStructure': {
             'base': base_url,
             'appended': '/folder_contents'
         },
         'moveUrl':
         '%s{path}/fc-itemOrder' % base_url,
         'indexOptionsUrl':
         '%s/@@qsOptions' % base_url,
         'contextInfoUrl':
         '%s{path}/@@fc-contextInfo' % base_url,
         'setDefaultPageUrl':
         '%s{path}/@@fc-setDefaultPage' % base_url,
         'availableColumns':
         columns,
         'attributes': [
             'Title', 'path', 'getURL', 'getIcon', 'getMimeIcon',
             'portal_type'
         ] + list(columns.keys()),  # noqa
         'buttons':
         self.get_actions(),
         'rearrange': {
             'properties': self.get_indexes(),
             'url': '%s{path}/@@fc-rearrange' % base_url
         },
         'basePath':
         '/' + '/'.join(context_path[len(site_path):]),
         'upload': {
             'relativePath': 'fileUpload',
             'baseUrl': base_url,
             'initialFolder': IUUID(self.context, None),
             'useTus': TUS_ENABLED
         },
         'thumb_scale':
         self.get_thumb_scale(),
     }
     return options
Ejemplo n.º 5
0
    def populate_with_object(self, obj):
        super(ListTile, self).populate_with_object(obj)
        uuid = IUUID(obj, None)
        data_mgr = ITileDataManager(self)

        old_data = data_mgr.get()
        if data_mgr.get()['uuids']:
            uuids = data_mgr.get()['uuids']
            if type(uuids) != list:
                uuids = [uuid]
            elif uuid not in uuids:
                uuids.append(uuid)

            old_data['uuids'] = uuids[:self.limit]
        else:
            old_data['uuids'] = [uuid]
        data_mgr.set(old_data)
Ejemplo n.º 6
0
def createItem(message, event):
    """Consume item creation message"""

    uuid = message.header_frame.correlation_id
    container = uuidToObject(uuid)

    obj = createContentInContainer(container,
                                   "collective.zamqpdemo.item",
                                   checkConstraints=True,
                                   **message.body)
    kwargs = {"uuid": IUUID(obj)}

    producer = getUtility(IProducer, name="amqpdemo.delete")
    producer._register()
    producer.publish(kwargs)

    message.ack()
Ejemplo n.º 7
0
def short_uuid(obj):
    uuid = IUUID(obj, None)
    if uuid is not None:
        portal_catalog = getToolByName(obj, 'portal_catalog')
        short_uuids = portal_catalog.uniqueValuesFor('short_uuid')
        uuid = uuid.replace('-', '')
        for i in xrange(0, 32):
            short_uuid_ = uuid[:i]
            if short_uuid_ in short_uuids:
                same_short = portal_catalog.searchResults(
                    short_uuid=short_uuid_
                )
                if same_short[0]['UID'] == uuid:
                    return short_uuid_
            else:
                return short_uuid_
    return uuid
Ejemplo n.º 8
0
 def item_ordered(self, state=[]):
     """Return total count buyable item was ordered.
     """
     context = self.context
     bookings_soup = get_bookings_soup(context)
     order_bookings = dict()
     for booking in bookings_soup.query(Eq('buyable_uid', IUUID(context))):
         bookings = order_bookings.setdefault(booking.attrs['order_uid'],
                                              list())
         bookings.append(booking)
     count = Decimal('0')
     for order_uid, bookings in order_bookings.items():
         for booking in bookings:
             if state and booking.attrs['state'] not in state:
                 continue
             count += booking.attrs['buyable_count']
     return count
Ejemplo n.º 9
0
    def remove(self):
        request = self.request
        user = request.AUTHENTICATED_USER
        view = request.get('view', '')
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        site = getNavigationRootObject(self.context, portal)
        IFavoriteStorage(site).remove_favorite(user.getId(),
                                               id=IUUID(self.context))

        statusmsg = IStatusMessage(request)
        if IFolderish.providedBy(self.context):
            statusmsg.add(_("The folder has been removed from your favorites"))
        else:
            statusmsg.add(
                _("The document has been removed from your favorites"))

        request.response.redirect(self.context.absolute_url() + '/' + view)
Ejemplo n.º 10
0
    def _get_markers(self, brain):
        """Return dict of marker details.

        Handle Info objects in special way.
        """
        markers = []
        if brain.portal_type == 'tbfac.Info':
            # get related Venues
            obj = brain.getObject()
            if obj is None:
                return []

            refs = obj.venue
            if not refs:
                return []

            for ref in refs:
                venue = ref.to_object
                geo = IGeoManager(venue, None)
                if geo and geo.isGeoreferenceable():
                    geometry, coordinates = geo.getCoordinates()
                    if not coordinates or len(coordinates) != 2:
                        continue
                    else:
                        longitude, latitude = coordinates
                    if geometry == 'Point' and longitude and latitude:
                        markers.append({
                            'uid': IUUID(venue),
                            'search_uid': brain.UID,
                            'url': brain.getURL(),
                            'title': brain.Title,
                            'tags': brain.Subject or [],
                            'start': brain.start or '',
                            'end': brain.end or '',
                            'geometry': {
                                'style': None,
                                'type': 'Point',
                                'coordinates': (longitude, latitude)
                            },
                            'latitude': latitude,
                            'longitude': longitude,
                        })
        else:
            markers = super(UshahidiMapView, self)._get_markers(brain)

        return markers
Ejemplo n.º 11
0
def get_venue_url(venue):
    """Get URL to venue.
    We explicitly support here venues defined in other subsites. If so, URL is
    specially constructed, so that we can show the venue in our own site.
    """
    # construct url to location
    site = getSite()
    venue_url = venue.absolute_url()
    site_path = u'/'.join(site.getPhysicalPath())
    venue_path = u'/'.join(venue.getPhysicalPath())
    if site_path not in venue_path:
        # venue in different site - cannot directly open it
        venue_url = u'{0}/@@venue_view?uid={1}'.format(
            site.absolute_url(),
            IUUID(venue)
        )
    return venue_url
Ejemplo n.º 12
0
    def num_more_occurrences(self):
        """Return the number of extra occurrences, which are not listed by
        next_occurrences.
        """
        uid = IUUID(self.event_context, None)
        if not uid:
            # Might be an occurrence
            return 0
        catalog = getToolByName(self.event_context, 'portal_catalog')
        brains = catalog(UID=uid)
        if len(brains) == 0:
            return 0
        brain = brains[0]  # assuming, that current context is in the catalog
        idx = catalog.getIndexDataForRID(brain.getRID())

        num = len(idx['start']) - self.max_occurrences
        return num if num > 0 else 0
Ejemplo n.º 13
0
def getUID(context):
    uid = IUUID(context, None)
    if uid is not None:
        return uid

    if hasattr(context, 'UID'):
        return context.UID()

    try:
        return '/'.join(context.getPhysicalPath())
    except AttributeError:
        pass

    try:
        return context.id
    except AttributeError:
        return 'unknown'
Ejemplo n.º 14
0
    def test_scanin_to_new_private_dossier(self, browser):
        self.login(self.manager, browser)
        private_folder = self.create_private_folder()

        body, headers = self.prepare_request(destination='private')
        browser.open(self.portal.absolute_url() + '/@scan-in',
                     method='POST',
                     headers=headers,
                     data=body)

        self.assertEqual(201, browser.status_code)
        dossier = private_folder.objectValues()[0]
        self.assertEqual('Scaneingang', dossier.Title())
        self.assertIsNotNone(IUUID(dossier))
        self.assertIsNotNone(obj2brain(dossier).UID)
        doc = dossier.objectValues()[0]
        self.assertEqual('mydocument', doc.Title())
    def test_maintenance_error(self):
        portal = self.layer['portal']
        request = self.layer['request']
        folder = self.layer['folder']

        request.form['uid'] = IUUID(folder)

        _portlet, portlet_hash = self._get_portlet_and_hash()
        self._expect_request().throw(MaintenanceError())

        self.replay()
        request.form['hash'] = portlet_hash

        view = queryMultiAdapter((portal, request), name='watcher-load-data')
        self.assertNotEqual(view, None)

        self.assertEqual(view(), '"MAINTENANCE"')
Ejemplo n.º 16
0
 def _move_selected_content(self, origin_tile, target_tile, obj):
     """Move selected content from one tile to another tile"""
     target_tile.populate_with_object(obj)
     if IListTile.providedBy(origin_tile):
         uuid = IUUID(obj)
         origin_tile.remove_item(uuid)
     else:
         origin_dmgr = ITileDataManager(origin_tile)
         origin_data = origin_dmgr.get()
         target_dmgr = ITileDataManager(target_tile)
         target_data = target_dmgr.get()
         for k, v in origin_data.iteritems():
             if k in target_data and not k.startswith(
                     'uuid') and v is not None:
                 target_data[k] = v
         target_dmgr.set(target_data)
         origin_dmgr.delete()
Ejemplo n.º 17
0
    def test_UIDIndexer(self):
        uc = getattr(self.portal, config.UID_CATALOG)
        dext = DexterityLike()
        dext.path = list(self.folder.getPhysicalPath())
        self.folder[dext.id] = dext
        notify(ObjectCreatedEvent(dext))  # it supposed to add uuid attribute

        # catalog dext instance
        uc.catalog_object(dext, '/'.join(dext.getPhysicalPath()))

        # check lookup
        uuid = IUUID(dext, None)
        results = uc(UID=uuid)

        self.assertTrue(len(results) == 1)
        self.assertTrue(results[0].UID == uuid)
        self.assertTrue(results[0].Title == str(dext.Title()))
Ejemplo n.º 18
0
    def test_create_document_with_image_block_stores_uuid(self):
        self.portal.invokeFactory("Image", id="image", title="Image")
        image_file = os.path.join(os.path.dirname(__file__), "image.png")
        with open(image_file, "rb") as f:
            image_data = f.read()
        self.portal.image.image = NamedBlobImage(data=image_data,
                                                 contentType="image/png",
                                                 filename="image.png")
        self.portal.image.image_caption = "This is an image caption."
        transaction.commit()

        target_uuid = IUUID(self.portal.image)

        response = requests.post(
            self.portal.folder1.absolute_url(),
            headers={"Accept": "application/json"},
            auth=(SITE_OWNER_NAME, SITE_OWNER_PASSWORD),
            json={
                "@type": "Document",
                "id": "mydocument",
                "title": "My Document",
                "blocks": {
                    "09e39ddf-a945-49f2-b609-ea427ac3430b": {
                        "@type": "image",
                        "url": f"{self.portal_url}/image",
                    },
                    "21270e22-3a61-4780-b164-d6be56d942f4": {
                        "@type": "title"
                    },
                },
                "blocks_layout": {
                    "items": [
                        "21270e22-3a61-4780-b164-d6be56d942f4",
                        "09e39ddf-a945-49f2-b609-ea427ac3430b",
                    ]
                },
            },
        )
        self.assertEqual(201, response.status_code)
        transaction.begin()

        self.assertEqual(
            f"../../resolveuid/{target_uuid}",
            self.portal.folder1.mydocument.blocks.get(
                "09e39ddf-a945-49f2-b609-ea427ac3430b").get("url"),
        )
Ejemplo n.º 19
0
def move_file(obj):
    _, bucket = get_bucket()
    if bucket is None:
        return

    uid = IUUID(obj)
    if not uid:
        logger.info('Could not get uid of object')
        return

    key = KEY_PREFIX + uid
    filename = obj.file.filename
    if not isinstance(filename, unicode):
        filename = unicode(filename, 'utf-8', errors="ignore")
    filename = urllib.quote(filename.encode("utf8"))
    disposition = "attachment; filename*=UTF-8''%s" % filename

    size = obj.file.getSize()
    chunk_count = int(math.ceil(size / float(CHUNK_SIZE)))
    content_type = obj.file.contentType
    mp = bucket.initiate_multipart_upload(key,
                                          metadata={
                                              'Content-Type': content_type,
                                              'Content-Disposition':
                                              disposition
                                          })

    blob_fi = obj.file._blob.open('r')

    for i in range(chunk_count):
        chunk = blob_fi.read(CHUNK_SIZE)
        fp = io.BytesIO(chunk)
        mp.upload_part_from_file(fp, part_num=i + 1)

    mp.complete_upload()
    blob_fi.close()

    obj._p_jar.sync()
    obj.file = NamedBlobFile(data='',
                             contentType=obj.file.contentType,
                             filename=FILENAME)
    obj.file.original_filename = filename
    obj.file.original_content_type = content_type
    obj.file.original_size = size

    set_permission(obj)
Ejemplo n.º 20
0
    def setUp(self):
        self.portal = self.layer['portal']
        login(self.portal, TEST_USER_NAME)
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        self.portal.invokeFactory('Document', id="page", title="page")
        self.portal.page.reindexObject()

        self.env = {'HTTP_ACCEPT_LANGUAGE': 'en', 'REQUEST_METHOD': 'POST'}
        self.request = makerequest(self.layer['app']).REQUEST
        self.request.environ.update(self.env)
        self.request.form = {
            'selection': '["' + IUUID(self.portal.page) + '"]',
            '_authenticator': createToken(),
            'folder': '/'
        }
        self.request.REQUEST_METHOD = 'POST'
Ejemplo n.º 21
0
 def serialize(self,
               use_json=True,
               include_uid=False,
               encDefault=json.JSONEncoder.default):
     """
     Serialze queries of context to JSON, or if use_json is False, to an
     equivalent dict of data.
     """
     enc = lambda v: encDefault(v) if not isinstance(v, set) else list(v)
     data = {}
     if include_uid:
         data['uid'] = IUUID(self.context)
     data['operator'] = self.context.operator
     data['rows'] = [self._mkrow(q) for q in self.context.values()]
     if use_json:
         return json.dumps(data, indent=4, default=enc)
     return data
Ejemplo n.º 22
0
    def test_existing_content_tile(self):
        page = api.content.create(type='Document',
                                  id='page1',
                                  container=self.portal,
                                  subject=('foobar', ),
                                  title='Foobar',
                                  description='Some foobar stuff')
        api.content.transition(obj=page, to_state='published')

        data = {'content': [IUUID(page)]}
        name = self.prefix + 'existing'
        html = render_tile(self.request, page, name, data)
        self.assertTrue('existing-content-basic' in html)

        data['display_type'] = 'backgroundimage'
        html = render_tile(self.request, page, name, data)
        self.assertTrue('existing-content-backgroundimage' in html)
Ejemplo n.º 23
0
    def _add_grouping_values(self, grouping, values, obj):
        """ Add $uid to the list of uids stored under the grouping values
            (provided by $values) in the groupings datastructure.

            If the list doesn't exist yet, add it.
        """
        uid = IUUID(obj)
        groupings = self.get_groupings()
        if grouping not in groupings:
            logger.info('Adding grouping %s to object %r', grouping, obj)
            groupings[grouping] = OrderedBTreeFolderBase()

        for value in values:
            if value in groupings[grouping]:
                groupings[grouping][value].add(uid)
            else:
                groupings[grouping][value] = GroupingStorageValues([uid])
Ejemplo n.º 24
0
 def filters(self):
     if not hasattr(self, '_filters'):
         self._filters = []
         included = self.include_queries()
         for name in included:
             title = name.title()
             composed = self.composed_query(name)
             found = self.find_filters(composed)
             if found:
                 rfilter = found[0]
                 self._filters.append({
                     'groupname': name,
                     'uid': IUUID(rfilter),
                     'title': title,
                     'filter': rfilter,
                 })
     return self._filters
Ejemplo n.º 25
0
class RenameForm(plone_actions.RenameForm):
    @button.buttonAndHandler(_(u"Rename"), name="Rename")
    def handle_rename(self, action):
        request = self.request
        data, errors = self.extractData()
        if errors:
            return
        context = self.context
        parent = aq_parent(aq_inner(context))
        sm = getSecurityManager()
        if not sm.checkPermission("Copy or Move", parent):
            raise Unauthorized(
                _(
                    u"Permission denied to rename ${title}.",
                    mapping={u"title": context.title},
                ))

        newid = data["new_id"]
        newtitle = data["new_title"]

        try:
            notify(events.AsyncBeforeRename(context, newid, newtitle))
        except Unauthorized:
            IStatusMessage(self.request).add(
                _(
                    u"Permission denied to rename ${title}.",
                    mapping={u"title": context.title},
                ))
            return self.request.response.redirect(context.absolute_url())
        except interfaces.AsyncValidationFailed, e:
            IStatusMessage(request).add(unicode(e))
            return request.response.redirect(context.absolute_url())

        uuid = IUUID(context, 0)
        task_id = utils.register_task(
            action=constants.RENAME,
            context=uuid,
            old_title=context.title,
            old_id=context.id,
            new_id=newid,
            new_title=newtitle,
        )
        tasks.rename.apply_async(
            [context, data["new_id"], data["new_title"], task_id], dict())
        return self.request.response.redirect(parent.absolute_url())
Ejemplo n.º 26
0
        def test_add_to_folder(self):
            browser = Browser(self.layer['app'])
            browser.handleErrors = False

            uuid = IUUID(self.folder)

            # Login
            browser.open(self.portal.absolute_url() + '/login')
            browser.getControl(name='__ac_name').value = TEST_USER_NAME
            browser.getControl(name='__ac_password').value = TEST_USER_PASSWORD
            browser.getControl('Log in').click()

            # Enter the add screen for a temporary
            # portal_factory-managed object
            browser.open(
                '{}/portal_factory/Document/document.2010-02-04.2866363923/edit?_authenticator={}'
                .format(  # noqa
                    self.folder.absolute_url(), createToken()))

            # We should now have cookies with the drafts information
            cookies = browser.cookies.forURL(browser.url)
            path = '"{0}/portal_factory/Document/document.2010-02-04.2866363923"'  # noqa
            self.assertEqual(
                path.format(self.folder.absolute_url_path()),
                cookies['plone.app.drafts.path'],
            )
            self.assertEqual(
                '"{0}%3ADocument"'.format(uuid),
                cookies['plone.app.drafts.targetKey'],
            )
            self.assertNotIn(
                'plone.app.drafts.draftName',
                browser.cookies.forURL(browser.url),
            )

            # We can now cancel the edit. The cookies should expire.
            browser.getControl(name='form.button.cancel').click()
            self.assertNotIn(
                'plone.app.drafts.targetKey',
                browser.cookies.forURL(browser.url),
            )
            self.assertNotIn(
                'plone.app.drafts.path',
                browser.cookies.forURL(browser.url),
            )
Ejemplo n.º 27
0
    def create_file_from_request(self, name):
        context = self.context
        filedata = self.request.form.get(name, None)
        if not filedata:
            return
        filename = filedata.filename
        content_type = mimetypes.guess_type(filename)[0] or ""
        # Determine if the default file/image types are DX or AT based
        ctr = api.portal.get_tool('content_type_registry')
        type_ = ctr.findTypeName(filename.lower(), content_type, '')

        if not type_ == 'Image':
            type_ = 'File'

        pt = api.portal.get_tool('portal_types')

        if IDexterityFTI.providedBy(getattr(pt, type_)):
            obj = self.create_dx_file(filename, content_type, filedata, type_)
            self.post_factory(obj)
            notify(ObjectCreatedEvent(obj))
            if hasattr(obj, 'file'):
                size = obj.file.getSize()
                content_type = obj.file.contentType
            elif hasattr(obj, 'image'):
                size = obj.image.getSize()
                content_type = obj.image.contentType
            else:
                return
            result = {"type": content_type, "size": size}
        else:
            from Products.ATContentTypes.interfaces import IATCTFileFactory
            obj = IATCTFileFactory(context)(filename, content_type, filedata)
            self.post_factory(obj)
            try:
                size = obj.getSize()
            except AttributeError:
                size = obj.getObjSize()
            result = {"type": obj.getContentType(), "size": size}
        result.update({
            'url': obj.absolute_url(),
            'name': obj.getId(),
            'UID': IUUID(obj),
            'filename': filename
        })
        return result
Ejemplo n.º 28
0
    def delete(self, obj, fieldNames=[], force=False):
        '''Pass an xmlrpc call to the daemon when a video is deleted'''
        UID = IUUID(obj)
        log = logging.getLogger('collective.transcode.star')
        tt = getUtility(ITranscodeTool)
        fields = self._getFields(obj, fieldNames)
        if not self._hasFiles(obj, fields):
            return
        address = self._getDaemonAddress()
        if address is None:
            return
        (transcodeServer, daemonProfiles) = self._getDaemon(address)
        if transcodeServer is None or daemonProfiles is None:
            return
        secret = self.secret()

        for field in fields:
            info = self._getFieldInfo(obj, field)
            if info is None:
                continue
            fieldName = info['fieldName']
            md5sum = info['md5sum']
            fileType = info['fileType']
            fileName = info['fileName']
            filePath = obj.absolute_url()
            portal_url = getToolByName(obj, 'portal_url')()
            fileUrl = portal_url + '/@@serve_daemon'
            norm = queryUtility(IIDNormalizer)
            fileName = norm.normalize(fileName.decode('utf-8'))

            options = dict()
            payload = {
                'path': filePath,
                'url': fileUrl,
                'type': fileType,
                # don't send fieldName if it's the primary field
                'fieldName': fieldNames and fieldName or '',
                'fileName': fileName,
                'uid': UID,
            }
            # Encrypt and send the transcode request
            payload = {'key': b64encode(encrypt(str(payload), secret))}
            transcodeServer.delete(payload, options, portal_url)
            tt.__delitem__(UID)
        return
Ejemplo n.º 29
0
    def set_related_items(self, value):
        """ Set related items
        """
        instance = self
        field = self.getField('relatedItems')

        tool = getToolByName(instance, REFERENCE_CATALOG)
        targetUIDs = [
            ref.targetUID
            for ref in tool.getReferences(instance, field.relationship)
        ]

        if value is None:
            value = ()

        if not isinstance(value, (list, tuple)):
            value = value,
        elif not field.multiValued and len(value) > 1:
            raise ValueError(
                "Multiple values given for single valued field %r" % self)

        # convert objects to uids if necessary
        uids = []
        for v in value:
            if isinstance(v, basestring):
                uids.append(v)
            else:
                uids.append(IUUID(v, None))

        add = [x for x in uids if x and x not in targetUIDs]
        sub = [t for t in targetUIDs if t not in uids]

        for uid in add:
            # __traceback_info__ = (instance, uid, value, targetUIDs)
            # throws IndexError if uid is invalid
            tool.addReference(instance, uid, field.relationship)

        for uid in sub:
            tool.deleteReference(instance, uid, field.relationship)

        if not hasattr(aq_base(instance), 'at_ordered_refs'):
            instance.at_ordered_refs = {}

        tpl_uids = tuple([u for u in uids if u is not None])
        instance.at_ordered_refs[field.relationship] = tpl_uids
Ejemplo n.º 30
0
    def test_search(self):
        from plone.uuid.interfaces import IUUID

        portal = self.layer['portal']
        setRoles(portal, TEST_USER_ID, ['Manager'])

        portal.invokeFactory('Document', 'd1')
        portal.invokeFactory('Document', 'd2')

        d1 = portal['d1']
        uuid = IUUID(d1)

        catalog = portal['portal_catalog']
        results = catalog(UID=uuid)

        self.assertEqual(1, len(results))
        self.assertEqual(uuid, results[0].UID)
        self.assertEqual('/'.join(d1.getPhysicalPath()), results[0].getPath())