Пример #1
0
 def queryCatalog(self, batch=True, b_start=0, b_size=30, sort_on=None):
     from plone.app.contenttypes.behaviors.collection import \
         ICollection as ICollection_behavior
     return ICollection_behavior(self).results(batch,
                                               b_start,
                                               b_size,
                                               sort_on=sort_on)
Пример #2
0
    def test_collection_templates(self):
        self.portal.acl_users.userFolderAddUser(SITE_OWNER_NAME,
                                                SITE_OWNER_PASSWORD,
                                                ['Manager'], [])
        browser = self.browser
        portal = self.portal
        login(portal, SITE_OWNER_NAME)
        # add an image that will be listed by the collection
        portal.invokeFactory('Image', 'image', title='Image example')

        image = self.portal['image']
        image.image = dummy_image()

        # add a collection, so we can add a query to it
        portal.invokeFactory('Collection',
                             'collection',
                             title='New Collection')
        collection = portal['collection']
        # Search for images
        query = [{
            'i': 'Type',
            'o': 'plone.app.querystring.operation.string.is',
            'v': 'Image',
        }]
        collection.text = RichTextValue(u'Lorem collection ipsum',
                                        'text/plain', 'text/html')

        wrapped = ICollection_behavior(collection)
        # set the query and publish the collection
        wrapped.query = query
        workflow = portal.portal_workflow
        workflow.doActionFor(collection, 'publish')
        commit()
        logout()
        # open a browser to see if our image is in the results
        browser.handleErrors = False
        url = collection.absolute_url()
        browser.open(url)
        self.assertIn('Lorem collection ipsum', browser.contents)
        self.assertIn('Image example', browser.contents)

        # open summary_view template
        browser.open('{0}/@@summary_view'.format(url))
        self.assertIn('Lorem collection ipsum', browser.contents)
        self.assertIn('Image example', browser.contents)

        # open full_view template
        browser.open('{0}/@@full_view'.format(url))
        self.assertIn('Lorem collection ipsum', browser.contents)
        self.assertIn('Image example', browser.contents)

        # open tabular_view template
        browser.open('{0}/@@tabular_view'.format(url))
        self.assertIn('Lorem collection ipsum', browser.contents)
        self.assertIn('Image example', browser.contents)

        # open thumbnail_view template
        browser.open('{0}/@@album_view'.format(url))
        self.assertIn('Lorem collection ipsum', browser.contents)
        self.assertIn('Image example', browser.contents)
Пример #3
0
 def selectedViewFields(self):
     """Returns a list of all metadata fields from the catalog that were
        selected.
     """
     from plone.app.contenttypes.behaviors.collection import \
         ICollection as ICollection_behavior
     return ICollection_behavior(self).selectedViewFields()
Пример #4
0
    def __call__(self, context, **query):
        ctool = getToolByName(context, 'portal_faceted', None)
        if ctool:
            search = ctool.search
        else:
            logger.debug('portal_faceted not present, using portal_catalog')
            ctool = getToolByName(context, 'portal_catalog')
            search = ctool.searchResults

        # Also get query from Topic
        buildQuery = getattr(context, 'buildQuery', None)
        newquery = buildQuery and buildQuery() or {}
        formquery = None

        # Get query from Collection
        if HAS_PAT:
            if PACI.ICollection.providedBy(context):
                infos = ICollection_behavior(context)
                sort_order = ('descending'
                              if infos.sort_reversed
                              else 'ascending')
                sort_on = infos.sort_on
                formquery = infos.query

        if ICollection.providedBy(context):
            getRawQuery = getattr(context, 'getRawQuery', lambda: [])
            formquery = getRawQuery()

            getSortOn = getattr(context, 'getSort_on', lambda: None)
            sort_on = getSortOn()

            if sort_on:
                getSortReversed = getattr(
                    context, 'getSort_reversed', lambda: None)
                sort_order = getSortReversed()
                if sort_order:
                    sort_order = 'descending'
                else:
                    sort_order = 'ascending'
            else:
                sort_order = None

        if formquery is not None:
            newquery = parseFormquery(context, formquery, sort_on, sort_order)

        if not isinstance(newquery, dict):
            newquery = {}

        # Avoid mixing sorting params from faceted and collection
        if 'sort_on' not in query:
            query.pop('sort_order', None)

        if 'sort_on' in query and 'sort_order' not in query:
            newquery.pop('sort_order', None)

        newquery.update(query)

        notify(QueryWillBeExecutedEvent(context, newquery))
        return search(**newquery)
