Esempio n. 1
0
    def test_occurrence(self):
        # start date of self.now_event = 2013-05-05, 10:00.
        # recurrence rule = 'RRULE:FREQ=DAILY;COUNT=3;INTERVAL=2'

        # Try to traverse to inexistent occurrence
        self.assertRaises(
            AttributeError,
            self.occ_traverser_1.publishTraverse,
            self.request, '2000-01-01')

        # Try to traverse to future occurrence
        self.assertRaises(
            AttributeError,
            self.occ_traverser_1.publishTraverse,
            self.request, '2030-01-01')

        # Traverse to existent occurrence
        item = self.occ_traverser_1.publishTraverse(self.request, '2013-05-07')
        self.assertTrue(IOccurrence.providedBy(item))
        self.assertEqual(type(self.now_event), type(item.aq_parent))

        # Test attributes of Occurrence
        self.assertEqual(item.portal_type, 'Occurrence')
        self.assertEqual(item.id, '2013-05-07')
        delta = datetime.timedelta(days=2)
        self.assertEqual(item.start, self.now + delta)
        self.assertEqual(item.end, self.now + delta + self.duration)
Esempio n. 2
0
 def __call__(self):
     if IOccurrence.providedBy(self.context):
         # The transient Occurrence objects cannot be edited. disable the
         # edit border for them.
         self.request.set('disable_border', True)
     self.update()
     return self.index()
Esempio n. 3
0
 def _get_generation_context(self, helper_view, pod_template):
     result = super(IDocumentGenerationView,
                    self)._get_generation_context(helper_view, pod_template)
     # if pod_template.portal_type == 'ConfigurablePODTemplate':
     if IFacetedNavigable.providedBy(self.context):
         brains = getDashboardQueryResult(self.context)
         result['brains'] = brains
         if len(brains) > 0 and brains[0].portal_type == 'Event':
             expandevents = expand_events(brains, 2)
             events = []
             for event in expandevents:
                 if IOccurrence.providedBy(event):
                     start = event.start
                     end = event.end
                     parent = zope.copy.copy(event.aq_parent.aq_base)
                     parent.start = start
                     parent.end = end
                     req = event.REQUEST
                     parent.REQUEST = req
                     parent.occurrence = True
                     parent.base_event = event.aq_parent
                     events.append(parent)
                 else:
                     events.append(event)
             result['brains'] = events
         return result
def ticket_title_generator(obj):
    """Generate a title for the ticket, also using event information.
    """

    event = obj
    ret = {
        'title': obj.title, 'eventtitle': '', 'eventstart': '', 'eventend': ''
    }

    if ITicketOccurrence.providedBy(event):
        event = aq_parent(aq_parent(event))
        # Traverse to the Occurrence object
        if IATEvent.providedBy(event):
            # get the request out of thin air to be able to publishTraverse to
            # the transient Occurrence object.
            traverser = OccTravAT(event, getRequest())
        elif IDXEvent.providedBy(event):
            # TODO
            traverser = OccTravDX(event, getRequest())
        else:
            raise NotImplementedError(
                u"There is no event occurrence traverser implementation for "
                u"this kind of object."
            )
        try:
            event = traverser.publishTraverse(getRequest(), obj.id)
        except KeyError:
            # Maybe the ticket occurrence isn't valid anymore because the
            # event occurence doesn't exist anymore.
            # Just ignore that case.
            return ret

    elif ITicket.providedBy(event):
        event = aq_parent(event)

    if IEvent.providedBy(event) or IOccurrence.providedBy(event):
        acc = IEventAccessor(event)
        lstart = ulocalized_time(
            DT(acc.start),
            long_format=True,
            context=event
        )
        lend = ulocalized_time(
            DT(acc.start),
            long_format=True,
            context=event
        )
        # XXX: no unicode, store as utf-8 encoded string instead
        ret = dict(
            title=u'%s - %s (%s - %s)' % (
                safe_unicode(acc.title),
                safe_unicode(obj.title),
                lstart,
                lend,
            ),
            eventtitle=acc.title,
            eventstart=acc.start,
            eventend=acc.end,
        )
    return ret
Esempio n. 5
0
 def _get_generation_context(self, helper_view, pod_template):
     result = super(IDocumentGenerationView, self)._get_generation_context(
         helper_view, pod_template)
     # if pod_template.portal_type == 'ConfigurablePODTemplate':
     if IFacetedNavigable.providedBy(self.context):
         brains = getDashboardQueryResult(self.context)
         result['brains'] = brains
         if len(brains) > 0 and brains[0].portal_type == 'Event':
             expandevents = expand_events(brains, 2)
             events = []
             for event in expandevents:
                 if IOccurrence.providedBy(event):
                     start = event.start
                     end = event.end
                     parent = zope.copy.copy(event.aq_parent.aq_base)
                     parent.start = start
                     parent.end = end
                     req = event.REQUEST
                     parent.REQUEST = req
                     parent.occurrence = True
                     parent.base_event = event.aq_parent
                     events.append(parent)
                 else:
                     events.append(event)
             result['brains'] = events
         return result
