def test_past_events_url_and_navigation_root(self):
        # ensure support of INavigationRoot features dosen't break #9246 #9668

        # remove default plone content(s)
        if "events" in self.portal:
            self.portal._delObject("events")

        # lets create mynewsite
        self.portal.invokeFactory("Folder", "mynewsite")
        directlyProvides(self.portal.mynewsite, INavigationRoot)
        self.failUnless(INavigationRoot.providedBy(self.portal.mynewsite))

        lb = ICalendarLinkbase(self.portal.mynewsite)

        # mynewsite events:
        # -- events
        # ---- aggregator
        # ------ previous
        self.portal.mynewsite.invokeFactory("Folder", "events")
        self.portal.mynewsite.events.invokeFactory("Folder", "aggregator")
        self.portal.mynewsite.events.aggregator.invokeFactory("Folder", "previous")
        self.failUnless(lb.past_events_url().endswith("/mynewsite/events/aggregator/previous"))

        # mynewsite events:
        # -- events
        # ---- previous
        self.portal.mynewsite._delObject("events")
        self.portal.mynewsite.invokeFactory("Folder", "events")
        self.portal.mynewsite.events.invokeFactory("Folder", "previous")
        self.failUnless(lb.past_events_url().endswith("/mynewsite/events/previous"))

        # no mynewsite events
        self.portal.mynewsite._delObject("events")
        self.assertTrue("@@search?advanced_search=True&end.query" in lb.past_events_url())
 def test_date_events_url(self):
     lb = ICalendarLinkbase(self.portal)
     res = 'http://nohost/plone/@@search?advanced_search=True&start.query'\
           ':record:list:date=2012-12-24+23:59:59&start.range:record=max&'\
           'end.query:record:list:date=2012-12-24+00:00:00&end.range:reco'\
           'rd=min&object_provides=plone.event.interfaces.IEvent'
     self.assertTrue(lb.date_events_url('2012-12-24') == res)
    def test_next_events_url(self):
        # if there is an 'events' object in the portal root, we expect
        # the events portlet to link to it
        if "events" in self.portal:
            self.portal._delObject("events")
        lb = ICalendarLinkbase(self.portal)
        self.failUnless("@@search?advanced_search=True&start.query" in lb.next_events_url())

        self.portal.invokeFactory("Folder", "events")
        self.failUnless(lb.next_events_url().endswith("/events"))
    def test_next_events_url_and_navigation_root(self):
        # ensure support of INavigationRoot features dosen't break #9246 #9668
        self.portal.invokeFactory("Folder", "mynewsite")
        directlyProvides(self.portal.mynewsite, INavigationRoot)
        self.failUnless(INavigationRoot.providedBy(self.portal.mynewsite))

        lb = ICalendarLinkbase(self.portal.mynewsite)
        self.failUnless("mynewsite/@@search?advanced_search=True&start.query" in lb.next_events_url())

        self.portal.mynewsite.invokeFactory("Folder", "events")
        self.failUnless(lb.next_events_url().endswith("/mynewsite/events"))
    def test_all_events_url(self):
        # if there is an 'events' object in the portal root, we expect
        # the events portlet to link to it
        if 'events' in self.portal:
            self.portal._delObject('events')
        lb = ICalendarLinkbase(self.portal)
        self.failUnless('@@search?advanced_search=True&object_provides'
                        in lb.all_events_url())

        self.portal.invokeFactory('Folder', 'events')
        self.failUnless(lb.all_events_url().endswith('/events'))
    def test_all_events_url_and_navigation_root(self):
        # ensure support of INavigationRoot features dosen't break #9246 #9668
        self.portal.invokeFactory('Folder', 'mynewsite')
        directlyProvides(self.portal.mynewsite, INavigationRoot)
        self.failUnless(INavigationRoot.providedBy(self.portal.mynewsite))

        lb = ICalendarLinkbase(self.portal.mynewsite)
        self.failUnless('mynewsite/@@search?advanced_search=True&object_prov'
                        in lb.all_events_url())

        self.portal.mynewsite.invokeFactory('Folder', 'events')
        self.failUnless(lb.all_events_url().endswith('/mynewsite/events'))
    def update(self):
        context = aq_inner(self.context)

        self.calendar_linkbase = ICalendarLinkbase(context)
        self.calendar_linkbase.urlpath = '%s%s' % (
                self.calendar_linkbase.urlpath, self.data.search_base)

        self.year, self.month = year, month = self.year_month_display()
        self.prev_year, self.prev_month = prev_year, prev_month = (
            self.get_previous_month(year, month))
        self.next_year, self.next_month = next_year, next_month = (
            self.get_next_month(year, month))
        # TODO: respect current url-query string
        self.prev_query = '?month=%s&year=%s' % (prev_month, prev_year)
        self.next_query = '?month=%s&year=%s' % (next_month, next_year)

        self.cal = calendar.Calendar(first_weekday())
        self._ts = getToolByName(context, 'translation_service')
        self.month_name = PLMF(self._ts.month_msgid(month),
                              default=self._ts.month_english(month))

        # strftime %w interprets 0 as Sunday unlike the calendar.
        strftime_wkdays = [cal_to_strftime_wkday(day)
                for day in self.cal.iterweekdays()]
        self.weekdays = [PLMF(self._ts.day_msgid(day, format='s'),
                              default=self._ts.weekday_english(day, format='a'))
                         for day in strftime_wkdays]
    def test_events_url_with_navigation_root(self):
        # ensure support of INavigationRoot features dosen't break #9246 #9668
        self.portal.invokeFactory('Folder', 'mynewsite')
        directlyProvides(self.portal.mynewsite, INavigationRoot)
        self.failUnless(INavigationRoot.providedBy(self.portal.mynewsite))
        lb = ICalendarLinkbase(self.portal.mynewsite)

        url = 'http://nohost/plone/mynewsite/@@event_listing?mode=day&date=2012-12-07'
        self.failUnless(lb.date_events_url('2012-12-07') == url)

        url = 'http://nohost/plone/mynewsite/@@event_listing?mode=all'
        self.failUnless(lb.all_events_url() == url)

        url = 'http://nohost/plone/mynewsite/@@event_listing?mode=future'
        self.failUnless(lb.next_events_url() == url)

        url = 'http://nohost/plone/mynewsite/@@event_listing?mode=past'
        self.failUnless(lb.past_events_url() == url)
    def test_past_events_url(self):
        lb = ICalendarLinkbase(self.portal)
        if lb._events_folder():
            self.failUnless(lb.past_events_url().endswith("/events/aggregator/previous"))

        if lb._events_folder():
            self.portal._delObject("events")

        self.portal.invokeFactory("Folder", "events")
        self.portal.events.invokeFactory("Folder", "previous")
        self.failUnless(lb.past_events_url().endswith("/events/previous"))

        self.portal._delObject("events")
        self.failUnless("@@search?advanced_search=True&end.query" in lb.past_events_url())
    def test_past_events_url(self):
        lb = ICalendarLinkbase(self.portal)
        if lb._events_folder():
            self.failUnless(lb.past_events_url().endswith(
                '/events/aggregator/previous'))

        if lb._events_folder():
            self.portal._delObject('events')

        self.portal.invokeFactory('Folder', 'events')
        self.portal.events.invokeFactory('Folder', 'previous')
        self.failUnless(lb.past_events_url().endswith(
            '/events/previous'))

        self.portal._delObject('events')
        self.failUnless('@@search?advanced_search=True&end.query'
                        in lb.past_events_url())
 def test_past_events_url(self):
     lb = ICalendarLinkbase(self.portal)
     url = 'http://nohost/plone/@@event_listing?mode=past'
     self.failUnless(lb.past_events_url() == url)
 def test_date_events_url(self):
     lb = ICalendarLinkbase(self.portal)
     url = 'http://nohost/plone/@@event_listing?mode=day&date=2012-12-07'
     self.assertEqual(lb.date_events_url('2012-12-07'), url)