Пример #5
0
    def test_collection_templates(self):
        browser = self.browser
        portal = self.layer['portal']
        login(portal, 'admin')
        # add an image that will be listed by the collection
        portal.invokeFactory("Image", "image", title="Image example")

        image = self.portal['image']
        image.image = dummy_image()

        # add a collection, so we can add a query to it
        portal.invokeFactory("Collection",
                             "collection",
                             title="New Collection")
        collection = portal['collection']
        # Search for images
        query = [{
            'i': 'Type',
            'o': 'plone.app.querystring.operation.string.is',
            'v': 'Image',
        }]
        collection.text = RichTextValue(u"Lorem collection ipsum",
                                        'text/plain', 'text/html')

        wrapped = ICollection_behavior(collection)
        # set the query and publish the collection
        wrapped.query = query
        workflow = portal.portal_workflow
        workflow.doActionFor(collection, "publish")
        commit()
        logout()
        # open a browser to see if our image is in the results
        browser.handleErrors = False
        url = collection.absolute_url()
        browser.open(url)
        self.assertTrue("Lorem collection ipsum" in browser.contents)
        self.assertTrue("Image example" in browser.contents)

        # open summary_view template
        browser.open('%s/@@summary_view' % url)
        self.assertTrue("Lorem collection ipsum" in browser.contents)
        self.assertTrue("Image example" in browser.contents)

        # open full_view template
        browser.open('%s/@@full_view' % url)
        self.assertTrue("Lorem collection ipsum" in browser.contents)
        self.assertTrue("Image example" in browser.contents)

        # open tabular_view template
        browser.open('%s/@@tabular_view' % url)
        self.assertTrue("Lorem collection ipsum" in browser.contents)
        self.assertTrue("Image example" in browser.contents)

        # open thumbnail_view template
        browser.open('%s/@@album_view' % url)
        self.assertTrue("Lorem collection ipsum" in browser.contents)
        self.assertTrue("Image example" in browser.contents)
Пример #6
0
    def test_respect_navigation_root(self):
        self.portal.acl_users.userFolderAddUser(SITE_OWNER_NAME,
                                                SITE_OWNER_PASSWORD,
                                                ['Manager'], [])
        portal = self.portal
        login(portal, SITE_OWNER_NAME)

        # Create two subsites i.e create two folders and mark them with
        # INavigationRoot
        for i in range(1, 3):
            folder_id = 'folder{0}'.format(i)
            portal.invokeFactory('Folder',
                                 folder_id,
                                 title='Folder{0}'.format(i))
            folder = portal[folder_id]
            alsoProvides(folder, INavigationRoot)
        folders = (portal['folder1'], portal['folder2'])

        # Add a content item to each folder
        for f in folders:
            f_id = f.getId()
            f.invokeFactory('Document',
                            'item_in_{0}'.format(f_id),
                            title='Item In {0}'.format(f_id))

        # Add a collection to folder1
        folder1 = folders[0]
        folder1.invokeFactory('Collection',
                              'collection1',
                              title='Collection 1')
        collection1 = folder1['collection1']
        wrapped = ICollection_behavior(collection1)
        wrapped.query = [
            {
                'i': 'portal_type',
                'o': 'plone.app.querystring.operation.string.is',
                'v': 'Document',
            },
            # use a "/" path and navroot works fine!
            {
                'i': 'path',
                'o': 'plone.app.querystring.operation.string.path',
                'v': '/',
            },
        ]

        # Check if only the item inside folder1 is returned, since it's a
        # navigation root.
        items = wrapped.results(batch=False)
        ids = [i.getId() for i in items]
        self.assertListEqual(ids, ['item_in_folder1'])