Esempio n. 6
0
    def recurrence(self):
        if not self.event.recurrence or IOccurrence.providedBy(self.context):
            return None

        ret = []
        for recdef in self.event.recurrence.split():
            prop, val = recdef.split(':')
            if prop == 'RRULE':
                ret.append({
                    'property': prop,
                    'value': icalendar.prop.vRecur.from_ical(val)
                })

            elif prop in ('EXDATE', 'RDATE'):
                factory = icalendar.prop.vDDDLists

                # localize ex/rdate
                # TODO: should better already be localized by event object
                tzid = self.event.timezone
                if isinstance(tzid, tuple):
                    tzid = tzid[0]
                # get list of datetime values from ical string
                try:
                    dtlist = factory.from_ical(val, timezone=tzid)
                except ValueError:
                    # TODO: caused by a bug in plone.formwidget.recurrence,
                    # where the recurrencewidget or plone.event fails with
                    # COUNT=1 and a extra RDATE.
                    # TODO: REMOVE this workaround, once this failure is
                    # fixed in recurrence widget.
                    continue
                ret.append({'property': prop, 'value': dtlist})

        return ret
Esempio n. 7
0
    def test_recurrence_occurrences_with_range_start_2(self):
        # Test with range
        rs = datetime.datetime(2011, 11, 16, 11, 0, tzinfo=self.tz)
        result = IRecurrenceSupport(self.data).occurrences(range_start=rs)

        self.assertEqual(3, len(result))

        # Only IOccurrence objects in the result set
        self.assertTrue(IOccurrence.providedBy(result[0]))
Esempio n. 8
0
    def test_recurrence_occurrences_with_range_start_2(self):
        # Test with range
        rs = datetime.datetime(2011, 11, 16, 11, 0, tzinfo=self.tz)
        result = IRecurrenceSupport(self.data).occurrences(range_start=rs)

        self.assertEqual(3, len(result))

        # Only IOccurrence objects in the result set
        self.assertTrue(IOccurrence.providedBy(result[0]))
Esempio n. 9
0
def ticket_title_generator(obj):
    """Generate a title for the ticket, also using event information.
    """

    event = obj
    ret = {
        'title': obj.title,
        'eventtitle': '',
        'eventstart': '',
        'eventend': ''
    }

    if ITicketOccurrence.providedBy(event):
        event = aq_parent(aq_parent(event))
        # Traverse to the Occurrence object
        if IATEvent.providedBy(event):
            # get the request out of thin air to be able to publishTraverse to
            # the transient Occurrence object.
            traverser = OccTravAT(event, getRequest())
        elif IDXEvent.providedBy(event):
            # TODO
            traverser = OccTravDX(event, getRequest())
        else:
            raise NotImplementedError(
                u"There is no event occurrence traverser implementation for "
                u"this kind of object.")
        try:
            event = traverser.publishTraverse(getRequest(), obj.id)
        except KeyError:
            # Maybe the ticket occurrence isn't valid anymore because the
            # event occurence doesn't exist anymore.
            # Just ignore that case.
            return ret

    elif ITicket.providedBy(event):
        event = aq_parent(event)

    if IEvent.providedBy(event) or IOccurrence.providedBy(event):
        acc = IEventAccessor(event)
        lstart = ulocalized_time(DT(acc.start),
                                 long_format=True,
                                 context=event)
        lend = ulocalized_time(DT(acc.start), long_format=True, context=event)
        # XXX: no unicode, store as utf-8 encoded string instead
        ret = dict(
            title=u'%s - %s (%s - %s)' % (
                safe_unicode(acc.title),
                safe_unicode(obj.title),
                lstart,
                lend,
            ),
            eventtitle=acc.title,
            eventstart=acc.start,
            eventend=acc.end,
        )
    return ret
Esempio n. 10
0
    def test_recurrence_occurrences(self):
        result = IRecurrenceSupport(self.data).occurrences()

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 11
0
    def test_recurrence_occurrences(self):
        result = IRecurrenceSupport(self.data).occurrences()

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 12
0
    def test_occurrence(self):
        # start date of self.now_event = 2013-05-05, 10:00.
        # recurrence rule = 'RRULE:FREQ=DAILY;COUNT=3;INTERVAL=2'

        # Try to traverse to inexistent occurrence
        self.assertRaises(AttributeError, self.traverser.publishTraverse,
                          self.request, '2000-01-01')

        # Traverse to existent occurrence
        item = self.traverser.publishTraverse(self.request, '2013-05-07')
        self.assertTrue(IOccurrence.providedBy(item))
        self.assertEqual(type(self.now_event), type(item.aq_parent))
Esempio n. 13
0
    def test_recurrence_occurrences_with_range_start_1(self):
        # Test with range
        rs = datetime.datetime(2011, 11, 15, 11, 0, tzinfo=self.tz)
        result = IRecurrenceSupport(self.data).occurrences(range_start=rs)

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 14
0
    def test_recurrence_occurrences_with_range_start_1(self):
        # Test with range
        rs = datetime.datetime(2011, 11, 15, 11, 0, tzinfo=self.tz)
        result = IRecurrenceSupport(self.data).occurrences(range_start=rs)

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 15
0
 def childsiteForContext(self, item):
     """Returns the childsite UUID for a context object by looking up it's
     brain in the catalog.
     """
     childsite = ""
     if IOccurrence and IOccurrence.providedBy(item):
         item = aq_parent(item)
     portal = plone.api.portal.get()
     cat = getToolByName(self.context, "portal_catalog")
     res = cat(UID=IUUID(item, None), path=portal.getPhysicalPath())
     if res:
         childsite = res[0].childsite
     return childsite
