[CalendarServer-changes] [13517] CalendarServer/trunk/txdav/caldav/datastore/scheduling

source_changes at macosforge.org source_changes at macosforge.org
Tue May 20 11:50:48 PDT 2014


Revision: 13517
          http://trac.calendarserver.org//changeset/13517
Author:   cdaboo at apple.com
Date:     2014-05-20 11:50:48 -0700 (Tue, 20 May 2014)
Log Message:
-----------
Fix some ischedule/dkim issues. Change % -> format style strs/logging.

Modified Paths:
--------------
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/delivery.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/scheduler.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/cuaddress.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/delivery.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/delivery.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/smtpsender.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/delivery.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/dkim.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/localservers.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/remoteservers.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/resource.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/scheduler.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/test/data/db.example.com
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/utils.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/xml.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/scheduler.py

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/delivery.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/delivery.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/delivery.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -121,7 +121,7 @@
     @inlineCallbacks
     def generateResponse(self, recipient, responses):
         # Hash the iCalendar data for use as the last path element of the URI path
-        name = "%s-%s.ics" % (hashlib.md5(self.scheduler.calendar.resourceUID()).hexdigest(), str(uuid.uuid4())[:8],)
+        name = "{hash}-{r}.ics".format(hash=hashlib.md5(self.scheduler.calendar.resourceUID()).hexdigest(), r=str(uuid.uuid4())[:8],)
 
         # Do implicit scheduling message processing.
         try:

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/scheduler.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/scheduler.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/caldav/scheduler.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -78,7 +78,10 @@
     def checkAuthorization(self):
         # Must have an authenticated user
         if not self.internal_request and self.originator_uid == None:
-            log.error("Unauthenticated originators not allowed: %s" % (self.originator,))
+            log.error(
+                "Unauthenticated originators not allowed: {o}",
+                o=self.originator,
+            )
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["originator-denied"],
@@ -96,7 +99,10 @@
         originatorAddress = yield calendarUserFromCalendarUserAddress(self.originator, self.txn)
         if not originatorAddress.hosted():
             # Local requests MUST have a principal.
-            log.error("Could not find principal for originator: %s" % (self.originator,))
+            log.error(
+                "Could not find principal for originator: {o}",
+                o=self.originator,
+            )
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["originator-denied"],
@@ -104,7 +110,10 @@
             ))
         else:
             if not originatorAddress.validOriginator() or isinstance(originatorAddress, OtherServerCalendarUser):
