[CalendarServer-changes] [8351] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Nov 29 16:10:17 PST 2011


Revision: 8351
          http://trac.macosforge.org/projects/calendarserver/changeset/8351
Author:   sagen at apple.com
Date:     2011-11-29 16:10:15 -0800 (Tue, 29 Nov 2011)
Log Message:
-----------
Don't send IMIP messages for events earlier than a configurable threshold.  (10093288)

Modified Paths:
--------------
    CalendarServer/trunk/conf/caldavd-test.plist
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/twistedcaldav/mail.py
    CalendarServer/trunk/twistedcaldav/stdconfig.py
    CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
    CalendarServer/trunk/twistedcaldav/test/test_mail.py

Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist	2011-11-29 22:23:57 UTC (rev 8350)
+++ CalendarServer/trunk/conf/caldavd-test.plist	2011-11-30 00:10:15 UTC (rev 8351)
@@ -778,6 +778,8 @@
           <string></string>
           <key>Address</key>
           <string></string> <!-- Address email will be sent from -->
+          <key>SupressionDays</key>
+          <integer>7</integer> <!-- Don't send messages for events earlier than this many days in the past -->
         </dict>
         <key>Receiving</key>
         <dict>

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2011-11-29 22:23:57 UTC (rev 8350)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2011-11-30 00:10:15 UTC (rev 8351)
@@ -2491,6 +2491,32 @@
         
         return tuple(results)
 
+
+    def hasInstancesAfter(self, limit):
+        """
+        Determine whether an event exists completely prior to a given moment.
+
+        @param limit: the moment to compare against.
+        @type limit: L{PyCalendarDateTime}
+
+        @return: a C{bool}, True if the event has any instances occurring after
+        limit, False otherwise.
+        """
+        instanceList = self.expandTimeRanges(limit)
+
+        if instanceList.limit is not None:
+            # There are instances after the limit
+            return True
+
+        # All instances begin prior to limit, but now check their end times to
+        # see if they extend beyond limit
+        for instance in instanceList.instances.itervalues():
+            if instance.end > limit:
+                return True
+
+        # Exists completely prior to limit
+        return False
+
 ##
 # Timezones
 ##

Modified: CalendarServer/trunk/twistedcaldav/mail.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/mail.py	2011-11-29 22:23:57 UTC (rev 8350)
+++ CalendarServer/trunk/twistedcaldav/mail.py	2011-11-30 00:10:15 UTC (rev 8351)
@@ -33,6 +33,9 @@
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
 
+from pycalendar.datetime import PyCalendarDateTime
+from pycalendar.duration import PyCalendarDuration
+
 from zope.interface import implements
 
 from twisted.application import internet, service
@@ -1165,9 +1168,15 @@
 
 
     def outbound(self, originator, recipient, calendar, language='en',
-                 send=True):
+                 send=True, onlyAfter=None):
         # create token, send email
 
+        settings = config.Scheduling['iMIP']['Sending']
+
+        if onlyAfter is None:
+            duration = PyCalendarDuration(days=settings.SuppressionDays)
+            onlyAfter = PyCalendarDateTime.getNowUTC() - duration
+
         component = calendar.masterComponent()
         if component is None:
             component = calendar.mainComponent(True)
@@ -1205,8 +1214,6 @@
                              "operation." % (recipient,))
         recipient = recipient[7:]
 
-        settings = config.Scheduling['iMIP']['Sending']
-
         if method != "REPLY":
             # Invites and cancellations:
 
@@ -1302,6 +1309,12 @@
             orgCN = calendar.getOrganizerProperty().parameterValue('CN', None)
             addressWithToken = formattedFrom
 
+        # At the point we've created the token in the db, which we always
+        # want to do, but if this message is for an event completely in
+        # the past we don't want to actually send an email.
+        if not calendar.hasInstancesAfter(onlyAfter):
+            self.log_debug("Skipping IMIP message for old event")
+            return succeed(True)
 
         # Now prevent any "internal" CUAs from being exposed by converting
         # to mailto: if we have one

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2011-11-29 22:23:57 UTC (rev 8350)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2011-11-30 00:10:15 UTC (rev 8351)
@@ -591,6 +591,7 @@
                 "UseSSL"        : True,
                 "Username"      : "",    # For account sending mail
                 "Password"      : "",    # For account sending mail