Пример #7
0
    def test_custom_query(self):
        self.portal.acl_users.userFolderAddUser(SITE_OWNER_NAME,
                                                SITE_OWNER_PASSWORD,
                                                ['Manager'], [])
        portal = self.portal
        login(portal, SITE_OWNER_NAME)
        query = [{
            'i': 'portal_type',
            'o': 'plone.app.querystring.operation.string.is',
            'v': ['News Item', 'Document'],
        }]
        portal.invokeFactory(
            'Collection',
            'collection',
            title='New Collection',
            query=query,
        )

        # item 1
        portal.invokeFactory(id='testnews', type_name='News Item')
        item1 = portal.testnews
        item1.reindexObject()

        # item 2
        portal.invokeFactory(id='testdoc', type_name='Document')
        item2 = portal.testdoc
        item2.reindexObject()

        collection = portal['collection']
        wrapped = ICollection_behavior(collection)

        # Test unmodified query
        results = wrapped.results(batch=False)
        self.assertEqual(len(results), 2)

        # Test with custom query
        results = wrapped.results(batch=False,
                                  custom_query={'portal_type': 'Document'})
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].id, 'testdoc')

        # Test with custom query, which should not find anything
        results = wrapped.results(batch=False,
                                  custom_query={
                                      'portal_type': 'Document',
                                      'id': 'bla'
                                  })
        self.assertEqual(len(results), 0)
    def test_sorting_1(self):
        self.portal.acl_users.userFolderAddUser(
            SITE_OWNER_NAME, SITE_OWNER_PASSWORD, ['Manager'], [])

        portal = self.portal
        login(portal, SITE_OWNER_NAME)
        query = [{
            'i': 'portal_type',
            'o': 'plone.app.querystring.operation.string.is',
            'v': 'News Item',
        }]
        portal.invokeFactory('Collection',
                             'collection',
                             title='New Collection',
                             query=query,
                             sort_on='created',
                             sort_reversed=True,
                             )

        now = DateTime()
        # News Item 1
        portal.invokeFactory(id='newsitem1',
                             type_name='News Item')
        item1 = portal.newsitem1
        item1.creation_date = now - 2
        item1.reindexObject()
        # News Item 2
        portal.invokeFactory(id='newsitem2',
                             type_name='News Item')
        item2 = portal.newsitem2
        item2.creation_date = now - 1
        item2.reindexObject()
        # News Item 3
        portal.invokeFactory(id='newsitem3',
                             type_name='News Item')
        item3 = portal.newsitem3
        item3.creation_date = now
        item3.reindexObject()

        collection = portal['collection']
        wrapped = ICollection_behavior(collection)
        results = wrapped.results(batch=False)
        ritem0 = results[0]
        ritem1 = results[1]
        ritem2 = results[2]

        self.assertTrue(ritem0.CreationDate() > ritem1.CreationDate())
        self.assertTrue(ritem1.CreationDate() > ritem2.CreationDate())