-                log.error("Originator not enabled or hosted on this server: %s" % (self.originator,))
+                log.error(
+                    "Originator not enabled or hosted on this server: {o}",
+                    o=self.originator,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["originator-denied"],
@@ -131,7 +140,7 @@
             # user. Also if server-to-server is not enabled then remote addresses are not allowed.
             if not recipientAddress.hosted():
                 if isinstance(recipientAddress, InvalidCalendarUser):
-                    log.error("Unknown calendar user address: %s" % (recipient,))
+                    log.error("Unknown calendar user address: {r}", r=recipient,)
                 results.append(recipientAddress)
             else:
                 # Map recipient to their inbox and cache on calendar user object
@@ -148,7 +157,7 @@
                 if inbox:
                     results.append(recipientAddress)
                 else:
-                    log.error("No scheduling for calendar user: %s" % (recipient,))
+                    log.error("No scheduling for calendar user: {r}", r=recipient,)
                     results.append(InvalidCalendarUser(recipient))
 
         self.recipients = results
@@ -171,7 +180,7 @@
                     # to be handled later when we know whether a new invite is being added
                     # (which we reject) vs an update to an existing one (which we allow).
                     if self.checkForFreeBusy() and not organizerAddress.record.enabledAsOrganizer():
-                        log.error("ORGANIZER not allowed to be an Organizer: %s" % (self.calendar,))
+                        log.error("ORGANIZER not allowed to be an Organizer: {cal}", cal=self.calendar,)
                         raise HTTPError(self.errorResponse(
                             responsecode.FORBIDDEN,
                             self.errorElements["organizer-denied"],
@@ -180,7 +189,7 @@
 
                     self.organizer = organizerAddress
                 else:
-                    log.error("No scheduling for ORGANIZER: %s" % (organizer,))
+                    log.error("No scheduling for ORGANIZER: {o}", o=organizer,)
                     raise HTTPError(self.errorResponse(
                         responsecode.FORBIDDEN,
                         self.errorElements["organizer-denied"],
@@ -189,7 +198,7 @@
             else:
                 localUser = (yield addressmapping.mapper.isCalendarUserInMyDomain(organizer))
                 if localUser:
-                    log.error("No principal for ORGANIZER in calendar data: %s" % (self.calendar,))
+                    log.error("No principal for ORGANIZER in calendar data: {cal}", cal=self.calendar,)
                     raise HTTPError(self.errorResponse(
                         responsecode.FORBIDDEN,
                         self.errorElements["organizer-denied"],
@@ -198,7 +207,7 @@
                 else:
                     self.organizer = organizerAddress
         else:
-            log.error("ORGANIZER missing in calendar data: %s" % (self.calendar,))
+            log.error("ORGANIZER missing in calendar data: {cal}", cal=self.calendar,)
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["invalid-scheduling-message"],
@@ -210,7 +219,7 @@
 
         # Make sure that the ORGANIZER is local
         if not isinstance(self.organizer, LocalCalendarUser):
-            log.error("ORGANIZER is not local to server in calendar data: %s" % (self.calendar,))
+            log.error("ORGANIZER is not local to server in calendar data: {cal}", cal=self.calendar,)
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["organizer-denied"],
@@ -219,7 +228,7 @@
 
         # Make sure that the ORGANIZER's is the request URI owner
         if self.doingPOST is not None and self.organizer.record.uid != self.originator_uid:
-            log.error("Wrong outbox for ORGANIZER in calendar data: %s" % (self.calendar,))
+            log.error("Wrong outbox for ORGANIZER in calendar data: {cal}", cal=self.calendar,)
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["organizer-denied"],
@@ -238,14 +247,14 @@
         attendeeAddress = yield calendarUserFromCalendarUserAddress(self.attendee, self.txn)
         if attendeeAddress.hosted():
             if self.doingPOST is not None and attendeeAddress.record.uid != self.originator_uid:
-                log.error("ATTENDEE in calendar data does not match owner of Outbox: %s" % (self.attendee,))
+                log.error("ATTENDEE in calendar data does not match owner of Outbox: {a}", a=self.attendee,)
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["attendee-denied"],
                     "Outbox does not belong to attendee",
                 ))
         else:
-            log.error("Unknown ATTENDEE in calendar data: %s" % (self.attendee,))
+            log.error("Unknown ATTENDEE in calendar data: {a}", a=self.attendee,)
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["attendee-denied"],

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/cuaddress.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/cuaddress.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/cuaddress.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -118,7 +118,7 @@
 
 
     def __str__(self):
-        return "Local calendar user: %s" % (self.cuaddr,)
+        return "Local calendar user: {}".format(self.cuaddr)
 
 
 
@@ -132,7 +132,7 @@
 
 
     def __str__(self):
-        return "Other server calendar user: %s" % (self.cuaddr,)
+        return "Other server calendar user: {}".format(self.cuaddr)
 
 
 
@@ -147,7 +147,7 @@
 
 
     def __str__(self):
-        return "Remote calendar user: %s" % (self.cuaddr,)
+        return "Remote calendar user: {}".format(self.cuaddr)
 
 
     def extractDomain(self):
@@ -171,7 +171,7 @@
 
 
     def __str__(self):
-        return "Email/iMIP calendar user: %s" % (self.cuaddr,)
+        return "Email/iMIP calendar user: {}".format(self.cuaddr)
 
 
 
@@ -182,7 +182,7 @@
     """
 
     def __str__(self):
-        return "Invalid calendar user: %s" % (self.cuaddr,)
+        return "Invalid calendar user: {}".format(self.cuaddr)
 
 
     def validOriginator(self):

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/delivery.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/delivery.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/delivery.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -69,7 +69,11 @@
                 if re.match(pattern, cuaddr) is not None:
                     return succeed(True)
             except re.error:
-                log.error("Invalid regular expression for Scheduling configuration '%s/LocalAddresses': %s" % (cls.serviceType(), pattern,))
+                log.error(
+                    "Invalid regular expression for Scheduling configuration '{stype}/LocalAddresses': {pat}",
+                    stype=cls.serviceType(),
+                    pat=pattern,
+                )
 
         return succeed(False)
 

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/delivery.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/delivery.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/delivery.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -76,12 +76,15 @@
                 "CANCEL",
                 "DECLINE_COUNTER",
             ):
-                log.info("Could not do server-to-imip method: %s" % (method,))
+                log.info(
+                    "Could not do server-to-imip method: {method}",
+                    method=method,
+                )
                 for recipient in self.recipients:
                     err = HTTPError(ErrorResponse(
                         responsecode.FORBIDDEN,
                         (caldav_namespace, "recipient-failed"),
-                        "iMIP method not allowed: %s" % (method,),
+                        "iMIP method not allowed: {}".format(method,),
                     ))
                     self.responses.add(
                         recipient.cuaddr,
@@ -96,11 +99,16 @@
                 try:
                     toAddr = str(recipient.cuaddr)
                     if not toAddr.lower().startswith("mailto:"):
-                        raise ValueError("ATTENDEE address '%s' must be mailto: for iMIP operation." % (toAddr,))
+                        raise ValueError("ATTENDEE address '{}' must be mailto: for iMIP operation.".format(toAddr,))
 
                     fromAddr = str(self.scheduler.originator.cuaddr)
 
-                    log.debug("Submitting iMIP message...  To: '%s', From :'%s'\n%s" % (toAddr, fromAddr, caldata,))
+                    log.debug(
+                        "Submitting iMIP message...  To: '{to}', From :'{fr}'\n{data}",
+                        to=toAddr,
+                        fr=fromAddr,
+                        data=caldata,
+                    )
 
                     def enqueueOp(txn):
                         return txn.enqueue(IMIPInvitationWork, fromAddr=fromAddr,
@@ -108,14 +116,19 @@
 
                     yield inTransaction(
                         lambda: self.scheduler.txn.store().newTransaction(
-                            "Submitting iMIP message for UID: %s" % (
+                            "Submitting iMIP message for UID: {}".format(
                             self.scheduler.calendar.resourceUID(),)),
                         enqueueOp
                     )
 
                 except Exception, e:
                     # Generated failed response for this recipient
-                    log.debug("iMIP request %s failed for recipient %s: %s" % (self, recipient, e))
+                    log.debug(
+                        "iMIP request {req} failed for recipient {r}: {exc}",
+                        req=self,
+                        r=recipient,
+                        exc=e,
+                    )
                     failForRecipient(recipient)
 
                 else:
@@ -127,6 +140,6 @@
 
         except Exception, e:
             # Generated failed responses for each recipient
-            log.debug("iMIP request %s failed: %s" % (self, e))
+            log.debug("iMIP request {req} failed: {exc}", req=self, exc=e)
             for recipient in self.recipients:
                 failForRecipient(recipient)

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/smtpsender.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/smtpsender.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/imip/smtpsender.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -40,17 +40,24 @@
 
     def sendMessage(self, fromAddr, toAddr, msgId, message):
 
-        log.debug("Sending: %s" % (message,))
+        log.debug("Sending: {msg}", msg=message)
         def _success(result, msgId, fromAddr, toAddr):
-            log.info("Sent IMIP message %s from %s to %s" %
-                (msgId, fromAddr, toAddr))
+            log.info(
+                "Sent IMIP message {id} from {fr} to {to}",
+                id=msgId,
+                fr=fromAddr,
+                to=toAddr,
+            )
             return True
 
         def _failure(failure, msgId, fromAddr, toAddr):
-            log.error("Failed to send IMIP message %s from %s "
-                           "to %s (Reason: %s)" %
-                           (msgId, fromAddr, toAddr,
-                            failure.getErrorMessage()))
+            log.error(
+                "Failed to send IMIP message {id} from {fr} to {to} (Reason: {err})",
+                id=msgId,
+                fr=fromAddr,
+                to=toAddr,
+                err=failure.getErrorMessage(),
+            )
             return False
 
         deferred = defer.Deferred()

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/delivery.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/delivery.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/delivery.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -31,6 +31,7 @@
 from txweb2.stream import MemoryStream
 
 from twisted.internet.defer import inlineCallbacks, DeferredList, returnValue
+from twisted.internet.error import ConnectionDone
 from twisted.internet.protocol import Factory
 from twisted.python.failure import Failure
 
@@ -116,10 +117,10 @@
                             cls.domainServerMap[domain] = None
                         else:
                             # Create the iSchedule server record for this server
-                            cls.domainServerMap[domain] = IScheduleServerRecord(uri="http://%s:%s/.well-known/ischedule" % result)
+                            cls.domainServerMap[domain] = IScheduleServerRecord(uri="http://{}:{}/.well-known/ischedule".format(*result))
                     else:
                         # Create the iSchedule server record for this server
-                        cls.domainServerMap[domain] = IScheduleServerRecord(uri="https://%s:%s/.well-known/ischedule" % result)
+                        cls.domainServerMap[domain] = IScheduleServerRecord(uri="https://{}:{}/.well-known/ischedule".format(*result))
             else:
                 cls.domainServerMap[domain] = None
 
@@ -260,11 +261,15 @@
                 xml = (yield davXMLFromStream(response.stream))
                 self._parseResponse(xml)
             else:
-                raise ValueError("Incorrect server response status code: %s" % (response.code,))
+                raise ValueError("Incorrect server response status code: {code}".format(code=response.code))
 
         except Exception, e:
             # Generated failed responses for each recipient
-            log.error("Could not do server-to-server request : %s %s" % (self, e))
+            log.error(
+                "Could not do server-to-server request : {req} {exc}",
+                req=self,
+                exc=e,
+            )
             for recipient in self.recipients:
                 err = HTTPError(ErrorResponse(
                     responsecode.FORBIDDEN,
@@ -283,17 +288,17 @@
         iostr = StringIO()
         iostr.write(">>>> Request start\n\n")
         if hasattr(request, "clientproto"):
-            protocol = "HTTP/%d.%d" % (request.clientproto[0], request.clientproto[1],)
+            protocol = "HTTP/{:d}.{:d}".format(request.clientproto[0], request.clientproto[1])
         else:
             protocol = "HTTP/1.1"
-        iostr.write("%s %s %s\n" % (request.method, request.uri, protocol,))
+        iostr.write("{} {} {}\n".format(request.method, request.uri, protocol,))
         for name, valuelist in request.headers.getAllRawHeaders():
             for value in valuelist:
                 # Do not log authorization details
                 if name not in ("Authorization",):
-                    iostr.write("%s: %s\n" % (name, value))
+                    iostr.write("{}: {}\n".format(name, value))
                 else:
-                    iostr.write("%s: xxxxxxxxx\n" % (name,))
+                    iostr.write("{}: xxxxxxxxx\n".format(name,))
         iostr.write("\n")
 
         # We need to play a trick with the request stream as we can only read it once. So we
@@ -316,20 +321,23 @@
         iostr = StringIO()
         iostr.write(">>>> Response start\n\n")
         code_message = responsecode.RESPONSES.get(response.code, "Unknown Status")
-        iostr.write("HTTP/1.1 %s %s\n" % (response.code, code_message,))
+        iostr.write("HTTP/1.1 {} {}\n".format(response.code, code_message,))
         for name, valuelist in response.headers.getAllRawHeaders():
             for value in valuelist:
                 # Do not log authorization details
                 if name not in ("WWW-Authenticate",):
-                    iostr.write("%s: %s\n" % (name, value))
+                    iostr.write("{}: {}\n".format(name, value))
                 else:
-                    iostr.write("%s: xxxxxxxxx\n" % (name,))
+                    iostr.write("{}: xxxxxxxxx\n".format(name,))
         iostr.write("\n")
 
         # We need to play a trick with the response stream to ensure we don't mess it up. So we
         # read it, store the value in a MemoryStream, and replace the response's stream with that,
         # so the data can be read again.
-        data = (yield allDataFromStream(response.stream))
+        try:
+            data = (yield allDataFromStream(response.stream))
+        except ConnectionDone:
+            data = ""
         iostr.write(data)
         response.stream = MemoryStream(data if data is not None else "")
         response.stream.doStartReading = None
@@ -358,7 +366,7 @@
         self.sign_headers = []
 
         self.headers = Headers()
-        self.headers.setHeader("Host", utf8String(host + ":%s" % (port,)))
+        self.headers.setHeader("Host", utf8String(host + ":{}".format(port,)))
 
         # The Originator must be the ORGANIZER (for a request) or ATTENDEE (for a reply)
         originator = self.scheduler.organizer.cuaddr if self.scheduler.isiTIPRequest else self.scheduler.attendee
@@ -385,7 +393,7 @@
         ))
         self.sign_headers.append("Content-Type")
 
-        self.headers.setHeader("User-Agent", "CalendarServer/%s" % (version,))
+        self.headers.setHeader("User-Agent", "CalendarServer/{}".format(version,))
         self.sign_headers.append("User-Agent")
 
         # Add any additional headers
@@ -400,7 +408,7 @@
         if self.server.authentication and self.server.authentication[0] == "basic":
             self.headers.setHeader(
                 "Authorization",
-                ('Basic', ("%s:%s" % (self.server.authentication[1], self.server.authentication[2],)).encode('base64')[:-1])
+                ('Basic', ("{}:{}".format(self.server.authentication[1], self.server.authentication[2],)).encode('base64')[:-1])
             )
             self.sign_headers.append("Authorization")
 

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/dkim.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/dkim.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/dkim.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -862,7 +862,7 @@
         """
 
         # First we do an SRV lookup for _domainkey to get the public key server host/port
-        result = (yield lookupServerViaSRV(self.dkim_tags["d"], service="_domainkey"))
+        result = (yield lookupServerViaSRV(self.dkim_tags["d"], service="_domainkey_lookup"))
         if result is None:
             log.debug("DKIM: SRV _domainkey failed on: %s trying domain directly" % (self.dkim_tags["d"],))
             host = self.dkim_tags["d"]

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/localservers.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/localservers.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/localservers.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -75,7 +75,7 @@
                 self._thisServer = server
                 break
         else:
-            raise ValueError("No server in %s matches this server." % (self._xmlFile,))
+            raise ValueError("No server in {} matches this server.".format(self._xmlFile,))
 
 
     def clear(self):
@@ -168,7 +168,7 @@
         try:
             ips = getIPsFromHost(parsed_uri.hostname)
         except socket.gaierror, e:
-            msg = "Unable to lookup ip-addr for server '%s': %s" % (parsed_uri.hostname, str(e))
+            msg = "Unable to lookup ip-addr for server '{}': {}".format(parsed_uri.hostname, str(e))
             log.error(msg)
             if ignoreIPLookupFailures:
                 ips = ()
@@ -182,7 +182,7 @@
                 try:
                     ips = getIPsFromHost(item)
                 except socket.gaierror, e:
-                    msg = "Unable to lookup ip-addr for allowed-from '%s': %s" % (item, str(e))
+                    msg = "Unable to lookup ip-addr for allowed-from '{}': {}".format(item, str(e))
                     log.error(msg)
                     if not ignoreIPLookupFailures:
                         raise ValueError(msg)
@@ -214,13 +214,22 @@
         request_secret = headers.getRawHeaders(SERVER_SECRET_HEADER)
 
         if request_secret is not None and self.shared_secret is None:
-            log.error("iSchedule request included unexpected %s header" % (SERVER_SECRET_HEADER,))
+            log.error(
+                "iSchedule request included unexpected {hdr} header",
+                hdr=SERVER_SECRET_HEADER,
+            )
             return False
         elif request_secret is None and self.shared_secret is not None:
-            log.error("iSchedule request did not include required %s header" % (SERVER_SECRET_HEADER,))
+            log.error(
+                "iSchedule request did not include required {hdr} header",
+                hdr=SERVER_SECRET_HEADER,
+            )
             return False
         elif (request_secret[0] if request_secret else None) != self.shared_secret:
-            log.error("iSchedule request %s header did not match" % (SERVER_SECRET_HEADER,))
+            log.error(
+                "iSchedule request {hdr} header did not match",
+                hdr=SERVER_SECRET_HEADER,
+            )
             return False
         else:
             return True
@@ -278,12 +287,12 @@
         try:
             _ignore_tree, servers_node = readXML(xmlFile, ELEMENT_SERVERS)
         except ValueError, e:
-            raise RuntimeError("XML parse error for '%s' because: %s" % (xmlFile, e,))
+            raise RuntimeError("XML parse error for '{}' because: {}".format(xmlFile, e,))
 
         for child in servers_node:
 
             if child.tag != ELEMENT_SERVER:
-                raise RuntimeError("Unknown server type: '%s' in servers file: '%s'" % (child.tag, xmlFile,))
+                raise RuntimeError("Unknown server type: '{}' in servers file: '{}'".format(child.tag, xmlFile,))
 
             server = Server()
             server.isImplicit = child.get(ATTR_IMPLICIT, ATTR_VALUE_YES) == ATTR_VALUE_YES
@@ -298,10 +307,10 @@
                 elif node.tag == ELEMENT_SHARED_SECRET:
                     server.shared_secret = node.text
                 else:
-                    raise RuntimeError("Invalid element '%s' in servers file: '%s'" % (node.tag, xmlFile,))
+                    raise RuntimeError("Invalid element '{}' in servers file: '{}'".format(node.tag, xmlFile,))
 
             if server.id is None or server.uri is None:
-                raise RuntimeError("Invalid server '%s' in servers file: '%s'" % (child.tag, xmlFile,))
+                raise RuntimeError("Invalid server '{}' in servers file: '{}'".format(child.tag, xmlFile,))
 
             server.check(ignoreIPLookupFailures=ignoreIPLookupFailures)
             results[server.id] = server

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/remoteservers.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/remoteservers.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/remoteservers.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -109,7 +109,7 @@
     Server-to-server configuration file parser.
     """
     def __repr__(self):
-        return "<%s %r>" % (self.__class__.__name__, self.xmlFile)
+        return "<{} {}>".format(self.__class__.__name__, self.xmlFile)
 
 
     def __init__(self, xmlFile):
@@ -188,7 +188,7 @@
             elif child.tag == ELEMENT_CLIENT_HOSTS:
                 self._parseList(child, ELEMENT_HOST, self.client_hosts)
             else:
-                raise RuntimeError("[%s] Unknown attribute: %s" % (self.__class__, child.tag,))
+                raise RuntimeError("[{}] Unknown attribute: {}".format(self.__class__, child.tag,))
 
         self._parseDetails()
 

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/resource.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/resource.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/resource.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -111,12 +111,12 @@
     def render(self, request):
         output = """<html>
 <head>
-<title>%(rtype)s Inbox Resource</title>
+<title>{rtype} Inbox Resource</title>
 </head>
 <body>
-<h1>%(rtype)s Inbox Resource.</h1>
+<h1>{rtype} Inbox Resource.</h1>
 </body
-</html>""" % {"rtype" : "Podding" if self._podding else "iSchedule", }
+</html>""".format(rtype="Podding" if self._podding else "iSchedule")
 
         response = Response(200, {}, output)
         response.headers.setHeader("content-type", MimeType("text", "html"))
@@ -238,7 +238,7 @@
         format = self.determineType(contentType)
 
         if format is None:
-            msg = "MIME type %s not allowed in iSchedule request" % (contentType,)
+            msg = "MIME type {} not allowed in iSchedule request".format(contentType,)
             self.log.error(msg)
             raise HTTPError(scheduler.errorResponse(
                 responsecode.FORBIDDEN,
@@ -272,7 +272,7 @@
         """
         format = None
         if content_type is not None:
-            format = "%s/%s" % (content_type.mediaType, content_type.mediaSubtype,)
+            format = "{}/{}".format(content_type.mediaType, content_type.mediaSubtype,)
         return format if format in Component.allowedTypes() else None
 
 
@@ -295,7 +295,10 @@
         # Get list of Recipient headers
         rawRecipients = request.headers.getRawHeaders("recipient")
         if rawRecipients is None or (len(rawRecipients) == 0):
-            self.log.error("%s request must have at least one Recipient header" % (self.method,))
+            self.log.error(
+                "{method} request must have at least one Recipient header",
+                method=self.method,
+            )
             raise HTTPError(ErrorResponse(
                 responsecode.FORBIDDEN,
                 (ischedule_namespace, "recipient-missing"),
@@ -318,7 +321,10 @@
         # Must be content-type text/calendar
         contentType = request.headers.getHeader("content-type")
         if contentType is not None and (contentType.mediaType, contentType.mediaSubtype) != ("text", "calendar"):
-            self.log.error("MIME type %s not allowed in iSchedule POST request" % (contentType,))
+            self.log.error(
+                "MIME type {ct} not allowed in iSchedule POST request",
+                ct=contentType,
+            )
             raise HTTPError(ErrorResponse(
                 responsecode.FORBIDDEN,
                 (ischedule_namespace, "invalid-calendar-data-type"),
@@ -330,7 +336,10 @@
             calendar = (yield Component.fromIStream(request.stream))
         except:
             # FIXME: Bare except
-            self.log.error("Error while handling iSchedule POST: %s" % (Failure(),))
+            self.log.error(
+                "Error while handling iSchedule POST: {f}",
+                f=Failure(),
+            )
             raise HTTPError(ErrorResponse(
                 responsecode.FORBIDDEN,
                 (ischedule_namespace, "invalid-calendar-data"),

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/scheduler.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/scheduler.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/scheduler.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -97,7 +97,7 @@
 
 
     def __repr__(self):
-        return "<%s %s %s>" % (self.__class__.__name__, self.code, self.error.sname())
+        return "<{} {} {}>".format(self.__class__.__name__, self.code, self.error.sname())
 
 
 
@@ -171,9 +171,9 @@
                 # If DKIM is enabled and there was a DKIM header present, then fail
                 msg = "Failed to verify DKIM signature"
                 _debug_msg = str(e)
-                log.debug("%s:%s" % (msg, _debug_msg,))
+                log.debug("{msg}:{exc}", msg=msg, exc=_debug_msg,)
                 if config.Scheduling.iSchedule.DKIM.ProtocolDebug:
-                    msg = "%s:%s" % (msg, _debug_msg,)
+                    msg = "{}:{}".format(msg, _debug_msg,)
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     (ischedule_namespace, "verification-failed"),
@@ -211,7 +211,10 @@
     def checkAuthorization(self):
         # Must have an unauthenticated user
         if self.originator_uid is not None:
-            log.error("Authenticated originators not allowed: %s" % (self.originator_uid,))
+            log.error(
+                "Authenticated originators not allowed: {o}",
+                o=self.originator_uid,
+            )
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["originator-denied"],
@@ -233,7 +236,10 @@
 
             # iSchedule must never deliver for users hosted on the server or any pod
             if not self._podding:
-                log.error("Cannot use originator that is local to this server: %s" % (self.originator,))
+                log.error(
+                    "Cannot use originator that is local to this server: {o}",
+                    o=self.originator,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["originator-denied"],
@@ -242,7 +248,10 @@
 
             # Cannot deliver message for someone hosted on the same pod
             elif isinstance(originatorAddress, LocalCalendarUser):
-                log.error("Cannot use originator that is on this server: %s" % (self.originator,))
+                log.error(
+                    "Cannot use originator that is on this server: {o}",
+                    o=self.originator,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["originator-denied"],
@@ -253,7 +262,10 @@
                 self._validAlternateServer(originatorAddress)
         else:
             if self._podding:
-                log.error("Cannot use originator that is external to this server: %s" % (self.originator,))
+                log.error(
+                    "Cannot use originator that is external to this server: {o}",
+                    o=self.originator,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["originator-denied"],
@@ -277,7 +289,10 @@
         servermgr = IScheduleServers()
         server = servermgr.mapDomain(self.originator.domain)
         if not server or not server.allow_from:
-            log.error("Originator not on recognized server: %s" % (self.originator,))
+            log.error(
+                "Originator not on recognized server: {o}",
+                o=self.originator,
+            )
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["originator-denied"],
@@ -309,15 +324,26 @@
                                     matched = True
                                     break
                             except re.error:
-                                log.debug("Invalid regular expression for ServerToServer white list for server domain %s: %s" % (self.originator.domain, pattern,))
+                                log.debug(
+                                    "Invalid regular expression for ServerToServer white list for server domain {domain}: {pat}",
+                                    dom=self.originator.domain,
+                                    pat=pattern,
+                                )
                         else:
                             continue
                         break
                 except socket.herror, e:
-                    log.debug("iSchedule cannot lookup client ip '%s': %s" % (clientip, str(e),))
+                    log.debug(
+                        "iSchedule cannot lookup client ip '{ip}': {exc}",
+                        ip=clientip,
+                        exc=str(e),
+                    )
 
             if not matched:
-                log.error("Originator not on allowed server: %s" % (self.originator,))
+                log.error(
+                    "Originator not on allowed server: {o}",
+                    o=self.originator,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["originator-denied"],
@@ -348,7 +374,10 @@
         elif serversDB.getThisServer().hasAllowedFromIP():
             matched = serversDB.getThisServer().checkAllowedFromIP(clientip)
             if not matched:
-                log.error("Invalid iSchedule connection from client: %s" % (clientip,))
+                log.error(
+                    "Invalid iSchedule connection from client: {o}",
+                    o=clientip,
+                )
 
         # Next compare as dotted IP
         elif isIPAddress(expected_uri.hostname):
@@ -363,7 +392,11 @@
                         matched = True
                         break
             except socket.herror, e:
-                log.debug("iSchedule cannot lookup client ip '%s': %s" % (clientip, str(e),))
+                log.debug(
+                    "iSchedule cannot lookup client ip '{ip}': {exc}",
+                    ip=clientip,
+                    exc=str(e),
+                )
 
         # Check possible shared secret
         if matched and not serversDB.getThisServer().checkSharedSecret(self.headers):
@@ -371,7 +404,10 @@
             matched = False
 
         if not matched:
-            log.error("Originator not on allowed server: %s" % (self.originator,))
+            log.error(
+                "Originator not on allowed server: {o}",
+                o=self.originator,
+            )
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["originator-denied"],
@@ -391,7 +427,10 @@
             organizerAddress = yield calendarUserFromCalendarUserAddress(organizer, self.txn)
             if organizerAddress.hosted():
                 if isinstance(organizerAddress, LocalCalendarUser):
-                    log.error("Invalid ORGANIZER in calendar data: %s" % (self.calendar,))
+                    log.error(
+                        "Invalid ORGANIZER in calendar data: {cal}",
+                        cal=self.calendar,
+                    )
                     raise HTTPError(self.errorResponse(
                         responsecode.FORBIDDEN,
                         self.errorElements["organizer-denied"],
@@ -404,7 +443,10 @@
             else:
                 localUser = (yield addressmapping.mapper.isCalendarUserInMyDomain(organizer))
                 if localUser:
-                    log.error("Unsupported ORGANIZER in calendar data: %s" % (self.calendar,))
+                    log.error(
+                        "Unsupported ORGANIZER in calendar data: {cal}",
+                        cal=self.calendar,
+                    )
                     raise HTTPError(self.errorResponse(
                         responsecode.FORBIDDEN,
                         self.errorElements["organizer-denied"],
@@ -413,7 +455,10 @@
                 else:
                     self.organizer = RemoteCalendarUser(organizer)
         else:
-            log.error("ORGANIZER missing in calendar data: %s" % (self.calendar,))
+            log.error(
+                "ORGANIZER missing in calendar data: {cal}",
+                cal=self.calendar,
+            )
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["organizer-denied"],
@@ -432,7 +477,10 @@
         attendeeAddress = yield calendarUserFromCalendarUserAddress(self.attendee, self.txn)
         if attendeeAddress.hosted():
             if isinstance(attendeeAddress, LocalCalendarUser):
-                log.error("Invalid ATTENDEE in calendar data: %s" % (self.calendar,))
+                log.error(
+                    "Invalid ATTENDEE in calendar data: {cal}",
+                    cal=self.calendar,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["attendee-denied"],
@@ -443,7 +491,10 @@
         else:
             localUser = (yield addressmapping.mapper.isCalendarUserInMyDomain(self.attendee))
             if localUser:
-                log.error("Unknown ATTENDEE in calendar data: %s" % (self.calendar,))
+                log.error(
+                    "Unknown ATTENDEE in calendar data: {cal}",
+                    cal=self.calendar,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["attendee-denied"],
@@ -468,7 +519,10 @@
             yield self.checkAttendeeAsOriginator()
 
         else:
-            log.error("Unknown iTIP METHOD for security checks: %s" % (self.calendar.propertyValue("METHOD"),))
+            log.error(
+                "Unknown iTIP METHOD for security checks: {method}",
+                method=self.calendar.propertyValue("METHOD"),
+            )
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
                 self.errorElements["invalid-scheduling-message"],

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/test/data/db.example.com
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/test/data/db.example.com	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/test/data/db.example.com	2014-05-20 18:50:48 UTC (rev 13517)
@@ -15,5 +15,5 @@
 _ischedule._domainkey.example.com.	10800 IN TXT	"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjUfDqd8ICAL0dyq2KdjKN6LS8O/Y4yMxOxgATqtSIMi7baKXEs1w5Wj9efOC2nU+aqyhP2/J6AzfFJfSB+GV5gcIT+LAC4btJKPGjPUyXcQFJV4a73y0jIgCTBzWxdaP6qD9P9rzYlvMPcdrrKiKoAOtI3JZqAAdZudOmGlc4QQIDAQAB"
 _revoked._domainkey.example.com.	10800 IN TXT	"v=DKIM1; p="
 
-_domainkey._tcp.example.com.		10800 IN SRV	0	0	8443	key.example.com.
-_domainkey._tcp.www.example.com.	10800 IN SRV	0	0	80		key.example.com.
+_domainkey_lookup._tcp.example.com.		10800 IN SRV	0	0	8443	key.example.com.
+_domainkey_lookup._tcp.www.example.com.	10800 IN SRV	0	0	80		key.example.com.

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/utils.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/utils.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/utils.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -58,19 +58,19 @@
 
     _initResolver()
 
-    lookup = "%s._tcp.%s" % (service, domain,)
-    log.debug("DNS SRV: lookup: %s" % (lookup,))
+    lookup = "{}._tcp.{}".format(service, domain,)
+    log.debug("DNS SRV: lookup: {l}", l=lookup)
     try:
         answers = (yield DebugResolver.lookupService(lookup))[0]
     except (DomainError, AuthoritativeDomainError), e:
-        log.debug("DNS SRV: lookup failed: %s" % (e,))
+        log.debug("DNS SRV: lookup failed: {exc}", exc=e)
         returnValue(None)
 
     if len(answers) == 1 and answers[0].type == dns.SRV \
                          and answers[0].payload \
                          and answers[0].payload.target == dns.Name('.'):
         # decidedly not available
-        log.debug("DNS SRV: disabled: %s" % (lookup,))
+        log.debug("DNS SRV: disabled: {l}", l=lookup)
         returnValue(None)
 
     servers = []
@@ -81,7 +81,7 @@
 
         servers.append((a.payload.priority, a.payload.weight, str(a.payload.target), a.payload.port))
 
-    log.debug("DNS SRV: lookup results: %s\n%s" % (lookup, servers,))
+    log.debug("DNS SRV: lookup results: {l}\n{s}", l=lookup, s=servers)
 
 
     def _serverCmp(a, b):
@@ -104,10 +104,10 @@
             host = host.rstrip(".")
             break
     else:
-        log.debug("DNS SRV: unable to determine best record to use: %s" % (lookup,))
+        log.debug("DNS SRV: unable to determine best record to use: {l}", l=lookup)
         returnValue(None)
 
-    log.debug("DNS SRV: lookup chosen service: %s %s %s" % (lookup, host, port,))
+    log.debug("DNS SRV: lookup chosen service: {l} {h} {p}", l=lookup, h=host, p=port)
     returnValue((host, port,))
 
 
@@ -117,12 +117,12 @@
 
     _initResolver()
 
-    lookup = "%s.%s" % (prefix, domain,) if prefix else domain
-    log.debug("DNS TXT: lookup: %s" % (lookup,))
+    lookup = "{}.{}".format(prefix, domain,) if prefix else domain
+    log.debug("DNS TXT: lookup: {l}", l=lookup)
     try:
         answers = (yield DebugResolver.lookupText(lookup))[0]
     except (DomainError, AuthoritativeDomainError), e:
-        log.debug("DNS TXT: lookup failed: %s" % (e,))
+        log.debug("DNS TXT: lookup failed: {exc}", exc=e)
         answers = ()
 
     results = []
@@ -133,7 +133,7 @@
 
         results.append("".join(a.payload.data))
 
-    log.debug("DNS TXT: lookup results: %s\n%s" % (lookup, "\n".join(results),))
+    log.debug("DNS TXT: lookup results: {l}\n{r}", l=lookup, r="\n".join(results))
     returnValue(results)
 
 
@@ -142,9 +142,20 @@
 
     @inlineCallbacks
     def _lookup(self, name, cls, type, timeout=None):
-        log.debug("DNS FakeBindAuthority: lookup: %s %s %s" % (name, cls, type,))
+        log.debug(
+            "DNS FakeBindAuthority: lookup: {name} {cls} {type}",
+            name=name,
+            cls=cls,
+            type=type,
+        )
         result = yield BindAuthority._lookup(self, name, cls, type, timeout)
-        log.debug("DNS FakeBindAuthority: lookup results: %s %s %s\n%s" % (name, cls, type, result[0]))
+        log.debug(
+            "DNS FakeBindAuthority: lookup results: {name} {cls} {type}\n{r}",
+            name=name,
+            cls=cls,
+            type=type,
+            r=result[0],
+        )
         returnValue(result)
 
 

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/xml.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/xml.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/ischedule/xml.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -269,10 +269,10 @@
                 raise ValueError("Missing calendar data")
             return clazz(PCDATAElement(calendar))
         elif isinstance(calendar, iComponent):
-            assert calendar.name() == "VCALENDAR", "Not a calendar: %r" % (calendar,)
+            assert calendar.name() == "VCALENDAR", "Not a calendar: {}".format(calendar)
             return clazz(PCDATAElement(calendar.getTextWithTimezones(includeTimezones=not config.EnableTimezonesByReference, format=format)))
         else:
-            raise ValueError("Not a calendar: %s" % (calendar,))
+            raise ValueError("Not a calendar: {}".format(calendar))
 
     fromTextData = fromCalendar
 

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/scheduler.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/scheduler.py	2014-05-20 18:49:22 UTC (rev 13516)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/scheduler.py	2014-05-20 18:50:48 UTC (rev 13517)
@@ -172,7 +172,7 @@
         # of data for all events with the same UID. So detect this and use a lock
         if calendar.resourceType() != "VFREEBUSY":
             uid = calendar.resourceUID()
-            yield NamedLock.acquire(self.txn, "ImplicitUIDLock:%s" % (hashlib.md5(uid).hexdigest(),))
+            yield NamedLock.acquire(self.txn, "ImplicitUIDLock:{}".format(hashlib.md5(uid).hexdigest(),))
 
         result = (yield self.doSchedulingDirectly("POST", originator, recipients, calendar))
         returnValue(result)
@@ -276,7 +276,12 @@
             try:
                 self.calendar.validCalendarData()
             except ValueError, e:
-                log.error("%s request calendar component is not valid:%s %s" % (self.method, e, self.calendar,))
+                log.error(
+                    "{method} request calendar component is not valid:{exc} {cal}",
+                    method=self.method,
+                    exc=e,
+                    cal=self.calendar,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["invalid-calendar-data"],
@@ -285,7 +290,11 @@
 
             # Must have a METHOD
             if not self.calendar.isValidMethod():
-                log.error("%s request must have valid METHOD property in calendar component: %s" % (self.method, self.calendar,))
+                log.error(
+                    "{method} request must have valid METHOD property in calendar component: {cal}",
+                    method=self.method,
+                    cal=self.calendar,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["invalid-scheduling-message"],
@@ -294,7 +303,11 @@
 
             # Verify iTIP behavior
             if not self.calendar.isValidITIP():
-                log.error("%s request must have a calendar component that satisfies iTIP requirements: %s" % (self.method, self.calendar,))
+                log.error(
+                    "{method} request must have a calendar component that satisfies iTIP requirements: {cal}",
+                    method=self.method,
+                    cal=self.calendar,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["invalid-scheduling-message"],
@@ -303,7 +316,11 @@
 
             # X-CALENDARSERVER-ACCESS is not allowed in Outbox POSTs
             if self.calendar.hasProperty(Component.ACCESS_PROPERTY):
-                log.error("X-CALENDARSERVER-ACCESS not allowed in a calendar component %s request: %s" % (self.method, self.calendar,))
+                log.error(
+                    "X-CALENDARSERVER-ACCESS not allowed in a calendar component {method} request: {cal}",
+                    method=self.method,
+                    cal=self.calendar,
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     (calendarserver_namespace, "no-access-restrictions"),
@@ -322,7 +339,10 @@
 
             # Must have only one
             if len(attendees) != 1:
-                log.error("Wrong number of ATTENDEEs in calendar data: %s" % (str(self.calendar),))
+                log.error(
+                    "Wrong number of ATTENDEEs in calendar data: {cal}",
+                    cal=str(self.calendar),
+                )
                 raise HTTPError(self.errorResponse(
                     responsecode.FORBIDDEN,
                     self.errorElements["invalid-scheduling-message"],
@@ -331,7 +351,7 @@
             self.attendee = attendees[0]
 
         else:
-            msg = "Unknown iTIP METHOD: %s" % (self.calendar.propertyValue("METHOD"),)
+            msg = "Unknown iTIP METHOD: {}".format(self.calendar.propertyValue("METHOD"),)
             log.error(msg)
             raise HTTPError(self.errorResponse(
                 responsecode.FORBIDDEN,
@@ -346,7 +366,10 @@
                 # Extract time range from VFREEBUSY object
                 vfreebusies = [v for v in self.calendar.subcomponents() if v.name() == "VFREEBUSY"]
                 if len(vfreebusies) != 1:
-                    log.error("iTIP data is not valid for a VFREEBUSY request: %s" % (self.calendar,))
+                    log.error(
+                        "iTIP data is not valid for a VFREEBUSY request: {cal}",
+                        cal=str(self.calendar),
+                    )
                     raise HTTPError(self.errorResponse(
                         responsecode.FORBIDDEN,
                         self.errorElements["invalid-scheduling-message"],
@@ -355,7 +378,10 @@
                 dtstart = vfreebusies[0].getStartDateUTC()
                 dtend = vfreebusies[0].getEndDateUTC()
                 if dtstart is None or dtend is None:
-                    log.error("VFREEBUSY start/end not valid: %s" % (self.calendar,))
+                    log.error(
+                        "VFREEBUSY start/end not valid: {cal}",
+                        cal=str(self.calendar),
+                    )
                     raise HTTPError(self.errorResponse(
                         responsecode.FORBIDDEN,
                         self.errorElements["invalid-scheduling-message"],
@@ -364,7 +390,10 @@
 
                 # Some clients send floating instead of UTC - coerce to UTC
                 if not dtstart.utc() or not dtend.utc():
-                    log.error("VFREEBUSY start or end not UTC: %s" % (self.calendar,))
+                    log.error(
+                        "VFREEBUSY start or end not UTC: {cal}",
+                        cal=self.calendar,
+                    )
                     raise HTTPError(self.errorResponse(
                         responsecode.FORBIDDEN,
                         self.errorElements["invalid-scheduling-message"],
@@ -406,12 +435,11 @@
                 emitAccounting(
                     accountingType,
                     self.organizer.record,
-                    "Originator: %s\nRecipients:\n%sMethod:%s\n\n%s"
-                    % (
-                        str(self.originator),
-                        str("".join(["    %s\n" % (recipient,) for recipient in self.recipients])),
-                        str(self.method),
-                        str(self.calendar),
+                    "Originator: {o}\nRecipients:\n{r}Method:{method}\n\n{cal}".format(
+                        o=str(self.originator),
+                        r=str("".join(["    {}\n".format(recipient,) for recipient in self.recipients])),
+                        method=str(self.method),
+                        cal=str(self.calendar),
                     )
                 )
 
@@ -426,7 +454,11 @@
     @inlineCallbacks
     def generateSchedulingResponse(self):
 
-        log.info("METHOD: %s, Component: %s" % (self.calendar.propertyValue("METHOD"), self.calendar.mainType(),))
+        log.info(
+            "METHOD: {method}, Component: {comp}",
+            method=self.calendar.propertyValue("METHOD"),
+            comp=self.calendar.mainType(),
+        )
 
         # For free-busy do immediate determination of iTIP result rather than fan-out
         freebusy = self.checkForFreeBusy()
@@ -559,9 +591,15 @@
             if not recipientAddress.hosted():
                 localUser = (yield addressmapping.mapper.isCalendarUserInMyDomain(recipient))
                 if localUser:
-                    log.error("No record for calendar user address: %s" % (recipient,))
+                    log.error(
+                        "No record for calendar user address: {r}",
+                        r=recipient,
+                    )
                 else:
-                    log.error("Unknown calendar user address: %s" % (recipient,))
+                    log.error(
+                        "Unknown calendar user address: {r}",
+                        r=recipient,
+                    )
                 results.append(InvalidCalendarUser(recipient))
             else:
                 # Map recipient to their inbox and cache on calendar user object
@@ -578,7 +616,10 @@
                 if inbox:
                     results.append(recipientAddress)
                 else:
-                    log.error("No scheduling for calendar user: %s" % (recipient,))
+                    log.error(
+                        "No scheduling for calendar user: {r}",
+                        r=recipient,
+                    )
                     results.append(InvalidCalendarUser(recipient))
 
         self.recipients = results
@@ -704,13 +745,17 @@
             error = self.errorForFailure(what)
             message = messageForFailure(what)
         else:
-            raise AssertionError("Unknown data type: %r" % (what,))
+            raise AssertionError("Unknown data type: {}".format(what,))
 
         if self.recipient_mapper is not None:
             recipient = self.recipient_mapper(recipient)
 
         if not suppressErrorLog and code > 400: # Error codes only
-            self.log.error("Error during %s for %s: %s" % (self.method, recipient, message))
+            self.log.error("Error during {method} for {r}: {msg}",
+                method=self.method,
+                r=recipient,
+                msg=message,
+            )
 
         details = ScheduleResponseQueue.ScheduleResonseDetails(
             self.recipient_element(davxml.HRef.fromString(recipient)) if self.recipient_uses_href else self.recipient_element.fromString(recipient),
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140520/3a35a67f/attachment-0001.html>


More information about the calendarserver-changes mailing list