class Renderer(base.Renderer):
    render = ViewPageTemplateFile('portlet_calendar.pt')

    def update(self):
        context = aq_inner(self.context)

        self.calendar_linkbase = ICalendarLinkbase(context)
        self.calendar_linkbase.urlpath = '%s%s' % (
                self.calendar_linkbase.urlpath, self.data.search_base)

        self.year, self.month = year, month = self.year_month_display()
        self.prev_year, self.prev_month = prev_year, prev_month = (
            self.get_previous_month(year, month))
        self.next_year, self.next_month = next_year, next_month = (
            self.get_next_month(year, month))
        # TODO: respect current url-query string
        self.prev_query = '?month=%s&year=%s' % (prev_month, prev_year)
        self.next_query = '?month=%s&year=%s' % (next_month, next_year)

        self.cal = calendar.Calendar(first_weekday())
        self._ts = getToolByName(context, 'translation_service')
        self.month_name = PLMF(self._ts.month_msgid(month),
                              default=self._ts.month_english(month))

        # strftime %w interprets 0 as Sunday unlike the calendar.
        strftime_wkdays = [cal_to_strftime_wkday(day)
                for day in self.cal.iterweekdays()]
        self.weekdays = [PLMF(self._ts.day_msgid(day, format='s'),
                              default=self._ts.weekday_english(day, format='a'))
                         for day in strftime_wkdays]

    def year_month_display(self):
        """ Return the year and month to display in the calendar.
        """
        context = aq_inner(self.context)
        request = self.request

        # Try to get year and month from requst
        year = request.get('year', None)
        month = request.get('month', None)

        # Or use current date
        if not year or month:
            today = localized_today(context)
            if not year:
                year = today.year
            if not month:
                month = today.month

        return int(year), int(month)

    def get_previous_month(self, year, month):
        if month==0 or month==1:
            month, year = 12, year - 1
        else:
            month-=1
        return (year, month)

    def get_next_month(self, year, month):
        if month==12:
            month, year = 1, year + 1
        else:
            month+=1
        return (year, month)

    def date_events_url(self, date):
        return self.calendar_linkbase.date_events_url(date)

    @property
    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

        occurrences = get_occurrences_by_date(
            context, monthdates[0], monthdates[-1], **query_kw)
        # [[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 occurrences:
                date_events = occurrences[isodat]

            events_string = u""
            if date_events:
                for occ in date_events:
                    accessor = IEventAccessor(occ)
                    location = accessor.location
                    events_string += u'%s<a href="%s">%s</a>%s' % (
                        events_string and u"</br>" or u"",
                        accessor.url,
                        accessor.title,
                        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
class Renderer(base.Renderer):
    render = ViewPageTemplateFile('portlet_calendar.pt')

    def update(self):
        context = aq_inner(self.context)

        sb = self.data.search_base
        self.calendar_linkbase = ICalendarLinkbase(context)
        self.calendar_linkbase.urlpath = '%s%s' % (
                self.calendar_linkbase.urlpath, sb and sb or '')

        self.year, self.month = year, month = self.year_month_display()
        self.prev_year, self.prev_month = prev_year, prev_month = (
            self.get_previous_month(year, month))
        self.next_year, self.next_month = next_year, next_month = (
            self.get_next_month(year, month))
        # TODO: respect current url-query string
        self.prev_query = '?month=%s&year=%s' % (prev_month, prev_year)
        self.next_query = '?month=%s&year=%s' % (next_month, next_year)

        self.cal = calendar.Calendar(first_weekday())
        self._ts = getToolByName(context, 'translation_service')
        self.month_name = PLMF(self._ts.month_msgid(month),
                              default=self._ts.month_english(month))

        # strftime %w interprets 0 as Sunday unlike the calendar.
        strftime_wkdays = [wkday_to_mon1(day)
                for day in self.cal.iterweekdays()]
        self.weekdays = [
            PLMF(self._ts.day_msgid(day, format='s'),
                 default=self._ts.weekday_english(day, format='a'))
            for day in strftime_wkdays
        ]

    def year_month_display(self):
        """ Return the year and month to display in the calendar.
        """
        context = aq_inner(self.context)
        request = self.request

        # Try to get year and month from request
        year = request.get('year', None)
        month = request.get('month', None)

        # Or use current date
        today = localized_today(context)
        if not year:
            year = today.year
        if not month:
            month = today.month

        # try to transform to number but fall back to current
        # date if this is ambiguous
        try:
            year, month = int(year), int(month)
        except (TypeError, ValueError):
            year, month = today.year, today.month

        return year, month

    def get_previous_month(self, year, month):
        if month == 0 or month == 1:
            month, year = 12, year - 1
        else:
            month -= 1
        return (year, month)

    def get_next_month(self, year, month):
        if month == 12:
            month, year = 1, year + 1
        else:
            month += 1
        return (year, month)

    def date_events_url(self, date):
        return self.calendar_linkbase.date_events_url(date)

    @property
    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

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

        # [[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.decode('utf-8'),
                        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