Beispiel #1
0
    def test_noexpand_start(self):
        # now+future events
        res = self.fmt(
            get_events(self.portal,
                       expand=False,
                       start=self.now,
                       ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u'Long Event', '2013-04-25 10:00:00', '2013-06-04 10:00:00'),
            (u'Now Event', '2013-05-05 10:00:00', '2013-05-05 11:00:00'),
            (u'Tomorrow event', '2013-05-06 10:00:00', '2013-05-06 23:59:59'),
            # Past Recur next occurrence: '2013-05-09 11:00:00'
            # Past Recur brain.start: '2013-04-25 11:00:00'
            (u'Past Recur', '2013-04-25 11:00:00', '2013-04-25 12:00:00'),
            (u'Future Event', '2013-05-15 10:00:00', '2013-05-15 11:00:00')
        ]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited now+future events
        res = self.fmt(
            get_events(self.portal,
                       expand=False,
                       start=self.now,
                       limit=3,
                       ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
    def test_recurrence_indexing(self):
        tz = pytz.timezone("Europe/Vienna")
        e1 = createContentInContainer(
            self.portal,
            'plone.app.event.dx.event',
            title=u'event1',
            start=tz.localize(datetime(2011, 11, 11, 11, 0)),
            end=tz.localize(datetime(2011, 11, 11, 12, 0)),
        )

        # When editing via behaviors, the attributes should also be available
        # on the context itself.
        IEventRecurrence(e1).recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        self.assertTrue(e1.recurrence == IEventRecurrence(e1).recurrence)

        e1.reindexObject()

        # get_events, no expanded occurrences
        result = get_events(self.portal)
        self.assertEqual(len(result), 1)

        # Get all the occurrences
        result = get_events(
            self.portal,
            start=tz.localize(datetime(2011, 11, 11, 11, 0)),
            ret_mode=base.RET_MODE_OBJECTS,
            expand=True
        )
        self.assertEqual(len(result), 4)
Beispiel #3
0
    def test_recurrence_indexing(self):
        tz = pytz.timezone("Europe/Vienna")
        e1 = createContentInContainer(
            self.portal,
            'plone.app.event.dx.event',
            title='event1',
            start=tz.localize(datetime(2011, 11, 11, 11, 0)),
            end=tz.localize(datetime(2011, 11, 11, 12, 0)),
        )

        # When editing via behaviors, the attributes should also be available
        # on the context itself.
        IEventRecurrence(e1).recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        self.assertTrue(e1.recurrence == IEventRecurrence(e1).recurrence)

        e1.reindexObject()

        # get_events, no expanded occurrences
        result = get_events(self.portal)
        self.assertEqual(len(result), 1)

        # Get all the occurrences
        result = get_events(self.portal,
                            start=tz.localize(datetime(2011, 11, 11, 11, 0)),
                            ret_mode=base.RET_MODE_OBJECTS,
                            expand=True)
        self.assertEqual(len(result), 4)
Beispiel #4
0
    def test_get_event_limit(self):
        """Test pull-request #93.
        The limit on the query has to be removed, because:

            - In the index, for each occurrence an index entry is created with
              reference to the originating event object (not an occurrence
              object - such doesn't exist).

            - The event object's start and end dates are the very first
              occurrence. Every other occurence is not stored anywhere but
              created on the fly from a recurrence rule.

            - Sorting on start sorts on the very first occurrence - this is
              where the problem originates.

        When doing a range search for events from now on and sorting for the
        start date, an event in the past might be sorted before tomorrow's
        event even if the next occurrence is somewhere in the future.

        Now, when limiting the result set with the catalog's sort_limit before
        expanding the recurrence to occurrences, tomorrow's event might fall
        out and the past event might be in. So limiting the result set can only
        be done after expanding the occurrences. Then we really have the
        correct order.
        """
        factory = self.event_factory
        factory(
            container=self.portal,
            content_id='past_recur',
            title=u'Past Event recurring',
            start=self.past,
            end=self.past + self.duration,
            location=u"Dornbirn",
            recurrence='RRULE:FREQ=WEEKLY;COUNT=4',
        )

        tomorrow = factory(
            container=self.portal,
            content_id='tomorrow',
            title=u'Tomorrow event',
            start=self.tomorrow,
            end=self.tomorrow + self.duration,
            open_end=True,
            location=u"Dornbirn",
        )
        tomorrow.reindexObject()

        limit = get_events(self.portal,
                           start=self.now,
                           expand=True,
                           ret_mode=RET_MODE_ACCESSORS,
                           limit=3)
        all_ = get_events(self.portal,
                          start=self.now,
                          expand=True,
                          ret_mode=RET_MODE_ACCESSORS)
        self.assertEqual([e.url for e in limit], [e.url for e in all_[:3]])
    def test_get_event_limit(self):
        """Test pull-request #93.
        The limit on the query has to be removed, because:

            - In the index, for each occurrence an index entry is created with
              reference to the originating event object (not an occurrence
              object - such doesn't exist).

            - The event object's start and end dates are the very first
              occurrence. Every other occurence is not stored anywhere but
              created on the fly from a recurrence rule.

            - Sorting on start sorts on the very first occurrence - this is
              where the problem originates.

        When doing a range search for events from now on and sorting for the
        start date, an event in the past might be sorted before tomorrow's
        event even if the next occurrence is somewhere in the future.

        Now, when limiting the result set with the catalog's sort_limit before
        expanding the recurrence to occurrences, tomorrow's event might fall
        out and the past event might be in. So limiting the result set can only
        be done after expanding the occurrences. Then we really have the
        correct order.
        """
        factory = self.event_factory
        factory(
            container=self.portal,
            content_id='past_recur',
            title=u'Past Event recurring',
            start=self.past,
            end=self.past + self.duration,
            location=u"Dornbirn",
            recurrence='RRULE:FREQ=WEEKLY;COUNT=4',
        )
        # data_postprocessing normalization is not needed, as we values are set
        # correctly in the first place.

        tomorrow = factory(
            container=self.portal,
            content_id='tomorrow',
            title=u'Tomorrow event',
            start=self.tomorrow,
            end=self.tomorrow + self.duration,
            open_end=True,
            location=u"Dornbirn",
        )
        # Normalize values and reindex, what normally the form would do
        # (especially, end time isn't set like open_end settings requests to.
        data_postprocessing_context(tomorrow)
        tomorrow.reindexObject()

        limit = get_events(self.portal, start=self.now, expand=True,
                           ret_mode=RET_MODE_ACCESSORS, limit=3)
        all_ = get_events(self.portal, start=self.now, expand=True,
                          ret_mode=RET_MODE_ACCESSORS)
        self.assertEqual([e.url for e in limit], [e.url for e in all_[:3]])
    def test_get_occurrences(self):
        res = get_events(self.portal, ret_mode=3, expand=True)
        self.assertTrue(len(res) == 9)

        res = get_events(self.portal, start=self.now, ret_mode=3, expand=True)
        self.assertTrue(len(res) == 9)

        res = get_events(self.portal, ret_mode=3, expand=True, limit=5)
        self.assertTrue(len(res) == 5)
        self.assertTrue(IEventAccessor.providedBy(res[0]))
    def test_get_occurrences(self):
        res = get_events(self.portal, ret_mode=3, expand=True)
        self.assertTrue(len(res) == 9)

        res = get_events(self.portal, start=self.now, ret_mode=3, expand=True)
        self.assertTrue(len(res) == 9)

        res = get_events(self.portal, ret_mode=3, expand=True, limit=5)
        self.assertTrue(len(res) == 5)
        self.assertTrue(IEventAccessor.providedBy(res[0]))
    def test_get_event_limit(self):
        """Test pull-request #93.
        The limit on the query has to be removed, because:

            - In the index, for each occurrence an index entry is created with
              reference to the originating event object (not an occurrence
              object - such doesn't exist).

            - The event object's start and end dates are the very first
              occurrence. Every other occurence is not stored anywhere but
              created on the fly from a recurrence rule.

            - Sorting on start sorts on the very first occurrence - this is
              where the problem originates.

        When doing a range search for events from now on and sorting for the
        start date, an event in the past might be sorted before tomorrow's
        event even if the next occurrence is somewhere in the future.

        Now, when limiting the result set with the catalog's sort_limit before
        expanding the recurrence to occurrences, tomorrow's event might fall
        out and the past event might be in. So limiting the result set can only
        be done after expanding the occurrences. Then we really have the
        correct order.
        """
        factory = self.event_factory()
        factory(
            container=self.portal,
            content_id='past_recur1',
            title=u'Past Event recurring 1',
            start=self.past,
            end=self.past + self.duration,
            location=u"Dornbirn",
            timezone=TEST_TIMEZONE,
            recurrence='RRULE:FREQ=WEEKLY;COUNT=4',
        )
        factory(
            container=self.portal,
            content_id='tomorrow',
            title=u'Tomorrow event',
            start=self.tomorrow,
            end=self.tomorrow + self.duration,
            open_end=True,
            location=u"Dornbirn",
            timezone=TEST_TIMEZONE,
        )

        limit = get_events(self.portal, start=self.now, expand=True,
                           ret_mode=RET_MODE_ACCESSORS, limit=3)
        all_ = get_events(self.portal, start=self.now, expand=True,
                          ret_mode=RET_MODE_ACCESSORS)
        self.assertEqual([e.url for e in limit], [e.url for e in all_[:3]])

        self.portal.manage_delObjects(['past_recur1', 'tomorrow'])
Beispiel #9
0
    def test_get_occurrences(self):
        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS,
                         expand=True)
        self.assertEqual(len(res), 9)
        res = get_events(self.portal, start=self.now,
                         ret_mode=RET_MODE_ACCESSORS, expand=True)
        self.assertEqual(len(res), 8)

        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS,
                         expand=True, limit=5)
        self.assertEqual(len(res), 5)
        self.assertTrue(IEventAccessor.providedBy(res[0]))
    def test_noexpand_end(self):
        # past+now events
        res = self.fmt(get_events(self.portal, expand=False, end=self.now, ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u"Past Event", "2013-04-25 00:00:00", "2013-04-25 23:59:59"),
            (u"Long Event", "2013-04-25 10:00:00", "2013-06-04 10:00:00"),
            (u"Past Recur", "2013-04-25 11:00:00", "2013-04-25 12:00:00"),
            (u"Now Event", "2013-05-05 10:00:00", "2013-05-05 11:00:00"),
        ]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited past+now events
        res = self.fmt(get_events(self.portal, expand=False, end=self.now, limit=3, ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
    def test_noexpand_start_end(self):
        # only now events
        res = self.fmt(get_events(self.portal, expand=False, start=self.now, end=self.now, ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u"Long Event", "2013-04-25 10:00:00", "2013-06-04 10:00:00"),
            (u"Now Event", "2013-05-05 10:00:00", "2013-05-05 11:00:00"),
        ]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited now events
        res = self.fmt(
            get_events(self.portal, expand=False, start=self.now, end=self.now, limit=3, ret_mode=RET_MODE_ACCESSORS)
        )
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
Beispiel #12
0
 def test_expand_start_limit(self):
     # limited now+future occurrences
     res = self.fmt(get_events(self.portal, expand=True,
                               start=self.now, limit=3,
                               ret_mode=RET_MODE_ACCESSORS))
     expect = self.occ[1:2] + self.occ[6:8]  # includes ongoing long event
     self.assertEqual(res, expect, self.diff(res, expect))
    def _get_events(self, ret_mode=3):
        context = self.context
        kw = {}
        if self.path:
            kw['path'] = self.path
        elif self.settings.current_folder_only:
            kw['path'] = '/'.join(context.getPhysicalPath())
        #kw['b_start'] = self.b_start
        #kw['b_size']  = self.b_size

        if self.tags:
            kw['Subject'] = {'query': self.tags, 'operator': 'and'}

        if self.searchable_text:
            kw['SearchableText'] = self.searchable_text

        start, end = self._start_end

        sort = 'start'
        sort_reverse = False
        if self.mode in ('past', 'all'):
            sort_reverse = True
        return get_events(context, start=start, end=end,
                          sort=sort, sort_reverse=sort_reverse,
                          ret_mode=ret_mode, expand=True, **kw)
Beispiel #14
0
    def _get_events(self, ret_mode=RET_MODE_ACCESSORS, expand=True):
        context = self.context
        kw = {}
        if self.uid:
            # In this case, restrict search for single event
            kw['UID'] = self.uid
        else:
            if self.path:
                kw['path'] = self.path
            else:
                # Search current and subsequent folders
                kw['path'] = '/'.join(context.getPhysicalPath())

            if self.tags:
                kw['Subject'] = {'query': self.tags, 'operator': 'and'}

            if self.searchable_text:
                kw['SearchableText'] = self.searchable_text

        # kw['b_start'] = self.b_start
        # kw['b_size']  = self.b_size

        start, end = self._start_end

        sort = 'start'
        sort_reverse = False
        if self.mode in ('past', 'all'):
            sort_reverse = True
        return get_events(context, start=start, end=end,
                          sort=sort, sort_reverse=sort_reverse,
                          ret_mode=ret_mode, expand=expand, **kw)
Beispiel #15
0
 def test_expand_all_limit(self):
     # limited occurrences
     res = self.fmt(get_events(self.portal, expand=True,
                               limit=3,
                               ret_mode=RET_MODE_ACCESSORS))
     expect = self.occ[:3]
     self.assertEqual(res, expect, self.diff(res, expect))
    def test_noexpand_all(self):
        # all events
        res = self.fmt(get_events(self.portal, expand=False, ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u"Past Event", "2013-04-25 00:00:00", "2013-04-25 23:59:59"),
            (u"Long Event", "2013-04-25 10:00:00", "2013-06-04 10:00:00"),
            (u"Past Recur", "2013-04-25 11:00:00", "2013-04-25 12:00:00"),
            (u"Now Event", "2013-05-05 10:00:00", "2013-05-05 11:00:00"),
            (u"Tomorrow event", "2013-05-06 10:00:00", "2013-05-06 23:59:59"),
            (u"Future Event", "2013-05-15 10:00:00", "2013-05-15 11:00:00"),
        ]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited events
        res = self.fmt(get_events(self.portal, expand=False, limit=3, ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
    def _get_events(self, ret_mode=RET_MODE_ACCESSORS, expand=True):
        context = self.context
        kw = {}
        if self.uid:
            # In this case, restrict search for single event
            kw['UID'] = self.uid
        else:
            if self.path:
                kw['path'] = self.path
            else:
                # Search current and subsequent folders
                kw['path'] = '/'.join(context.getPhysicalPath())

            if self.tags:
                kw['Subject'] = {'query': self.tags, 'operator': 'and'}

            if self.searchable_text:
                kw['SearchableText'] = self.searchable_text

        # kw['b_start'] = self.b_start
        # kw['b_size']  = self.b_size

        start, end = self._start_end

        sort = 'start'
        sort_reverse = False
        if self.mode in ('past', 'all'):
            sort_reverse = True
        return get_events(context, start=start, end=end,
                          sort=sort, sort_reverse=sort_reverse,
                          ret_mode=ret_mode, expand=expand, **kw)
Beispiel #18
0
    def get_all_events(self, batch=True):
        # Fall back to default language for local events
        kw = {}
        default_lang = api.portal.get_tool(
            "portal_languages").getDefaultLanguage()
        if ITranslatable.providedBy(self.context):
            if default_lang != self.context.Language():
                portal = getSite()
                trans = ITranslationManager(self.context).get_translation(
                    default_lang)
                root = getNavigationRootObject(trans, portal)
                kw['path'] = '/'.join(root.getPhysicalPath())
                kw['Language'] = [default_lang, '']
        start, end = self._start_end
        sort = 'start'
        sort_reverse = False
        if self.mode in ('past', 'all'):
            sort_reverse = True
        expand = True
        local_events = get_events(
            self.context, start=start, end=end, sort=sort,
            sort_reverse=sort_reverse, ret_mode=RET_MODE_ACCESSORS,
            expand=expand, **kw)

        remote_events = self._remote_events()
        reverse = self.mode == 'past'
        all_events = sorted(local_events + remote_events, key=lambda x: x.start, reverse=reverse)
        if batch:
            b_start = self.b_start
            b_size = self.b_size
            res = Batch(all_events, size=b_size, start=b_start, orphan=self.orphan)
        else:
            res = all_events
        return res
Beispiel #19
0
    def test_recurrence_indexing(self):
        utc = pytz.utc
        self.portal.invokeFactory(
            'plone.app.event.dx.event',
            'event1',
            start=datetime(2011, 11, 11, 11, 0, tzinfo=utc),
            end=datetime(2011, 11, 11, 12, 0, tzinfo=utc),
            timezone='UTC',
            whole_day=False
        )
        e1 = self.portal['event1']
        e1rec = IEventRecurrence(e1)
        e1rec.recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        e1.reindexObject()

        # test, if the recurrence attribute is available on the context.
        # DRI needs that for indexing.
        self.assertTrue(e1.recurrence == e1rec.recurrence)

        # test, if the occurrences are indexed by DRI
        result = get_events(
            e1,
            start=datetime(2011, 11, 12, 11, 0, tzinfo=utc)
        )
        self.assertTrue(len(result) == 1)
    def test_recurrence_indexing(self):
        utc = pytz.utc
        self.portal.invokeFactory(
            'plone.app.event.dx.event',
            'event1',
            start=datetime(2011, 11, 11, 11, 0, tzinfo=utc),
            end=datetime(2011, 11, 11, 12, 0, tzinfo=utc),
            timezone='UTC',
            whole_day=False
        )
        e1 = self.portal['event1']
        e1rec = IEventRecurrence(e1)
        e1rec.recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        e1.reindexObject()

        # test, if the recurrence attribute is available on the context.
        # DRI needs that for indexing.
        self.assertTrue(e1.recurrence == e1rec.recurrence)

        # test, if the occurrences are indexed by DRI
        result = get_events(
            e1,
            start=datetime(2011, 11, 12, 11, 0, tzinfo=utc)
        )
        self.assertTrue(len(result) == 1)

        self.portal.manage_delObjects(['event1'])
Beispiel #21
0
    def _get_events(self, ret_mode=RET_MODE_ACCESSORS, expand=True):
        context = self.context
        kw = {}
        if self.path:
            kw['path'] = self.path
        elif self.settings.current_folder_only:
            kw['path'] = '/'.join(context.getPhysicalPath())
        #kw['b_start'] = self.b_start
        #kw['b_size']  = self.b_size

        if self.tags:
            kw['Subject'] = {'query': self.tags, 'operator': 'and'}

        if self.searchable_text:
            kw['SearchableText'] = self.searchable_text

        start, end = self._start_end

        sort = 'start'
        sort_reverse = False
        if self.mode in ('past', 'all'):
            sort_reverse = True
        return get_events(context,
                          start=start,
                          end=end,
                          sort=sort,
                          sort_reverse=sort_reverse,
                          ret_mode=ret_mode,
                          expand=expand,
                          **kw)
 def test_construct_calendar(self):
     res = get_events(self.portal, ret_mode=2, expand=True)
     cal = construct_calendar(res)  # keys are date-strings.
     # Should be more than one, but we can't exactly say how much. This
     # depends on the date, the test is run. E.g. on last day of month, only
     # long, past and now without recurrences are returned, others are in
     # next month.
     self.assertTrue(len(cal.keys()) > 1)
    def test_noexpand_start(self):
        # now+future events
        res = self.fmt(get_events(self.portal, expand=False, start=self.now, ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u"Long Event", "2013-04-25 10:00:00", "2013-06-04 10:00:00"),
            (u"Now Event", "2013-05-05 10:00:00", "2013-05-05 11:00:00"),
            (u"Tomorrow event", "2013-05-06 10:00:00", "2013-05-06 23:59:59"),
            # Past Recur next occurrence: '2013-05-09 11:00:00'
            # Past Recur brain.start: '2013-04-25 11:00:00'
            (u"Past Recur", "2013-04-25 11:00:00", "2013-04-25 12:00:00"),
            (u"Future Event", "2013-05-15 10:00:00", "2013-05-15 11:00:00"),
        ]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited now+future events
        res = self.fmt(get_events(self.portal, expand=False, start=self.now, limit=3, ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
Beispiel #24
0
def calendar_from_collection(context):
    """Container/Event adapter. Returns an icalendar.Calendar object from a
    Collection.

    """
    context = aq_inner(context)
    result = get_events(context)
    return construct_icalendar(context, result)
Beispiel #25
0
def calendar_from_collection(context):
    """Container/Event adapter. Returns an icalendar.Calendar object from a
    Collection.

    """
    context = aq_inner(context)
    result = get_events(context)
    return construct_icalendar(context, result)
    def test_expand_end_noongoing(self):
        # past events
        res = self.fmt(get_events(self.portal, expand=False,
                                  end=self.now,
                                  ongoing=False,
                                  ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u'Past Event', '2013-04-25 00:00:00', '2013-04-25 23:59:59'),
            (u'Past Recur', '2013-04-25 11:00:00', '2013-04-25 12:00:00')]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited past+now events
        res = self.fmt(get_events(self.portal, expand=False,
                                  end=self.now,
                                  limit=3,
                                  ongoing=False,
                                  ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
Beispiel #27
0
    def test_noexpand_end(self):
        # past+now events
        res = self.fmt(get_events(self.portal, expand=False,
                                  end=self.now,
                                  ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u'Past Event', '2013-04-25 00:00:00', '2013-04-25 23:59:59'),
            (u'Long Event', '2013-04-25 10:00:00', '2013-06-04 10:00:00'),
            (u'Past Recur', '2013-04-25 11:00:00', '2013-04-25 12:00:00'),
            (u'Now Event', '2013-05-05 10:00:00', '2013-05-05 11:00:00')]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited past+now events
        res = self.fmt(get_events(self.portal, expand=False,
                                  end=self.now,
                                  limit=3,
                                  ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
Beispiel #28
0
    def test_noexpand_all(self):
        # all events
        res = self.fmt(get_events(self.portal, expand=False,
                                  ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u'Past Event', '2013-04-25 00:00:00', '2013-04-25 23:59:59'),
            (u'Long Event', '2013-04-25 10:00:00', '2013-06-04 10:00:00'),
            (u'Past Recur', '2013-04-25 11:00:00', '2013-04-25 12:00:00'),
            (u'Now Event', '2013-05-05 10:00:00', '2013-05-05 11:00:00'),
            (u'Tomorrow event', '2013-05-06 10:00:00', '2013-05-06 23:59:59'),
            (u'Future Event', '2013-05-15 10:00:00', '2013-05-15 11:00:00')]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited events
        res = self.fmt(get_events(self.portal, expand=False,
                                  limit=3,
                                  ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
Beispiel #29
0
    def test_noexpand_start_end(self):
        # only now events
        res = self.fmt(get_events(self.portal, expand=False,
                                  start=self.now,
                                  end=self.now,
                                  ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u'Long Event', '2013-04-25 10:00:00', '2013-06-04 10:00:00'),
            (u'Now Event', '2013-05-05 10:00:00', '2013-05-05 11:00:00')]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited now events
        res = self.fmt(get_events(self.portal, expand=False,
                                  start=self.now,
                                  end=self.now,
                                  limit=3,
                                  ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
Beispiel #30
0
def calendar_from_container(context):
    """Container adapter. Returns an icalendar.Calendar object from a
    Containerish context like a Folder.

    """
    context = aq_inner(context)
    path = '/'.join(context.getPhysicalPath())
    result = get_events(context, path=path)
    return construct_icalendar(context, result)
Beispiel #31
0
def calendar_from_container(context):
    """Container adapter. Returns an icalendar.Calendar object from a
    Containerish context like a Folder.

    """
    context = aq_inner(context)
    path = '/'.join(context.getPhysicalPath())
    result = get_events(context, path=path)
    return construct_icalendar(context, result)
Beispiel #32
0
    def test_expand_start_end_noongoing(self):
        # only today
        res = self.fmt(get_events(self.portal, expand=False,
                                  start=self.now,
                                  end=self.tomorrow,  # NB
                                  ongoing=False,
                                  ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u'Now Event', '2013-05-05 10:00:00', '2013-05-05 11:00:00')]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited today
        res = self.fmt(get_events(self.portal, expand=False,
                                  start=self.now,
                                  end=self.tomorrow,  # NB
                                  limit=3,
                                  ongoing=False,
                                  ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
Beispiel #33
0
    def reply_events(self):
        """
        use plone.app.event query for a better recurrences management
        """
        (
            start,
            end,
            fullobjects,
            b_size,
            b_start,
            query,
            sort_reverse,
            sort,
            limit,
        ) = self.generate_query_for_events()
        brains = get_events(
            start=start,
            end=end,
            context=self.context,
            sort=sort,
            sort_reverse=sort_reverse,
            limit=limit,
            **query,
        )
        batch = HypermediaBatch(self.request, brains)
        results = {}
        results["@id"] = batch.canonical_url
        results["items_total"] = batch.items_total
        links = batch.links
        if links:
            results["batching"] = links

        results["items"] = []
        for brain in batch:
            result = None
            if fullobjects:
                try:
                    result = getMultiAdapter(
                        (brain.getObject(), self.request),
                        ISerializeToJson)(include_items=False)
                except KeyError:
                    # Guard in case the brain returned refers to an object that
                    # doesn't exists because it failed to uncatalog itself or
                    # the catalog has stale cataloged objects for some reason
                    logger.warning(
                        "Brain getObject error: {} doesn't exist anymore".
                        format(  # noqa
                            brain.getPath()))
            else:
                result = getMultiAdapter((brain, self.request),
                                         ISerializeToJsonSummary)()
            if result:
                results["items"].append(result)

        return results
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        kw = {}
        if data.search_base:
            kw["path"] = {"query": "%s%s" % ("/".join(self.portal.getPhysicalPath()), data.search_base)}
        if data.state:
            kw["review_state"] = data.state

        return get_events(context, start=localized_now(context), ret_mode=3, expand=True, limit=data.count, **kw)
Beispiel #35
0
 def events(self):
     context = aq_inner(self.context)
     portal = api.portal.get()
     container = portal["termine"]
     kw = {}
     kw["path"] = dict(query="/".join(container.getPhysicalPath()), depth=1)
     kw["review_state"] = "published"
     items = get_events(
         context, start=localized_now(context), ret_mode=RET_MODE_ACCESSORS, expand=True, limit=3, **kw
     )
     return items
    def _get_events(self, ret_mode=3):
        context = self.context
        kw = {}
        if not self._all:
            kw['path'] = '/'.join(context.getPhysicalPath())
        #kw['b_start'] = self.b_start
        #kw['b_size']  = self.b_size

        start, end = self._start_end
        return get_events(context, start=start, end=end,
                          ret_mode=ret_mode, expand=True, **kw)
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        query = {}
        if data.state:
            query['review_state'] = data.state

        events = []
        query.update(self.request.get('contentFilter', {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(
                search_base, search_base.query,
                sort_on='start', sort_order=None
            )

            start = None
            if 'start' in query:
                start = query['start']
            else:
                start = localized_now(context)

            end = None
            if 'end' in query:
                end = query['end']

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(
                batch=False, brains=True, custom_query=query,
                limit=data.count
            )
            events = expand_events(
                events, ret_mode=RET_MODE_ACCESSORS,
                start=start, end=end,
                sort='start', sort_reverse=False
            )
            events = events[:data.count]  # limit expanded
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}
            events = get_events(
                context, start=localized_now(context),
                ret_mode=RET_MODE_ACCESSORS,
                expand=True, limit=data.count, **query
            )
            eventlist=[]
            for ev in events:
                hasimage = bool(getattr(ev.context, 'image', None))
                eventlist.append((ev, hasimage))
        return eventlist
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        query = {}
        if data.state:
            query['review_state'] = data.state

        events = []
        query.update(self.request.get('contentFilter', {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(search_base,
                                               search_base.query,
                                               sort_on='start',
                                               sort_order=None)

            start = None
            if 'start' in query:
                start = query['start']
            else:
                start = localized_now(context)

            end = None
            if 'end' in query:
                end = query['end']

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(batch=False,
                                         brains=True,
                                         custom_query=query,
                                         limit=data.count)
            events = expand_events(events,
                                   ret_mode=RET_MODE_ACCESSORS,
                                   start=start,
                                   end=end,
                                   sort='start',
                                   sort_reverse=False)
            events = events[:data.count]  # limit expanded
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}
            events = get_events(context,
                                start=localized_now(context),
                                ret_mode=RET_MODE_ACCESSORS,
                                expand=True,
                                limit=data.count,
                                **query)

        return events
Beispiel #39
0
    def test_construct_calendar(self):
        res = get_events(self.portal, ret_mode=RET_MODE_OBJECTS, expand=True)
        cal = construct_calendar(res)  # keys are date-strings.

        def _num_events(values):
            num = 0
            for val in values:
                num += len(val)
            return num

        # The long_event occurs on every day in the resulting calendar data
        # structure.
        self.assertEqual(_num_events(cal.values()), 48)

        # Test with range
        #

        # Completly outside range and start, end given as datetime
        cal = construct_calendar(
            res,
            start=datetime(2000, 1, 1, 10, 0),
            end=datetime(2000, 1, 2, 10, 0)
        )
        self.assertEqual(_num_events(cal.values()), 0)

        # Within range
        cal = construct_calendar(
            res,
            start=date(2013, 5, 1),
            end=date(2013, 5, 31)
        )
        self.assertEqual(_num_events(cal.values()), 35)
        # First day must also be set in the calendar
        self.assertTrue('2013-05-01' in cal.keys())

        # invalid start
        def _invalid_start():
            return construct_calendar(
                res,
                start='invalid',
                end=datetime(2000, 1, 2, 10, 0)
            )

        self.assertRaises(AssertionError, _invalid_start)

        # invalid end
        def _invalid_end():
            return construct_calendar(
                res,
                start=datetime(2000, 1, 1, 10, 0),
                end='invalid'
            )
        self.assertRaises(AssertionError, _invalid_end)
Beispiel #40
0
    def _query_future_events(self):
        """Get all future events from this folder."""
        now = localized_now()
        path = '/'.join(self.context.getPhysicalPath())

        future_events = get_events(context=self.context,
                                   path=path,
                                   start=now,
                                   ret_mode=RET_MODE_OBJECTS,
                                   expand=True,
                                   sort_on='start')
        return future_events
    def test_expand_start_noongoing(self):
        # now+future events
        res = self.fmt(get_events(self.portal, expand=False,
                                  start=self.now,
                                  ongoing=False,
                                  ret_mode=RET_MODE_ACCESSORS))
        expect = [
            (u'Now Event', '2013-05-05 10:00:00', '2013-05-05 11:00:00'),
            (u'Tomorrow event', '2013-05-06 10:00:00', '2013-05-06 23:59:59'),
            # Past Recur next occurrence: '2013-05-09 11:00:00'
            # Past Recur brain.start: '2013-04-25 11:00:00'
            (u'Past Recur', '2013-04-25 11:00:00', '2013-04-25 12:00:00'),
            (u'Future Event', '2013-05-15 10:00:00', '2013-05-15 11:00:00')]
        self.assertEqual(res, expect, self.diff(res, expect))

        # limited now+future events
        res = self.fmt(get_events(self.portal, expand=False,
                                  start=self.now,
                                  limit=3,
                                  ongoing=False,
                                  ret_mode=RET_MODE_ACCESSORS))
        self.assertEqual(res, expect[:3], self.diff(res, expect[:3]))
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        kw = {}
        if data.search_base:
            kw['path'] = {'query': '%s%s' % (
                '/'.join(self.portal.getPhysicalPath()), data.search_base)}
        if data.state:
            kw['review_state'] = data.state

        return get_events(context, start=localized_now(context),
                          ret_mode=3, expand=True, limit=data.count, **kw)
Beispiel #43
0
 def published_events_expanded(self):
     """
     Return expanded ongoing events, i.e. taking into account their
     occurrences in case they are recurrent events.
     """
     return [self.event_to_view_obj(event) for event in get_events(
         self.context,
         ret_mode=2,
         start=localized_now(),
         expand=True,
         sort='start',
         limit=self.data.count,
         review_state=self.data.state)]
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        kw = {}
        search_base_path = self.search_base_path()
        if search_base_path:
            kw['path'] = {'query': search_base_path}
        if data.state:
            kw['review_state'] = data.state

        return get_events(context, start=localized_now(context),
                          ret_mode=RET_MODE_ACCESSORS,
                          expand=True, limit=data.count, **kw)
Beispiel #45
0
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        kw = {}
        search_base_path = self.search_base_path()
        if search_base_path:
            kw['path'] = {'query': search_base_path}
        if data.state:
            kw['review_state'] = data.state

        return get_events(context,
                          start=localized_now(context),
                          ret_mode=RET_MODE_ACCESSORS,
                          expand=True,
                          limit=data.count,
                          **kw)
Beispiel #46
0
    def get_all_events(self, batch=True):
        # Fall back to default language for local events
        kw = {}
        default_lang = api.portal.get_tool(
            "portal_languages").getDefaultLanguage()
        if ITranslatable.providedBy(self.context):
            if default_lang != self.context.Language():
                portal = getSite()
                trans = ITranslationManager(
                    self.context).get_translation(default_lang)
                root = getNavigationRootObject(trans, portal)
                kw['path'] = '/'.join(root.getPhysicalPath())
                kw['Language'] = [default_lang, '']
        start, end = self._start_end
        sort = 'start'
        sort_reverse = False
        if self.mode in ('past', 'all'):
            sort_reverse = True
        expand = True
        local_events = get_events(self.context,
                                  start=start,
                                  end=end,
                                  sort=sort,
                                  review_state='published',
                                  sort_reverse=sort_reverse,
                                  ret_mode=RET_MODE_ACCESSORS,
                                  expand=expand,
                                  **kw)

        remote_events = self._remote_events()
        reverse = self.mode == 'past'
        all_events = sorted(local_events + remote_events,
                            key=lambda x: x.start,
                            reverse=reverse)
        if batch:
            b_start = self.b_start
            b_size = self.b_size
            res = Batch(all_events,
                        size=b_size,
                        start=b_start,
                        orphan=self.orphan)
        else:
            res = all_events
        return res
Beispiel #47
0
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        kw = {}
        if data.search_base:
            kw['path'] = {
                'query':
                '%s%s' %
                ('/'.join(self.portal.getPhysicalPath()), data.search_base)
            }
        if data.state:
            kw['review_state'] = data.state

        return get_events(context,
                          start=localized_now(context),
                          ret_mode=RET_MODE_ACCESSORS,
                          expand=True,
                          limit=data.count,
                          **kw)
Beispiel #48
0
    def all_events(self):
        events = get_events(self.context,
                            ret_mode=RET_MODE_ACCESSORS,
                            expand=True,
                            start=DateTime(self.request.get('start')),
                            end=DateTime(self.request.get('end')))

        for event in events:
            duration = event.end - event.start
            yield {"id": "UID_%s" % (event.uid),
                   "title": event.title,
                   "location": event.location,
                   "start": rfc822_dt(event.start),
                   "end": rfc822_dt(event.end),
                   "url": event.url,
                   "editable": False,
                   "allDay": (event.whole_day or duration >
                              timedelta(seconds=86390)),
                   "className": '',
                   "description": event.description}
Beispiel #49
0
    def test_get_events(self):

        # whole range
        res = get_events(self.portal)
        self.assertEqual(len(res), 4)

        res = get_events(self.portal,
                         start=self.past,
                         end=self.future)
        self.assertEqual(len(res), 4)

        res = get_events(self.portal,
                         end=self.future)
        self.assertEqual(len(res), 4)

        res = get_events(self.portal,
                         start=self.past)
        self.assertEqual(len(res), 4)

        # Limit
        res = get_events(self.portal, limit=2)
        self.assertEqual(len(res), 2)

        # Return objects
        res = get_events(self.portal, ret_mode=RET_MODE_OBJECTS)
        self.assertTrue(IEvent.providedBy(res[0]))

        # Return IEventAccessor
        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS)
        self.assertTrue(IEventAccessor.providedBy(res[0]))
        # Test sorting
        self.assertTrue(res[0].start < res[-1].start)

        # Test reversed sorting
        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS,
                         sort_reverse=True)
        self.assertTrue(res[0].start > res[-1].start)

        # Test sort_on
        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS,
                         sort="start")
        self.assertEqual(
            [it.title for it in res][2:],
            [u'Now Event', u'Future Event']
        )
        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS, sort="end")
        self.assertEqual(
            [it.title for it in res],
            [u'Past Event', u'Now Event', u'Future Event', u'Long Event']
        )

        # Test expansion
        res = get_events(self.portal, ret_mode=RET_MODE_OBJECTS, expand=True)
        self.assertEqual(len(res), 8)

        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS, expand=True)
        self.assertEqual(len(res), 8)
        # Test sorting
        self.assertTrue(res[0].start < res[-1].start)

        res = get_events(self.portal, ret_mode=RET_MODE_ACCESSORS,
                         expand=True, sort_reverse=True)
        # Test sorting
        self.assertTrue(res[0].start > res[-1].start)

        # only on now-date
        res = get_events(self.portal,
                         start=self.now,
                         end=self.now)
        self.assertEqual(len(res), 2)

        # only on now-date as date
        # NOTE: converting self.now to python datetime to allow testing also
        # with dates as Zope DateTime objects.
        res = get_events(self.portal,
                         start=pydt(self.now).date(),
                         end=pydt(self.now).date())
        self.assertEqual(len(res), 2)

        # only on past date
        res = get_events(self.portal,
                         start=self.past,
                         end=self.past)
        self.assertEqual(len(res), 2)

        # one recurrence occurrence in far future
        res = get_events(self.portal,
                         start=self.far,
                         end=self.far)
        self.assertEqual(len(res), 1)

        # from now on
        res = get_events(self.portal,
                         start=self.now)
        self.assertEqual(len(res), 3)

        # until now
        res = get_events(self.portal,
                         end=self.now)
        self.assertEqual(len(res), 3)

        # in subfolder
        path = '/'.join(self.portal.sub.getPhysicalPath())
        res = get_events(self.portal, path=path)
        self.assertEqual(len(res), 1)
    def cal_data(self):
        """Calendar iterator over weeks and days of the month to display.
        """
        context = aq_inner(self.context)
        today = localized_today(context)
        year, month = self.year_month_display()
        monthdates = [dat for dat in self.cal.itermonthdates(year, month)]

        start = monthdates[0]
        end = monthdates[-1]

        data = self.data
        query = {}
        if data.state:
            query['review_state'] = data.state

        events = []
        query.update(self.request.get('contentFilter', {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(
                search_base, search_base.query,
                sort_on='start', sort_order=None
            )

            # restrict start/end with those from query, if given.
            if 'start' in query and query['start'] > start:
                start = query['start']
            if 'end' in query and query['end'] < end:
                end = query['end']

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(
                batch=False, brains=True, custom_query=query
            )
            events = expand_events(
                events, ret_mode=RET_MODE_OBJECTS,
                start=start, end=end,
                sort='start', sort_reverse=False
            )
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}
            events = get_events(context, start=start, end=end,
                                ret_mode=RET_MODE_OBJECTS,
                                expand=True, **query)

        #today += datetime.timedelta(days=1)
        cal_dict = construct_calendar(events, start=today, end=end)

        # [[day1week1, day2week1, ... day7week1], [day1week2, ...]]
        caldata = [[]]
        for dat in monthdates:
            if len(caldata[-1]) == 7:
                caldata.append([])
            date_events = None
            isodat = dat.isoformat()
            if isodat in cal_dict:
                date_events = cal_dict[isodat]

            events_string_list = []
            if date_events:
                for occ in date_events:
                    accessor = IEventAccessor(occ)
                    location = accessor.location
                    whole_day = accessor.whole_day

                    time = accessor.start.time().strftime('%H:%M')
                    # TODO: make 24/12 hr format configurable
                    events_string_list.append(
                        u'{0}{1}{2}{3}'.format(
                            accessor.title,
                            u' {0}'.format(time) if not whole_day else u'',
                            u', ' if not whole_day and location else u'',
                            u' {0}'.format(location) if location else u''
                        )
                    )
            caldata[-1].append(
                {'date': dat,
                 'day': dat.day,
                 'prev_month': dat.month < month,
                 'next_month': dat.month > month,
                 'today':
                    dat.year == today.year and
                    dat.month == today.month and
                    dat.day == today.day,
                 'date_string': u"%s-%s-%s" % (dat.year, dat.month, dat.day),
                 'events_string': u' | '.join(events_string_list),
                 'events': date_events})
        return caldata
    def _get_occs(self):
        date = guess_date_from(self.date)
        if date:
            start, end = start_end_from_mode('day', date, self.context)
            query = {}
            query['review_state'] = self.data.state
            
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}

            list_events = []
            events = get_events(self.context, start=start, end=end, sort='start', sort_reverse=False, ret_mode=RET_MODE_OBJECTS, expand=True, **query)

            today = datetime.datetime.today().date()

            for occ in events:
                if IOccurrence.providedBy(occ):
                    occurrence_id = occ.id
                    event = aq_parent(occ)
                    occ_data = ITicketOccurrenceData(event)
                    occs = occ_data.ticket_occurrences(occurrence_id)
                    if occs:
                        occurrence_ticket = occs[0]
                        item_stock = get_item_stock(occurrence_ticket)
                        if item_stock:
                            stock = item_stock.available
                        else:
                            stock = 0

                        is_today = occ.start.date() == today

                        new_event = {
                            "start": occ.start,
                            "uid": occurrence_ticket.UID(),
                            "stock": stock,
                            "is_today": is_today
                        }
                        list_events.append(new_event)
                        
                elif IBuyableEvent.providedBy(occ):
                    occ_data = ITicketOccurrenceData(occ)
                    occs = occ_data.tickets
                    if occs:
                        occurrence_ticket = occs[0]
                        item_stock = get_item_stock(occurrence_ticket)
                        if item_stock:
                            stock = item_stock.available
                        else:
                            stock = 0
                        
                        is_today = occ.start.date() == today
  
                        new_event = {
                            "start": occ.start,
                            "uid": occurrence_ticket.UID(),
                            "stock": stock,
                            "is_today": is_today
                        }
                        list_events.append(new_event)
                else:
                    print 'NOT AVAILABLE'

            return list_events
        else:
            return []
    def cal_data(self):
        """Calendar iterator over weeks and days of the month to display.
        """
        context = aq_inner(self.context)
        today = localized_today(context)
        year, month = self.year_month_display()
        monthdates = [dat for dat in self.cal.itermonthdates(year, month)]

        data = self.data
        query_kw = {}
        if data.search_base:
            portal = getToolByName(context, 'portal_url').getPortalObject()
            query_kw['path'] = {
                'query':
                '%s%s' % ('/'.join(portal.getPhysicalPath()), data.search_base)
            }

        if data.state:
            query_kw['review_state'] = data.state

        start = monthdates[0]
        end = monthdates[-1]
        events = get_events(context,
                            start=start,
                            end=end,
                            ret_mode=2,
                            expand=True,
                            **query_kw)
        cal_dict = construct_calendar(events, start=start, end=end)

        # [[day1week1, day2week1, ... day7week1], [day1week2, ...]]
        caldata = [[]]
        for dat in monthdates:
            if len(caldata[-1]) == 7:
                caldata.append([])
            date_events = None
            isodat = dat.isoformat()
            if isodat in cal_dict:
                date_events = cal_dict[isodat]

            events_string = u""
            if date_events:
                for occ in date_events:
                    accessor = IEventAccessor(occ)
                    location = accessor.location
                    whole_day = accessor.whole_day
                    time = accessor.start.time().strftime('%H:%M')
                    # TODO: make 24/12 hr format configurable
                    base = u'<a href="%s"><span class="title">%s</span>'\
                           u'%s%s%s</a>'
                    events_string += base % (
                        accessor.url, accessor.title,
                        not whole_day and u' %s' % time
                        or u'', not whole_day and location and u', '
                        or u'', location and u' %s' % location or u'')

            caldata[-1].append(
                {'date': dat,
                 'day': dat.day,
                 'prev_month': dat.month < month,
                 'next_month': dat.month > month,
                 'today': dat.year == today.year and\
                          dat.month == today.month and\
                          dat.day == today.day,
                 'date_string': u"%s-%s-%s" % (dat.year, dat.month, dat.day),
                 'events_string': events_string,
                 'events': date_events})
        return caldata
Beispiel #53
0
 def test_expand_all(self):
     # all occurrences, sorted by start
     res = self.fmt(get_events(self.portal, expand=True,
                               ret_mode=RET_MODE_ACCESSORS))
     self.assertEqual(res, self.occ)