Пример #9
0
    def test_sorting_1(self):
        portal = self.layer['portal']
        login(portal, 'admin')
        query = [{
            'i': 'portal_type',
            'o': 'plone.app.querystring.operation.string.is',
            'v': 'News Item',
        }]
        portal.invokeFactory("Collection",
                             "collection",
                             title="New Collection",
                             query=query,
                             sort_on='created',
                             sort_reversed=True,
                             )

        now = DateTime()
        # News Item 1
        portal.invokeFactory(id='newsitem1',
                             type_name='News Item')
        item1 = portal.newsitem1
        item1.creation_date = now - 2
        item1.reindexObject()
        # News Item 2
        portal.invokeFactory(id='newsitem2',
                             type_name='News Item')
        item2 = portal.newsitem2
        item2.creation_date = now - 1
        item2.reindexObject()
        # News Item 3
        portal.invokeFactory(id='newsitem3',
                             type_name='News Item')
        item3 = portal.newsitem3
        item3.creation_date = now
        item3.reindexObject()

        collection = portal['collection']
        wrapped = ICollection_behavior(collection)
        results = wrapped.results(batch=False)
        ritem0 = results[0]
        ritem1 = results[1]
        ritem2 = results[2]

        self.assertTrue(ritem0.CreationDate() > ritem1.CreationDate())
        self.assertTrue(ritem1.CreationDate() > ritem2.CreationDate())
Пример #10
0
    def test_custom_query(self):
        portal = self.layer['portal']
        login(portal, 'admin')
        query = [{
            'i': 'portal_type',
            'o': 'plone.app.querystring.operation.string.is',
            'v': ['News Item', 'Document'],
        }]
        portal.invokeFactory(
            "Collection",
            "collection",
            title="New Collection",
            query=query,
        )

        # item 1
        portal.invokeFactory(id='testnews', type_name='News Item')
        item1 = portal.testnews
        item1.reindexObject()

        # item 2
        portal.invokeFactory(id="testdoc", type_name='Document')
        item2 = portal.testdoc
        item2.reindexObject()

        collection = portal['collection']
        wrapped = ICollection_behavior(collection)

        # Test unmodified query
        results = wrapped.results(batch=False)
        self.assertEqual(len(results), 2)

        # Test with custom query
        results = wrapped.results(batch=False,
                                  custom_query={'portal_type': 'Document'})
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].id, 'testdoc')

        # Test with custom query, which should not find anything
        results = wrapped.results(batch=False,
                                  custom_query={
                                      'portal_type': 'Document',
                                      'id': 'bla'
                                  })
        self.assertEqual(len(results), 0)
Пример #11
0
    def test_respect_navigation_root(self):
        portal = self.layer['portal']
        login(portal, 'admin')

        # Create two subsites i.e create two folders and mark them with
        # INavigationRoot
        for i in xrange(1, 3):
            folder_id = 'folder{}'.format(i)
            portal.invokeFactory('Folder',
                                 folder_id,
                                 title='Folder{}'.format(i))
            folder = portal[folder_id]
            alsoProvides(folder, INavigationRoot)
        folders = (portal['folder1'], portal['folder2'])

        # Add a content item to each folder
        for f in folders:
            f_id = f.getId()
            f.invokeFactory('Document',
                            'item_in_{}'.format(f_id),
                            title='Item In {}'.format(f_id))

        # Add a collection to folder1
        folder1 = folders[0]
        folder1.invokeFactory('Collection',
                              'collection1',
                              title='Collection 1')
        collection1 = folder1['collection1']
        wrapped = ICollection_behavior(collection1)
        wrapped.query = [{
            'i': 'portal_type',
            'o': 'plone.app.querystring.operation.string.is',
            'v': 'Document',
        }]

        # Check if only the item inside folder1 is returned, since it's a
        # navigation root.
        items = wrapped.results(batch=False)
        ids = [i.getId() for i in items]
        self.assertListEqual(ids, ['item_in_folder1'])
Пример #12
0
 def results(self, **kwargs):
     from plone.app.contenttypes.behaviors.collection import \
         ICollection as ICollection_behavior
     return ICollection_behavior(self).results(**kwargs)