+                "SuppressionDays" : 7,   # Messages for events older than this may days are not sent
             },
             "Receiving": {
                 "Server"        : "",    # Server to retrieve email messages from

Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2011-11-29 22:23:57 UTC (rev 8350)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2011-11-30 00:10:15 UTC (rev 8351)
@@ -5371,3 +5371,377 @@
             
             diff = "\n".join(unified_diff(ical1, ical2))
             self.assertEqual(len(dtstamps1 & dtstamps2), 0, "Failed comparison: %s\n%s" % (title, diff,))
+
+
+    def test_hasInstancesAfter(self):
+        data = (
+            ("In the past (single)", False,
+"""BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:8EF0EB56-186E-4A77-9753-9B5D1D067CB5
+DTSTART;TZID=America/Los_Angeles:20111123T140000
+DTEND;TZID=America/Los_Angeles:20111123T150000
+CREATED:20111129T183822Z
+DTSTAMP:20111129T183845Z
+SEQUENCE:3
+SUMMARY:In the past (single)
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("In the past (repeating)", False,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:5812AF81-AB8E-484C-BE72-94DBB43C7E71
+DTSTART;TZID=America/Los_Angeles:20111123T150000
+DTEND;TZID=America/Los_Angeles:20111123T160000
+CREATED:20111129T183850Z
+DTSTAMP:20111129T184251Z
+RRULE:FREQ=DAILY;COUNT=4
+SEQUENCE:5
+SUMMARY:In the past (repeating)
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:5812AF81-AB8E-484C-BE72-94DBB43C7E71
+RECURRENCE-ID;TZID=America/Los_Angeles:20111125T150000
+DTSTART;TZID=America/Los_Angeles:20111125T153000
+DTEND;TZID=America/Los_Angeles:20111125T163000
+CREATED:20111129T183850Z
+DTSTAMP:20111129T184305Z
+SEQUENCE:6
+SUMMARY:In the past (repeating)
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("Straddling (repeating)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:60C25FF1-70EF-40EC-BBBB-F78F0A5FE45E
+DTSTART;TZID=America/Los_Angeles:20111129T143000
+DTEND;TZID=America/Los_Angeles:20111129T153000
+CREATED:20111129T184427Z
+DTSTAMP:20111129T184538Z
+RRULE:FREQ=DAILY;COUNT=4
+SEQUENCE:10
+SUMMARY:Straddling (repeating)
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:60C25FF1-70EF-40EC-BBBB-F78F0A5FE45E
+RECURRENCE-ID;TZID=America/Los_Angeles:20111201T143000
+DTSTART;TZID=America/Los_Angeles:20111201T150000
+DTEND;TZID=America/Los_Angeles:20111201T160000
+CREATED:20111129T184427Z
+DTSTAMP:20111129T184556Z
+SEQUENCE:11
+SUMMARY:Straddling (repeating)
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("Future (single)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:B79B392D-ADCC-4C61-A472-6E24BE0D72EF
+DTSTART;TZID=America/Los_Angeles:20111201T140000
+DTEND;TZID=America/Los_Angeles:20111201T150000
+CREATED:20111129T184650Z
+DTSTAMP:20111129T184655Z
+SEQUENCE:2
+SUMMARY:Future (single)
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("Future (repeating)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:E65FF863-D670-4C70-9537-6880739E0D34
+DTSTART;TZID=America/Los_Angeles:20111202T133000
+DTEND;TZID=America/Los_Angeles:20111202T143000
+CREATED:20111129T184745Z
+DTSTAMP:20111129T184803Z
+RRULE:FREQ=DAILY;COUNT=4
+SEQUENCE:5
+SUMMARY:Future (repeating)
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:E65FF863-D670-4C70-9537-6880739E0D34
+RECURRENCE-ID;TZID=America/Los_Angeles:20111204T133000
+DTSTART;TZID=America/Los_Angeles:20111204T140000
+DTEND;TZID=America/Los_Angeles:20111204T150000
+CREATED:20111129T184745Z
+DTSTAMP:20111129T184809Z
+SEQUENCE:6
+SUMMARY:Future (repeating)
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("On the day (single)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:94BAE82D-58E4-4511-9AB5-558F4873DA34
+DTSTART;TZID=America/Los_Angeles:20111130T100000
+DTEND;TZID=America/Los_Angeles:20111130T110000
+CREATED:20111129T214043Z
+DTSTAMP:20111129T214052Z
+SEQUENCE:1
+SUMMARY:On the day
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("Long non-all-day straddling (single)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:74B0B0A9-662F-4E2F-A0DF-ABEE1A311B92
+DTSTART;TZID=America/Los_Angeles:20111129T073000
+DTEND;TZID=America/Los_Angeles:20111202T083000
+CREATED:20111129T214210Z
+DTSTAMP:20111129T214230Z
+SEQUENCE:4
+SUMMARY:Long non-all-day straddling
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("All Day in the past (repeating)", False,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VEVENT
+UID:A2351816-49BD-4C5D-9399-CF5A3DBA0667
+DTSTART;VALUE=DATE:20111126
+DTEND;VALUE=DATE:20111127
+CREATED:20111129T211012Z
+DTSTAMP:20111129T211102Z
+RRULE:FREQ=DAILY;COUNT=3
+SEQUENCE:5
+SUMMARY:All day in the past
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("Straddling All Day (repeating)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VEVENT
+UID:B327F71E-43D5-442D-B8F4-06AC588C490A
+DTSTART;VALUE=DATE:20111129
+DTEND;VALUE=DATE:20111130
+CREATED:20111129T212257Z
+DTSTAMP:20111129T212314Z
+RRULE:FREQ=DAILY;COUNT=4
+SEQUENCE:5
+SUMMARY:All day repeated straddling
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("Straddling All Day (single multiday)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VEVENT
+UID:7A887675-8021-4432-A7C6-9E912339D415
+DTSTART;VALUE=DATE:20111129
+DTEND;VALUE=DATE:20111202
+CREATED:20111129T210711Z
+DTSTAMP:20111129T210734Z
+SEQUENCE:3
+SUMMARY:All Day Straddling
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+            ("Future All Day (single)", True,
+"""
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 5.0.1//EN
+BEGIN:VEVENT
+UID:DE1605D9-9BD8-4382-9E12-561332455748
+DTSTART;VALUE=DATE:20111203
+DTEND;VALUE=DATE:20111204
+CREATED:20111129T211219Z
+DTSTAMP:20111129T211224Z
+SEQUENCE:2
+SUMMARY:Future all day
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
+""",
+            ),
+        )
+        cutoff = PyCalendarDateTime(2011, 11, 30, 0, 0, 0)
+        for title, expected, body in data:
+            ical = Component.fromString(body)
+            self.assertEquals(expected, ical.hasInstancesAfter(cutoff))

Modified: CalendarServer/trunk/twistedcaldav/test/test_mail.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_mail.py	2011-11-29 22:23:57 UTC (rev 8350)
+++ CalendarServer/trunk/twistedcaldav/test/test_mail.py	2011-11-30 00:10:15 UTC (rev 8351)
@@ -35,6 +35,7 @@
 from twistedcaldav.test.util import xmlFile, augmentsFile
 import datetime
 import email
+from pycalendar.datetime import PyCalendarDateTime
 
 
 def echo(*args):
@@ -577,7 +578,8 @@
                     inputOriginator,
                     inputRecipient,
                     Component.fromString(inputCalendar.replace("\n", "\r\n")),
-                    send=False)
+                    send=False,
+                    onlyAfter=PyCalendarDateTime(2010, 1, 1, 0, 0, 0))
                 )
 
             self.assertEquals(actualInviteState, inviteState)
@@ -611,6 +613,18 @@
                 self.assertEquals(actualReplyTo, actualFrom)
 
 
+            # Check that we don't send any messages for events completely in
+            # the past.
+            result = (yield self.handler.outbound(
+                    inputOriginator,
+                    inputRecipient,
+                    Component.fromString(inputCalendar.replace("\n", "\r\n")),
+                    send=False,
+                    onlyAfter=PyCalendarDateTime(2012, 1, 1, 0, 0, 0))
+                )
+            self.assertEquals(result, True)
+
+
     @inlineCallbacks
     def test_mailtoTokens(self):
         """
@@ -638,7 +652,8 @@
                 inputOriginator,
                 inputRecipient,
                 Component.fromString(inputCalendar.replace("\n", "\r\n")),
-                send=False)
+                send=False,
+                onlyAfter=PyCalendarDateTime(2010, 1, 1, 0, 0, 0))
             )
 
         # Verify we didn't create a new token...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20111129/7517d5a7/attachment-0001.html>


More information about the calendarserver-changes mailing list