Esempio n. 16
0
 def childsiteForContext(self, item):
     """Returns the childsite UUID for a context object by looking up it's
     brain in the catalog.
     """
     childsite = ''
     if IOccurrence and IOccurrence.providedBy(item):
         item = aq_parent(item)
     portal = plone.api.portal.get()
     cat = getToolByName(self.context, 'portal_catalog')
     res = cat(UID=IUUID(item, None), path=portal.getPhysicalPath())
     if res:
         childsite = res[0].childsite
     return childsite
Esempio n. 17
0
    def test_occurrence(self):
        # start date of self.now_event = 2013-05-05, 10:00.
        # recurrence rule = 'RRULE:FREQ=DAILY;COUNT=3;INTERVAL=2'

        # Try to traverse to inexistent occurrence
        self.assertRaises(
            AttributeError,
            self.traverser.publishTraverse,
            self.request, '2000-01-01')

        # Traverse to existent occurrence
        item = self.traverser.publishTraverse(self.request, '2013-05-07')
        self.assertTrue(IOccurrence.providedBy(item))
        self.assertEqual(type(self.now_event), type(item.aq_parent))
Esempio n. 18
0
    def test_recurrence_occurrences_with_range_start_and_end(self):
        # Test with range
        rs = datetime.datetime(2011, 11, 11, 11, 0, tzinfo=self.tz)
        re = datetime.datetime(2011, 11, 12, 11, 0, tzinfo=self.tz)
        result = IRecurrenceSupport(self.data).occurrences(range_start=rs,
                                                           range_end=re)
        result = list(result)  # cast generator to list

        self.assertEqual(2, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 19
0
    def test_occurrence(self):
        self.at.setRecurrence('RRULE:FREQ=WEEKLY;COUNT=10')

        # does not match occurrence date
        qdate = datetime.date.today() + datetime.timedelta(days=4)
        self.assertRaises(
            AttributeError,
            self.at_traverser.publishTraverse,
            self.layer['request'], str(qdate))

        qdatedt = pydt(self.at.start() + 7)
        item = self.at_traverser.publishTraverse(self.layer['request'],
                                                 str(qdatedt.date()))
        self.assertTrue(IOccurrence.providedBy(item))
        self.assertTrue(IATEvent.providedBy(item.aq_parent))
Esempio n. 20
0
    def test_recurrence_occurrences_with_range_start_and_end(self):
        # Test with range
        rs = datetime.datetime(2011, 11, 11, 11, 0, tzinfo=self.tz)
        re = datetime.datetime(2011, 11, 12, 11, 0, tzinfo=self.tz)
        result = IRecurrenceSupport(self.data).occurrences(range_start=rs,
                                                           range_end=re)
        result = list(result)  # cast generator to list

        self.assertEqual(2, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 21
0
    def test_recurrence(self):
        tz = pytz.timezone('Europe/Vienna')
        duration = datetime.timedelta(days=4)
        data = MockEvent()
        data.start = datetime.datetime(2011, 11, 11, 11, 00, tzinfo=tz)
        data.end = data.start + duration
        data.recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        zope.interface.alsoProvides(data, IEvent, IEventRecurrence)
        result = IRecurrenceSupport(data).occurrences()

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 22
0
    def test_recurrence(self):
        tz = pytz.timezone('Europe/Vienna')
        duration = datetime.timedelta(days=4)
        data = MockEvent()
        data.start = datetime.datetime(2011, 11, 11, 11, 00, tzinfo=tz)
        data.end = data.start + duration
        data.recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        zope.interface.alsoProvides(data, IEvent, IEventRecurrence)
        result = IRecurrenceSupport(data).occurrences()

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
 def attachments(self):
     context = aq_inner(self.context)
     if IOccurrence.providedBy(context):
         # support for related images on event occurrences
         context = context.aq_parent
     atts = IRelatedMedia(context).related_attachments
     _target_blank = api.portal.get_registry_record(
         'collective.behavior.relatedmedia.open_attachment_in_new_window')
     link_target = _target_blank and 'blank' or 'top'
     for att in atts:
         att_obj = att.to_object
         if att_obj:
             yield dict(
                 url=att_obj.absolute_url(),
                 title=att_obj.Title(),
                 size="{:.1f} MB".format(
                     att_obj.file.getSize() / 1024.0 / 1024.0),
                 icon=att_obj.getIcon(),
                 target=link_target,
             )
Esempio n. 24
0
    def test_recurrence(self):
        tz = pytz.timezone('Europe/Vienna')
        duration = timedelta(days=4)
        mock = MockEvent()
        mock.start = tz.localize(datetime(2011, 11, 11, 11, 0))
        mock.end = mock.start + duration
        mock.recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        zope.interface.alsoProvides(mock, IEvent, IEventBasic,
                                    IEventRecurrence, IDXEvent,
                                    IDXEventRecurrence)
        result = IRecurrenceSupport(mock).occurrences()
        result = list(result)  # cast generator to list

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 25
0
    def test_recurrence(self):
        tz = pytz.timezone('Europe/Vienna')
        duration = timedelta(days=4)
        mock = MockEvent()
        mock.start = tz.localize(datetime(2011, 11, 11, 11, 0))
        mock.end = mock.start + duration
        mock.recurrence = 'RRULE:FREQ=DAILY;COUNT=4'
        zope.interface.alsoProvides(
            mock, IEvent, IEventBasic, IEventRecurrence,
            IDXEvent, IDXEventRecurrence)
        result = IRecurrenceSupport(mock).occurrences()
        result = list(result)  # cast generator to list

        self.assertEqual(4, len(result))

        # First occurrence is an IEvent object
        self.assertTrue(IEvent.providedBy(result[0]))

        # Subsequent ones are IOccurrence objects
        self.assertTrue(IOccurrence.providedBy(result[1]))
Esempio n. 26
0
    def test_occurrence(self):
        # start date of self.now_event = 2013-05-05, 10:00.
        # recurrence rule = 'RRULE:FREQ=DAILY;COUNT=3;INTERVAL=2'

        # Try to traverse to inexistent occurrence
        self.assertRaises(
            AttributeError,
            self.traverser.publishTraverse,
            self.request, '2000-01-01')

        # Traverse to existent occurrence
        item = self.traverser.publishTraverse(self.request, '2013-05-07')
        self.assertTrue(IOccurrence.providedBy(item))
        self.assertEqual(type(self.now_event), type(item.aq_parent))

        # Test attributes of Occurrence
        self.assertEqual(item.portal_type, 'Occurrence')
        self.assertEqual(item.id, '2013-05-07')
        delta = datetime.timedelta(days=2)
        self.assertEqual(item.start, self.now + delta)
        self.assertEqual(item.end, self.now + delta + self.duration)
Esempio n. 27
0
    def recurrence(self):
        if not self.event.recurrence or IOccurrence.providedBy(self.context):
            return None

        ret = []
        for recdef in self.event.recurrence.split():
            prop, val = recdef.split(':')
            if prop == 'RRULE':
                ret.append({
                    'property': prop,
                    'value': icalendar.prop.vRecur.from_ical(val)
                })

            elif prop in ('EXDATE', 'RDATE'):
                factory = icalendar.prop.vDDDLists

                # localize ex/rdate
                # TODO: should better already be localized by event object
                tzid = self.event.timezone
                if isinstance(tzid, tuple):
                    tzid = tzid[0]
                # get list of datetime values from ical string
                try:
                    dtlist = factory.from_ical(val, timezone=tzid)
                except ValueError:
                    # TODO: caused by a bug in plone.formwidget.recurrence,
                    # where the recurrencewidget or plone.event fails with
                    # COUNT=1 and a extra RDATE.
                    # TODO: REMOVE this workaround, once this failure is
                    # fixed in recurrence widget.
                    continue
                ret.append({
                    'property': prop,
                    'value': dtlist
                })

        return ret
Esempio n. 28
0
 def __call__(self):
     if IOccurrence.providedBy(self.context):
         # The transient Occurrence objects cannot be edited. disable the
         # edit border for them.
         self.request.set('disable_border', True)
     return self.index()  # render me.
Esempio n. 29
0
 def is_occurrence(self):
     return IOccurrence.providedBy(self.context)
Esempio n. 30
0
def construct_icalendar(context, events):
    """Returns an icalendar.Calendar object.

    :param context: A content object, which is used for calendar details like
                    Title and Description. Usually a container, collection or
                    the event itself.

    :param events: The list of event objects, which are included in this
                   calendar.
    """
    cal = icalendar.Calendar()
    cal.add('prodid', PRODID)
    cal.add('version', VERSION)

    cal_tz = default_timezone(context)
    if cal_tz:
        cal.add('x-wr-timezone', cal_tz)

    tzmap = {}
    if not getattr(events, '__getitem__', False):
        events = [events]
    for event in events:
        if ICatalogBrain.providedBy(event) or\
                IContentListingObject.providedBy(event):
            event = event.getObject()
        if not (IEvent.providedBy(event) or IOccurrence.providedBy(event)):
            # Must be an event.
            continue
        acc = IEventAccessor(event)
        tz = acc.timezone
        # TODO: the standard wants each recurrence to have a valid timezone
        # definition. sounds decent, but not realizable.
        if not acc.whole_day:  # whole day events are exported as dates without
                               # timezone information
            if isinstance(tz, tuple):
                tz_start, tz_end = tz
            else:
                tz_start = tz_end = tz
            tzmap = add_to_zones_map(tzmap, tz_start, acc.start)
            tzmap = add_to_zones_map(tzmap, tz_end, acc.end)
        cal.add_component(IICalendarEventComponent(event).to_ical())

    for (tzid, transitions) in tzmap.items():
        cal_tz = icalendar.Timezone()
        cal_tz.add('tzid', tzid)
        cal_tz.add('x-lic-location', tzid)

        for (transition, tzinfo) in transitions.items():

            if tzinfo['dst']:
                cal_tz_sub = icalendar.TimezoneDaylight()
            else:
                cal_tz_sub = icalendar.TimezoneStandard()

            cal_tz_sub.add('tzname', tzinfo['name'])
            cal_tz_sub.add('dtstart', transition)
            cal_tz_sub.add('tzoffsetfrom', tzinfo['tzoffsetfrom'])
            cal_tz_sub.add('tzoffsetto', tzinfo['tzoffsetto'])
            # TODO: add rrule
            # tzi.add('rrule',
            #         {'freq': 'yearly', 'bymonth': 10, 'byday': '-1su'})
            cal_tz.add_component(cal_tz_sub)
        cal.add_component(cal_tz)

    return cal
Esempio n. 31
0
def construct_icalendar(context, events):
    """Returns an icalendar.Calendar object.

    :param context: A content object, which is used for calendar details like
                    Title and Description. Usually a container, collection or
                    the event itself.

    :param events: The list of event objects, which are included in this
                   calendar.
    """
    cal = icalendar.Calendar()
    cal.add('prodid', PRODID)
    cal.add('version', VERSION)

    cal_tz = default_timezone(context)
    if cal_tz:
        cal.add('x-wr-timezone', cal_tz)

    tzmap = {}
    if not getattr(events, '__getitem__', False):
        events = [events]
    for event in events:
        if ICatalogBrain.providedBy(event) or\
                IContentListingObject.providedBy(event):
            event = event.getObject()
        if not (IEvent.providedBy(event) or IOccurrence.providedBy(event)):
            # Must be an event.
            continue
        acc = IEventAccessor(event)
        tz = acc.timezone
        # TODO: the standard wants each recurrence to have a valid timezone
        # definition. sounds decent, but not realizable.
        if not acc.whole_day:  # whole day events are exported as dates without
            # timezone information
            if isinstance(tz, tuple):
                tz_start, tz_end = tz
            else:
                tz_start = tz_end = tz
            tzmap = add_to_zones_map(tzmap, tz_start, acc.start)
            tzmap = add_to_zones_map(tzmap, tz_end, acc.end)
        cal.add_component(IICalendarEventComponent(event).to_ical())

    for (tzid, transitions) in tzmap.items():
        cal_tz = icalendar.Timezone()
        cal_tz.add('tzid', tzid)
        cal_tz.add('x-lic-location', tzid)

        for (transition, tzinfo) in transitions.items():

            if tzinfo['dst']:
                cal_tz_sub = icalendar.TimezoneDaylight()
            else:
                cal_tz_sub = icalendar.TimezoneStandard()

            cal_tz_sub.add('tzname', tzinfo['name'])
            cal_tz_sub.add('dtstart', transition)
            cal_tz_sub.add('tzoffsetfrom', tzinfo['tzoffsetfrom'])
            cal_tz_sub.add('tzoffsetto', tzinfo['tzoffsetto'])
            # TODO: add rrule
            # tzi.add('rrule',
            #         {'freq': 'yearly', 'bymonth': 10, 'byday': '-1su'})
            cal_tz.add_component(cal_tz_sub)
        cal.add_component(cal_tz)

    return cal
    def images(self):
        context = aq_inner(self.context)
        if IOccurrence.providedBy(context):
            # support for related images on event occurrences
            context = context.aq_parent
        rm_behavior = IRelatedMedia(context)
        imgs = rm_behavior.related_images or []
        tcap = rm_behavior.show_titles_as_caption
        first_img_scales = None
        further_images = []
        gallery = []

        if rm_behavior.include_leadimage and ILeadImage.providedBy(context):
            first_img_scales = context.restrictedTraverse('@@images')
            first_img_caption = ILeadImage(context).image_caption
            further_images = imgs
        elif len(imgs):
            first_img = imgs[0]
            first_img_obj = first_img.to_object
            if first_img_obj:
                first_img_scales = first_img_obj.restrictedTraverse(
                    '@@images')
                first_img_caption = tcap and first_img_obj.Title() or u''
                further_images = imgs[1:]

        if first_img_scales:
            scale = first_img_scales.scale(
                'image', scale=rm_behavior.first_image_scale,
                direction=rm_behavior.first_image_scale_direction and
                'down' or 'thumbnail')
            if scale:
                large_scale_url = first_img_scales.scale(
                    'image', scale='large').url
                gallery.append(dict(
                    url=large_scale_url,
                    tag=scale.tag(
                        title=first_img_caption,
                        alt=first_img_caption,
                    ),
                    caption=tcap and first_img_caption or u'',
                    title=first_img_caption,
                ))

        for img in further_images:
            img_obj = img.to_object
            if img_obj:
                scales = img_obj.restrictedTraverse('@@images')
                scale = scales.scale(
                    'image', scale=rm_behavior.preview_scale,
                    direction=rm_behavior.preview_scale_direction and
                    'down' or 'thumbnail')
                if scale:
                    large_scale_url = scales.scale('image', scale='large').url
                    gallery.append(dict(
                        url=large_scale_url,
                        tag=scale.tag(),
                        caption=tcap and img_obj.Title() or u'',
                        title=img_obj.Title(),
                    ))

        return gallery
Esempio n. 33
0
    def dict_from_item(item):
        if hasPloneAppEvent and (IEvent.providedBy(item) or
                                 IOccurrence.providedBy(item)):
            # plone.app.event DX or AT Event
            is_occurrence = IOccurrence.providedBy(item)
            acc = IEventAccessor(item)
            return {
                "status": "ok",
                "id": "UID_%s" % (acc.uid),
                "title": acc.title,
                "description": acc.description,
                "start": acc.start.isoformat(),
                "end": acc.end.isoformat(),
                "url": acc.url,
                "editable": editable,
                "allDay": acc.whole_day,
                "className": "contextualContentMenuEnabled %s %s %s %s" % (
                                state and "state-%s" % str(state) or "",
                                editable and "editable" or "",
                                css and css or "",
                                is_occurrence and "occurrence" or ""),
                "color": color}
        elif IATEvent.providedBy(item):
            # Products.ATContentTypes ATEvent
            allday = (item.end() - item.start()) > 1.0
            adapted = interfaces.ISFBaseEventFields(item, None)
            if adapted:
                allday = adapted.allDay

            return {
                "status": "ok",
                "id": "UID_%s" % (item.UID()),
                "title": item.Title(),
                "description": item.Description(),
                "start": item.start().ISO8601(),
                "end": item.end().ISO8601(),
                "url": item.absolute_url(),
                "editable": editable,
                "allDay": allday,
                "className": "contextualContentMenuEnabled %s %s %s" % (
                                state and "state-%s" % str(state) or "",
                                editable and "editable" or "",
                                css and css or ""),
                "color": color}
        elif ICatalogBrain.providedBy(item):
            # Event catalog brain
            if type(item.end) != DateTime:
                brainend = DateTime(item.end)
                brainstart = DateTime(item.start)
            else:
                brainend = item.end
                brainstart = item.start

            allday = (brainend - brainstart) > 1.0

            if getattr(item, 'SFAllDay', None) in [False, True]:
                allday = item.SFAllDay

            return {
                "status": "ok",
                "id": "UID_%s" % (item.UID),
                "title": item.Title,
                "description": item.Description,
                "start": brainstart.ISO8601(),
                "end": brainend.ISO8601(),
                "url": item.getURL(),
                "editable": editable,
                "allDay": allday,
                "className": "contextualContentMenuEnabled %s %s %s" % (
                                state and "state-%s" % str(state) or "",
                                editable and "editable" or "",
                                css and css or ""),
                "color": color}
        else:
            raise ValueError('item type not supported for: %s' % repr(item))
Esempio n. 34
0
    def dict_from_item(item):
        if hasPloneAppEvent and (IEvent.providedBy(item) or IOccurrence.providedBy(item)):
            is_occurrence = IOccurrence.providedBy(item) and True or False
            acc = IEventAccessor(item)
            return {
                "status": "ok",
                "id": "UID_%s" % (acc.uid),
                "title": acc.title,
                "description": acc.description,
                "start": acc.start.isoformat(),
                "end": acc.end.isoformat(),
                "url": acc.url,
                "editable": editable,
                "allDay": acc.whole_day,
                "className": "contextualContentMenuEnabled %s %s %s %s"
                % (
                    state and "state-%s" % str(state) or "",
                    editable and "editable" or "",
                    css and css or "",
                    is_occurrence and "occurrence" or "",
                ),
                "color": color,
            }
        elif IATEvent.providedBy(item):

            allday = (item.end() - item.start()) > 1.0
            adapted = interfaces.ISFBaseEventFields(item, None)
            if adapted:
                allday = adapted.allDay

            return [
                {
                    "status": "ok",
                    "id": "UID_%s" % (item.UID()),
                    "title": item.Title(),
                    "description": item.Description(),
                    "start": item.start().rfc822(),
                    "end": item.end().rfc822(),
                    "url": item.absolute_url(),
                    "editable": editable,
                    "allDay": allday,
                    "className": "contextualContentMenuEnabled %s %s %s"
                    % (state and "state-%s" % str(state) or "", editable and "editable" or "", css and css or ""),
                    "color": color,
                }
            ]
        elif ICatalogBrain.providedBy(item):
            if type(item.end) != DateTime:
                brainend = DateTime(item.end)
                brainstart = DateTime(item.start)
            else:
                brainend = item.end
                brainstart = item.start

            allday = (brainend - brainstart) > 1.0

            if getattr(item, "SFAllDay", None) in [False, True]:
                allday = item.SFAllDay

            return [
                {
                    "status": "ok",
                    "id": "UID_%s" % (item.UID),
                    "title": item.Title,
                    "description": item.Description,
                    "start": brainstart.rfc822(),
                    "end": brainend.rfc822(),
                    "url": item.getURL(),
                    "editable": editable,
                    "allDay": allday,
                    "className": "contextualContentMenuEnabled %s %s %s"
                    % (state and "state-%s" % str(state) or "", editable and "editable" or "", css and css or ""),
                    "color": color,
                }
            ]
        else:
            raise ValueError("item type not supported for: %s" % repr(item))
Esempio n. 35
0
    def to_ical(self):
        ical = icalendar.Event()
        event = self.event

        # TODO: event.text

        # must be in utc
        ical.add('dtstamp', utc(datetime.now()))
        ical.add('created', utc(event.created))
        ical.add('last-modified', utc(event.last_modified))

        if event.sync_uid:
            # Re-Use existing icalendar event UID
            ical.add('uid', event.sync_uid)
        else:
            # Else, use plone.uuid
            ical.add('uid', event.uid)

        ical.add('url', event.url)

        ical.add('summary', event.title)

        if event.description:
            ical.add('description', event.description)

        if event.whole_day:
            ical.add('dtstart', event.start.date())
            # RFC5545, 3.6.1
            # For cases where a "VEVENT" calendar component
            # specifies a "DTSTART" property with a DATE value type but no
            # "DTEND" nor "DURATION" property, the event's duration is taken to
            # be one day.
            #
            # RFC5545 doesn't define clearly, if all-day events should have
            # a end date on the same date or one day after the start day at
            # 0:00. Most icalendar libraries use the latter method.
            # Internally, whole_day events end on the same day one second
            # before midnight. Using the RFC5545 preferred method for
            # plone.app.event seems not appropriate, since we would have to fix
            # the date to end a day before for displaying.
            # For exporting, we let whole_day events end on the next day at
            # midnight.
            # See:
            # http://stackoverflow.com/questions/1716237/single-day-all-day
            # -appointments-in-ics-files
            # http://icalevents.com/1778-all-day-events-adding-a-day-or-not/
            # http://www.innerjoin.org/iCalendar/all-day-events.html
            ical.add('dtend', event.end.date() + timedelta(days=1))
        elif event.open_end:
            # RFC5545, 3.6.1
            # For cases where a "VEVENT" calendar component
            # specifies a "DTSTART" property with a DATE-TIME value type but no
            # "DTEND" property, the event ends on the same calendar date and
            # time of day specified by the "DTSTART" property.
            ical.add('dtstart', event.start)
        else:
            ical.add('dtstart', event.start)
            ical.add('dtend', event.end)

        if event.recurrence and not IOccurrence.providedBy(self.context):
            for recdef in event.recurrence.split():
                prop, val = recdef.split(':')
                if prop == 'RRULE':
                    ical.add(prop, icalendar.prop.vRecur.from_ical(val))
                elif prop in ('EXDATE', 'RDATE'):
                    factory = icalendar.prop.vDDDLists

                    # localize ex/rdate
                    # TODO: should better already be localized by event object
                    tzid = event.timezone
                    # get list of datetime values from ical string
                    try:
                        dtlist = factory.from_ical(val, timezone=tzid)
                    except ValueError:
                        # TODO: caused by a bug in plone.formwidget.recurrence,
                        # where the recurrencewidget or plone.event fails with
                        # COUNT=1 and a extra RDATE.
                        # TODO: REMOVE this workaround, once this failure is
                        # fixed in recurrence widget.
                        continue
                    ical.add(prop, dtlist)

        if event.location:
            ical.add('location', event.location)

        # TODO: revisit and implement attendee export according to RFC
        if event.attendees:
            for attendee in event.attendees:
                att = icalendar.prop.vCalAddress(attendee)
                att.params['cn'] = icalendar.prop.vText(attendee)
                att.params['ROLE'] = icalendar.prop.vText('REQ-PARTICIPANT')
                ical.add('attendee', att)

        cn = []
        if event.contact_name:
            cn.append(event.contact_name)
        if event.contact_phone:
            cn.append(event.contact_phone)
        if event.contact_email:
            cn.append(event.contact_email)
        if event.event_url:
            cn.append(event.event_url)
        if cn:
            ical.add('contact', u', '.join(cn))

        if event.subjects:
            for subject in event.subjects:
                ical.add('categories', subject)

        return ical
Esempio n. 36
0
    def to_ical(self):
        ical = icalendar.Event()
        event = self.event

        # TODO: event.text

        # must be in utc
        ical.add('dtstamp', utc(datetime.now()))
        ical.add('created', utc(event.created))
        ical.add('last-modified', utc(event.last_modified))

        if event.sync_uid:
            # Re-Use existing icalendar event UID
            ical.add('uid', event.sync_uid)
        else:
            # Else, use plone.uuid
            ical.add('uid', event.uid)

        ical.add('url', event.url)

        ical.add('summary', event.title)

        if event.description:
            ical.add('description', event.description)

        if event.whole_day:
            ical.add('dtstart', event.start.date())
            # RFC5545, 3.6.1
            # For cases where a "VEVENT" calendar component
            # specifies a "DTSTART" property with a DATE value type but no
            # "DTEND" nor "DURATION" property, the event's duration is taken to
            # be one day.
            #
            # RFC5545 doesn't define clearly, if all-day events should have
            # a end date on the same date or one day after the start day at
            # 0:00. Most icalendar libraries use the latter method.
            # Internally, whole_day events end on the same day one second
            # before midnight. Using the RFC5545 preferred method for
            # plone.app.event seems not appropriate, since we would have to fix
            # the date to end a day before for displaying.
            # For exporting, we let whole_day events end on the next day at
            # midnight.
            # See:
            # http://stackoverflow.com/questions/1716237/single-day-all-day
            # -appointments-in-ics-files
            # http://icalevents.com/1778-all-day-events-adding-a-day-or-not/
            # http://www.innerjoin.org/iCalendar/all-day-events.html
            ical.add('dtend', event.end.date() + timedelta(days=1))
        elif event.open_end:
            # RFC5545, 3.6.1
            # For cases where a "VEVENT" calendar component
            # specifies a "DTSTART" property with a DATE-TIME value type but no
            # "DTEND" property, the event ends on the same calendar date and
            # time of day specified by the "DTSTART" property.
            ical.add('dtstart', event.start)
        else:
            ical.add('dtstart', event.start)
            ical.add('dtend', event.end)

        if event.recurrence and not IOccurrence.providedBy(self.context):
            for recdef in event.recurrence.split():
                prop, val = recdef.split(':')
                if prop == 'RRULE':
                    ical.add(prop, icalendar.prop.vRecur.from_ical(val))
                elif prop in ('EXDATE', 'RDATE'):
                    factory = icalendar.prop.vDDDLists

                    # localize ex/rdate
                    # TODO: should better already be localized by event object
                    tzid = event.timezone
                    # get list of datetime values from ical string
                    try:
                        dtlist = factory.from_ical(val, timezone=tzid)
                    except ValueError:
                        # TODO: caused by a bug in plone.formwidget.recurrence,
                        # where the recurrencewidget or plone.event fails with
                        # COUNT=1 and a extra RDATE.
                        # TODO: REMOVE this workaround, once this failure is
                        # fixed in recurrence widget.
                        continue
                    ical.add(prop, dtlist)

        if event.location:
            ical.add('location', event.location)

        # TODO: revisit and implement attendee export according to RFC
        if event.attendees:
            for attendee in event.attendees:
                att = icalendar.prop.vCalAddress(attendee)
                att.params['cn'] = icalendar.prop.vText(attendee)
                att.params['ROLE'] = icalendar.prop.vText('REQ-PARTICIPANT')
                ical.add('attendee', att)

        cn = []
        if event.contact_name:
            cn.append(event.contact_name)
        if event.contact_phone:
            cn.append(event.contact_phone)
        if event.contact_email:
            cn.append(event.contact_email)
        if event.event_url:
            cn.append(event.event_url)
        if cn:
            ical.add('contact', u', '.join(cn))

        if event.subjects:
            for subject in event.subjects:
                ical.add('categories', subject)

        return ical
Esempio n. 37
0
 def is_occurrence(self):
     return IOccurrence.providedBy(self.context)
    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 []
Esempio n. 39
0
    def __init__(self, context, request):
        super(RelatedBaseView, self).__init__(context, request)

        if IOccurrence.providedBy(self.context):
            self.context = self.context.aq_parent
 def __init__(self, context, request):
     super(Uploader, self).__init__(context, request)
     self.intids = getUtility(IIntIds)
     if IOccurrence.providedBy(context):
         # support for related images on event occurrences
         self.context = aq_inner(context).aq_parent
Esempio n. 41
0
    def dict_from_item(item):
        if hasPloneAppEvent and (IEvent.providedBy(item) or
                                 IOccurrence.providedBy(item)):
            # plone.app.event DX or AT Event
            is_occurrence = IOccurrence.providedBy(item)
            acc = IEventAccessor(item)

            return {
                "status": "ok",
                "id": "UID_%s" % (acc.uid),
                "title": acc.title,
                "description": acc.description,
                "start": acc.start.isoformat(),
                "end": acc.end.isoformat(),
                "url": acc.url,
                "editable": editable,
                "allDay": acc.whole_day,
                "className": "contextualContentMenuEnabled %s %s %s %s" % (
                                state and "state-%s" % str(state) or "",
                                editable and "editable" or "",
                                css and css or "",
                                is_occurrence and "occurrence" or ""),
                "color": color}
        elif IATEvent.providedBy(item):
            # Products.ATContentTypes ATEvent
            allday = (item.end() - item.start()) > 1.0
            adapted = interfaces.ISFBaseEventFields(item, None)
            if adapted:
                allday = adapted.allDay
            return {
                "status": "ok",
                "id": "UID_%s" % (item.UID()),
                "title": item.Title(),
                "description": item.Description(),
                "start": item.start().ISO8601(),
                "end": item.end().ISO8601(),
                "url": item.absolute_url(),
                "editable": editable,
                "allDay": allday,
                "className": "contextualContentMenuEnabled %s %s %s" % (
                                state and "state-%s" % str(state) or "",
                                editable and "editable" or "",
                                css and css or ""),
                "color": color}
        elif ICatalogBrain.providedBy(item):
            # Event catalog brain
            if type(item.end) != DateTime:
                brainend = DateTime(item.end)
                brainstart = DateTime(item.start)
            else:
                brainend = item.end
                brainstart = item.start

            allday = (brainend - brainstart) > 1.0

            if getattr(item, 'SFAllDay', None) in [False, True]:
                allday = item.SFAllDay

            # Set Mexico City Time
            brainstart = DateTime(' '.join(
                (brainstart.Date(), brainstart.Time(), 'America/Mexico_City')))
            brainend = DateTime(' '.join(
                (brainend.Date(), brainend.Time(), 'America/Mexico_City')))

            return {
                "status": "ok",
                "id": "UID_%s" % (item.UID),
                "title": item.Title,
                "description": item.Description,
                "start": brainstart.ISO8601(),
                "end": brainend.ISO8601(),
                "url": item.getURL(),
                "editable": editable,
                "allDay": allday,
                "className": "contextualContentMenuEnabled %s %s %s" % (
                                state and "state-%s" % str(state) or "",
                                editable and "editable" or "",
                                css and css or ""),
                "color": color}
        else:
            raise ValueError('item type not supported for: %s' % repr(item))