Пример #13
0
    def __call__(self, context, **query):
        # return super(FacetedCatalog, self).__call__(context, **query)
        ctool = getToolByName(context, 'portal_faceted', None)
        if ctool:
            search = ctool.search
        else:
            logger.debug('portal_faceted not present, using portal_catalog')
            ctool = getToolByName(context, 'portal_catalog')
            search = ctool.searchResults

        # Also get query from Topic
        buildQuery = getattr(context, 'buildQuery', None)
        newquery = buildQuery and buildQuery() or {}
        formquery = None

        # Get query from Collection
        if HAS_PAT:
            if PACI.ICollection.providedBy(context):
                infos = ICollection_behavior(context)
                sort_order = ('descending'
                              if infos.sort_reversed else 'ascending')
                sort_on = infos.sort_on
                formquery = infos.query

        if ICollection.providedBy(context):
            getRawQuery = getattr(context, 'getRawQuery', lambda: [])
            formquery = getRawQuery()

            getSortOn = getattr(context, 'getSort_on', lambda: None)
            sort_on = getSortOn()

            if sort_on:
                getSortReversed = getattr(context, 'getSort_reversed',
                                          lambda: None)
                sort_order = getSortReversed()
                if sort_order:
                    sort_order = 'descending'
                else:
                    sort_order = 'ascending'
            else:
                sort_order = None

        if formquery is not None:
            newquery = parseFormquery(context, formquery, sort_on, sort_order)

        if not isinstance(newquery, dict):
            newquery = {}

        # Avoid mixing sorting params from faceted and collection
        if 'sort_on' not in query:
            query.pop('sort_order', None)

        if 'sort_on' in query and 'sort_order' not in query:
            newquery.pop('sort_order', None)

        newquery.update(query)

        notify(QueryWillBeExecutedEvent(context, newquery))

        # code above is unchanged from original code

        # example of query:
        #{'sort_order': 'descending',
        # 'Language': ['fr', ''],
        # 'portal_type': {'query': ['operationalobjective']},
        # 'sort_on': 'created',
        # ':has_child': {'query': {
        #     'portal_type': {'query': ['pstaction']},
        #     'planned_end_date': {'query': DateTime('2016/08/12 12:49:6.218718 GMT+2'), 'range': 'max'}}}}

        has_child_filters = [
            k for k in newquery.keys() if k.startswith(':has_child')
        ]
        if len(has_child_filters) > 1:
            raise Exception('We only support one :has_child filter')

        if has_child_filters:
            sort_on = newquery.pop('sort_on', None)
            sort_order = newquery.pop('sort_order', None)
            limit = newquery.pop('limit', None)
            b_start = int(newquery.pop('b_start', 0))
            b_size = newquery.pop('b_size', None)
            if b_size is not None:
                b_size = int(b_size)

            if b_size is not None:
                limit = b_start + b_size
            elif limit and b_size is None:
                b_size = limit

            has_child_filter = deepcopy(
                newquery[has_child_filters[0]]['query'])
            # be sure we don't do a useless sort and we have all results
            has_child_filter.pop('sort_on', None)
            has_child_filter.pop('sort_order', None)
            has_child_filter.pop('limit', None)
            has_child_filter.pop('b_size', None)
            children_results = search(**has_child_filter)
            parentRIDs = IISet()
            for b in children_results:
                # TODO: possible optimization is to add parentRID as brain metadata
                parentRID = ctool._catalog.uids.get('/'.join(
                    b.getPath().split('/')[:-1]))
                parentRIDs.add(parentRID)

            brains = search(**newquery)
            # brains should be a LazyMap, access direct to brains._seq which is a list of rids
            # instead of doing IISet(brain.getRID() for brain in brains)
            rs = weightedIntersection(IISet(brains._seq), parentRIDs)[1]

            rlen = len(rs)
            if sort_on is not None:
                # We only support single sort order
                sort_index = ctool._catalog.indexes[sort_on]
                reverse = 1 if sort_order == 'descending' else 0
                brains = ctool._catalog.sortResults(rs,
                                                    sort_index,
                                                    reverse,
                                                    limit,
                                                    merge=1,
                                                    actual_result_count=rlen,
                                                    b_start=b_start,
                                                    b_size=b_size)
            else:
                brains = brains.__class__(brains._func, rs, rlen, rlen)
        else:
            brains = search(**newquery)

        return brains