<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[12363] CalendarServer/trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/12363">12363</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2014-01-16 14:01:41 -0800 (Thu, 16 Jan 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Whitespace.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinoddsattributespy">CalendarServer/trunk/calendarserver/platform/darwin/od/dsattributes.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinoddsquerypy">CalendarServer/trunk/calendarserver/platform/darwin/od/dsquery.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinododframeworkpy">CalendarServer/trunk/calendarserver/platform/darwin/od/odframework.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinodopendirectorypy">CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinodsetup_directorypy">CalendarServer/trunk/calendarserver/platform/darwin/od/setup_directory.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinodsetup_testuserspy">CalendarServer/trunk/calendarserver/platform/darwin/od/setup_testusers.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinodtesttest_opendirectorypy">CalendarServer/trunk/calendarserver/platform/darwin/od/test/test_opendirectory.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverplatformdarwinwikipy">CalendarServer/trunk/calendarserver/platform/darwin/wiki.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverprovisiontesttest_rootpy">CalendarServer/trunk/calendarserver/provision/test/test_root.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverpushapplepushpy">CalendarServer/trunk/calendarserver/push/applepush.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverpushutilpy">CalendarServer/trunk/calendarserver/push/util.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertap__init__py">CalendarServer/trunk/calendarserver/tap/__init__.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertapcfgchildpy">CalendarServer/trunk/calendarserver/tap/cfgchild.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertapprofilingpy">CalendarServer/trunk/calendarserver/tap/profiling.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertaptesttest_caldavpy">CalendarServer/trunk/calendarserver/tap/test/test_caldav.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsagentpy">CalendarServer/trunk/calendarserver/tools/agent.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsampnotificationspy">CalendarServer/trunk/calendarserver/tools/ampnotifications.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsbackup_pgpy">CalendarServer/trunk/calendarserver/tools/backup_pg.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsbootstrapdatabasepy">CalendarServer/trunk/calendarserver/tools/bootstrapdatabase.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolscalverify_diffpy">CalendarServer/trunk/calendarserver/tools/calverify_diff.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolschangeip_calendarpy">CalendarServer/trunk/calendarserver/tools/changeip_calendar.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsconfigpy">CalendarServer/trunk/calendarserver/tools/config.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsicalsplitpy">CalendarServer/trunk/calendarserver/tools/icalsplit.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsmanagepostgrespy">CalendarServer/trunk/calendarserver/tools/managepostgres.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsmigratepy">CalendarServer/trunk/calendarserver/tools/migrate.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsnotificationspy">CalendarServer/trunk/calendarserver/tools/notifications.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsprincipalspy">CalendarServer/trunk/calendarserver/tools/principals.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsresourcespy">CalendarServer/trunk/calendarserver/tools/resources.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsshellcmdpy">CalendarServer/trunk/calendarserver/tools/shell/cmd.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsshellterminalpy">CalendarServer/trunk/calendarserver/tools/shell/terminal.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsshelltesttest_cmdpy">CalendarServer/trunk/calendarserver/tools/shell/test/test_cmd.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolsshellvfspy">CalendarServer/trunk/calendarserver/tools/shell/vfs.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolstablespy">CalendarServer/trunk/calendarserver/tools/tables.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolstesttest_agentpy">CalendarServer/trunk/calendarserver/tools/test/test_agent.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolstesttest_configpy">CalendarServer/trunk/calendarserver/tools/test/test_config.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolstesttest_gatewaypy">CalendarServer/trunk/calendarserver/tools/test/test_gateway.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolstesttest_resourcespy">CalendarServer/trunk/calendarserver/tools/test/test_resources.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertoolstesttest_utilpy">CalendarServer/trunk/calendarserver/tools/test/test_util.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverwebcalresourcepy">CalendarServer/trunk/calendarserver/webcal/resource.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverwebcaltesttest_resourcepy">CalendarServer/trunk/calendarserver/webcal/test/test_resource.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryappleopendirectorypy">CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectorycalendarpy">CalendarServer/trunk/twistedcaldav/directory/calendar.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectorycalendaruserproxypy">CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectorycalendaruserproxyloaderpy">CalendarServer/trunk/twistedcaldav/directory/calendaruserproxyloader.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectorydigestpy">CalendarServer/trunk/twistedcaldav/directory/digest.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryinternalpy">CalendarServer/trunk/twistedcaldav/directory/internal.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryldapdirectorypy">CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryresourceinfopy">CalendarServer/trunk/twistedcaldav/directory/resourceinfo.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectorytesttest_ldapdirectorypy">CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryutilpy">CalendarServer/trunk/twistedcaldav/directory/util.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryxmlaccountsparserpy">CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoresqlpy">CalendarServer/trunk/txdav/common/datastore/sql.py</a></li>
<li><a href="#CalendarServertrunktxdavidavpy">CalendarServer/trunk/txdav/idav.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlbasepy">CalendarServer/trunk/txdav/xml/base.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlelementpy">CalendarServer/trunk/txdav/xml/element.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlparserpy">CalendarServer/trunk/txdav/xml/parser.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlparser_basepy">CalendarServer/trunk/txdav/xml/parser_base.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlparser_etreepy">CalendarServer/trunk/txdav/xml/parser_etree.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlparser_saxpy">CalendarServer/trunk/txdav/xml/parser_sax.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlrfc2518py">CalendarServer/trunk/txdav/xml/rfc2518.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlrfc3253py">CalendarServer/trunk/txdav/xml/rfc3253.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlrfc3744py">CalendarServer/trunk/txdav/xml/rfc3744.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlrfc4331py">CalendarServer/trunk/txdav/xml/rfc4331.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlrfc5397py">CalendarServer/trunk/txdav/xml/rfc5397.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlrfc5842py">CalendarServer/trunk/txdav/xml/rfc5842.py</a></li>
<li><a href="#CalendarServertrunktxdavxmlrfc5995py">CalendarServer/trunk/txdav/xml/rfc5995.py</a></li>
<li><a href="#CalendarServertrunktxdavxmltesttest_basepy">CalendarServer/trunk/txdav/xml/test/test_base.py</a></li>
<li><a href="#CalendarServertrunktxdavxmltesttest_xmlpy">CalendarServer/trunk/txdav/xml/test/test_xml.py</a></li>
<li><a href="#CalendarServertrunktxdavxmltesttest_xml_rfc3744py">CalendarServer/trunk/txdav/xml/test/test_xml_rfc3744.py</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunkcalendarserverplatformdarwinoddsattributespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/dsattributes.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/od/dsattributes.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/dsattributes.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -21,22 +21,22 @@
</span><span class="cx">
</span><span class="cx"> # Specific match types
</span><span class="cx">
</span><del>-eDSExact = 0x2001
-eDSStartsWith = 0x2002
-eDSEndsWith = 0x2003
-eDSContains = 0x2004
</del><ins>+eDSExact = 0x2001
+eDSStartsWith = 0x2002
+eDSEndsWith = 0x2003
+eDSContains = 0x2004
</ins><span class="cx">
</span><del>-eDSLessThan = 0x2005
-eDSGreaterThan = 0x2006
-eDSLessEqual = 0x2007
-eDSGreaterEqual = 0x2008
</del><ins>+eDSLessThan = 0x2005
+eDSGreaterThan = 0x2006
+eDSLessEqual = 0x2007
+eDSGreaterEqual = 0x2008
</ins><span class="cx">
</span><span class="cx"> # Specific Record Type Constants
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> DirectoryService Specific Record Type Constants
</span><span class="cx"> """
</span><del>-
</del><ins>+
</ins><span class="cx"> """
</span><span class="cx"> kDSStdRecordTypeAccessControls
</span><span class="cx"> Record type that contains directory access control directives.
</span><span class="lines">@@ -129,7 +129,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSStdRecordTypeFileMakerServers
</span><del>- FileMaker servers record type. Describes available FileMaker servers,
</del><ins>+ FileMaker servers record type. Describes available FileMaker servers,
</ins><span class="cx"> used for service discovery.
</span><span class="cx"> """
</span><span class="cx"> kDSStdRecordTypeFileMakerServers = "dsRecTypeStandard:FileMakerServers"
</span><span class="lines">@@ -399,8 +399,8 @@
</span><span class="cx">
</span><span class="cx"> NOTE #2: Attributes in the model are available for records and directory nodes.
</span><span class="cx"> """
</span><del>-
</del><span class="cx">
</span><ins>+
</ins><span class="cx"> # Single Valued Specific Attribute Type Constants
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -458,7 +458,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrBootFile
</span><del>- Attribute type in host or machine records for the name of the
</del><ins>+ Attribute type in host or machine records for the name of the
</ins><span class="cx"> kernel that this machine will use by default when NetBooting.
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrBootFile = "dsAttrTypeStandard:BootFile"
</span><span class="lines">@@ -480,8 +480,8 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrCapacity
</span><del>- Attribute type for the capacity of a resource.
- found in resource records (kDSStdRecordTypeResources).
</del><ins>+ Attribute type for the capacity of a resource.
+ found in resource records (kDSStdRecordTypeResources).
</ins><span class="cx"> Example: 50
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrCapacity = "dsAttrTypeStandard:Capacity"
</span><span class="lines">@@ -514,14 +514,14 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrContactGUID
</span><del>- Attribute type for the contact GUID of a group.
- found in group records (kDSStdRecordTypeGroups).
</del><ins>+ Attribute type for the contact GUID of a group.
+ found in group records (kDSStdRecordTypeGroups).
</ins><span class="cx"> """
</span><span class="cx"> kDS1AttrContactGUID = "dsAttrTypeStandard:ContactGUID"
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrContactPerson
</span><del>- Attribute type for the contact person of the machine.
</del><ins>+ Attribute type for the contact person of the machine.
</ins><span class="cx"> Found in host or machine records.
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrContactPerson = "dsAttrTypeStandard:ContactPerson"
</span><span class="lines">@@ -535,7 +535,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrCrossCertificatePair
</span><del>- Attribute containing the binary of a pair of certificates which
</del><ins>+ Attribute containing the binary of a pair of certificates which
</ins><span class="cx"> verify each other. Both certificates have the same level of authority.
</span><span class="cx"> Usually found in kDSStdRecordTypeCertificateAuthority records.
</span><span class="cx"> """
</span><span class="lines">@@ -587,7 +587,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrGeneratedUID
</span><del>- Used for 36 character (128 bit) unique ID. Usually found in user,
</del><ins>+ Used for 36 character (128 bit) unique ID. Usually found in user,
</ins><span class="cx"> group, and computer records. An example value is "A579E95E-CDFE-4EBC-B7E7-F2158562170F".
</span><span class="cx"> The standard format contains 32 hex characters and four hyphen characters.
</span><span class="cx"> """
</span><span class="lines">@@ -678,7 +678,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrMetaAutomountMap
</span><del>- Used to query for kDSStdRecordTypeAutomount entries associated with a specific
</del><ins>+ Used to query for kDSStdRecordTypeAutomount entries associated with a specific
</ins><span class="cx"> kDSStdRecordTypeAutomountMap.
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrMetaAutomountMap = "dsAttrTypeStandard:MetaAutomountMap"
</span><span class="lines">@@ -728,15 +728,15 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrOwner
</span><del>- Attribute type for the owner of a record.
</del><ins>+ Attribute type for the owner of a record.
</ins><span class="cx"> Typically the value is a LDAP distinguished name.
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrOwner = "dsAttrTypeStandard:Owner"
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrOwnerGUID
</span><del>- Attribute type for the owner GUID of a group.
- found in group records (kDSStdRecordTypeGroups).
</del><ins>+ Attribute type for the owner GUID of a group.
+ found in group records (kDSStdRecordTypeGroups).
</ins><span class="cx"> """
</span><span class="cx"> kDS1AttrOwnerGUID = "dsAttrTypeStandard:OwnerGUID"
</span><span class="cx">
</span><span class="lines">@@ -796,7 +796,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrPrimaryComputerGUID
</span><del>- Single-valued attribute that defines a primary computer of the computer group.
</del><ins>+ Single-valued attribute that defines a primary computer of the computer group.
</ins><span class="cx"> added via extensible object for computer group record type (kDSStdRecordTypeComputerGroups)
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrPrimaryComputerGUID = "dsAttrTypeStandard:PrimaryComputerGUID"
</span><span class="lines">@@ -809,7 +809,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrPrimaryGroupID
</span><del>- This is the 32 bit unique ID that represents the primary group
</del><ins>+ This is the 32 bit unique ID that represents the primary group
</ins><span class="cx"> a user is part of, or the ID of a group. Format is a signed 32 bit integer
</span><span class="cx"> represented as a string.
</span><span class="cx"> """
</span><span class="lines">@@ -860,7 +860,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrPrinterXRISupported
</span><span class="cx"> Multi-valued attribute that defines additional URIs supported by a printer.
</span><del>- This is used when configuring a printer. This attribute is based on the IPP
</del><ins>+ This is used when configuring a printer. This attribute is based on the IPP
</ins><span class="cx"> Printing Specification RFC and IETF IPP-LDAP Printer Record.
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrPrinterXRISupported = "dsAttrTypeStandard:PrinterXRISupported"
</span><span class="lines">@@ -912,14 +912,14 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrSMBHome
</span><del>-
</del><ins>+
</ins><span class="cx"> UNC address of Windows homedirectory mount point (\\server\\sharepoint).
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrSMBHome = "dsAttrTypeStandard:SMBHome"
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrSMBHomeDrive
</span><del>-
</del><ins>+
</ins><span class="cx"> Drive letter for homedirectory mount point.
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrSMBHomeDrive = "dsAttrTypeStandard:SMBHomeDrive"
</span><span class="lines">@@ -977,7 +977,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrSMBSID
</span><span class="cx"> SMB Security ID, stored as a string attribute of up to 64 bytes.
</span><del>- Found in user, group, and computer records (kDSStdRecordTypeUsers,
</del><ins>+ Found in user, group, and computer records (kDSStdRecordTypeUsers,
</ins><span class="cx"> kDSStdRecordTypeGroups, kDSStdRecordTypeComputers).
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrSMBSID = "dsAttrTypeStandard:SMBSID"
</span><span class="lines">@@ -991,7 +991,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrServiceType
</span><span class="cx"> Represents the service type for the service. This is the raw service type of the
</span><del>- service. For example a service record type of kDSStdRecordTypeWebServer
</del><ins>+ service. For example a service record type of kDSStdRecordTypeWebServer
</ins><span class="cx"> might have a service type of "http" or "https".
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrServiceType = "dsAttrTypeStandard:ServiceType"
</span><span class="lines">@@ -1038,14 +1038,14 @@
</span><span class="cx"> kDS1AttrUserCertificate
</span><span class="cx"> Attribute containing the binary of the user's certificate.
</span><span class="cx"> Usually found in user records. The certificate is data which identifies a user.
</span><del>- This data is attested to by a known party, and can be independently verified
</del><ins>+ This data is attested to by a known party, and can be independently verified
</ins><span class="cx"> by a third party.
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrUserCertificate = "dsAttrTypeStandard:UserCertificate"
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrUserPKCS12Data
</span><del>- Attribute containing binary data in PKCS #12 format.
</del><ins>+ Attribute containing binary data in PKCS #12 format.
</ins><span class="cx"> Usually found in user records. The value can contain keys, certificates,
</span><span class="cx"> and other related information and is encrypted with a passphrase.
</span><span class="cx"> """
</span><span class="lines">@@ -1061,7 +1061,7 @@
</span><span class="cx"> kDS1AttrUserSMIMECertificate
</span><span class="cx"> Attribute containing the binary of the user's SMIME certificate.
</span><span class="cx"> Usually found in user records. The certificate is data which identifies a user.
</span><del>- This data is attested to by a known party, and can be independently verified
</del><ins>+ This data is attested to by a known party, and can be independently verified
</ins><span class="cx"> by a third party. SMIME certificates are often used for signed or encrypted
</span><span class="cx"> emails.
</span><span class="cx"> """
</span><span class="lines">@@ -1094,7 +1094,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrWeblogURI
</span><span class="cx"> Single-valued attribute that defines the URI of a user's weblog.
</span><del>- Usually found in user records (kDSStdRecordTypeUsers).
</del><ins>+ Usually found in user records (kDSStdRecordTypeUsers).
</ins><span class="cx"> Example: http://example.com/blog/jsmith
</span><span class="cx"> """
</span><span class="cx"> kDS1AttrWeblogURI = "dsAttrTypeStandard:WeblogURI"
</span><span class="lines">@@ -1193,7 +1193,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrBuilding
</span><span class="cx"> Represents the building name for a user or person record.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrBuilding = "dsAttrTypeStandard:Building"
</span><span class="lines">@@ -1207,7 +1207,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrCity
</span><span class="cx"> Usually, city for a user or person record.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrCity = "dsAttrTypeStandard:City"
</span><span class="lines">@@ -1235,7 +1235,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrCountry
</span><span class="cx"> Represents country of a record entry.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrCountry = "dsAttrTypeStandard:Country"
</span><span class="lines">@@ -1243,7 +1243,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrDepartment
</span><span class="cx"> Represents the department name of a user or person.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrDepartment = "dsAttrTypeStandard:Department"
</span><span class="lines">@@ -1263,7 +1263,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrEMailContacts
</span><span class="cx"> multi-valued attribute that defines a record's custom email addresses .
</span><del>- found in user records (kDSStdRecordTypeUsers).
</del><ins>+ found in user records (kDSStdRecordTypeUsers).
</ins><span class="cx"> Example: home:johndoe@mymail.com
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrEMailContacts = "dsAttrTypeStandard:EMailContacts"
</span><span class="lines">@@ -1271,7 +1271,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrFaxNumber
</span><span class="cx"> Represents the FAX numbers of a user or person.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrFaxNumber = "dsAttrTypeStandard:FAXNumber"
</span><span class="lines">@@ -1297,7 +1297,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrGroupServices
</span><span class="cx"> xml-plist attribute that defines a group's services .
</span><del>- found in group records (kDSStdRecordTypeGroups).
</del><ins>+ found in group records (kDSStdRecordTypeGroups).
</ins><span class="cx"> """
</span><span class="cx"> kDSNAttrGroupServices = "dsAttrTypeStandard:GroupServices"
</span><span class="cx">
</span><span class="lines">@@ -1336,9 +1336,9 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrIPAddressAndENetAddress
</span><del>- A pairing of IPv4 or IPv6 addresses with Ethernet addresses
- (e.g., "10.1.1.1/00:16:cb:92:56:41"). Usually found on kDSStdRecordTypeComputers for use by
- services that need specific pairing of the two values. This should be in addition to
</del><ins>+ A pairing of IPv4 or IPv6 addresses with Ethernet addresses
+ (e.g., "10.1.1.1/00:16:cb:92:56:41"). Usually found on kDSStdRecordTypeComputers for use by
+ services that need specific pairing of the two values. This should be in addition to
</ins><span class="cx"> kDSNAttrIPAddress, kDSNAttrIPv6Address and kDS1AttrENetAddress. This is necessary because not
</span><span class="cx"> all directories return attribute values in a guaranteed order.
</span><span class="cx"> """
</span><span class="lines">@@ -1347,15 +1347,15 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrIPv6Address
</span><span class="cx"> IPv6 address expressed in the standard notation (e.g., "fe80::236:caff:fcc2:5641" )
</span><del>- Usually found on kDSStdRecordTypeComputers, kDSStdRecordTypeHosts, and
</del><ins>+ Usually found on kDSStdRecordTypeComputers, kDSStdRecordTypeHosts, and
</ins><span class="cx"> kDSStdRecordTypeMachines.
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrIPv6Address = "dsAttrTypeStandard:IPv6Address"
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrJPEGPhoto
</span><del>- Used to store binary picture data in JPEG format.
- Usually found in user, people or group records (kDSStdRecordTypeUsers,
</del><ins>+ Used to store binary picture data in JPEG format.
+ Usually found in user, people or group records (kDSStdRecordTypeUsers,
</ins><span class="cx"> kDSStdRecordTypePeople, kDSStdRecordTypeGroups).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrJPEGPhoto = "dsAttrTypeStandard:JPEGPhoto"
</span><span class="lines">@@ -1363,7 +1363,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrJobTitle
</span><span class="cx"> Represents the job title of a user.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrJobTitle = "dsAttrTypeStandard:JobTitle"
</span><span class="lines">@@ -1394,7 +1394,7 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMachineServes
</span><del>- Attribute type in host or machine records for storing NetInfo
</del><ins>+ Attribute type in host or machine records for storing NetInfo
</ins><span class="cx"> domains served.
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMachineServes = "dsAttrTypeStandard:MachineServes"
</span><span class="lines">@@ -1410,7 +1410,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMapURI
</span><span class="cx"> attribute that defines the URI of a user's location.
</span><del>- Usually found in user records (kDSStdRecordTypeUsers).
</del><ins>+ Usually found in user records (kDSStdRecordTypeUsers).
</ins><span class="cx"> Example: http://example.com/bldg1
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMapURI = "dsAttrTypeStandard:MapURI"
</span><span class="lines">@@ -1423,20 +1423,20 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMIME
</span><del>- Data contained in this attribute type is a fully qualified MIME Type.
</del><ins>+ Data contained in this attribute type is a fully qualified MIME Type.
</ins><span class="cx"> """
</span><span class="cx"> kDSNAttrMIME = "dsAttrTypeStandard:MIME"
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMember
</span><del>- List of member records.
</del><ins>+ List of member records.
</ins><span class="cx"> """
</span><span class="cx"> kDSNAttrMember = "dsAttrTypeStandard:Member"
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMobileNumber
</span><span class="cx"> Represents the mobile numbers of a user or person.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrMobileNumber = "dsAttrTypeStandard:MobileNumber"
</span><span class="lines">@@ -1463,7 +1463,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrNickName
</span><span class="cx"> Represents the nickname of a user or person.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrNickName = "dsAttrTypeStandard:NickName"
</span><span class="lines">@@ -1490,7 +1490,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrPagerNumber
</span><span class="cx"> Represents the pager numbers of a user or person.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrPagerNumber = "dsAttrTypeStandard:PagerNumber"
</span><span class="lines">@@ -1498,7 +1498,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrPhoneContacts
</span><span class="cx"> multi-valued attribute that defines a record's custom phone numbers .
</span><del>- found in user records (kDSStdRecordTypeUsers).
</del><ins>+ found in user records (kDSStdRecordTypeUsers).
</ins><span class="cx"> Example: home fax:408-555-4444
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrPhoneContacts = "dsAttrTypeStandard:PhoneContacts"
</span><span class="lines">@@ -1539,7 +1539,7 @@
</span><span class="cx"> kDSNAttrNamePrefix
</span><span class="cx"> Represents the title prefix of a user or person.
</span><span class="cx"> ie. Mr., Ms., Mrs., Dr., etc.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrNamePrefix = "dsAttrTypeStandard:NamePrefix"
</span><span class="lines">@@ -1559,7 +1559,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrRelationships
</span><span class="cx"> multi-valued attribute that defines the relationship to the record type .
</span><del>- found in user records (kDSStdRecordTypeUsers).
</del><ins>+ found in user records (kDSStdRecordTypeUsers).
</ins><span class="cx"> Example: brother:John
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrRelationships = "dsAttrTypeStandard:Relationships"
</span><span class="lines">@@ -1572,8 +1572,8 @@
</span><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrResourceType
</span><del>- Attribute type for the kind of resource.
- found in resource records (kDSStdRecordTypeResources).
</del><ins>+ Attribute type for the kind of resource.
+ found in resource records (kDSStdRecordTypeResources).
</ins><span class="cx"> Example: ConferenceRoom
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrResourceType = "dsAttrTypeStandard:ResourceType"
</span><span class="lines">@@ -1593,7 +1593,7 @@
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrStreet
</span><span class="cx"> Represents the street address of a user or person.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrStreet = "dsAttrTypeStandard:Street"
</span><span class="lines">@@ -1602,7 +1602,7 @@
</span><span class="cx"> kDSNAttrNameSuffix
</span><span class="cx"> Represents the name suffix of a user or person.
</span><span class="cx"> ie. Jr., Sr., etc.
</span><del>- Usually found in user or people records (kDSStdRecordTypeUsers or
</del><ins>+ Usually found in user or people records (kDSStdRecordTypeUsers or
</ins><span class="cx"> kDSStdRecordTypePeople).
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrNameSuffix = "dsAttrTypeStandard:NameSuffix"
</span><span class="lines">@@ -1837,7 +1837,7 @@
</span><span class="cx"> """
</span><span class="cx"> Search Node attribute type Constants
</span><span class="cx"> """
</span><del>-
</del><ins>+
</ins><span class="cx"> """
</span><span class="cx"> kDS1AttrSearchPath
</span><span class="cx"> Search path used by the search node.
</span><span class="lines">@@ -1891,4 +1891,3 @@
</span><span class="cx"> Retained only for backward compatibility.
</span><span class="cx"> """
</span><span class="cx"> kDSNAttrCSPSearchPath = "dsAttrTypeStandard:CSPSearchPath"
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunkcalendarserverplatformdarwinoddsquerypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/dsquery.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/od/dsquery.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/dsquery.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -35,16 +35,19 @@
</span><span class="cx"> self.value = value
</span><span class="cx"> self.matchType = matchType
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def generate(self):
</span><span class="cx"> return {
</span><del>- dsattributes.eDSExact : "(%s=%s)",
- dsattributes.eDSStartsWith : "(%s=%s*)",
- dsattributes.eDSEndsWith : "(%s=*%s)",
- dsattributes.eDSContains : "(%s=*%s*)",
- dsattributes.eDSLessThan : "(%s<%s)",
- dsattributes.eDSGreaterThan : "(%s>%s)",
</del><ins>+ dsattributes.eDSExact: "(%s=%s)",
+ dsattributes.eDSStartsWith: "(%s=%s*)",
+ dsattributes.eDSEndsWith: "(%s=*%s)",
+ dsattributes.eDSContains: "(%s=*%s*)",
+ dsattributes.eDSLessThan: "(%s<%s)",
+ dsattributes.eDSGreaterThan : "(%s>%s)",
</ins><span class="cx"> }.get(self.matchType, "(%s=*%s*)") % (self.attribute, self.value,)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class expression(object):
</span><span class="cx"> """
</span><span class="cx"> Represents a query expression that includes a boolean operator, and a list
</span><span class="lines">@@ -53,7 +56,7 @@
</span><span class="cx"> """
</span><span class="cx">
</span><span class="cx"> AND = "&"
</span><del>- OR = "|"
</del><ins>+ OR = "|"
</ins><span class="cx"> NOT = "!"
</span><span class="cx">
</span><span class="cx"> def __init__(self, operator, subexpressions):
</span><span class="lines">@@ -61,6 +64,7 @@
</span><span class="cx"> self.operator = operator
</span><span class="cx"> self.subexpressions = subexpressions
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def generate(self):
</span><span class="cx"> result = ""
</span><span class="cx"> if self.operator == expression.NOT:
</span><span class="lines">@@ -80,7 +84,7 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> # Do some tests
</span><del>-if __name__=='__main__':
</del><ins>+if __name__ == '__main__':
</ins><span class="cx"> exprs = (
</span><span class="cx"> (expression(
</span><span class="cx"> expression.AND, (
</span><span class="lines">@@ -106,26 +110,26 @@
</span><span class="cx"> )
</span><span class="cx"> ), "(ServicesLocator=*GUID:VGUID:calendar*)"),
</span><span class="cx"> (expression(
</span><del>- expression.NOT, match(dsattributes.kDSNAttrNickName, "", dsattributes.eDSStartsWith )
</del><ins>+ expression.NOT, match(dsattributes.kDSNAttrNickName, "", dsattributes.eDSStartsWith)
</ins><span class="cx"> ), "(!(" + dsattributes.kDSNAttrNickName + "=*))"),
</span><span class="cx"> (expression(
</span><span class="cx"> expression.AND, (
</span><span class="cx"> expression(
</span><del>- expression.NOT, match(dsattributes.kDSNAttrNickName, "Billy", dsattributes.eDSContains )
</del><ins>+ expression.NOT, match(dsattributes.kDSNAttrNickName, "Billy", dsattributes.eDSContains)
</ins><span class="cx"> ),
</span><span class="cx"> expression(
</span><del>- expression.NOT, match(dsattributes.kDSNAttrEMailAddress, "Billy", dsattributes.eDSContains )
</del><ins>+ expression.NOT, match(dsattributes.kDSNAttrEMailAddress, "Billy", dsattributes.eDSContains)
</ins><span class="cx"> ),
</span><span class="cx"> ),
</span><span class="cx"> ), "(&(!(" + dsattributes.kDSNAttrNickName + "=*Billy*))(!(" + dsattributes.kDSNAttrEMailAddress + "=*Billy*)))"),
</span><span class="cx"> (expression(
</span><span class="cx"> expression.NOT, expression(
</span><span class="cx"> expression.OR, (
</span><del>- match(dsattributes.kDSNAttrNickName, "", dsattributes.eDSStartsWith ),
- match(dsattributes.kDSNAttrEMailAddress, "", dsattributes.eDSStartsWith ),
</del><ins>+ match(dsattributes.kDSNAttrNickName, "", dsattributes.eDSStartsWith),
+ match(dsattributes.kDSNAttrEMailAddress, "", dsattributes.eDSStartsWith),
</ins><span class="cx"> ),
</span><span class="cx"> ),
</span><del>- ), "(!(|("+dsattributes.kDSNAttrNickName+"=*)("+dsattributes.kDSNAttrEMailAddress+"=*)))"),
</del><ins>+ ), "(!(|(" + dsattributes.kDSNAttrNickName + "=*)(" + dsattributes.kDSNAttrEMailAddress + "=*)))"),
</ins><span class="cx"> )
</span><span class="cx">
</span><span class="cx"> for expr, result in exprs:
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverplatformdarwinododframeworkpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/odframework.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/od/odframework.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/odframework.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -5,4 +5,3 @@
</span><span class="cx"> frameworkPath=_objc.pathForFramework(
</span><span class="cx"> "/System/Library/Frameworks/OpenDirectory.framework"),
</span><span class="cx"> globals=globals())
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunkcalendarserverplatformdarwinodopendirectorypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -84,6 +84,7 @@
</span><span class="cx"> self.node = node
</span><span class="cx"> self.nodeName = nodeName
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __str__(self):
</span><span class="cx"> return "OpenDirectory node: %s" % (self.nodeName)
</span><span class="cx">
</span><span class="lines">@@ -96,6 +97,7 @@
</span><span class="cx"> # return caseInsensitiveEquivalents[matchType] if caseInsensitive else matchType
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def recordToResult(record, encodings):
</span><span class="cx"> """
</span><span class="cx"> Takes an ODRecord and turns it into a (recordName, attributesDictionary)
</span><span class="lines">@@ -132,6 +134,7 @@
</span><span class="cx"> return (details.get(dsattributes.kDSNAttrRecordName, [None])[0], result)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def attributeNamesFromList(attributes):
</span><span class="cx"> """
</span><span class="cx"> The attributes list can contain string names or tuples of the form (name,
</span><span class="lines">@@ -152,6 +155,7 @@
</span><span class="cx"> return names, encodings
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @autoPooled
</span><span class="cx"> def odInit(nodeName):
</span><span class="cx"> """
</span><span class="lines">@@ -216,6 +220,7 @@
</span><span class="cx"> raise ODNSError(error)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @autoPooled
</span><span class="cx"> def listAllRecordsWithAttributes_list(directory, recordType, attributes, count=0):
</span><span class="cx"> """
</span><span class="lines">@@ -265,6 +270,7 @@
</span><span class="cx"> raise ODNSError(error)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @autoPooled
</span><span class="cx"> def queryRecordsWithAttribute_list(directory, attr, value, matchType, casei, recordType, attributes, count=0):
</span><span class="cx"> """
</span><span class="lines">@@ -319,6 +325,7 @@
</span><span class="cx"> raise ODNSError(error)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @autoPooled
</span><span class="cx"> def queryRecordsWithAttributes_list(directory, compound, casei, recordType, attributes, count=0):
</span><span class="cx"> """
</span><span class="lines">@@ -372,6 +379,7 @@
</span><span class="cx"> raise ODNSError(error)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def getUserRecord(directory, user):
</span><span class="cx"> """
</span><span class="cx"> Look up the record for the given user within the directory's node
</span><span class="lines">@@ -404,6 +412,7 @@
</span><span class="cx"> raise ODNSError(error)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @autoPooled
</span><span class="cx"> def authenticateUserBasic(directory, nodeName, user, password):
</span><span class="cx"> """
</span><span class="lines">@@ -422,7 +431,7 @@
</span><span class="cx"> tries = NUM_TRIES
</span><span class="cx"> while tries:
</span><span class="cx">
</span><del>- log.debug("Checking basic auth for user '{user}' (tries remaining: {tries})",
</del><ins>+ log.debug("Checking basic auth for user '{user}' (tries remaining: {tries})",
</ins><span class="cx"> user=user, tries=tries)
</span><span class="cx">
</span><span class="cx"> result, error = record.verifyPassword_error_(password, None)
</span><span class="lines">@@ -448,6 +457,7 @@
</span><span class="cx"> raise ODNSError(error)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @autoPooled
</span><span class="cx"> def authenticateUserDigest(directory, nodeName, user, challenge, response, method):
</span><span class="cx"> """
</span><span class="lines">@@ -472,7 +482,7 @@
</span><span class="cx"> user=user, tries=tries)
</span><span class="cx">
</span><span class="cx"> # TODO: what are these other return values?
</span><del>- result, mystery1, mystery2, error = record.verifyExtendedWithAuthenticationType_authenticationItems_continueItems_context_error_(
</del><ins>+ result, _ignore_mystery1, _ignore_mystery2, error = record.verifyExtendedWithAuthenticationType_authenticationItems_continueItems_context_error_(
</ins><span class="cx"> DIGEST_MD5,
</span><span class="cx"> [user, challenge, response, method],
</span><span class="cx"> None, None, None
</span><span class="lines">@@ -499,6 +509,7 @@
</span><span class="cx"> raise ODNSError(error)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class ODError(Exception):
</span><span class="cx"> """
</span><span class="cx"> Exceptions from DirectoryServices errors.
</span><span class="lines">@@ -506,10 +517,12 @@
</span><span class="cx"> def __init__(self, msg, code):
</span><span class="cx"> self.message = (msg, code)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __str__(self):
</span><span class="cx"> return "<OD Error %s %d>" % (self.message[0], self.message[1])
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class ODNSError(ODError):
</span><span class="cx"> """
</span><span class="cx"> Converts an NSError.
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverplatformdarwinodsetup_directorypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/setup_directory.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/od/setup_directory.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/setup_directory.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -240,6 +240,8 @@
</span><span class="cx">
</span><span class="cx"> return records[0]
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def createRecord(node, recordType, recordName, attrs):
</span><span class="cx"> record, error = node.createRecordWithRecordType_name_attributes_error_(
</span><span class="cx"> recordType,
</span><span class="lines">@@ -251,6 +253,8 @@
</span><span class="cx"> raise ODError(error)
</span><span class="cx"> return record
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def main():
</span><span class="cx">
</span><span class="cx"> try:
</span><span class="lines">@@ -258,7 +262,7 @@
</span><span class="cx"> except GetoptError, e:
</span><span class="cx"> usage(e)
</span><span class="cx">
</span><del>- for opt, arg in optargs:
</del><ins>+ for opt, _ignore_arg in optargs:
</ins><span class="cx"> if opt in ("-h", "--help"):
</span><span class="cx"> usage()
</span><span class="cx">
</span><span class="lines">@@ -373,6 +377,8 @@
</span><span class="cx">
</span><span class="cx"> print("")
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class ODError(Exception):
</span><span class="cx"> def __init__(self, error):
</span><span class="cx"> self.message = (str(error), error.code())
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverplatformdarwinodsetup_testuserspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/setup_testusers.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/od/setup_testusers.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/setup_testusers.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def lookupRecordName(node, recordType, name):
</span><span class="cx"> query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
</span><span class="cx"> node,
</span><span class="lines">@@ -59,6 +60,8 @@
</span><span class="cx">
</span><span class="cx"> return records[0]
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def createRecord(node, recordType, recordName, attrs):
</span><span class="cx"> record, error = node.createRecordWithRecordType_name_attributes_error_(
</span><span class="cx"> recordType,
</span><span class="lines">@@ -70,6 +73,8 @@
</span><span class="cx"> raise ODError(error)
</span><span class="cx"> return record
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def main():
</span><span class="cx">
</span><span class="cx"> try:
</span><span class="lines">@@ -77,7 +82,7 @@
</span><span class="cx"> except GetoptError, e:
</span><span class="cx"> usage(e)
</span><span class="cx">
</span><del>- for opt, arg in optargs:
</del><ins>+ for opt, _ignore_arg in optargs:
</ins><span class="cx"> if opt in ("-h", "--help"):
</span><span class="cx"> usage()
</span><span class="cx">
</span><span class="lines">@@ -108,7 +113,7 @@
</span><span class="cx">
</span><span class="cx"> print("Creating users within %s:" % (nodeName,))
</span><span class="cx"> for i in xrange(99):
</span><del>- j = i+1
</del><ins>+ j = i + 1
</ins><span class="cx"> recordName = "user%02d" % (j,)
</span><span class="cx"> password = "user%02d" % (j,)
</span><span class="cx"> attrs = {
</span><span class="lines">@@ -137,6 +142,7 @@
</span><span class="cx"> print("User %s already exists" % (recordName,))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class ODError(Exception):
</span><span class="cx"> def __init__(self, error):
</span><span class="cx"> self.message = (str(error), error.code())
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverplatformdarwinodtesttest_opendirectorypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/test/test_opendirectory.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/od/test/test_opendirectory.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/test/test_opendirectory.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -48,17 +48,20 @@
</span><span class="cx"> print("Unable to import OpenDirectory framework")
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def generateNonce():
</span><span class="cx"> c = tuple([random.randrange(sys.maxint) for _ in range(3)])
</span><span class="cx"> c = '%d%d%d' % c
</span><span class="cx"> return c
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def getChallengeResponse(user, password, node, uri, method):
</span><span class="cx"> nonce = generateNonce()
</span><span class="cx">
</span><span class="cx"> ha1 = hashlib.md5("%s:%s:%s" % (user, node, password)).hexdigest()
</span><span class="cx"> ha2 = hashlib.md5("%s:%s" % (method, uri)).hexdigest()
</span><del>- response = hashlib.md5("%s:%s:%s"% (ha1, nonce, ha2)).hexdigest()
</del><ins>+ response = hashlib.md5("%s:%s:%s" % (ha1, nonce, ha2)).hexdigest()
</ins><span class="cx">
</span><span class="cx"> fields = {
</span><span class="cx"> 'username': user,
</span><span class="lines">@@ -135,7 +138,7 @@
</span><span class="cx"> count=0
</span><span class="cx"> )
</span><span class="cx"> recordNames = [x[0] for x in results]
</span><del>- for recordName, info in setup_directory.masterUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.masterUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><span class="cx">
</span><span class="cx"> def test_listAllRecordsWithAttributes_list_local(self):
</span><span class="lines">@@ -148,7 +151,7 @@
</span><span class="cx"> count=0
</span><span class="cx"> )
</span><span class="cx"> recordNames = [x[0] for x in results]
</span><del>- for recordName, info in setup_directory.localUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.localUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -333,9 +336,9 @@
</span><span class="cx"> count=0
</span><span class="cx"> )
</span><span class="cx"> recordNames = [x[0] for x in results]
</span><del>- for recordName, info in setup_directory.masterUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.masterUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><del>- for recordName, info in setup_directory.localUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.localUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><span class="cx">
</span><span class="cx"> def test_queryRecordsWithAttribute_list_lastname_begins_insensitive_match_multitype(self):
</span><span class="lines">@@ -358,9 +361,9 @@
</span><span class="cx"> count=0
</span><span class="cx"> )
</span><span class="cx"> recordNames = [x[0] for x in results]
</span><del>- for recordName, info in setup_directory.masterUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.masterUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><del>- for recordName, info in setup_directory.localUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.localUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><span class="cx">
</span><span class="cx"> def test_queryRecordsWithAttribute_list_lastname_contains_insensitive_match(self):
</span><span class="lines">@@ -378,9 +381,9 @@
</span><span class="cx"> count=0
</span><span class="cx"> )
</span><span class="cx"> recordNames = [x[0] for x in results]
</span><del>- for recordName, info in setup_directory.masterUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.masterUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><del>- for recordName, info in setup_directory.localUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.localUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><span class="cx">
</span><span class="cx"> def test_queryRecordsWithAttribute_list_lastname_contains_insensitive_match_multitype(self):
</span><span class="lines">@@ -403,9 +406,9 @@
</span><span class="cx"> count=0
</span><span class="cx"> )
</span><span class="cx"> recordNames = [x[0] for x in results]
</span><del>- for recordName, info in setup_directory.masterUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.masterUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><del>- for recordName, info in setup_directory.localUsers:
</del><ins>+ for recordName, _ignore_info in setup_directory.localUsers:
</ins><span class="cx"> self.assertTrue(recordName in recordNames)
</span><span class="cx">
</span><span class="cx"> def test_queryRecordsWithAttribute_list_email_begins_insensitive_match(self):
</span><span class="lines">@@ -451,7 +454,6 @@
</span><span class="cx"> self.assertTrue("odtestamanda" in recordNames)
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> def test_queryRecordsWithAttribute_list_guid_exact_sensitive_match_master(self):
</span><span class="cx">
</span><span class="cx"> directory = opendirectory.odInit("/Search")
</span><span class="lines">@@ -537,7 +539,6 @@
</span><span class="cx"> self.assertTrue("odtestalbert" in recordNames)
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> def test_queryRecordsWithAttribute_list_groupMembers_recordName_master(self):
</span><span class="cx">
</span><span class="cx"> directory = opendirectory.odInit("/Search")
</span><span class="lines">@@ -659,7 +660,6 @@
</span><span class="cx"> recordNames = [x[0] for x in results]
</span><span class="cx"> self.assertTrue("odtestgrouptop" in recordNames)
</span><span class="cx">
</span><del>-
</del><span class="cx"> results = opendirectory.queryRecordsWithAttribute_list(
</span><span class="cx"> directory,
</span><span class="cx"> dsattributes.kDSNAttrNestedGroups,
</span><span class="lines">@@ -856,7 +856,7 @@
</span><span class="cx"> def test_result_types(self):
</span><span class="cx"> directory = opendirectory.odInit("/Search")
</span><span class="cx"> record = opendirectory.getUserRecord(directory, "odtestbill")
</span><del>- name, data = opendirectory.recordToResult(record, {})
</del><ins>+ _ignore_name, data = opendirectory.recordToResult(record, {})
</ins><span class="cx"> for value in data.values():
</span><span class="cx"> if isinstance(value, list):
</span><span class="cx"> for item in value:
</span><span class="lines">@@ -925,7 +925,7 @@
</span><span class="cx"> ([], {}), opendirectory.attributeNamesFromList(None)
</span><span class="cx"> )
</span><span class="cx"> self.assertEquals(
</span><del>- (["a", "b"], {"b":"base64"}),
</del><ins>+ (["a", "b"], {"b": "base64"}),
</ins><span class="cx"> opendirectory.attributeNamesFromList(["a", ("b", "base64")])
</span><span class="cx"> )
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverplatformdarwinwikipy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/platform/darwin/wiki.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/platform/darwin/wiki.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/platform/darwin/wiki.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -52,6 +52,8 @@
</span><span class="cx"> else:
</span><span class="cx"> raise WebAuthError("Could not look up token: %s" % (token,))
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def accessForUserToWiki(user, wiki, host="localhost", port=4444):
</span><span class="cx"> """
</span><span class="cx"> Send a GET request to the wiki collabd service to retrieve the access level
</span><span class="lines">@@ -72,6 +74,7 @@
</span><span class="cx"> return _getPage(url, host, port)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _getPage(url, host, port):
</span><span class="cx"> """
</span><span class="cx"> Fetch the body of the given url via HTTP, connecting to the given host
</span><span class="lines">@@ -91,6 +94,8 @@
</span><span class="cx"> connect(GAIEndpoint(reactor, host, port), factory)
</span><span class="cx"> return factory.deferred
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class WebAuthError(RuntimeError):
</span><span class="cx"> """
</span><span class="cx"> Error in web auth
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverprovisiontesttest_rootpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/provision/test/test_root.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/provision/test/test_root.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/provision/test/test_root.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> def __init__(self, sacls=None):
</span><span class="cx"> self.sacls = sacls or {}
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __call__(self, username, service):
</span><span class="cx"> if service not in self.sacls:
</span><span class="cx"> return 1
</span><span class="lines">@@ -50,6 +51,8 @@
</span><span class="cx">
</span><span class="cx"> return 1
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class RootTests(TestCase):
</span><span class="cx">
</span><span class="cx"> def setUp(self):
</span><span class="lines">@@ -127,7 +130,7 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> class SACLTests(RootTests):
</span><del>-
</del><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_noSacls(self):
</span><span class="cx"> """
</span><span class="lines">@@ -141,7 +144,7 @@
</span><span class="cx"> "GET",
</span><span class="cx"> "/principals/")
</span><span class="cx">
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> self.root.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="lines">@@ -157,6 +160,7 @@
</span><span class="cx">
</span><span class="cx"> self.assertEquals(segments, [])
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_inSacls(self):
</span><span class="cx"> """
</span><span class="lines">@@ -179,7 +183,7 @@
</span><span class="cx"> })
</span><span class="cx"> )
</span><span class="cx">
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> self.root.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="lines">@@ -205,6 +209,7 @@
</span><span class="cx"> )
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_notInSacls(self):
</span><span class="cx"> """
</span><span class="lines">@@ -227,17 +232,18 @@
</span><span class="cx"> })
</span><span class="cx"> )
</span><span class="cx">
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> self.root.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="cx"> try:
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> resrc.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx"> except HTTPError, e:
</span><span class="cx"> self.assertEquals(e.response.code, 403)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_unauthenticated(self):
</span><span class="cx"> """
</span><span class="lines">@@ -254,12 +260,12 @@
</span><span class="cx"> "/principals/"
</span><span class="cx"> )
</span><span class="cx">
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> self.root.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="cx"> try:
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> resrc.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx"> raise AssertionError(
</span><span class="lines">@@ -268,6 +274,7 @@
</span><span class="cx"> except HTTPError, e:
</span><span class="cx"> self.assertEquals(e.response.code, 401)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_badCredentials(self):
</span><span class="cx"> """
</span><span class="lines">@@ -286,19 +293,18 @@
</span><span class="cx"> "Authorization": ["basic", "%s" % (
</span><span class="cx"> "dreid:dreid".encode("base64"),)]}))
</span><span class="cx">
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> self.root.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="cx"> try:
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> resrc.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx"> except HTTPError, e:
</span><span class="cx"> self.assertEquals(e.response.code, 401)
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> def test_DELETE(self):
</span><span class="cx"> def do_test(response):
</span><span class="cx"> response = IResponse(response)
</span><span class="lines">@@ -310,6 +316,7 @@
</span><span class="cx"> request = SimpleRequest(self.site, "DELETE", "/")
</span><span class="cx"> return self.send(request, do_test)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_COPY(self):
</span><span class="cx"> def do_test(response):
</span><span class="cx"> response = IResponse(response)
</span><span class="lines">@@ -322,10 +329,11 @@
</span><span class="cx"> self.site,
</span><span class="cx"> "COPY",
</span><span class="cx"> "/",
</span><del>- headers=http_headers.Headers({"Destination":"/copy/"})
</del><ins>+ headers=http_headers.Headers({"Destination": "/copy/"})
</ins><span class="cx"> )
</span><span class="cx"> return self.send(request, do_test)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_MOVE(self):
</span><span class="cx"> def do_test(response):
</span><span class="cx"> response = IResponse(response)
</span><span class="lines">@@ -338,12 +346,14 @@
</span><span class="cx"> self.site,
</span><span class="cx"> "MOVE",
</span><span class="cx"> "/",
</span><del>- headers=http_headers.Headers({"Destination":"/copy/"})
</del><ins>+ headers=http_headers.Headers({"Destination": "/copy/"})
</ins><span class="cx"> )
</span><span class="cx"> return self.send(request, do_test)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class SACLCacheTests(RootTests):
</span><del>-
</del><ins>+
</ins><span class="cx"> class StubResponseCacheResource(object):
</span><span class="cx"> def __init__(self):
</span><span class="cx"> self.cache = {}
</span><span class="lines">@@ -354,16 +364,18 @@
</span><span class="cx"> if str(request) in self.cache:
</span><span class="cx"> self.cacheHitCount += 1
</span><span class="cx"> return self.cache[str(request)]
</span><del>-
-
</del><ins>+
+
</ins><span class="cx"> def cacheResponseForRequest(self, request, response):
</span><span class="cx"> self.cache[str(request)] = response
</span><span class="cx"> return response
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setUp(self):
</span><span class="cx"> super(SACLCacheTests, self).setUp()
</span><span class="cx"> self.root.resource.responseCache = SACLCacheTests.StubResponseCacheResource()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_PROPFIND(self):
</span><span class="cx"> self.root.resource.useSacls = True
</span><span class="cx">
</span><span class="lines">@@ -383,7 +395,7 @@
</span><span class="cx"> headers=http_headers.Headers({
</span><span class="cx"> 'Authorization': ['basic', '%s' % ('dreid:dierd'.encode('base64'),)],
</span><span class="cx"> 'Content-Type': 'application/xml; charset="utf-8"',
</span><del>- 'Depth':'1',
</del><ins>+ 'Depth': '1',
</ins><span class="cx"> }),
</span><span class="cx"> content=body
</span><span class="cx"> )
</span><span class="lines">@@ -399,7 +411,7 @@
</span><span class="cx"> headers=http_headers.Headers({
</span><span class="cx"> 'Authorization': ['basic', '%s' % ('dreid:dierd'.encode('base64'),)],
</span><span class="cx"> 'Content-Type': 'application/xml; charset="utf-8"',
</span><del>- 'Depth':'1',
</del><ins>+ 'Depth': '1',
</ins><span class="cx"> }),
</span><span class="cx"> content=body
</span><span class="cx"> )
</span><span class="lines">@@ -415,8 +427,10 @@
</span><span class="cx"> d = self.send(request, gotResponse1)
</span><span class="cx"> return d
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class WikiTests(RootTests):
</span><del>-
</del><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_oneTime(self):
</span><span class="cx"> """
</span><span class="lines">@@ -426,10 +440,10 @@
</span><span class="cx">
</span><span class="cx"> request = SimpleRequest(self.site, "GET", "/principals/")
</span><span class="cx">
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> self.root.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><del>- resrc, segments = (yield maybeDeferred(
</del><ins>+ resrc, _ignore_segments = (yield maybeDeferred(
</ins><span class="cx"> resrc.locateChild, request, ["principals"]
</span><span class="cx"> ))
</span><span class="cx"> self.assertTrue(request.checkedWiki)
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverpushapplepushpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/push/applepush.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/push/applepush.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/push/applepush.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -51,9 +51,9 @@
</span><span class="cx"> """
</span><span class="cx"> Maps calendarserver.push.util.PushPriority values to APNS-specific values
</span><span class="cx"> """
</span><del>- low = ValueConstant(PushPriority.low.value)
</del><ins>+ low = ValueConstant(PushPriority.low.value)
</ins><span class="cx"> medium = ValueConstant(PushPriority.medium.value)
</span><del>- high = ValueConstant(PushPriority.high.value)
</del><ins>+ high = ValueConstant(PushPriority.high.value)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -400,26 +400,26 @@
</span><span class="cx"> # Frame struct.pack format
</span><span class="cx"> # ! Network byte order
</span><span class="cx"> command = self.COMMAND_PROVIDER # B
</span><del>- frameLength = ( # I
</del><ins>+ frameLength = (# I
</ins><span class="cx"> # Item 1 (Device token)
</span><del>- 1 + # Item number # B
- 2 + # Item length # H
</del><ins>+ 1 + # Item number # B
+ 2 + # Item length # H
</ins><span class="cx"> 32 + # device token # 32s
</span><span class="cx"> # Item 2 (Payload)
</span><del>- 1 + # Item number # B
- 2 + # Item length # H
</del><ins>+ 1 + # Item number # B
+ 2 + # Item length # H
</ins><span class="cx"> payloadLength + # the JSON payload # %d s
</span><span class="cx"> # Item 3 (Notification ID)
</span><del>- 1 + # Item number # B
- 2 + # Item length # H
- 4 + # Notification ID # I
</del><ins>+ 1 + # Item number # B
+ 2 + # Item length # H
+ 4 + # Notification ID # I
</ins><span class="cx"> # Item 4 (Expiration)
</span><del>- 1 + # Item number # B
- 2 + # Item length # H
- 4 + # Expiration seconds since epoch # I
</del><ins>+ 1 + # Item number # B
+ 2 + # Item length # H
+ 4 + # Expiration seconds since epoch # I
</ins><span class="cx"> # Item 5 (Priority)
</span><del>- 1 + # Item number # B
- 2 + # Item length # H
</del><ins>+ 1 + # Item number # B
+ 2 + # Item length # H
</ins><span class="cx"> 1 # Priority # B
</span><span class="cx"> )
</span><span class="cx">
</span><span class="lines">@@ -453,6 +453,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class APNProviderFactory(ReconnectingClientFactory):
</span><span class="cx"> log = Logger()
</span><span class="cx">
</span><span class="lines">@@ -629,7 +630,7 @@
</span><span class="cx"> """
</span><span class="cx"> for token in tokens:
</span><span class="cx"> tokenKeyPair = (token, key)
</span><del>- for existingPair, timstamp, priority in self.queue:
</del><ins>+ for existingPair, _ignore_timstamp, priority in self.queue:
</ins><span class="cx"> if tokenKeyPair == existingPair:
</span><span class="cx"> self.log.debug("APNProviderService has no connection; skipping duplicate: %s %s" % (token, key))
</span><span class="cx"> break # Already scheduled
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverpushutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/push/util.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/push/util.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/push/util.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -24,9 +24,9 @@
</span><span class="cx"> """
</span><span class="cx"> Constants to use for push priorities
</span><span class="cx"> """
</span><del>- low = ValueConstant(1)
</del><ins>+ low = ValueConstant(1)
</ins><span class="cx"> medium = ValueConstant(5)
</span><del>- high = ValueConstant(10)
</del><ins>+ high = ValueConstant(10)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertap__init__py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/__init__.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/__init__.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tap/__init__.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -26,4 +26,3 @@
</span><span class="cx"> "profiling",
</span><span class="cx"> "util"
</span><span class="cx"> ]
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunkcalendarservertapcfgchildpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/cfgchild.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/cfgchild.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tap/cfgchild.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -95,12 +95,12 @@
</span><span class="cx"> # Adjust the child's configuration to add all the relevant options for
</span><span class="cx"> # the store that won't be mentioned in the config file.
</span><span class="cx"> changedConfig = dict(
</span><del>- EnableCalDAV = True,
- EnableCardDAV = True,
- LogID = logID,
- PIDFile = pidFile,
- MultiProcess = dict(
- ProcessCount = processCount
</del><ins>+ EnableCalDAV=True,
+ EnableCardDAV=True,
+ LogID=logID,
+ PIDFile=pidFile,
+ MultiProcess=dict(
+ ProcessCount=processCount
</ins><span class="cx"> )
</span><span class="cx"> )
</span><span class="cx"> setupMemcached(self.config)
</span><span class="lines">@@ -177,16 +177,16 @@
</span><span class="cx"> # until the call to spawn (and hence spawnProcess) below; otherwise
</span><span class="cx"> # that end of the socket will be closed and there will be nothing
</span><span class="cx"> # to inherit.
</span><del>- poolskt = self.dispenser.dispense()
- poolfd = poolskt.fileno()
</del><ins>+ poolskt = self.dispenser.dispense()
+ poolfd = poolskt.fileno()
</ins><span class="cx"> childFDs = {
</span><span class="cx"> 0: "w", 1: "r", 2: "r", # behave like normal, but
</span><span class="cx"> poolfd: poolfd # bonus FD
</span><span class="cx"> }
</span><del>- extra = dict(connectionPoolFD=poolfd)
</del><ins>+ extra = dict(connectionPoolFD=poolfd)
</ins><span class="cx"> else:
</span><span class="cx"> childFDs = None
</span><del>- extra = {}
</del><ins>+ extra = {}
</ins><span class="cx"> controller = yield self.spawn(
</span><span class="cx"> AMP(), ChildConfigurator, childFDs=childFDs
</span><span class="cx"> )
</span><span class="lines">@@ -201,6 +201,3 @@
</span><span class="cx"> **extra
</span><span class="cx"> )
</span><span class="cx"> returnValue(swapAMP(controller, here))
</span><del>-
-
-
</del></span></pre></div>
<a id="CalendarServertrunkcalendarservertapprofilingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/profiling.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/profiling.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tap/profiling.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -29,7 +29,8 @@
</span><span class="cx"> Run reactor under the cProfile profiler.
</span><span class="cx"> """
</span><span class="cx"> try:
</span><del>- import cProfile, pstats
</del><ins>+ import cProfile
+ import pstats
</ins><span class="cx"> except ImportError, e:
</span><span class="cx"> self._reportImportError("cProfile", e)
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertaptesttest_caldavpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/test/test_caldav.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/test/test_caldav.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tap/test/test_caldav.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -1473,24 +1473,29 @@
</span><span class="cx"> self.assertFalse(triggerFile.exists())
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class StubStorageService(object):
</span><span class="cx">
</span><span class="cx"> def __init__(self):
</span><span class="cx"> self.hardStopCalled = False
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def hardStop(self):
</span><span class="cx"> self.hardStopCalled = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class StubReactor(object):
</span><span class="cx">
</span><span class="cx"> def __init__(self):
</span><span class="cx"> self.stopCalled = False
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def stop(self):
</span><span class="cx"> self.stopCalled = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class DataStoreMonitorTestCase(TestCase):
</span><span class="cx">
</span><span class="cx"> def test_monitor(self):
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsagentpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/agent.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/agent.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/agent.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> from twisted.application.internet import StreamServerEndpointService
</span><span class="cx"> from twisted.cred.checkers import ICredentialsChecker
</span><span class="cx"> from twisted.cred.credentials import IUsernameHashedPassword
</span><del>-from twisted.cred.error import UnauthorizedLogin
</del><ins>+from twisted.cred.error import UnauthorizedLogin
</ins><span class="cx"> from twisted.cred.portal import IRealm, Portal
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks, returnValue, succeed, fail
</span><span class="cx"> from twisted.internet.endpoints import AdoptedStreamServerEndpoint
</span><span class="lines">@@ -69,6 +69,7 @@
</span><span class="cx"> self.node = node
</span><span class="cx"> self.directory = self.directoryModule.odInit(node)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def requestAvatarId(self, credentials):
</span><span class="cx"> record = self.directoryModule.getUserRecord(self.directory, credentials.username)
</span><span class="cx">
</span><span class="lines">@@ -119,6 +120,7 @@
</span><span class="cx"> return fail(UnauthorizedLogin())
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class CustomDigestCredentialFactory(DigestCredentialFactory):
</span><span class="cx"> """
</span><span class="cx"> DigestCredentialFactory without qop, to interop with OD.
</span><span class="lines">@@ -130,6 +132,7 @@
</span><span class="cx"> return result
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class AgentRealm(object):
</span><span class="cx"> """
</span><span class="cx"> Only allow a specified list of avatar IDs to access the site
</span><span class="lines">@@ -144,6 +147,7 @@
</span><span class="cx"> self.root = root
</span><span class="cx"> self.allowedAvatarIds = allowedAvatarIds
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def requestAvatar(self, avatarId, mind, *interfaces):
</span><span class="cx"> if IResource in interfaces:
</span><span class="cx"> if avatarId in self.allowedAvatarIds:
</span><span class="lines">@@ -176,6 +180,7 @@
</span><span class="cx"> self.directory = directory
</span><span class="cx"> self.inactivityDetector = inactivityDetector
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def render_POST(self, request):
</span><span class="cx"> """
</span><span class="cx"> Take the body of the POST request and feed it to gateway.Runner();
</span><span class="lines">@@ -217,8 +222,6 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-
-
</del><span class="cx"> def makeAgentService(store):
</span><span class="cx"> """
</span><span class="cx"> Returns a service which will process GatewayAMPCommands, using a socket
</span><span class="lines">@@ -229,9 +232,9 @@
</span><span class="cx"> """
</span><span class="cx"> from twisted.internet import reactor
</span><span class="cx">
</span><del>- sockets = getLaunchDSocketFDs()
</del><ins>+ sockets = getLaunchDSocketFDs()
</ins><span class="cx"> fd = sockets["AgentSocket"][0]
</span><del>-
</del><ins>+
</ins><span class="cx"> family = socket.AF_INET
</span><span class="cx"> endpoint = AdoptedStreamServerEndpoint(reactor, fd, family)
</span><span class="cx">
</span><span class="lines">@@ -321,12 +324,13 @@
</span><span class="cx">
</span><span class="cx"> class GatewayAMPCommand(amp.Command):
</span><span class="cx"> """
</span><del>- A command to be executed by gateway.Runner
</del><ins>+ A command to be executed by gateway.Runner
</ins><span class="cx"> """
</span><span class="cx"> arguments = [('command', amp.String())]
</span><span class="cx"> response = [('result', amp.String())]
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class GatewayAMPProtocol(amp.AMP):
</span><span class="cx"> """
</span><span class="cx"> Passes commands to gateway.Runner and returns the results
</span><span class="lines">@@ -374,6 +378,7 @@
</span><span class="cx"> returnValue(dict(result=result))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class GatewayAMPFactory(Factory):
</span><span class="cx"> """
</span><span class="cx"> Builds GatewayAMPProtocols
</span><span class="lines">@@ -389,6 +394,7 @@
</span><span class="cx"> self.davRootResource = getRootResource(config, self.store)
</span><span class="cx"> self.directory = self.davRootResource.getDirectory()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def buildProtocol(self, addr):
</span><span class="cx"> return GatewayAMPProtocol(self.store, self.davRootResource,
</span><span class="cx"> self.directory)
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsampnotificationspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/ampnotifications.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/ampnotifications.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/ampnotifications.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx"> pass
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def main():
</span><span class="cx">
</span><span class="cx"> try:
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsbackup_pgpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/backup_pg.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/backup_pg.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/backup_pg.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -26,16 +26,16 @@
</span><span class="cx"> from twistedcaldav.config import config
</span><span class="cx"> from calendarserver.tools.util import loadConfig
</span><span class="cx">
</span><del>-SIPP = "/Applications/Server.app/Contents/ServerRoot"
</del><ins>+SIPP = "/Applications/Server.app/Contents/ServerRoot"
</ins><span class="cx"> if not os.path.exists(SIPP):
</span><del>- SIPP = ""
-USERNAME = "caldav"
-DATABASENAME = "caldav"
-DUMPFILENAME = "db_backup"
</del><ins>+ SIPP = ""
+USERNAME = "caldav"
+DATABASENAME = "caldav"
+DUMPFILENAME = "db_backup"
</ins><span class="cx">
</span><del>-PSQL = "%s/usr/bin/psql" % (SIPP,)
-PGDUMP = "%s/usr/bin/pg_dump" % (SIPP,)
-PGSOCKETDIR = "/var/run/caldavd/PostgresSocket"
</del><ins>+PSQL = "%s/usr/bin/psql" % (SIPP,)
+PGDUMP = "%s/usr/bin/pg_dump" % (SIPP,)
+PGSOCKETDIR = "/var/run/caldavd/PostgresSocket"
</ins><span class="cx">
</span><span class="cx"> def usage(e=None):
</span><span class="cx"> name = os.path.basename(sys.argv[0])
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def dumpData(dumpFile, verbose=False):
</span><span class="cx"> """
</span><span class="cx"> Use pg_dump to dump data to dumpFile
</span><span class="lines">@@ -90,6 +91,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def loadData(dumpFile, verbose=False):
</span><span class="cx"> """
</span><span class="cx"> Use psql to load data from dumpFile
</span><span class="lines">@@ -117,15 +119,18 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class BackupError(Exception):
</span><span class="cx"> pass
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def error(s):
</span><span class="cx"> sys.stderr.write("%s\n" % (s,))
</span><span class="cx"> sys.exit(1)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def main():
</span><span class="cx"> try:
</span><span class="cx"> (optargs, args) = getopt(
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsbootstrapdatabasepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/bootstrapdatabase.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/bootstrapdatabase.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/bootstrapdatabase.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -21,16 +21,16 @@
</span><span class="cx"> import subprocess
</span><span class="cx"> import sys
</span><span class="cx">
</span><del>-CONNECTNAME = "_postgres"
-USERNAME = "caldav"
-DATABASENAME = "caldav"
-PGSOCKETDIR = "/Library/Server/PostgreSQL For Server Services/Socket"
-SCHEMAFILE = "/Applications/Server.app/Contents/ServerRoot/usr/share/caldavd/lib/python/txdav/common/datastore/sql_schema/current.sql"
</del><ins>+CONNECTNAME = "_postgres"
+USERNAME = "caldav"
+DATABASENAME = "caldav"
+PGSOCKETDIR = "/Library/Server/PostgreSQL For Server Services/Socket"
+SCHEMAFILE = "/Applications/Server.app/Contents/ServerRoot/usr/share/caldavd/lib/python/txdav/common/datastore/sql_schema/current.sql"
</ins><span class="cx">
</span><span class="cx"> # Executables:
</span><del>-CREATEDB = "/Applications/Server.app/Contents/ServerRoot/usr/bin/createdb"
-CREATEUSER = "/Applications/Server.app/Contents/ServerRoot/usr/bin/createuser"
-PSQL = "/Applications/Server.app/Contents/ServerRoot/usr/bin/psql"
</del><ins>+CREATEDB = "/Applications/Server.app/Contents/ServerRoot/usr/bin/createdb"
+CREATEUSER = "/Applications/Server.app/Contents/ServerRoot/usr/bin/createuser"
+PSQL = "/Applications/Server.app/Contents/ServerRoot/usr/bin/psql"
</ins><span class="cx">
</span><span class="cx"> def usage(e=None):
</span><span class="cx"> name = os.path.basename(sys.argv[0])
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx"> else:
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def createUser(verbose=False):
</span><span class="cx"> """
</span><span class="cx"> Create the user which calendar server will use to access postgres.
</span><span class="lines">@@ -84,6 +86,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def createDatabase(verbose=False):
</span><span class="cx"> """
</span><span class="cx"> Create the database which calendar server will use within postgres.
</span><span class="lines">@@ -116,6 +119,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def getSchemaVersion(verbose=False):
</span><span class="cx"> """
</span><span class="cx"> Return the version number for the schema installed in the database.
</span><span class="lines">@@ -153,6 +157,8 @@
</span><span class="cx"> )
</span><span class="cx"> return version
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def installSchema(verbose=False):
</span><span class="cx"> """
</span><span class="cx"> Install the calendar server database schema.
</span><span class="lines">@@ -184,16 +190,21 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class BootstrapError(Exception):
</span><span class="cx"> pass
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def error(s):
</span><span class="cx"> sys.stderr.write("%s\n" % (s,))
</span><span class="cx"> sys.exit(1)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def main():
</span><span class="cx"> try:
</span><del>- (optargs, args) = getopt(
</del><ins>+ (optargs, _ignore_args) = getopt(
</ins><span class="cx"> sys.argv[1:], "hv", [
</span><span class="cx"> "help",
</span><span class="cx"> "verbose",
</span><span class="lines">@@ -204,7 +215,7 @@
</span><span class="cx">
</span><span class="cx"> verbose = False
</span><span class="cx">
</span><del>- for opt, arg in optargs:
</del><ins>+ for opt, _ignore_arg in optargs:
</ins><span class="cx"> if opt in ("-h", "--help"):
</span><span class="cx"> usage()
</span><span class="cx"> elif opt in ("-v", "--verbose"):
</span><span class="lines">@@ -212,7 +223,6 @@
</span><span class="cx"> else:
</span><span class="cx"> raise NotImplementedError(opt)
</span><span class="cx">
</span><del>-
</del><span class="cx"> # Create the calendar server database user within postgres
</span><span class="cx"> try:
</span><span class="cx"> newlyCreated = createUser(verbose=verbose)
</span><span class="lines">@@ -252,12 +262,12 @@
</span><span class="cx"> required_version = int(found.group(1))
</span><span class="cx"> if version == required_version:
</span><span class="cx"> print("Latest schema version (%d) is installed" % (version,))
</span><del>-
</del><ins>+
</ins><span class="cx"> elif version == 0: # No schema installed
</span><span class="cx"> installSchema(verbose=verbose)
</span><span class="cx"> version = getSchemaVersion(verbose=verbose)
</span><span class="cx"> print("Successfully installed schema version %d" % (version,))
</span><del>-
</del><ins>+
</ins><span class="cx"> else: # upgrade needed
</span><span class="cx"> error(
</span><span class="cx"> "Schema needs to be upgraded from %d to %d" %
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolscalverify_diffpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/calverify_diff.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/calverify_diff.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/calverify_diff.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def analyze(fname):
</span><del>-
</del><ins>+
</ins><span class="cx"> lines = open(os.path.expanduser(fname)).read().splitlines()
</span><span class="cx"> total = len(lines)
</span><span class="cx"> ctr = 0
</span><span class="lines">@@ -56,9 +56,11 @@
</span><span class="cx"> elif line.startswith("Attendee events mismatched in Organizer's calendar"):
</span><span class="cx"> ctr = _tableParser(ctr, "table4", parseTableMismatch)
</span><span class="cx"> ctr += 1
</span><del>-
</del><ins>+
</ins><span class="cx"> return results
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def parseTableMissing(line):
</span><span class="cx"> splits = line.split("|")
</span><span class="cx"> organizer = splits[1].strip()
</span><span class="lines">@@ -67,6 +69,8 @@
</span><span class="cx"> resid = splits[4].strip()
</span><span class="cx"> return (organizer, attendee, uid, resid,)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def parseTableMismatch(line):
</span><span class="cx"> splits = line.split("|")
</span><span class="cx"> organizer = splits[1].strip()
</span><span class="lines">@@ -76,35 +80,41 @@
</span><span class="cx"> attendee_resid = splits[7].strip()
</span><span class="cx"> return (organizer, attendee, uid, organizer_resid, attendee_resid,)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def diff(results1, results2):
</span><del>-
</del><ins>+
</ins><span class="cx"> print("\n\nEvents missing from Attendee's calendars")
</span><span class="cx"> diffSets(results1["table1"], results2["table1"])
</span><del>-
</del><ins>+
</ins><span class="cx"> print("\n\nEvents mismatched between Organizer's and Attendee's calendars")
</span><span class="cx"> diffSets(results1["table2"], results2["table2"])
</span><del>-
</del><ins>+
</ins><span class="cx"> print("\n\nAttendee events missing in Organizer's calendar")
</span><span class="cx"> diffSets(results1["table3"], results2["table3"])
</span><del>-
</del><ins>+
</ins><span class="cx"> print("\n\nAttendee events mismatched in Organizer's calendar")
</span><span class="cx"> diffSets(results1["table4"], results2["table4"])
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def diffSets(results1, results2):
</span><del>-
</del><ins>+
</ins><span class="cx"> s1 = set(results1)
</span><span class="cx"> s2 = set(results2)
</span><del>-
</del><ins>+
</ins><span class="cx"> d = s1 - s2
</span><span class="cx"> print("\nIn first, not in second: (%d)" % (len(d),))
</span><span class="cx"> for i in sorted(d):
</span><span class="cx"> print(i)
</span><del>-
</del><ins>+
</ins><span class="cx"> d = s2 - s1
</span><span class="cx"> print("\nIn second, not in first: (%d)" % (len(d),))
</span><span class="cx"> for i in sorted(d):
</span><span class="cx"> print(i)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def usage(error_msg=None):
</span><span class="cx"> if error_msg:
</span><span class="cx"> print(error_msg)
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolschangeip_calendarpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/changeip_calendar.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/changeip_calendar.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/changeip_calendar.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> print(" new-hostname - new FQDN for the server")
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def main():
</span><span class="cx">
</span><span class="cx"> name = os.path.basename(sys.argv[0])
</span><span class="lines">@@ -93,6 +94,8 @@
</span><span class="cx"> if verbose:
</span><span class="cx"> print("Calendar Server: done")
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def updatePlist(plist, oldIP, newIP, oldHostname, newHostname, verbose=False):
</span><span class="cx">
</span><span class="cx"> keys = (
</span><span class="lines">@@ -118,13 +121,13 @@
</span><span class="cx"> key = keyPath[-1]
</span><span class="cx">
</span><span class="cx"> for step in path:
</span><del>- if not parent.has_key(step):
</del><ins>+ if step not in parent:
</ins><span class="cx"> parent = None
</span><span class="cx"> break
</span><span class="cx"> parent = parent[step]
</span><span class="cx">
</span><span class="cx"> if parent:
</span><del>- if parent.has_key(key):
</del><ins>+ if key in parent:
</ins><span class="cx"> value = parent[key]
</span><span class="cx">
</span><span class="cx"> if isinstance(value, list):
</span><span class="lines">@@ -141,8 +144,5 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-
-
-
</del><span class="cx"> if __name__ == '__main__':
</span><span class="cx"> main()
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsconfigpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/config.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/config.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/config.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -94,6 +94,8 @@
</span><span class="cx"> else:
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def main():
</span><span class="cx"> try:
</span><span class="cx"> (optargs, args) = getopt(
</span><span class="lines">@@ -140,6 +142,7 @@
</span><span class="cx"> processArgs(writable, args)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def processArgs(writable, args, restart=True):
</span><span class="cx"> """
</span><span class="cx"> Perform the read/write operations requested in the command line args.
</span><span class="lines">@@ -159,7 +162,7 @@
</span><span class="cx"> # This is an assignment
</span><span class="cx"> configKey, stringValue = configKey.split("=")
</span><span class="cx"> value = writable.convertToValue(stringValue)
</span><del>- writable.set({configKey:value})
</del><ins>+ writable.set({configKey: value})
</ins><span class="cx"> else:
</span><span class="cx"> # This is a read
</span><span class="cx"> c = config
</span><span class="lines">@@ -208,6 +211,7 @@
</span><span class="cx"> """
</span><span class="cx"> self.commands = commands
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def validate(self):
</span><span class="cx"> """
</span><span class="cx"> Validate all the commands by making sure this class implements
</span><span class="lines">@@ -226,6 +230,7 @@
</span><span class="cx"> return False
</span><span class="cx"> return True
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def run(self):
</span><span class="cx"> """
</span><span class="cx"> Find the appropriate method for each command and call them.
</span><span class="lines">@@ -243,6 +248,7 @@
</span><span class="cx"> respondWithError("Command failed: '%s'" % (str(e),))
</span><span class="cx"> raise
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def command_readConfig(self, command):
</span><span class="cx"> """
</span><span class="cx"> Return current configuration
</span><span class="lines">@@ -261,6 +267,7 @@
</span><span class="cx"> setKeyPath(result, keyPath, value)
</span><span class="cx"> respond(command, result)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def command_writeConfig(self, command):
</span><span class="cx"> """
</span><span class="cx"> Write config to secondary, writable plist
</span><span class="lines">@@ -284,6 +291,7 @@
</span><span class="cx"> self.command_readConfig(command)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setKeyPath(parent, keyPath, value):
</span><span class="cx"> """
</span><span class="cx"> Allows the setting of arbitrary nested dictionary keys via a single
</span><span class="lines">@@ -311,6 +319,8 @@
</span><span class="cx"> parent[parts[-1]] = value
</span><span class="cx"> return original
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def getKeyPath(parent, keyPath):
</span><span class="cx"> """
</span><span class="cx"> Allows the getting of arbitrary nested dictionary keys via a single
</span><span class="lines">@@ -333,6 +343,8 @@
</span><span class="cx"> parent = child
</span><span class="cx"> return parent.get(parts[-1], None)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def flattenDictionary(dictionary, current=""):
</span><span class="cx"> """
</span><span class="cx"> Returns a generator of (keyPath, value) tuples for the given dictionary,
</span><span class="lines">@@ -353,6 +365,7 @@
</span><span class="cx"> yield (current + key, value)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def restartService(pidFilename):
</span><span class="cx"> """
</span><span class="cx"> Given the path to a PID file, sends a HUP signal to the contained pid
</span><span class="lines">@@ -375,6 +388,7 @@
</span><span class="cx"> pass
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WritableConfig(object):
</span><span class="cx"> """
</span><span class="cx"> A wrapper around a Config object which allows writing of values. The idea
</span><span class="lines">@@ -396,6 +410,7 @@
</span><span class="cx"> self.currentConfigSubset = ConfigDict()
</span><span class="cx"> self.dirty = False
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def set(self, data):
</span><span class="cx"> """
</span><span class="cx"> Merges data into a ConfigDict of changes intended to be saved to disk
</span><span class="lines">@@ -409,6 +424,7 @@
</span><span class="cx"> mergeData(self.currentConfigSubset, data)
</span><span class="cx"> self.dirty = True
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def read(self):
</span><span class="cx"> """
</span><span class="cx"> Reads in the data contained in the writable plist file.
</span><span class="lines">@@ -420,9 +436,11 @@
</span><span class="cx"> else:
</span><span class="cx"> self.currentConfigSubset = ConfigDict()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def toString(self):
</span><span class="cx"> return plistlib.writePlistToString(self.currentConfigSubset)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def save(self, restart=False):
</span><span class="cx"> """
</span><span class="cx"> Writes any outstanding changes to the writable plist file. Optionally
</span><span class="lines">@@ -437,6 +455,7 @@
</span><span class="cx"> if restart:
</span><span class="cx"> restartService(self.config.PIDFile)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @classmethod
</span><span class="cx"> def convertToValue(cls, string):
</span><span class="cx"> """
</span><span class="lines">@@ -461,8 +480,11 @@
</span><span class="cx"> return value
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def respond(command, result):
</span><span class="cx"> sys.stdout.write(writePlistToString({'command' : command['command'], 'result' : result}))
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def respondWithError(msg, status=1):
</span><span class="cx"> sys.stdout.write(writePlistToString({'error' : msg, }))
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsicalsplitpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/icalsplit.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/icalsplit.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/icalsplit.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -63,6 +63,7 @@
</span><span class="cx"> subcalendar_file.close()
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def usage(e=None):
</span><span class="cx"> if e:
</span><span class="cx"> print(e)
</span><span class="lines">@@ -85,6 +86,7 @@
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def main():
</span><span class="cx"> try:
</span><span class="cx"> (optargs, args) = getopt(
</span><span class="lines">@@ -95,7 +97,7 @@
</span><span class="cx"> except GetoptError, e:
</span><span class="cx"> usage(e)
</span><span class="cx">
</span><del>- for opt, arg in optargs:
</del><ins>+ for opt, _ignore_arg in optargs:
</ins><span class="cx"> if opt in ("-h", "--help"):
</span><span class="cx"> usage()
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsmanagepostgrespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/managepostgres.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/managepostgres.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/managepostgres.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -26,15 +26,19 @@
</span><span class="cx"> print(s)
</span><span class="cx"> sys.exit(1)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def cmd(s):
</span><span class="cx"> print(s)
</span><span class="cx"> subprocess.call(s, shell=True)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def doInit(basedir):
</span><del>-
</del><ins>+
</ins><span class="cx"> cmd("mkdir %s/data" % (basedir,))
</span><span class="cx"> cmd("%s/bin/initdb -D %s/data" % (basedir, basedir,))
</span><del>-
</del><ins>+
</ins><span class="cx"> # Have the DB listen on all interfaces
</span><span class="cx"> with open("%s/data/postgresql.conf" % (basedir,)) as f:
</span><span class="cx"> conf = f.read()
</span><span class="lines">@@ -42,7 +46,7 @@
</span><span class="cx"> conf = conf.replace("max_connections = 20 ", "max_connections = 500")
</span><span class="cx"> with open("%s/data/postgresql.conf" % (basedir,), "w") as f:
</span><span class="cx"> f.write(conf)
</span><del>-
</del><ins>+
</ins><span class="cx"> # Allow current user to auth to the DBs
</span><span class="cx"> with open("%s/data/pg_hba.conf" % (basedir,)) as f:
</span><span class="cx"> conf = f.read()
</span><span class="lines">@@ -56,22 +60,32 @@
</span><span class="cx"> cmd("%s/bin/createdb augments" % (basedir,))
</span><span class="cx"> cmd("%s/bin/pg_ctl -D %s/data -l logfile stop" % (basedir, basedir,))
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def doStart(basedir):
</span><del>-
</del><ins>+
</ins><span class="cx"> cmd("%s/bin/pg_ctl -D %s/data -l logfile start" % (basedir, basedir,))
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def doStop(basedir):
</span><del>-
</del><ins>+
</ins><span class="cx"> cmd("%s/bin/pg_ctl -D %s/data -l logfile stop" % (basedir, basedir,))
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def doRun(basedir, verbose):
</span><del>-
- cmd("%s/bin/postgres %s -D %s/data" % (basedir, "-d 3" if verbose else "", basedir,))
</del><span class="cx">
</span><ins>+ cmd("%s/bin/postgres %s -D %s/data" % (basedir, "-d 3" if verbose else "", basedir,))
+
+
+
</ins><span class="cx"> def doClean(basedir):
</span><del>-
</del><ins>+
</ins><span class="cx"> cmd("rm -rf %s/data" % (basedir,))
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def main():
</span><span class="cx">
</span><span class="cx"> usage = "%prog [options] ACTION"
</span><span class="lines">@@ -83,13 +97,13 @@
</span><span class="cx"> stop: stop postgres daemon
</span><span class="cx"> run: run postgres (non-daemon)
</span><span class="cx"> clean: remove databases
</span><del>-
</del><ins>+
</ins><span class="cx"> """
</span><span class="cx"> description = "Tool to manage PostgreSQL"
</span><span class="cx"> version = "%prog v1.0"
</span><span class="cx"> parser = OptionParser(usage=usage, description=description, version=version)
</span><span class="cx"> parser.epilog = epilog
</span><del>- parser.format_epilog = lambda _:epilog
</del><ins>+ parser.format_epilog = lambda _: epilog
</ins><span class="cx">
</span><span class="cx"> parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
</span><span class="cx"> default=True, help="Use debug logging for PostgreSQL")
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsmigratepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/migrate.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/migrate.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/migrate.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -54,6 +54,8 @@
</span><span class="cx"> else:
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def main():
</span><span class="cx"> try:
</span><span class="cx"> (optargs, args) = getopt(
</span><span class="lines">@@ -67,7 +69,6 @@
</span><span class="cx">
</span><span class="cx"> configFileName = None
</span><span class="cx">
</span><del>-
</del><span class="cx"> for opt, arg in optargs:
</span><span class="cx"> if opt in ("-h", "--help"):
</span><span class="cx"> usage()
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsnotificationspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/notifications.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/notifications.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/notifications.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def main():
</span><span class="cx"> try:
</span><span class="cx"> (optargs, args) = getopt(
</span><span class="lines">@@ -192,18 +193,21 @@
</span><span class="cx"> if sigint:
</span><span class="cx"> signal.signal(signal.SIGINT, self.sigint_handler)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def sigint_handler(self, num, frame):
</span><span class="cx"> print(" Shutting down...")
</span><span class="cx"> yield self.unsubscribeAll()
</span><span class="cx"> reactor.stop()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def unsubscribeAll(self):
</span><span class="cx"> if self.xmlStream is not None:
</span><del>- for node, (url, name, kind) in self.nodes.iteritems():
</del><ins>+ for node, (_ignore_url, name, kind) in self.nodes.iteritems():
</ins><span class="cx"> yield self.unsubscribe(node, name, kind)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def connected(self, xmlStream):
</span><span class="cx"> self.xmlStream = xmlStream
</span><span class="cx"> if self.verbose:
</span><span class="lines">@@ -213,6 +217,7 @@
</span><span class="cx"> xmlStream.addObserver("/message/event/items",
</span><span class="cx"> self.handleMessageEventItems)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def disconnected(self, xmlStream):
</span><span class="cx"> self.xmlStream = None
</span><span class="cx"> if self.presenceCall is not None:
</span><span class="lines">@@ -221,25 +226,29 @@
</span><span class="cx"> if self.verbose:
</span><span class="cx"> print("XMPP disconnected")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def initFailed(self, failure):
</span><span class="cx"> self.xmlStream = None
</span><span class="cx"> print("XMPP connection failure: %s" % (failure,))
</span><span class="cx"> reactor.stop()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def authenticated(self, xmlStream):
</span><span class="cx"> if self.verbose:
</span><span class="cx"> print("XMPP authentication successful")
</span><span class="cx"> self.sendPresence()
</span><del>- for node, (url, name, kind) in self.nodes.iteritems():
</del><ins>+ for node, (_ignore_url, name, kind) in self.nodes.iteritems():
</ins><span class="cx"> yield self.subscribe(node, name, kind)
</span><span class="cx">
</span><span class="cx"> print("Awaiting notifications (hit Control-C to end)")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def authFailed(self, e):
</span><span class="cx"> print("XMPP authentication failed")
</span><span class="cx"> reactor.stop()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def sendPresence(self):
</span><span class="cx"> if self.doKeepAlive and self.xmlStream is not None:
</span><span class="cx"> presence = domish.Element(('jabber:client', 'presence'))
</span><span class="lines">@@ -247,6 +256,7 @@
</span><span class="cx"> self.presenceCall = reactor.callLater(self.presenceSeconds,
</span><span class="cx"> self.sendPresence)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def handleMessageEventItems(self, iq):
</span><span class="cx"> item = iq.firstChildElement().firstChildElement()
</span><span class="cx"> if item:
</span><span class="lines">@@ -277,6 +287,7 @@
</span><span class="cx"> except Exception, e:
</span><span class="cx"> print("Subscription failure: %s %s" % (node, e))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def unsubscribe(self, node, name, kind):
</span><span class="cx"> iq = IQ(self.xmlStream)
</span><span class="lines">@@ -310,14 +321,17 @@
</span><span class="cx"> def rawDataIn(self, buf):
</span><span class="cx"> print("RECV: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace'))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def rawDataOut(self, buf):
</span><span class="cx"> print("SEND: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace'))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class PropfindRequestor(AuthorizedHTTPGetter):
</span><span class="cx"> handleStatus_207 = lambda self: self.handleStatus_200
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class PushMonitorService(Service):
</span><span class="cx"> """
</span><span class="cx"> A service which uses CalDAV to determine which pubsub node(s) correspond
</span><span class="lines">@@ -337,10 +351,11 @@
</span><span class="cx"> self.password = password
</span><span class="cx"> self.verbose = verbose
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def startService(self):
</span><span class="cx"> try:
</span><del>- subscribeNodes = { }
</del><ins>+ subscribeNodes = {}
</ins><span class="cx"> if self.nodes is None:
</span><span class="cx"> paths = set()
</span><span class="cx"> principal = "/principals/users/%s/" % (self.username,)
</span><span class="lines">@@ -379,6 +394,7 @@
</span><span class="cx"> print("Error:", e)
</span><span class="cx"> reactor.stop()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def getPrincipalDetails(self, path, includeCardDAV=True):
</span><span class="cx"> """
</span><span class="lines">@@ -443,8 +459,9 @@
</span><span class="cx"> print("Unable to look up principal details", e)
</span><span class="cx"> raise
</span><span class="cx">
</span><del>- returnValue( (name, homes) )
</del><ins>+ returnValue((name, homes))
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def getProxyFor(self):
</span><span class="cx"> """
</span><span class="lines">@@ -576,7 +593,7 @@
</span><span class="cx"> host = xmppServer
</span><span class="cx"> port = 5222
</span><span class="cx">
</span><del>- if key and not nodes.has_key(key):
</del><ins>+ if key and key not in nodes:
</ins><span class="cx"> nodes[key] = (href.text, name, kind)
</span><span class="cx">
</span><span class="cx"> except Exception, e:
</span><span class="lines">@@ -593,7 +610,7 @@
</span><span class="cx"> if port is None:
</span><span class="cx"> raise Exception("Unable to determine xmpp server port")
</span><span class="cx">
</span><del>- returnValue( (host, port, nodes) )
</del><ins>+ returnValue((host, port, nodes))
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> def startMonitoring(self, host, port, nodes):
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsprincipalspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/principals.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/principals.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/principals.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -719,6 +719,7 @@
</span><span class="cx"> print("No auto-accept-group assigned to %s" % (prettyPrincipal(principal),))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def action_setValue(rootResource, directory, store, principal, name, value):
</span><span class="cx"> print("Setting %s to %s for %s" % (
</span><span class="lines">@@ -735,6 +736,7 @@
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def action_getValue(rootResource, directory, store, principal, name):
</span><span class="cx"> print("%s for %s is %s" % (
</span><span class="cx"> name,
</span><span class="lines">@@ -743,6 +745,7 @@
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def abort(msg, status=1):
</span><span class="cx"> sys.stdout.write("%s\n" % (msg,))
</span><span class="cx"> try:
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsresourcespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/resources.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/resources.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/resources.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -62,6 +62,8 @@
</span><span class="cx">
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def abort(msg, status=1):
</span><span class="cx"> sys.stdout.write("%s\n" % (msg,))
</span><span class="cx"> try:
</span><span class="lines">@@ -70,9 +72,11 @@
</span><span class="cx"> pass
</span><span class="cx"> sys.exit(status)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def main():
</span><span class="cx"> try:
</span><del>- (optargs, args) = getopt(
</del><ins>+ (optargs, _ignore_args) = getopt(
</ins><span class="cx"> sys.argv[1:], "hf:v", [
</span><span class="cx"> "help",
</span><span class="cx"> "config=",
</span><span class="lines">@@ -175,6 +179,7 @@
</span><span class="cx"> reactor.stop()
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def queryForType(sourceService, recordType, verbose=False):
</span><span class="cx"> """
</span><span class="cx"> Queries OD for all records of the specified record type
</span><span class="lines">@@ -200,6 +205,7 @@
</span><span class="cx"> return results
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def migrateResources(sourceService, destService, autoSchedules=None,
</span><span class="cx"> queryMethod=queryForType, verbose=False):
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsshellcmdpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/shell/cmd.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/shell/cmd.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/shell/cmd.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -772,7 +772,7 @@
</span><span class="cx">
</span><span class="cx"> class Handler(object):
</span><span class="cx">
</span><del>- def addOutput(innerSelf, bytes, async=False):
</del><ins>+ def addOutput(innerSelf, bytes, async=False): #@NoSelf
</ins><span class="cx"> """
</span><span class="cx"> This is a delegate method, called by ManholeInterpreter.
</span><span class="cx"> """
</span><span class="lines">@@ -867,5 +867,5 @@
</span><span class="cx"> """
</span><span class="cx"> self.terminal.write("Nothing happens.")
</span><span class="cx"> self.terminal.nextLine()
</span><del>-
</del><ins>+
</ins><span class="cx"> cmd_sql.hidden = ""
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsshellterminalpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/shell/terminal.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/shell/terminal.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/shell/terminal.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -72,6 +72,7 @@
</span><span class="cx"> sys.exit(0)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class ShellOptions(Options):
</span><span class="cx"> """
</span><span class="cx"> Command line options for "calendarserver_shell".
</span><span class="lines">@@ -181,6 +182,7 @@
</span><span class="cx"> self.activeCommand = None
</span><span class="cx"> self.emulate = "emacs"
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def reloadCommands(self):
</span><span class="cx"> # FIXME: doesn't work for alternative Commands classes passed
</span><span class="cx"> # to __init__.
</span><span class="lines">@@ -190,6 +192,7 @@
</span><span class="cx"> reload(calendarserver.tools.shell.cmd)
</span><span class="cx"> self.commands = calendarserver.tools.shell.cmd.Commands(self)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> #
</span><span class="cx"> # Input handling
</span><span class="cx"> #
</span><span class="lines">@@ -201,7 +204,7 @@
</span><span class="cx"> self.keyHandlers['\x04'] = self.handle_EOF # Control-D
</span><span class="cx"> self.keyHandlers['\x1c'] = self.handle_QUIT # Control-\
</span><span class="cx"> self.keyHandlers['\x0c'] = self.handle_FF # Control-L
</span><del>- #self.keyHandlers['\t' ] = self.handle_TAB # Tab
</del><ins>+ #self.keyHandlers['\t' ] = self.handle_TAB # Tab
</ins><span class="cx">
</span><span class="cx"> if self.emulate == "emacs":
</span><span class="cx"> # EMACS key bindinds
</span><span class="lines">@@ -224,9 +227,11 @@
</span><span class="cx">
</span><span class="cx"> log.startLoggingWithObserver(observer)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def handle_INT(self):
</span><span class="cx"> return self.resetInputLine()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def handle_EOF(self):
</span><span class="cx"> if self.lineBuffer:
</span><span class="cx"> if self.emulate == "emacs":
</span><span class="lines">@@ -236,6 +241,7 @@
</span><span class="cx"> else:
</span><span class="cx"> self.handle_QUIT()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def handle_FF(self):
</span><span class="cx"> """
</span><span class="cx"> Handle a "form feed" byte - generally used to request a screen
</span><span class="lines">@@ -244,12 +250,15 @@
</span><span class="cx"> # FIXME: Clear screen != redraw screen.
</span><span class="cx"> return self.clearScreen()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def handle_QUIT(self):
</span><span class="cx"> return self.exit()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def handle_TAB(self):
</span><span class="cx"> return self.completeLine()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> #
</span><span class="cx"> # Utilities
</span><span class="cx"> #
</span><span class="lines">@@ -262,6 +271,7 @@
</span><span class="cx"> self.terminal.cursorHome()
</span><span class="cx"> self.drawInputLine()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def resetInputLine(self):
</span><span class="cx"> """
</span><span class="cx"> Reset the current input variables to their initial state.
</span><span class="lines">@@ -272,6 +282,7 @@
</span><span class="cx"> self.terminal.nextLine()
</span><span class="cx"> self.drawInputLine()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def completeLine(self):
</span><span class="cx"> """
</span><span class="lines">@@ -318,6 +329,7 @@
</span><span class="cx"> self.terminal.write("%s%s\n" % (word, completion))
</span><span class="cx"> self.drawInputLine()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def exit(self):
</span><span class="cx"> """
</span><span class="cx"> Exit.
</span><span class="lines">@@ -325,6 +337,7 @@
</span><span class="cx"> self.terminal.loseConnection()
</span><span class="cx"> self.service.reactor.stop()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def handleFailure(self, f):
</span><span class="cx"> """
</span><span class="cx"> Handle a failure raises in the interpreter by printing a
</span><span class="lines">@@ -337,6 +350,7 @@
</span><span class="cx"> log.info(f.getTraceback())
</span><span class="cx"> self.resetInputLine()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> #
</span><span class="cx"> # Command dispatch
</span><span class="cx"> #
</span><span class="lines">@@ -386,6 +400,7 @@
</span><span class="cx"> else:
</span><span class="cx"> self.drawInputLine()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @staticmethod
</span><span class="cx"> def tokenize(line):
</span><span class="cx"> """
</span><span class="lines">@@ -405,6 +420,7 @@
</span><span class="cx"> return tokens
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def main(argv=sys.argv, stderr=sys.stderr, reactor=None):
</span><span class="cx"> if reactor is None:
</span><span class="cx"> from twisted.internet import reactor
</span><span class="lines">@@ -415,6 +431,7 @@
</span><span class="cx"> except UsageError, e:
</span><span class="cx"> usage(e)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def makeService(store):
</span><span class="cx"> from twistedcaldav.config import config
</span><span class="cx"> directory = getDirectory()
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsshelltesttest_cmdpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/shell/test/test_cmd.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/shell/test/test_cmd.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/shell/test/test_cmd.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -15,7 +15,7 @@
</span><span class="cx"> # limitations under the License.
</span><span class="cx"> ##
</span><span class="cx">
</span><del>-import twisted.trial.unittest
</del><ins>+import twisted.trial.unittest
</ins><span class="cx"> from twisted.internet.defer import inlineCallbacks
</span><span class="cx">
</span><span class="cx"> from txdav.common.icommondatastore import NotFoundError
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> self.protocol = ShellProtocol(None, commandsClass=CommandsBase)
</span><span class="cx"> self.commands = self.protocol.commands
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_getTargetNone(self):
</span><span class="cx"> target = (yield self.commands.getTarget([], wdFallback=True))
</span><span class="lines">@@ -37,21 +38,25 @@
</span><span class="cx"> target = (yield self.commands.getTarget([]))
</span><span class="cx"> self.assertEquals(target, None)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_getTargetMissing(self):
</span><span class="cx"> self.assertFailure(self.commands.getTarget(["/foo"]), NotFoundError)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_getTargetOne(self):
</span><span class="cx"> target = (yield self.commands.getTarget(["users"]))
</span><span class="cx"> match = (yield self.commands.wd.locate(["users"]))
</span><span class="cx"> self.assertEquals(target, match)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_getTargetSome(self):
</span><span class="cx"> target = (yield self.commands.getTarget(["users", "blah"]))
</span><span class="cx"> match = (yield self.commands.wd.locate(["users"]))
</span><span class="cx"> self.assertEquals(target, match)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_commandsNone(self):
</span><span class="cx"> allCommands = self.commands.commands()
</span><span class="cx"> self.assertEquals(sorted(allCommands), [])
</span><span class="lines">@@ -59,6 +64,7 @@
</span><span class="cx"> allCommands = self.commands.commands(showHidden=True)
</span><span class="cx"> self.assertEquals(sorted(allCommands), [])
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_commandsSome(self):
</span><span class="cx"> protocol = ShellProtocol(None, commandsClass=SomeCommands)
</span><span class="cx"> commands = protocol.commands
</span><span class="lines">@@ -84,6 +90,7 @@
</span><span class="cx"> ]
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_complete(self):
</span><span class="cx"> items = (
</span><span class="cx"> "foo",
</span><span class="lines">@@ -96,15 +103,16 @@
</span><span class="cx"> def c(word):
</span><span class="cx"> return sorted(CommandsBase.complete(word, items))
</span><span class="cx">
</span><del>- self.assertEquals(c("" ), sorted(items))
- self.assertEquals(c("f" ), ["oo", "oobar"])
- self.assertEquals(c("foo" ), ["", "bar"])
- self.assertEquals(c("foobar" ), [""])
</del><ins>+ self.assertEquals(c(""), sorted(items))
+ self.assertEquals(c("f"), ["oo", "oobar"])
+ self.assertEquals(c("foo"), ["", "bar"])
+ self.assertEquals(c("foobar"), [""])
</ins><span class="cx"> self.assertEquals(c("foobars"), [])
</span><del>- self.assertEquals(c("baz" ), [""])
- self.assertEquals(c("q" ), ["uux"])
- self.assertEquals(c("xyzzy" ), [])
</del><ins>+ self.assertEquals(c("baz"), [""])
+ self.assertEquals(c("q"), ["uux"])
+ self.assertEquals(c("xyzzy"), [])
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_completeCommands(self):
</span><span class="cx"> protocol = ShellProtocol(None, commandsClass=SomeCommands)
</span><span class="cx"> commands = protocol.commands
</span><span class="lines">@@ -112,11 +120,12 @@
</span><span class="cx"> def c(word):
</span><span class="cx"> return sorted(commands.complete_commands(word))
</span><span class="cx">
</span><del>- self.assertEquals(c("" ), ["a", "b"])
</del><ins>+ self.assertEquals(c(""), ["a", "b"])
</ins><span class="cx"> self.assertEquals(c("a"), [""])
</span><span class="cx"> self.assertEquals(c("h"), ["idden"])
</span><span class="cx"> self.assertEquals(c("f"), [])
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def _test_completeFiles(self, tests):
</span><span class="cx"> protocol = ShellProtocol(None, commandsClass=SomeCommands)
</span><span class="lines">@@ -147,6 +156,7 @@
</span><span class="cx"> self.assertEquals((yield c(word)), completions, "Completing %r" % (word,))
</span><span class="cx"> self.assertEquals((yield d(word)), completions, "Completing %r" % (word,))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_completeFilesLevelOne(self):
</span><span class="cx"> return self._test_completeFiles((
</span><span class="cx"> (None , ["groups/", "locations/", "resources/", "uids/", "users/"]),
</span><span class="lines">@@ -157,6 +167,7 @@
</span><span class="cx"> ("groups", ["/"]),
</span><span class="cx"> ))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_completeFilesLevelOneSlash(self):
</span><span class="cx"> return self._test_completeFiles((
</span><span class="cx"> ("/" , ["groups/", "locations/", "resources/", "uids/", "users/"]),
</span><span class="lines">@@ -166,6 +177,7 @@
</span><span class="cx"> ("/groups", ["/"]),
</span><span class="cx"> ))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_completeFilesDirectory(self):
</span><span class="cx"> return self._test_completeFiles((
</span><span class="cx"> ("users/" , ["wsanchez", "admin"]), # FIXME: Look up users
</span><span class="lines">@@ -181,11 +193,17 @@
</span><span class="cx"> test_completeFilesLevelTwo.todo = "Doesn't work yet"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class SomeCommands(CommandsBase):
</span><span class="cx"> def cmd_a(self, tokens):
</span><span class="cx"> pass
</span><ins>+
+
</ins><span class="cx"> def cmd_b(self, tokens):
</span><span class="cx"> pass
</span><ins>+
+
</ins><span class="cx"> def cmd_hidden(self, tokens):
</span><span class="cx"> pass
</span><ins>+
</ins><span class="cx"> cmd_hidden.hidden = "Hidden"
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolsshellvfspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/shell/vfs.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/shell/vfs.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/shell/vfs.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -481,7 +481,7 @@
</span><span class="cx"> self._didInitChildren = True
</span><span class="cx">
</span><span class="cx">
</span><del>- def _needsChildren(m):
</del><ins>+ def _needsChildren(m): #@NoSelf
</ins><span class="cx"> def decorate(self, *args, **kwargs):
</span><span class="cx"> d = self._initChildren()
</span><span class="cx"> d.addCallback(lambda _: m(self, *args, **kwargs))
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolstablespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/tables.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/tables.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/tables.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -31,28 +31,29 @@
</span><span class="cx"> class Table(object):
</span><span class="cx"> """
</span><span class="cx"> Class that allows pretty printing ascii tables.
</span><del>-
</del><ins>+
</ins><span class="cx"> The table supports multiline headers and footers, independent
</span><del>- column formatting by row, alternative tab-delimited output.
</del><ins>+ column formatting by row, alternative tab-delimited output.
</ins><span class="cx"> """
</span><del>-
</del><ins>+
</ins><span class="cx"> class ColumnFormat(object):
</span><span class="cx"> """
</span><span class="cx"> Defines the format string, justification and span for a column.
</span><span class="cx"> """
</span><del>-
</del><ins>+
</ins><span class="cx"> LEFT_JUSTIFY = 0
</span><span class="cx"> RIGHT_JUSTIFY = 1
</span><span class="cx"> CENTER_JUSTIFY = 2
</span><span class="cx">
</span><span class="cx"> def __init__(self, strFormat="%s", justify=LEFT_JUSTIFY, span=1):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.format = strFormat
</span><span class="cx"> self.justify = justify
</span><span class="cx"> self.span = span
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, table=None):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.headers = []
</span><span class="cx"> self.headerColumnFormats = []
</span><span class="cx"> self.rows = []
</span><span class="lines">@@ -65,71 +66,83 @@
</span><span class="cx"> if table:
</span><span class="cx"> self.setData(table)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setData(self, table):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.hasTitles = True
</span><span class="cx"> self.headers.append(table[0])
</span><span class="cx"> self.rows = table[1:]
</span><span class="cx"> self._getMaxColumnCount()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setDefaultColumnFormats(self, columnFormats):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.defaultColumnFormats = columnFormats
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def addDefaultColumnFormat(self, columnFormat):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.defaultColumnFormats.append(columnFormat)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setHeaders(self, rows, columnFormats=None):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.headers = rows
</span><del>- self.headerColumnFormats = columnFormats if columnFormats else [None,] * len(self.headers)
</del><ins>+ self.headerColumnFormats = columnFormats if columnFormats else [None, ] * len(self.headers)
</ins><span class="cx"> self._getMaxColumnCount()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def addHeader(self, row, columnFormats=None):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.headers.append(row)
</span><span class="cx"> self.headerColumnFormats.append(columnFormats)
</span><span class="cx"> self._getMaxColumnCount()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def addHeaderDivider(self, skipColumns=()):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.headers.append((None, skipColumns,))
</span><span class="cx"> self.headerColumnFormats.append(None)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setFooters(self, row, columnFormats=None):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.footers = row
</span><del>- self.footerColumnFormats = columnFormats if columnFormats else [None,] * len(self.footers)
</del><ins>+ self.footerColumnFormats = columnFormats if columnFormats else [None, ] * len(self.footers)
</ins><span class="cx"> self._getMaxColumnCount()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def addFooter(self, row, columnFormats=None):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.footers.append(row)
</span><span class="cx"> self.footerColumnFormats.append(columnFormats)
</span><span class="cx"> self._getMaxColumnCount()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def addRow(self, row=None, columnFormats=None):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.rows.append(row)
</span><span class="cx"> if columnFormats:
</span><span class="cx"> self.columnFormatsByRow[len(self.rows) - 1] = columnFormats
</span><span class="cx"> self._getMaxColumnCount()
</span><del>-
</del><ins>+
+
</ins><span class="cx"> def addDivider(self, skipColumns=()):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.rows.append((None, skipColumns,))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def toString(self):
</span><span class="cx">
</span><span class="cx"> output = StringIO()
</span><span class="cx"> self.printTable(os=output)
</span><span class="cx"> return output.getvalue()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def printTable(self, os=stdout):
</span><del>-
</del><ins>+
</ins><span class="cx"> maxWidths = self._getMaxWidths()
</span><del>-
</del><ins>+
</ins><span class="cx"> self.printDivider(os, maxWidths, False)
</span><span class="cx"> if self.headers:
</span><span class="cx"> for header, format in zip(self.headers, self.headerColumnFormats):
</span><span class="lines">@@ -142,9 +155,10 @@
</span><span class="cx"> for footer, format in zip(self.footers, self.footerColumnFormats):
</span><span class="cx"> self.printRow(os, footer, self._getFooterColumnFormat(format), maxWidths)
</span><span class="cx"> self.printDivider(os, maxWidths, False)
</span><del>-
</del><ins>+
+
</ins><span class="cx"> def printRow(self, os, row, format, maxWidths):
</span><del>-
</del><ins>+
</ins><span class="cx"> if row is None or type(row) is tuple and row[0] is None:
</span><span class="cx"> self.printDivider(os, maxWidths, skipColumns=row[1] if type(row) is tuple else ())
</span><span class="cx"> else:
</span><span class="lines">@@ -165,8 +179,8 @@
</span><span class="cx"> t += " " + text + " |"
</span><span class="cx"> t += "\n"
</span><span class="cx"> os.write(t)
</span><del>-
</del><span class="cx">
</span><ins>+
</ins><span class="cx"> def printDivider(self, os, maxWidths, intermediate=True, double=False, skipColumns=()):
</span><span class="cx"> t = "|" if intermediate else "+"
</span><span class="cx"> for widthctr, width in enumerate(maxWidths):
</span><span class="lines">@@ -179,8 +193,9 @@
</span><span class="cx"> t += "\n"
</span><span class="cx"> os.write(t)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def printTabDelimitedData(self, os=stdout, footer=True):
</span><del>-
</del><ins>+
</ins><span class="cx"> if self.headers:
</span><span class="cx"> titles = [""] * len(self.headers[0])
</span><span class="cx"> for row, header in enumerate(self.headers):
</span><span class="lines">@@ -193,20 +208,22 @@
</span><span class="cx"> for footer in self.footers:
</span><span class="cx"> self.printTabDelimitedRow(os, footer, self._getFooterColumnFormat(self.footerColumnFormats[0]))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def printTabDelimitedRow(self, os, row, format):
</span><del>-
</del><ins>+
</ins><span class="cx"> if row is None:
</span><span class="cx"> row = [""] * self.columnCount
</span><del>-
</del><ins>+
</ins><span class="cx"> if len(row) != self.columnCount:
</span><span class="cx"> row = list(row)
</span><span class="cx"> row.extend([""] * (self.columnCount - len(row)))
</span><span class="cx">
</span><span class="cx"> textItems = [self._columnText(row, ctr, format) for ctr in xrange((len(row)))]
</span><span class="cx"> os.write("\t".join(textItems) + "\n")
</span><del>-
</del><ins>+
+
</ins><span class="cx"> def _getMaxColumnCount(self):
</span><del>-
</del><ins>+
</ins><span class="cx"> self.columnCount = 0
</span><span class="cx"> if self.headers:
</span><span class="cx"> for header in self.headers:
</span><span class="lines">@@ -217,6 +234,7 @@
</span><span class="cx"> for footer in self.footers:
</span><span class="cx"> self.columnCount = max(self.columnCount, len(footer) if footer else 0)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _getMaxWidths(self):
</span><span class="cx">
</span><span class="cx"> maxWidths = [0] * self.columnCount
</span><span class="lines">@@ -224,55 +242,60 @@
</span><span class="cx"> if self.headers:
</span><span class="cx"> for header, format in zip(self.headers, self.headerColumnFormats):
</span><span class="cx"> self._updateMaxWidthsFromRow(header, self._getHeaderColumnFormat(format), maxWidths)
</span><del>-
</del><ins>+
</ins><span class="cx"> for ctr, row in enumerate(self.rows):
</span><span class="cx"> self._updateMaxWidthsFromRow(row, self._getColumnFormatForRow(ctr), maxWidths)
</span><span class="cx">
</span><span class="cx"> if self.footers:
</span><span class="cx"> for footer, format in zip(self.footers, self.footerColumnFormats):
</span><span class="cx"> self._updateMaxWidthsFromRow(footer, self._getFooterColumnFormat(format), maxWidths)
</span><del>-
</del><ins>+
</ins><span class="cx"> return maxWidths
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _updateMaxWidthsFromRow(self, row, format, maxWidths):
</span><del>-
</del><ins>+
</ins><span class="cx"> if row and (type(row) is not tuple or row[0] is not None):
</span><span class="cx"> ctr = 0
</span><span class="cx"> while ctr < len(row):
</span><del>-
- text = self._columnText(row, ctr, format)
</del><ins>+
+ text = self._columnText(row, ctr, format)
</ins><span class="cx"> startCtr = ctr
</span><span class="cx"> for _ignore_span in xrange(format[startCtr].span if format else 1):
</span><span class="cx"> maxWidths[ctr] = max(maxWidths[ctr], len(text) / (format[startCtr].span if format else 1))
</span><span class="cx"> ctr += 1
</span><del>-
</del><ins>+
+
</ins><span class="cx"> def _getHeaderColumnFormat(self, format):
</span><del>-
</del><ins>+
</ins><span class="cx"> if format:
</span><span class="cx"> return format
</span><span class="cx"> else:
</span><span class="cx"> justify = Table.ColumnFormat.CENTER_JUSTIFY if len(self.headers) == 1 else Table.ColumnFormat.LEFT_JUSTIFY
</span><del>- return [Table.ColumnFormat(justify = justify)] * self.columnCount
</del><ins>+ return [Table.ColumnFormat(justify=justify)] * self.columnCount
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> def _getFooterColumnFormat(self, format):
</span><del>-
</del><ins>+
</ins><span class="cx"> if format:
</span><span class="cx"> return format
</span><span class="cx"> else:
</span><span class="cx"> return self.defaultColumnFormats
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _getColumnFormatForRow(self, ctr):
</span><del>-
</del><ins>+
</ins><span class="cx"> if ctr in self.columnFormatsByRow:
</span><span class="cx"> return self.columnFormatsByRow[ctr]
</span><span class="cx"> else:
</span><span class="cx"> return self.defaultColumnFormats
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _columnText(self, row, column, format, width=0):
</span><del>-
</del><ins>+
</ins><span class="cx"> if row is None or column >= len(row):
</span><span class="cx"> return ""
</span><del>-
</del><ins>+
</ins><span class="cx"> colData = row[column]
</span><span class="cx"> if colData is None:
</span><span class="cx"> colData = ""
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolstesttest_agentpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/test/test_agent.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/test/test_agent.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/test/test_agent.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -22,7 +22,7 @@
</span><span class="cx"> from twistedcaldav.test.util import TestCase
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks
</span><span class="cx"> from twisted.internet.task import Clock
</span><del>- from twisted.cred.error import UnauthorizedLogin
</del><ins>+ from twisted.cred.error import UnauthorizedLogin
</ins><span class="cx"> from twisted.web.resource import IResource
</span><span class="cx"> from twisted.web.resource import ForbiddenResource
</span><span class="cx"> RUN_TESTS = True
</span><span class="lines">@@ -31,7 +31,6 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> if RUN_TESTS:
</span><span class="cx"> class AgentTestCase(TestCase):
</span><span class="cx">
</span><span class="lines">@@ -67,7 +66,6 @@
</span><span class="cx"> else:
</span><span class="cx"> self.fail("Didn't raise UnauthorizedLogin")
</span><span class="cx">
</span><del>-
</del><span class="cx"> # Record exists, but invalid credentials
</span><span class="cx"> fakeOpenDirectory.returnThisRecord("fooRecord")
</span><span class="cx"> fakeOpenDirectory.returnThisAuthResponse(False)
</span><span class="lines">@@ -78,14 +76,12 @@
</span><span class="cx"> else:
</span><span class="cx"> self.fail("Didn't raise UnauthorizedLogin")
</span><span class="cx">
</span><del>-
</del><span class="cx"> # Record exists, valid credentials
</span><span class="cx"> fakeOpenDirectory.returnThisRecord("fooRecord")
</span><span class="cx"> fakeOpenDirectory.returnThisAuthResponse(True)
</span><span class="cx"> avatar = (yield c.requestAvatarId(creds))
</span><span class="cx"> self.assertEquals(avatar, "foo")
</span><span class="cx">
</span><del>-
</del><span class="cx"> # Record exists, but missing fields in credentials
</span><span class="cx"> del creds.fields["nonce"]
</span><span class="cx"> fakeOpenDirectory.returnThisRecord("fooRecord")
</span><span class="lines">@@ -102,11 +98,11 @@
</span><span class="cx"> realm = AgentRealm("root", ["abc"])
</span><span class="cx">
</span><span class="cx"> # Valid avatar
</span><del>- interface, resource, ignored = realm.requestAvatar("abc", None, IResource)
</del><ins>+ _ignore_interface, resource, ignored = realm.requestAvatar("abc", None, IResource)
</ins><span class="cx"> self.assertEquals(resource, "root")
</span><span class="cx">
</span><span class="cx"> # Not allowed avatar
</span><del>- interface, resource, ignored = realm.requestAvatar("def", None, IResource)
</del><ins>+ _ignore_interface, resource, ignored = realm.requestAvatar("def", None, IResource)
</ins><span class="cx"> self.assertTrue(isinstance(resource, ForbiddenResource))
</span><span class="cx">
</span><span class="cx"> # Interface unhandled
</span><span class="lines">@@ -118,7 +114,6 @@
</span><span class="cx"> self.fail("Didn't raise NotImplementedError")
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> class InactivityDectectorTestCase(TestCase):
</span><span class="cx">
</span><span class="cx"> def test_inactivity(self):
</span><span class="lines">@@ -156,7 +151,6 @@
</span><span class="cx"> return "127.0.0.1"
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> class FakeOpenDirectory(object):
</span><span class="cx">
</span><span class="cx"> def returnThisRecord(self, response):
</span><span class="lines">@@ -175,7 +169,6 @@
</span><span class="cx"> ODNSerror = "Error"
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> class FakeCredentials(object):
</span><span class="cx">
</span><span class="cx"> def __init__(self, username, fields):
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolstesttest_configpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/test/test_config.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/test/test_config.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/test/test_config.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -110,6 +110,7 @@
</span><span class="cx"> self.assertEquals(writable2.currentConfigSubset, {'key1': u'\U0001f4a3'})
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class ConfigTestCase(RunCommandTestCase):
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolstesttest_gatewaypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/test/test_gateway.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/test/test_gateway.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/test/test_gateway.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -187,7 +187,7 @@
</span><span class="cx"> self.assertEquals(results["result"]["RealName"], u'Updated Address')
</span><span class="cx"> self.assertEquals(results["result"]["StreetAddress"], u'Updated Street Address')
</span><span class="cx"> self.assertEquals(results["result"]["Geo"], u'Updated Geo')
</span><del>-
</del><ins>+
</ins><span class="cx"> results = yield self.runCommand(command_deleteAddress)
</span><span class="cx">
</span><span class="cx"> results = yield self.runCommand(command_getAddressList)
</span><span class="lines">@@ -333,6 +333,7 @@
</span><span class="cx"> results = yield self.runCommand(command_purgeOldEventsNoDays)
</span><span class="cx"> self.assertEquals(results["result"]["RetainDays"], 365)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_readConfig(self):
</span><span class="cx"> """
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolstesttest_resourcespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/test/test_resources.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/test/test_resources.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/test/test_resources.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx">
</span><span class="cx"> @classmethod
</span><span class="cx"> def getAugmentRecord(cls, guid, recordType):
</span><del>- if not cls.records.has_key(guid):
</del><ins>+ if guid not in cls.records:
</ins><span class="cx"> record = StubAugmentRecord(guid=guid)
</span><span class="cx"> cls.records[guid] = record
</span><span class="cx"> return succeed(cls.records[guid])
</span><span class="lines">@@ -128,11 +128,9 @@
</span><span class="cx">
</span><span class="cx"> self.assertTrue(guid in StubAugmentService.records)
</span><span class="cx">
</span><del>-
</del><span class="cx"> #
</span><span class="cx"> # Add more to OD and re-migrate
</span><span class="cx"> #
</span><del>-
</del><span class="cx"> data[dsattributes.kDSStdRecordTypeResources].append(
</span><span class="cx"> ['projector3', {
</span><span class="cx"> strGUID : '9C99E240-E915-4012-82FA-99E0F638D7EF',
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertoolstesttest_utilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tools/test/test_util.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tools/test/test_util.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/tools/test/test_util.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> self.assertEquals(config.EnableCalDAV, True)
</span><span class="cx"> self.assertEquals(config.EnableCardDAV, True)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_checkDirectory(self):
</span><span class="cx"> tmpDir = tempfile.mkdtemp()
</span><span class="cx"> tmpFile = os.path.join(tmpDir, "tmpFile")
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverwebcalresourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/webcal/resource.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/webcal/resource.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/webcal/resource.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -59,36 +59,44 @@
</span><span class="cx"> ),
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def etag(self):
</span><span class="cx"> # Can't be calculated here
</span><span class="cx"> return succeed(None)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def contentLength(self):
</span><span class="cx"> # Can't be calculated here
</span><span class="cx"> return None
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def lastModified(self):
</span><span class="cx"> return None
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def exists(self):
</span><span class="cx"> return True
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def displayName(self):
</span><span class="cx"> return "Web Calendar"
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def contentType(self):
</span><span class="cx"> return MimeType.fromString("text/html; charset=utf-8")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def contentEncoding(self):
</span><span class="cx"> return None
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def createSimilarFile(self, path):
</span><span class="cx"> return DAVFile(path, principalCollections=self.principalCollections())
</span><span class="cx">
</span><del>- _htmlContent_lastCheck = 0
- _htmlContent_statInfo = 0
</del><ins>+ _htmlContent_lastCheck = 0
+ _htmlContent_statInfo = 0
</ins><span class="cx"> _htmlContentDebug_lastCheck = 0
</span><del>- _htmlContentDebug_statInfo = 0
</del><ins>+ _htmlContentDebug_statInfo = 0
</ins><span class="cx">
</span><span class="cx"> def htmlContent(self, debug=False):
</span><span class="cx"> if debug:
</span><span class="lines">@@ -134,6 +142,7 @@
</span><span class="cx">
</span><span class="cx"> return getattr(self, cacheAttr)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def render(self, request):
</span><span class="cx"> if not self.fp.isdir():
</span><span class="cx"> return responsecode.NOT_FOUND
</span><span class="lines">@@ -202,6 +211,7 @@
</span><span class="cx"> return ""
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def getLocalTimezone():
</span><span class="cx"> """
</span><span class="cx"> Returns the default timezone for the server. The order of precedence is:
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverwebcaltesttest_resourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/webcal/test/test_resource.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/webcal/test/test_resource.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/calendarserver/webcal/test/test_resource.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -26,9 +26,11 @@
</span><span class="cx"> def stubLookup(self):
</span><span class="cx"> return self._storedLookup
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def stubHasTZ(self, ignored):
</span><span class="cx"> return self._storedHasTZ.pop()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setUp(self):
</span><span class="cx"> self.patch(
</span><span class="cx"> calendarserver.webcal.resource, "lookupSystemTimezone",
</span><span class="lines">@@ -38,6 +40,7 @@
</span><span class="cx"> calendarserver.webcal.resource, "hasTZ", self.stubHasTZ
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_getLocalTimezone(self):
</span><span class="cx">
</span><span class="cx"> # Empty config, system timezone known = use system timezone
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryappleopendirectorypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -121,7 +121,7 @@
</span><span class="cx"> self.restrictToGUID = True
</span><span class="cx"> self.restrictedTimestamp = 0
</span><span class="cx">
</span><del>- # Set up the /Local/Default node if it's in the search path so we can
</del><ins>+ # Set up the /Local/Default node if it's in the search path so we can
</ins><span class="cx"> # send custom queries to it
</span><span class="cx"> self.localNode = None
</span><span class="cx"> try:
</span><span class="lines">@@ -581,7 +581,7 @@
</span><span class="cx">
</span><span class="cx"> def collectResults(results):
</span><span class="cx"> self.log.debug("Got back %d records from OD" % (len(results),))
</span><del>- for key, value in results:
</del><ins>+ for _ignore_key, value in results:
</ins><span class="cx"> # self.log.debug("OD result: {key} {value}", key=key, value=value)
</span><span class="cx"> try:
</span><span class="cx"> recordNodeName = value.get(
</span><span class="lines">@@ -787,7 +787,7 @@
</span><span class="cx">
</span><span class="cx"> def collectResults(results):
</span><span class="cx"> self.log.debug("Got back %d records from OD" % (len(results),))
</span><del>- for key, value in results:
</del><ins>+ for _ignore_key, value in results:
</ins><span class="cx"> # self.log.debug("OD result: {key} {value}", key=key, value=value)
</span><span class="cx"> try:
</span><span class="cx"> recordNodeName = value.get(
</span><span class="lines">@@ -1375,12 +1375,13 @@
</span><span class="cx"> return results
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def buildNestedQueryFromTokens(tokens, mapping):
</span><span class="cx"> """
</span><span class="cx"> Build a DS query espression such that all the tokens must appear in either
</span><span class="cx"> the fullName (anywhere), emailAddresses (at the beginning) or record name
</span><span class="cx"> (at the beginning).
</span><del>-
</del><ins>+
</ins><span class="cx"> @param tokens: The tokens to search on
</span><span class="cx"> @type tokens: C{list} of C{str}
</span><span class="cx"> @param mapping: The mapping of DirectoryRecord attributes to OD attributes
</span><span class="lines">@@ -1409,6 +1410,7 @@
</span><span class="cx"> return dsquery.expression(dsquery.expression.AND, outer)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class OpenDirectoryRecord(CachingDirectoryRecord):
</span><span class="cx"> """
</span><span class="cx"> OpenDirectory implementation of L{IDirectoryRecord}.
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectorycalendarpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/calendar.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/calendar.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/calendar.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -36,11 +36,11 @@
</span><span class="cx">
</span><span class="cx"> from twistedcaldav.config import config
</span><span class="cx"> from twistedcaldav.directory.idirectory import IDirectoryService
</span><del>-from twistedcaldav.directory.common import uidsResourceName,\
</del><ins>+from twistedcaldav.directory.common import uidsResourceName, \
</ins><span class="cx"> CommonUIDProvisioningResource, CommonHomeTypeProvisioningResource
</span><span class="cx">
</span><span class="cx"> from twistedcaldav.directory.wiki import getWikiACL
</span><del>-from twistedcaldav.extensions import ReadOnlyResourceMixIn, DAVResource,\
</del><ins>+from twistedcaldav.extensions import ReadOnlyResourceMixIn, DAVResource, \
</ins><span class="cx"> DAVResourceWithChildrenMixin
</span><span class="cx"> from twistedcaldav.resource import CalendarHomeResource
</span><span class="cx">
</span><span class="lines">@@ -56,6 +56,8 @@
</span><span class="cx"> + config.CalDAVComplianceClasses
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class DirectoryCalendarProvisioningResource (
</span><span class="cx"> ReadOnlyResourceMixIn,
</span><span class="cx"> CalDAVComplianceMixIn,
</span><span class="lines">@@ -65,15 +67,19 @@
</span><span class="cx"> def defaultAccessControlList(self):
</span><span class="cx"> return config.ProvisioningResourceACL
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def etag(self):
</span><span class="cx"> return succeed(ETag(str(uuid4())))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def contentType(self):
</span><span class="cx"> return MimeType("httpd", "unix-directory")
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class DirectoryCalendarHomeProvisioningResource (DirectoryCalendarProvisioningResource):
</span><span class="cx"> """
</span><del>- Resource which provisions calendar home collections as needed.
</del><ins>+ Resource which provisions calendar home collections as needed.
</ins><span class="cx"> """
</span><span class="cx"> def __init__(self, directory, url, store):
</span><span class="cx"> """
</span><span class="lines">@@ -100,22 +106,27 @@
</span><span class="cx">
</span><span class="cx"> self.putChild(uidsResourceName, DirectoryCalendarHomeUIDProvisioningResource(self))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def url(self):
</span><span class="cx"> return self._url
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def listChildren(self):
</span><span class="cx"> return self.directory.recordTypes()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def principalCollections(self):
</span><span class="cx"> # FIXME: directory.principalCollection smells like a hack
</span><span class="cx"> # See DirectoryPrincipalProvisioningResource.__init__()
</span><span class="cx"> return self.directory.principalCollection.principalCollections()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def principalForRecord(self, record):
</span><span class="cx"> # FIXME: directory.principalCollection smells like a hack
</span><span class="cx"> # See DirectoryPrincipalProvisioningResource.__init__()
</span><span class="cx"> return self.directory.principalCollection.principalForRecord(record)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def homeForDirectoryRecord(self, record, request):
</span><span class="cx"> uidResource = self.getChild(uidsResourceName)
</span><span class="cx"> if uidResource is None:
</span><span class="lines">@@ -123,16 +134,20 @@
</span><span class="cx"> else:
</span><span class="cx"> return uidResource.homeResourceForRecord(record, request)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # DAV
</span><span class="cx"> ##
</span><del>-
</del><ins>+
</ins><span class="cx"> def isCollection(self):
</span><span class="cx"> return True
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def displayName(self):
</span><span class="cx"> return "calendars"
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class DirectoryCalendarHomeTypeProvisioningResource(
</span><span class="cx"> CommonHomeTypeProvisioningResource,
</span><span class="cx"> DirectoryCalendarProvisioningResource
</span><span class="lines">@@ -155,6 +170,7 @@
</span><span class="cx"> self.recordType = recordType
</span><span class="cx"> self._parent = parent
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def url(self):
</span><span class="cx"> return joinURL(self._parent.url(), self.recordType)
</span><span class="cx">
</span><span class="lines">@@ -173,19 +189,23 @@
</span><span class="cx"> # Not a listable collection
</span><span class="cx"> raise HTTPError(responsecode.FORBIDDEN)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def makeChild(self, name):
</span><span class="cx"> return None
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # DAV
</span><span class="cx"> ##
</span><del>-
</del><ins>+
</ins><span class="cx"> def isCollection(self):
</span><span class="cx"> return True
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def displayName(self):
</span><span class="cx"> return self.recordType
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # ACL
</span><span class="cx"> ##
</span><span class="lines">@@ -193,9 +213,12 @@
</span><span class="cx"> def principalCollections(self):
</span><span class="cx"> return self._parent.principalCollections()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def principalForRecord(self, record):
</span><span class="cx"> return self._parent.principalForRecord(record)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class DirectoryCalendarHomeUIDProvisioningResource (
</span><span class="cx"> CommonUIDProvisioningResource,
</span><span class="cx"> DirectoryCalendarProvisioningResource
</span><span class="lines">@@ -241,5 +264,6 @@
</span><span class="cx"> d.addCallback(gotACL)
</span><span class="cx"> return d
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def principalForRecord(self):
</span><span class="cx"> return self.parent.principalForRecord(self.record)
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectorycalendaruserproxypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -49,9 +49,9 @@
</span><span class="cx">
</span><span class="cx"> from twistedcaldav.directory.util import normalizeUUID
</span><span class="cx"> from twistedcaldav.config import config, fullServerPath
</span><del>-from twistedcaldav.database import AbstractADBAPIDatabase, ADBAPISqliteMixin,\
</del><ins>+from twistedcaldav.database import AbstractADBAPIDatabase, ADBAPISqliteMixin, \
</ins><span class="cx"> ADBAPIPostgreSQLMixin
</span><del>-from twistedcaldav.extensions import DAVPrincipalResource,\
</del><ins>+from twistedcaldav.extensions import DAVPrincipalResource, \
</ins><span class="cx"> DAVResourceWithChildrenMixin
</span><span class="cx"> from twistedcaldav.extensions import ReadOnlyWritePropertiesResourceMixIn
</span><span class="cx"> from twistedcaldav.memcacher import Memcacher
</span><span class="lines">@@ -177,16 +177,16 @@
</span><span class="cx"> super(CalendarUserProxyPrincipalResource, self).__init__()
</span><span class="cx"> DAVResourceWithChildrenMixin.__init__(self)
</span><span class="cx">
</span><del>- self.parent = parent
- self.proxyType = proxyType
- self._url = url
</del><ins>+ self.parent = parent
+ self.proxyType = proxyType
+ self._url = url
</ins><span class="cx">
</span><span class="cx"> # FIXME: if this is supposed to be public, it needs a better name:
</span><del>- self.pcollection = self.parent.parent.parent
</del><ins>+ self.pcollection = self.parent.parent.parent
</ins><span class="cx">
</span><span class="cx"> # Principal UID is parent's GUID plus the proxy type; this we can easily
</span><span class="cx"> # map back to a principal.
</span><del>- self.uid = "%s#%s" % (self.parent.principalUID(), proxyType)
</del><ins>+ self.uid = "%s#%s" % (self.parent.principalUID(), proxyType)
</ins><span class="cx"> self._alternate_urls = tuple(
</span><span class="cx"> joinURL(url, proxyType) + slash
</span><span class="cx"> for url in parent.alternateURIs()
</span><span class="lines">@@ -206,6 +206,7 @@
</span><span class="cx"> """
</span><span class="cx"> return ProxyDBService
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def resourceType(self):
</span><span class="cx"> if self.proxyType == "calendar-proxy-read":
</span><span class="cx"> return davxml.ResourceType.calendarproxyread #@UndefinedVariable
</span><span class="lines">@@ -214,6 +215,7 @@
</span><span class="cx"> else:
</span><span class="cx"> return super(CalendarUserProxyPrincipalResource, self).resourceType()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def isProxyType(self, read_write):
</span><span class="cx"> if (
</span><span class="cx"> read_write and self.proxyType == "calendar-proxy-write" or
</span><span class="lines">@@ -223,12 +225,15 @@
</span><span class="cx"> else:
</span><span class="cx"> return False
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def isCollection(self):
</span><span class="cx"> return True
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def etag(self):
</span><span class="cx"> return succeed(None)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def deadProperties(self):
</span><span class="cx"> if not hasattr(self, "_dead_properties"):
</span><span class="cx"> self._dead_properties = NonePropertyStore(self)
</span><span class="lines">@@ -302,6 +307,7 @@
</span><span class="cx"> [p.principalUID() for p in principals],
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # HTTP
</span><span class="cx"> ##
</span><span class="lines">@@ -329,15 +335,19 @@
</span><span class="cx"> # FIXME: Add API to IDirectoryRecord for getting a record URI?
</span><span class="cx"> return self._alternate_urls
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def principalURL(self):
</span><span class="cx"> return self._url
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def principalUID(self):
</span><span class="cx"> return self.uid
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def principalCollections(self):
</span><span class="cx"> return self.parent.principalCollections()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def _expandMemberUIDs(self, uid=None, relatives=None, uids=None, infinity=False):
</span><span class="cx"> if uid is None:
</span><span class="lines">@@ -367,6 +377,7 @@
</span><span class="cx">
</span><span class="cx"> returnValue(relatives)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def _directGroupMembers(self):
</span><span class="cx"> # Get member UIDs from database and map to principal resources
</span><span class="lines">@@ -377,7 +388,7 @@
</span><span class="cx"> if p:
</span><span class="cx"> # Only principals enabledForLogin can be a delegate
</span><span class="cx"> # (and groups as well)
</span><del>- if (p.record.enabledForLogin or
</del><ins>+ if (p.record.enabledForLogin or
</ins><span class="cx"> p.record.recordType == p.record.service.recordType_groups):
</span><span class="cx"> found.append(p)
</span><span class="cx"> # Make sure any outstanding deletion timer entries for
</span><span class="lines">@@ -388,9 +399,11 @@
</span><span class="cx">
</span><span class="cx"> returnValue(found)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def groupMembers(self):
</span><span class="cx"> return self._expandMemberUIDs()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def expandedGroupMembers(self):
</span><span class="cx"> """
</span><span class="lines">@@ -399,6 +412,7 @@
</span><span class="cx"> """
</span><span class="cx"> returnValue((yield self._expandMemberUIDs(infinity=True)))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def groupMemberships(self):
</span><span class="cx"> # Get membership UIDs and map to principal resources
</span><span class="cx"> d = self._index().getMemberships(self.uid)
</span><span class="lines">@@ -409,6 +423,7 @@
</span><span class="cx"> ])
</span><span class="cx"> return d
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def containsPrincipal(self, principal):
</span><span class="cx"> """
</span><span class="lines">@@ -427,6 +442,8 @@
</span><span class="cx"> returnValue(True)
</span><span class="cx"> returnValue(False)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class ProxyDB(AbstractADBAPIDatabase):
</span><span class="cx"> """
</span><span class="cx"> A database to maintain calendar user proxy group memberships.
</span><span class="lines">@@ -440,7 +457,7 @@
</span><span class="cx"> log = Logger()
</span><span class="cx">
</span><span class="cx"> schema_version = "4"
</span><del>- schema_type = "CALENDARUSERPROXY"
</del><ins>+ schema_type = "CALENDARUSERPROXY"
</ins><span class="cx">
</span><span class="cx"> class ProxyDBMemcacher(Memcacher):
</span><span class="cx">
</span><span class="lines">@@ -484,7 +501,7 @@
</span><span class="cx"> return self.delete("memberships:%s" % (str(guid),))
</span><span class="cx">
</span><span class="cx"> def setDeletionTimer(self, guid, delay):
</span><del>- return self.set("del:%s" % (str(guid),), str(self.getTime()+delay))
</del><ins>+ return self.set("del:%s" % (str(guid),), str(self.getTime() + delay))
</ins><span class="cx">
</span><span class="cx"> def checkDeletionTimer(self, guid):
</span><span class="cx"> # True means it's overdue, False means it's not, None means no timer
</span><span class="lines">@@ -510,11 +527,13 @@
</span><span class="cx"> theTime = int(time.time())
</span><span class="cx"> return theTime
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, dbID, dbapiName, dbapiArgs, **kwargs):
</span><span class="cx"> AbstractADBAPIDatabase.__init__(self, dbID, dbapiName, dbapiArgs, True, **kwargs)
</span><del>-
</del><ins>+
</ins><span class="cx"> self._memcacher = ProxyDB.ProxyDBMemcacher("ProxyDB")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def setGroupMembers(self, principalUID, members):
</span><span class="cx"> """
</span><span class="lines">@@ -542,6 +561,7 @@
</span><span class="cx"> yield self._memcacher.deleteMembership(member)
</span><span class="cx"> yield self._memcacher.deleteMember(principalUID)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def setGroupMembersInDatabase(self, principalUID, members):
</span><span class="cx"> """
</span><span class="lines">@@ -553,7 +573,8 @@
</span><span class="cx"> # Remove what is there, then add it back.
</span><span class="cx"> yield self._delete_from_db(principalUID)
</span><span class="cx"> yield self._add_to_db(principalUID, members)
</span><del>-
</del><ins>+
+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def changeGroupMembersInDatabase(self, principalUID, addMembers, removeMembers):
</span><span class="cx"> """
</span><span class="lines">@@ -568,7 +589,8 @@
</span><span class="cx"> yield self._delete_from_db_one(principalUID, member)
</span><span class="cx"> for member in addMembers:
</span><span class="cx"> yield self._add_to_db_one(principalUID, member)
</span><del>-
</del><ins>+
+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def removeGroup(self, principalUID):
</span><span class="cx"> """
</span><span class="lines">@@ -581,13 +603,14 @@
</span><span class="cx"> members = yield self.getMembers(principalUID)
</span><span class="cx">
</span><span class="cx"> yield self._delete_from_db(principalUID)
</span><del>-
</del><ins>+
</ins><span class="cx"> # Update cache
</span><span class="cx"> if members:
</span><span class="cx"> for member in members:
</span><span class="cx"> yield self._memcacher.deleteMembership(member)
</span><span class="cx"> yield self._memcacher.deleteMember(principalUID)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def removePrincipal(self, principalUID, delay=None):
</span><span class="cx"> """
</span><span class="lines">@@ -596,7 +619,7 @@
</span><span class="cx"> @param principalUID: the UID of the principal to remove.
</span><span class="cx"> """
</span><span class="cx"> # FIXME: This method doesn't appear to be used anywhere. Still needed?
</span><del>-
</del><ins>+
</ins><span class="cx"> if delay:
</span><span class="cx"> # We are going to remove the principal only after <delay> seconds
</span><span class="cx"> # has passed since we first chose to remove it, to protect against
</span><span class="lines">@@ -640,6 +663,7 @@
</span><span class="cx"> yield self._memcacher.deleteMembership(principalUID)
</span><span class="cx"> yield self._memcacher.clearDeletionTimer(principalUID)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def refreshPrincipal(self, principalUID):
</span><span class="cx"> """
</span><span class="cx"> Bring back to life a principal that was previously deleted.
</span><span class="lines">@@ -647,9 +671,10 @@
</span><span class="cx"> @param principalUID:
</span><span class="cx"> @type principalUID:
</span><span class="cx"> """
</span><del>-
</del><ins>+
</ins><span class="cx"> return self._memcacher.clearDeletionTimer(principalUID)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def getMembers(self, principalUID):
</span><span class="cx"> """
</span><span class="cx"> Return the list of group member UIDs for the specified principal.
</span><span class="lines">@@ -667,7 +692,7 @@
</span><span class="cx"> d.addCallback(lambda _: members)
</span><span class="cx"> return d
</span><span class="cx">
</span><del>- d = self.query("select MEMBER from GROUPS where GROUPNAME = :1", (principalUID.decode("utf-8"),))
</del><ins>+ d = self.query("select MEMBER from GROUPS where GROUPNAME = :1", (principalUID.decode("utf-8"),))
</ins><span class="cx"> d.addCallback(gotMembersFromDB)
</span><span class="cx"> return d
</span><span class="cx">
</span><span class="lines">@@ -675,10 +700,11 @@
</span><span class="cx"> d.addCallback(gotCachedMembers)
</span><span class="cx"> return d
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def getMemberships(self, principalUID):
</span><span class="cx"> """
</span><span class="cx"> Return the list of group principal UIDs the specified principal is a member of.
</span><del>-
</del><ins>+
</ins><span class="cx"> @return: a deferred returning a C{set} of memberships.
</span><span class="cx"> """
</span><span class="cx"> def gotCachedMemberships(memberships):
</span><span class="lines">@@ -692,7 +718,7 @@
</span><span class="cx"> d.addCallback(lambda _: memberships)
</span><span class="cx"> return d
</span><span class="cx">
</span><del>- d = self.query("select GROUPNAME from GROUPS where MEMBER = :1", (principalUID.decode("utf-8"),))
</del><ins>+ d = self.query("select GROUPNAME from GROUPS where MEMBER = :1", (principalUID.decode("utf-8"),))
</ins><span class="cx"> d.addCallback(gotMembershipsFromDB)
</span><span class="cx"> return d
</span><span class="cx">
</span><span class="lines">@@ -700,6 +726,7 @@
</span><span class="cx"> d.addCallback(gotCachedMemberships)
</span><span class="cx"> return d
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def _add_to_db(self, principalUID, members):
</span><span class="cx"> """
</span><span class="lines">@@ -716,6 +743,7 @@
</span><span class="cx"> """, (principalUID.decode("utf-8"), member,)
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _add_to_db_one(self, principalUID, memberUID):
</span><span class="cx"> """
</span><span class="cx"> Insert the specified entry into the database.
</span><span class="lines">@@ -730,6 +758,7 @@
</span><span class="cx"> """, (principalUID.decode("utf-8"), memberUID.decode("utf-8"),)
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _delete_from_db(self, principalUID):
</span><span class="cx"> """
</span><span class="cx"> Deletes the specified entry from the database.
</span><span class="lines">@@ -738,6 +767,7 @@
</span><span class="cx"> """
</span><span class="cx"> return self.execute("delete from GROUPS where GROUPNAME = :1", (principalUID.decode("utf-8"),))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _delete_from_db_one(self, principalUID, memberUID):
</span><span class="cx"> """
</span><span class="cx"> Deletes the specified entry from the database.
</span><span class="lines">@@ -747,6 +777,7 @@
</span><span class="cx"> """
</span><span class="cx"> return self.execute("delete from GROUPS where GROUPNAME = :1 and MEMBER = :2", (principalUID.decode("utf-8"), memberUID.decode("utf-8"),))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _delete_from_db_member(self, principalUID):
</span><span class="cx"> """
</span><span class="cx"> Deletes the specified member entry from the database.
</span><span class="lines">@@ -755,18 +786,21 @@
</span><span class="cx"> """
</span><span class="cx"> return self.execute("delete from GROUPS where MEMBER = :1", (principalUID.decode("utf-8"),))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _db_version(self):
</span><span class="cx"> """
</span><span class="cx"> @return: the schema version assigned to this index.
</span><span class="cx"> """
</span><span class="cx"> return ProxyDB.schema_version
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _db_type(self):
</span><span class="cx"> """
</span><span class="cx"> @return: the collection type assigned to this index.
</span><span class="cx"> """
</span><span class="cx"> return ProxyDB.schema_type
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def _db_init_data_tables(self):
</span><span class="cx"> """
</span><span class="lines">@@ -781,7 +815,7 @@
</span><span class="cx"> "GROUPS",
</span><span class="cx"> (
</span><span class="cx"> ("GROUPNAME", "text"),
</span><del>- ("MEMBER", "text"),
</del><ins>+ ("MEMBER", "text"),
</ins><span class="cx"> ),
</span><span class="cx"> ifnotexists=True,
</span><span class="cx"> )
</span><span class="lines">@@ -877,17 +911,19 @@
</span><span class="cx"> #
</span><span class="cx"> return self._db_execute("delete from GROUPS")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def clean(self):
</span><del>-
</del><ins>+
</ins><span class="cx"> if not self.initialized:
</span><span class="cx"> yield self.open()
</span><span class="cx">
</span><span class="cx"> for group in [row[0] for row in (yield self.query("select GROUPNAME from GROUPS"))]:
</span><span class="cx"> self.removeGroup(group)
</span><del>-
</del><ins>+
</ins><span class="cx"> yield super(ProxyDB, self).clean()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def getAllMembers(self):
</span><span class="cx"> """
</span><span class="lines">@@ -908,6 +944,8 @@
</span><span class="cx"> ADBAPISqliteMixin.__init__(self)
</span><span class="cx"> ProxyDB.__init__(self, "Proxies", "sqlite3", (fullServerPath(config.DataRoot, dbpath),))
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class ProxyPostgreSQLDB(ADBAPIPostgreSQLMixin, ProxyDB):
</span><span class="cx"> """
</span><span class="cx"> PostgreSQL based augment database implementation.
</span><span class="lines">@@ -915,7 +953,7 @@
</span><span class="cx">
</span><span class="cx"> def __init__(self, host, database, user=None, password=None, dbtype=None):
</span><span class="cx">
</span><del>- ADBAPIPostgreSQLMixin.__init__(self, )
</del><ins>+ ADBAPIPostgreSQLMixin.__init__(self,)
</ins><span class="cx"> ProxyDB.__init__(self, "Proxies", "pgdb", (), host=host, database=database, user=user, password=password,)
</span><span class="cx"> if dbtype:
</span><span class="cx"> ProxyDB.schema_type = dbtype
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectorycalendaruserproxyloaderpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/calendaruserproxyloader.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/calendaruserproxyloader.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/calendaruserproxyloader.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -34,15 +34,15 @@
</span><span class="cx">
</span><span class="cx"> log = Logger()
</span><span class="cx">
</span><del>-ELEMENT_PROXIES = "proxies"
-ELEMENT_RECORD = "record"
</del><ins>+ELEMENT_PROXIES = "proxies"
+ELEMENT_RECORD = "record"
</ins><span class="cx">
</span><del>-ELEMENT_GUID = "guid"
-ELEMENT_PROXIES = "proxies"
</del><ins>+ELEMENT_GUID = "guid"
+ELEMENT_PROXIES = "proxies"
</ins><span class="cx"> ELEMENT_READ_ONLY_PROXIES = "read-only-proxies"
</span><del>-ELEMENT_MEMBER = "member"
</del><ins>+ELEMENT_MEMBER = "member"
</ins><span class="cx">
</span><del>-ATTRIBUTE_REPEAT = "repeat"
</del><ins>+ATTRIBUTE_REPEAT = "repeat"
</ins><span class="cx">
</span><span class="cx"> class XMLCalendarUserProxyLoader(object):
</span><span class="cx"> """
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> def __repr__(self):
</span><span class="cx"> return "<%s %r>" % (self.__class__.__name__, self.xmlFile)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, xmlFile):
</span><span class="cx">
</span><span class="cx"> self.items = []
</span><span class="lines">@@ -65,13 +66,14 @@
</span><span class="cx"> # FIXME: RuntimeError is dumb.
</span><span class="cx"> self._parseXML(proxies_node)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _parseXML(self, rootnode):
</span><span class="cx"> """
</span><span class="cx"> Parse the XML root node from the augments configuration document.
</span><span class="cx"> @param rootnode: the L{Element} to parse.
</span><span class="cx"> """
</span><span class="cx"> for child in rootnode:
</span><del>-
</del><ins>+
</ins><span class="cx"> if child.tag != ELEMENT_RECORD:
</span><span class="cx"> raise RuntimeError("Unknown augment type: '%s' in augment file: '%s'" % (child.tag, self.xmlFile,))
</span><span class="cx">
</span><span class="lines">@@ -81,7 +83,7 @@
</span><span class="cx"> write_proxies = set()
</span><span class="cx"> read_proxies = set()
</span><span class="cx"> for node in child:
</span><del>-
</del><ins>+
</ins><span class="cx"> if node.tag == ELEMENT_GUID:
</span><span class="cx"> guid = node.text
</span><span class="cx">
</span><span class="lines">@@ -92,40 +94,43 @@
</span><span class="cx"> self._parseMembers(node, write_proxies if node.tag == ELEMENT_PROXIES else read_proxies)
</span><span class="cx"> else:
</span><span class="cx"> raise RuntimeError("Invalid element '%s' in proxies file: '%s'" % (node.tag, self.xmlFile,))
</span><del>-
</del><ins>+
</ins><span class="cx"> # Must have at least a guid
</span><span class="cx"> if not guid:
</span><span class="cx"> raise RuntimeError("Invalid record '%s' without a guid in proxies file: '%s'" % (child, self.xmlFile,))
</span><del>-
</del><ins>+
</ins><span class="cx"> if repeat > 1:
</span><del>- for i in xrange(1, repeat+1):
</del><ins>+ for i in xrange(1, repeat + 1):
</ins><span class="cx"> self._buildRecord(guid, write_proxies, read_proxies, i)
</span><span class="cx"> else:
</span><span class="cx"> self._buildRecord(guid, write_proxies, read_proxies)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _parseMembers(self, node, addto):
</span><span class="cx"> for child in node:
</span><span class="cx"> if child.tag == ELEMENT_MEMBER:
</span><span class="cx"> addto.add(child.text)
</span><del>-
</del><ins>+
+
</ins><span class="cx"> def _buildRecord(self, guid, write_proxies, read_proxies, count=None):
</span><span class="cx">
</span><span class="cx"> def expandCount(value, count):
</span><del>-
</del><ins>+
</ins><span class="cx"> if type(value) in types.StringTypes:
</span><span class="cx"> return value % (count,) if count and "%" in value else value
</span><span class="cx"> else:
</span><span class="cx"> return value
</span><del>-
</del><ins>+
</ins><span class="cx"> guid = expandCount(guid, count)
</span><span class="cx"> write_proxies = set([expandCount(member, count) for member in write_proxies])
</span><span class="cx"> read_proxies = set([expandCount(member, count) for member in read_proxies])
</span><del>-
</del><ins>+
</ins><span class="cx"> self.items.append((guid, write_proxies, read_proxies,))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def updateProxyDB(self):
</span><del>-
</del><ins>+
</ins><span class="cx"> db = calendaruserproxy.ProxyDBService
</span><span class="cx"> for item in self.items:
</span><span class="cx"> guid, write_proxies, read_proxies = item
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectorydigestpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/digest.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/digest.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/digest.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> """
</span><span class="cx"> pass
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def set(self, key, value):
</span><span class="cx"> """
</span><span class="cx"> Store per-client credential information the first time a nonce is generated and used.
</span><span class="lines">@@ -68,6 +69,7 @@
</span><span class="cx"> """
</span><span class="cx"> pass
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def get(self, key):
</span><span class="cx"> """
</span><span class="cx"> Validate client supplied credentials by comparing with the cached values. If valid, store the new
</span><span class="lines">@@ -80,6 +82,7 @@
</span><span class="cx"> """
</span><span class="cx"> pass
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def delete(self, key):
</span><span class="cx"> """
</span><span class="cx"> Remove the record associated with the supplied key.
</span><span class="lines">@@ -89,6 +92,8 @@
</span><span class="cx"> """
</span><span class="cx"> pass
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class DigestCredentialsMemcache(Memcacher):
</span><span class="cx">
</span><span class="cx"> implements(IDigestCredentialsDatabase)
</span><span class="lines">@@ -101,14 +106,16 @@
</span><span class="cx"> pickle=True,
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def has_key(self, key):
</span><span class="cx"> """
</span><span class="cx"> See IDigestCredentialsDatabase.
</span><span class="cx"> """
</span><span class="cx"> d = self.get(key)
</span><del>- d.addCallback(lambda value:value is not None)
</del><ins>+ d.addCallback(lambda value: value is not None)
</ins><span class="cx"> return d
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def set(self, key, value):
</span><span class="cx"> """
</span><span class="cx"> See IDigestCredentialsDatabase.
</span><span class="lines">@@ -119,6 +126,8 @@
</span><span class="cx"> expireTime=self.CHALLENGE_MAXTIME_SECS
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class QopDigestCredentialFactory(DigestCredentialFactory):
</span><span class="cx"> """
</span><span class="cx"> See txweb2.auth.digest.DigestCredentialFactory
</span><span class="lines">@@ -163,7 +172,7 @@
</span><span class="cx"> c = challenge['nonce']
</span><span class="cx">
</span><span class="cx"> # Make sure it is not a duplicate
</span><del>- result = (yield self.db.has_key(c))
</del><ins>+ result = (yield self.db.has_key(c)) #@IgnorePep8
</ins><span class="cx"> if result:
</span><span class="cx"> raise AssertionError("nonce value already cached in credentials database: %s" % (c,))
</span><span class="cx">
</span><span class="lines">@@ -237,13 +246,14 @@
</span><span class="cx"> self._real.authenticationRealm,
</span><span class="cx"> auth)
</span><span class="cx">
</span><del>- if not self.qop and credentials.fields.has_key('qop'):
</del><ins>+ if not self.qop and 'qop' in credentials.fields:
</ins><span class="cx"> del credentials.fields['qop']
</span><span class="cx">
</span><span class="cx"> returnValue(credentials)
</span><span class="cx"> else:
</span><span class="cx"> raise error.LoginFailed('Invalid nonce/cnonce values')
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def _validate(self, auth, request):
</span><span class="cx"> """
</span><span class="lines">@@ -303,6 +313,7 @@
</span><span class="cx">
</span><span class="cx"> returnValue(True)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _invalidate(self, nonce):
</span><span class="cx"> """
</span><span class="cx"> Invalidate cached credentials for the specified nonce value.
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryinternalpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/internal.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/internal.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/internal.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -45,20 +45,22 @@
</span><span class="cx"> def __repr__(self):
</span><span class="cx"> return "<%s %r>" % (self.__class__.__name__, self.realmName)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, realm):
</span><span class="cx"> super(InternalDirectoryService, self).__init__()
</span><span class="cx">
</span><span class="cx"> self.realmName = realm
</span><span class="cx"> self._records()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _records(self):
</span><span class="cx"> """
</span><span class="cx"> Build the list of records.
</span><del>-
</del><ins>+
</ins><span class="cx"> Right now we want public/global and public/directory for
</span><span class="cx"> global and directory address books.
</span><span class="cx"> """
</span><del>-
</del><ins>+
</ins><span class="cx"> if not hasattr(self, "_cachedRecords"):
</span><span class="cx"> self._cachedRecords = (
</span><span class="cx"> InternalDirectoryRecord(
</span><span class="lines">@@ -80,15 +82,18 @@
</span><span class="cx"> )
</span><span class="cx"> return self._cachedRecords
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def recordTypes(self):
</span><span class="cx"> return InternalDirectoryService.supportedRecordTypes
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def listRecords(self, recordType):
</span><span class="cx"> if recordType not in InternalDirectoryService.supportedRecordTypes:
</span><span class="cx"> raise UnknownRecordTypeError(recordType)
</span><span class="cx">
</span><span class="cx"> return self._records()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def recordWithShortName(self, recordType, shortName):
</span><span class="cx"> if recordType not in InternalDirectoryService.supportedRecordTypes:
</span><span class="cx"> raise UnknownRecordTypeError(recordType)
</span><span class="lines">@@ -97,11 +102,13 @@
</span><span class="cx"> if shortName in record.shortNames:
</span><span class="cx"> return record
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def requestAvatarId(self, credentials):
</span><span class="cx"> credentials = IPrincipalCredentials(credentials)
</span><span class="cx"> raise UnauthorizedLogin("No such user: %s" % (credentials.credentials.username,))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class InternalDirectoryRecord(DirectoryRecord):
</span><span class="cx"> """
</span><span class="cx"> L{DirectoryRecord} implementation for internal records.
</span><span class="lines">@@ -121,5 +128,6 @@
</span><span class="cx">
</span><span class="cx"> self.enabled = True # Explicitly enabled
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def verifyCredentials(self, credentials):
</span><span class="cx"> return False
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryldapdirectorypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -40,7 +40,6 @@
</span><span class="cx"> "LdapDirectoryService",
</span><span class="cx"> ]
</span><span class="cx">
</span><del>-import ldap
</del><span class="cx"> import ldap.async
</span><span class="cx"> from ldap.filter import escape_filter_chars as ldapEsc
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryresourceinfopy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/resourceinfo.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/resourceinfo.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/resourceinfo.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -62,12 +62,14 @@
</span><span class="cx"> autoSchedule = None
</span><span class="cx"> returnValue(autoSchedule)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, path):
</span><span class="cx"> path = os.path.join(path, ResourceInfoDatabase.dbFilename)
</span><span class="cx"> super(ResourceInfoDatabase, self).__init__(path, True)
</span><span class="cx">
</span><span class="cx"> self._memcacher = ResourceInfoDatabase.ResourceInfoDBMemcacher("resourceInfoDB")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def setAutoSchedule(self, guid, autoSchedule):
</span><span class="cx"> """
</span><span class="lines">@@ -81,6 +83,7 @@
</span><span class="cx"> # Update cache
</span><span class="cx"> (yield self._memcacher.setAutoSchedule(guid, autoSchedule))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def setAutoScheduleInDatabase(self, guid, autoSchedule):
</span><span class="cx"> """
</span><span class="cx"> A blocking call to set a resource/location's auto-Schedule boolean
</span><span class="lines">@@ -94,6 +97,7 @@
</span><span class="cx"> self._add_to_db(guid, autoSchedule)
</span><span class="cx"> self._db_commit()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def getAutoSchedule(self, guid):
</span><span class="cx"> """
</span><span class="lines">@@ -110,6 +114,7 @@
</span><span class="cx"> (yield self._memcacher.setAutoSchedule(guid, autoSchedule))
</span><span class="cx"> returnValue(autoSchedule)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _add_to_db(self, guid, autoSchedule):
</span><span class="cx"> """
</span><span class="cx"> Insert the specified entry into the database.
</span><span class="lines">@@ -124,6 +129,7 @@
</span><span class="cx"> """, guid, 1 if autoSchedule else 0
</span><span class="cx"> )
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _delete_from_db(self, guid):
</span><span class="cx"> """
</span><span class="cx"> Deletes the specified entry from the database.
</span><span class="lines">@@ -132,18 +138,21 @@
</span><span class="cx"> """
</span><span class="cx"> self._db_execute("delete from RESOURCEINFO where GUID = :1", guid)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _db_version(self):
</span><span class="cx"> """
</span><span class="cx"> @return: the schema version assigned to this index.
</span><span class="cx"> """
</span><span class="cx"> return ResourceInfoDatabase.dbFormatVersion
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _db_type(self):
</span><span class="cx"> """
</span><span class="cx"> @return: the collection type assigned to this index.
</span><span class="cx"> """
</span><span class="cx"> return ResourceInfoDatabase.dbType
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _db_init_data_tables(self, q):
</span><span class="cx"> """
</span><span class="cx"> Initialise the underlying database tables.
</span><span class="lines">@@ -166,4 +175,3 @@
</span><span class="cx"> create index RESOURCEGUIDS on RESOURCEINFO (GUID)
</span><span class="cx"> """
</span><span class="cx"> )
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectorytesttest_ldapdirectorypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -200,7 +200,6 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> class BuildFilterFromTokensTestCase(TestCase):
</span><span class="cx">
</span><span class="cx"> def test_buildFilterFromTokens(self):
</span><span class="lines">@@ -300,7 +299,6 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> class StubList(object):
</span><span class="cx"> def __init__(self, wrapper):
</span><span class="cx"> self.ldap = wrapper
</span><span class="lines">@@ -320,13 +318,11 @@
</span><span class="cx"> attrlist=self.attrList)
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> class StubAsync(object):
</span><span class="cx"> def List(self, wrapper):
</span><span class="cx"> return StubList(wrapper)
</span><span class="cx">
</span><span class="cx">
</span><del>-
</del><span class="cx"> class LdapDirectoryTestWrapper(object):
</span><span class="cx"> """
</span><span class="cx"> A test stub which replaces search_s( ) with a version that will return
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/util.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/util.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/util.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> return normalizeUUID(str(uuid5(UUID(namespace), name)))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def normalizeUUID(value):
</span><span class="cx"> """
</span><span class="cx"> Convert strings which the uuid.UUID( ) method can parse into normalized
</span><span class="lines">@@ -106,6 +107,7 @@
</span><span class="cx"> return transaction
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def splitIntoBatches(data, size):
</span><span class="cx"> """
</span><span class="cx"> Return a generator of sets consisting of the contents of the data set
</span><span class="lines">@@ -119,6 +121,7 @@
</span><span class="cx"> del data[:size]
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class NotFoundResource(DAVResource):
</span><span class="cx"> """
</span><span class="cx"> In order to prevent unauthenticated discovery of existing users via 401/404
</span><span class="lines">@@ -131,7 +134,7 @@
</span><span class="cx"> def renderHTTP(self, request):
</span><span class="cx">
</span><span class="cx"> try:
</span><del>- authnUser, authzUser = yield self.authenticate(request)
</del><ins>+ _ignore_authnUser, authzUser = yield self.authenticate(request)
</ins><span class="cx"> except Exception:
</span><span class="cx"> authzUser = davxml.Principal(davxml.Unauthenticated())
</span><span class="cx">
</span><span class="lines">@@ -145,4 +148,3 @@
</span><span class="cx"> else:
</span><span class="cx"> response = StatusResponse(responsecode.NOT_FOUND, "Resource not found")
</span><span class="cx"> returnValue(response)
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryxmlaccountsparserpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -36,30 +36,30 @@
</span><span class="cx">
</span><span class="cx"> log = Logger()
</span><span class="cx">
</span><del>-ELEMENT_ACCOUNTS = "accounts"
-ELEMENT_USER = "user"
-ELEMENT_GROUP = "group"
-ELEMENT_LOCATION = "location"
-ELEMENT_RESOURCE = "resource"
-ELEMENT_ADDRESS = "address"
</del><ins>+ELEMENT_ACCOUNTS = "accounts"
+ELEMENT_USER = "user"
+ELEMENT_GROUP = "group"
+ELEMENT_LOCATION = "location"
+ELEMENT_RESOURCE = "resource"
+ELEMENT_ADDRESS = "address"
</ins><span class="cx">
</span><del>-ELEMENT_SHORTNAME = "uid"
-ELEMENT_GUID = "guid"
-ELEMENT_PASSWORD = "password"
-ELEMENT_NAME = "name"
-ELEMENT_FIRST_NAME = "first-name"
-ELEMENT_LAST_NAME = "last-name"
-ELEMENT_EMAIL_ADDRESS = "email-address"
-ELEMENT_MEMBERS = "members"
-ELEMENT_MEMBER = "member"
-ELEMENT_EXTRAS = "extras"
</del><ins>+ELEMENT_SHORTNAME = "uid"
+ELEMENT_GUID = "guid"
+ELEMENT_PASSWORD = "password"
+ELEMENT_NAME = "name"
+ELEMENT_FIRST_NAME = "first-name"
+ELEMENT_LAST_NAME = "last-name"
+ELEMENT_EMAIL_ADDRESS = "email-address"
+ELEMENT_MEMBERS = "members"
+ELEMENT_MEMBER = "member"
+ELEMENT_EXTRAS = "extras"
</ins><span class="cx">
</span><del>-ATTRIBUTE_REALM = "realm"
-ATTRIBUTE_REPEAT = "repeat"
-ATTRIBUTE_RECORDTYPE = "type"
</del><ins>+ATTRIBUTE_REALM = "realm"
+ATTRIBUTE_REPEAT = "repeat"
+ATTRIBUTE_RECORDTYPE = "type"
</ins><span class="cx">
</span><del>-VALUE_TRUE = "true"
-VALUE_FALSE = "false"
</del><ins>+VALUE_TRUE = "true"
+VALUE_FALSE = "false"
</ins><span class="cx">
</span><span class="cx"> RECORD_TYPES = {
</span><span class="cx"> ELEMENT_USER : DirectoryService.recordType_users,
</span><span class="lines">@@ -76,6 +76,7 @@
</span><span class="cx"> def __repr__(self):
</span><span class="cx"> return "<%s %r>" % (self.__class__.__name__, self.xmlFile)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, xmlFile, externalUpdate=True):
</span><span class="cx">
</span><span class="cx"> if type(xmlFile) is str:
</span><span class="lines">@@ -84,7 +85,7 @@
</span><span class="cx"> self.xmlFile = xmlFile
</span><span class="cx"> self.realm = None
</span><span class="cx"> self.items = {}
</span><del>-
</del><ins>+
</ins><span class="cx"> for recordType in RECORD_TYPES.values():
</span><span class="cx"> self.items[recordType] = {}
</span><span class="cx">
</span><span class="lines">@@ -95,6 +96,7 @@
</span><span class="cx"> raise RuntimeError("XML parse error for '%s' because: %s" % (self.xmlFile, e,))
</span><span class="cx"> self._parseXML(accounts_node)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _parseXML(self, node):
</span><span class="cx"> """
</span><span class="cx"> Parse the XML root node from the accounts configuration document.
</span><span class="lines">@@ -120,7 +122,7 @@
</span><span class="cx"> principal = XMLAccountRecord(recordType)
</span><span class="cx"> principal.parseXML(child)
</span><span class="cx"> if repeat > 0:
</span><del>- for i in xrange(1, repeat+1):
</del><ins>+ for i in xrange(1, repeat + 1):
</ins><span class="cx"> newprincipal = principal.repeat(i)
</span><span class="cx"> self.items[recordType][newprincipal.shortNames[0]] = newprincipal
</span><span class="cx"> else:
</span><span class="lines">@@ -130,7 +132,9 @@
</span><span class="cx"> for records in self.items.itervalues():
</span><span class="cx"> for principal in records.itervalues():
</span><span class="cx"> updateMembership(principal)
</span><del>-
</del><ins>+
+
+
</ins><span class="cx"> class XMLAccountRecord (object):
</span><span class="cx"> """
</span><span class="cx"> Contains provision information for one user.
</span><span class="lines">@@ -151,6 +155,7 @@
</span><span class="cx"> self.groups = set()
</span><span class="cx"> self.extras = {}
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def repeat(self, ctr):
</span><span class="cx"> """
</span><span class="cx"> Create another object like this but with all text items having % substitution
</span><span class="lines">@@ -183,7 +188,7 @@
</span><span class="cx"> if m:
</span><span class="cx"> length = int(m.group(0)[1:])
</span><span class="cx"> hash = hashlib.md5(str(ctr)).hexdigest()
</span><del>- string = (hash*((length/32)+1))[:-(32-(length%32))]
</del><ins>+ string = (hash * ((length / 32) + 1))[:-(32 - (length % 32))]
</ins><span class="cx"> return text.replace(m.group(0), string)
</span><span class="cx"> return text
</span><span class="cx">
</span><span class="lines">@@ -223,7 +228,7 @@
</span><span class="cx"> emailAddresses.add(emailAddr % ctr)
</span><span class="cx"> else:
</span><span class="cx"> emailAddresses.add(emailAddr)
</span><del>-
</del><ins>+
</ins><span class="cx"> result = XMLAccountRecord(self.recordType)
</span><span class="cx"> result.shortNames = shortNames
</span><span class="cx"> result.guid = normalizeUUID(guid)
</span><span class="lines">@@ -236,6 +241,7 @@
</span><span class="cx"> result.extras = self.extras
</span><span class="cx"> return result
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def parseXML(self, node):
</span><span class="cx"> for child in node:
</span><span class="cx"> if child.tag == ELEMENT_SHORTNAME:
</span><span class="lines">@@ -264,12 +270,14 @@
</span><span class="cx"> if not self.shortNames:
</span><span class="cx"> self.shortNames.append(self.guid)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _parseMembers(self, node, addto):
</span><span class="cx"> for child in node:
</span><span class="cx"> if child.tag == ELEMENT_MEMBER:
</span><span class="cx"> recordType = child.get(ATTRIBUTE_RECORDTYPE, DirectoryService.recordType_users)
</span><span class="cx"> addto.add((recordType, child.text.encode("utf-8")))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _parseExtras(self, node, addto):
</span><span class="cx"> for child in node:
</span><span class="cx"> addto[child.tag] = child.text.encode("utf-8")
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/sql.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/sql.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -6861,4 +6861,3 @@
</span><span class="cx"> aboMembers.REVISION.In(Parameter("revisionsToRemove", len(revisionsToRemove)))
</span><span class="cx"> )
</span><span class="cx"> ).on(txn, revisionsToRemove=revisionsToRemove)
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktxdavidavpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/idav.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/idav.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/idav.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -240,9 +240,9 @@
</span><span class="cx"> types of changes to the appropriate push priority level.
</span><span class="cx"> TODO: make these values configurable in plist perhaps.
</span><span class="cx"> """
</span><del>- default = ValueConstant(PushPriority.high)
- inbox = ValueConstant(PushPriority.medium)
- attendeeITIPUpdate = ValueConstant(PushPriority.medium)
</del><ins>+ default = ValueConstant(PushPriority.high)
+ inbox = ValueConstant(PushPriority.medium)
+ attendeeITIPUpdate = ValueConstant(PushPriority.medium)
</ins><span class="cx"> organizerITIPUpdate = ValueConstant(PushPriority.medium)
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlbasepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/base.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/base.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/base.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -80,6 +80,7 @@
</span><span class="cx"> return sname.encode("utf-8")
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def decodeXMLName(name):
</span><span class="cx"> """
</span><span class="cx"> Decodes an XML (namespace, name) pair from an ASCII string as
</span><span class="lines">@@ -97,7 +98,7 @@
</span><span class="cx"> invalid()
</span><span class="cx">
</span><span class="cx"> namespace = name[1:index].decode("utf-8")
</span><del>- localname = name[index+1:].decode("utf-8")
</del><ins>+ localname = name[index + 1:].decode("utf-8")
</ins><span class="cx">
</span><span class="cx"> if not namespace:
</span><span class="cx"> namespace = None
</span><span class="lines">@@ -108,24 +109,25 @@
</span><span class="cx"> else:
</span><span class="cx"> namespace = None
</span><span class="cx"> localname = name.decode("utf-8")
</span><del>-
</del><ins>+
</ins><span class="cx"> if "{" in localname or "}" in localname:
</span><span class="cx"> invalid()
</span><span class="cx">
</span><span class="cx"> return (namespace, localname)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVElement (object):
</span><span class="cx"> """
</span><span class="cx"> WebDAV XML element. (RFC 2518, section 12)
</span><span class="cx"> """
</span><del>- namespace = dav_namespace # Element namespace (class variable)
- name = None # Element name (class variable)
- allowed_children = None # Types & count limits on child elements
</del><ins>+ namespace = dav_namespace # Element namespace (class variable)
+ name = None # Element name (class variable)
+ allowed_children = None # Types & count limits on child elements
</ins><span class="cx"> allowed_attributes = None # Allowed attribute names
</span><del>- hidden = False # Don't list in PROPFIND with <allprop>
- protected = False # See RFC 3253 section 1.4.1
- unregistered = False # Subclass of factory; doesn't register
</del><ins>+ hidden = False # Don't list in PROPFIND with <allprop>
+ protected = False # See RFC 3253 section 1.4.1
+ unregistered = False # Subclass of factory; doesn't register
</ins><span class="cx">
</span><span class="cx"> def __init__(self, *children, **attributes):
</span><span class="cx"> super(WebDAVElement, self).__init__()
</span><span class="lines">@@ -138,7 +140,7 @@
</span><span class="cx">
</span><span class="cx"> my_children = []
</span><span class="cx">
</span><del>- allowPCDATA = self.allowed_children.has_key(PCDATAElement)
</del><ins>+ allowPCDATA = PCDATAElement in self.allowed_children
</ins><span class="cx">
</span><span class="cx"> for child in children:
</span><span class="cx"> if child is None:
</span><span class="lines">@@ -155,14 +157,17 @@
</span><span class="cx"> self.children = tuple(my_children)
</span><span class="cx"> self.attributes = attributes
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @classmethod
</span><span class="cx"> def qname(cls):
</span><span class="cx"> return (cls.namespace, cls.name)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @classmethod
</span><span class="cx"> def sname(cls):
</span><span class="cx"> return encodeXMLName(cls.namespace, cls.name)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def validate(self):
</span><span class="cx"> children = self.children
</span><span class="cx"> attributes = self.attributes
</span><span class="lines">@@ -187,7 +192,7 @@
</span><span class="cx"> for child in children:
</span><span class="cx">
</span><span class="cx"> assert isinstance(child, (WebDAVElement, PCDATAElement)), "Not an element: %r" % (child,)
</span><del>-
</del><ins>+
</ins><span class="cx"> child.validate()
</span><span class="cx">
</span><span class="cx"> for allowed, (min, max) in allowed_children.items():
</span><span class="lines">@@ -244,36 +249,43 @@
</span><span class="cx">
</span><span class="cx"> self.attributes = my_attributes
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __str__(self):
</span><span class="cx"> return self.sname()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __repr__(self):
</span><span class="cx"> if hasattr(self, "attributes") and hasattr(self, "children"):
</span><span class="cx"> return "<%s %r: %r>" % (self.sname(), self.attributes, self.children)
</span><span class="cx"> else:
</span><span class="cx"> return "<%s>" % (self.sname())
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __eq__(self, other):
</span><span class="cx"> if isinstance(other, WebDAVElement):
</span><span class="cx"> return (
</span><del>- self.name == other.name and
- self.namespace == other.namespace and
</del><ins>+ self.name == other.name and
+ self.namespace == other.namespace and
</ins><span class="cx"> self.attributes == other.attributes and
</span><del>- self.children == other.children
</del><ins>+ self.children == other.children
</ins><span class="cx"> )
</span><span class="cx"> else:
</span><span class="cx"> return NotImplemented
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __ne__(self, other):
</span><span class="cx"> return not self.__eq__(other)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __contains__(self, child):
</span><span class="cx"> return child in self.children
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def writeXML(self, output, pretty=True):
</span><span class="cx"> output.write("<?xml version='1.0' encoding='UTF-8'?>" + ("\n" if pretty else ""))
</span><span class="cx"> self._writeToStream(output, "", 0, pretty)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _writeToStream(self, output, ns, level, pretty):
</span><span class="cx"> """
</span><span class="cx"> Fast XML output.
</span><span class="lines">@@ -283,11 +295,11 @@
</span><span class="cx"> @param level: C{int} containing the element nesting level (starts at 0).
</span><span class="cx"> @param pretty: C{bool} whether to use 'pretty' formatted output or not.
</span><span class="cx"> """
</span><del>-
</del><ins>+
</ins><span class="cx"> # Do pretty indent
</span><span class="cx"> if pretty and level:
</span><span class="cx"> output.write(" " * level)
</span><del>-
</del><ins>+
</ins><span class="cx"> # Check for empty element (one with either no children or a single PCDATA that is itself empty)
</span><span class="cx"> if (len(self.children) == 0 or
</span><span class="cx"> (len(self.children) == 1 and isinstance(self.children[0], PCDATAElement) and len(str(self.children[0])) == 0)):
</span><span class="lines">@@ -314,7 +326,7 @@
</span><span class="cx"> output.write(">")
</span><span class="cx"> else:
</span><span class="cx"> output.write("<%s>" % (self.name,))
</span><del>-
</del><ins>+
</ins><span class="cx"> # Determine nature of children when doing pretty print: we do
</span><span class="cx"> # not want to insert CRLFs or any other whitespace in PCDATA.
</span><span class="cx"> hasPCDATA = False
</span><span class="lines">@@ -322,13 +334,13 @@
</span><span class="cx"> if isinstance(child, PCDATAElement):
</span><span class="cx"> hasPCDATA = True
</span><span class="cx"> break
</span><del>-
</del><ins>+
</ins><span class="cx"> # Write out the children.
</span><span class="cx"> if pretty and not hasPCDATA:
</span><span class="cx"> output.write("\r\n")
</span><span class="cx"> for child in self.children:
</span><del>- child._writeToStream(output, ns, level+1, pretty)
-
</del><ins>+ child._writeToStream(output, ns, level + 1, pretty)
+
</ins><span class="cx"> # Close the element.
</span><span class="cx"> if pretty and not hasPCDATA and level:
</span><span class="cx"> output.write(" " * level)
</span><span class="lines">@@ -337,18 +349,21 @@
</span><span class="cx"> if pretty and level:
</span><span class="cx"> output.write("\r\n")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _writeAttributeToStream(self, output, name, value):
</span><del>-
</del><ins>+
</ins><span class="cx"> # Quote any single quotes. We do not need to be any smarter than this.
</span><span class="cx"> value = value.replace("'", "&apos;")
</span><span class="cx">
</span><del>- output.write(" %s='%s'" % (name, value,))
-
</del><ins>+ output.write(" %s='%s'" % (name, value,))
+
+
</ins><span class="cx"> def toxml(self, pretty=True):
</span><span class="cx"> output = StringIO.StringIO()
</span><span class="cx"> self.writeXML(output, pretty)
</span><span class="cx"> return str(output.getvalue())
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def element(self, document):
</span><span class="cx"> element = document.createElementNS(self.namespace, self.name)
</span><span class="cx"> if hasattr(self, "attributes"):
</span><span class="lines">@@ -359,6 +374,7 @@
</span><span class="cx"> element.setAttributeNodeNS(attribute)
</span><span class="cx"> return element
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def addToDOM(self, document, parent):
</span><span class="cx"> element = self.element(document)
</span><span class="cx">
</span><span class="lines">@@ -375,6 +391,7 @@
</span><span class="cx"> log.error("Unable to add child %r of element %s to DOM" % (child, self))
</span><span class="cx"> raise
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def childrenOfType(self, child_type):
</span><span class="cx"> """
</span><span class="cx"> Returns a list of children with the same qname as the given type.
</span><span class="lines">@@ -384,8 +401,9 @@
</span><span class="cx"> else:
</span><span class="cx"> qname = child_type.qname()
</span><span class="cx">
</span><del>- return [ c for c in self.children if c.qname() == qname ]
</del><ins>+ return [c for c in self.children if c.qname() == qname]
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> def childOfType(self, child_type):
</span><span class="cx"> """
</span><span class="cx"> Returns a child of the given type, if any, or None.
</span><span class="lines">@@ -398,6 +416,7 @@
</span><span class="cx"> found = child
</span><span class="cx"> return found
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def removeWhitespaceNodes(self):
</span><span class="cx"> """ Removes all of the whitespace-only text decendants of a DOM node. """
</span><span class="cx"> # prepare the list of text nodes to remove (and recurse when needed)
</span><span class="lines">@@ -418,6 +437,7 @@
</span><span class="cx"> self.children = tuple(newchildren)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class PCDATAElement (object):
</span><span class="cx"> def __init__(self, data):
</span><span class="cx"> super(PCDATAElement, self).__init__()
</span><span class="lines">@@ -431,29 +451,36 @@
</span><span class="cx">
</span><span class="cx"> self.data = data
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @classmethod
</span><span class="cx"> def qname(cls):
</span><span class="cx"> return (None, "#PCDATA")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @classmethod
</span><span class="cx"> def sname(cls):
</span><span class="cx"> return "#PCDATA"
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def validate(self):
</span><span class="cx"> pass
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __str__(self):
</span><span class="cx"> return str(self.data)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __repr__(self):
</span><span class="cx"> return "<%s: %r>" % (self.__class__.__name__, self.data)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __add__(self, other):
</span><span class="cx"> if isinstance(other, PCDATAElement):
</span><span class="cx"> return self.__class__(self.data + other.data)
</span><span class="cx"> else:
</span><span class="cx"> return self.__class__(self.data + other)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __eq__(self, other):
</span><span class="cx"> if isinstance(other, PCDATAElement):
</span><span class="cx"> return self.data == other.data
</span><span class="lines">@@ -462,18 +489,22 @@
</span><span class="cx"> else:
</span><span class="cx"> return NotImplemented
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __ne__(self, other):
</span><span class="cx"> return not self.__eq__(other)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def isWhitespace(self):
</span><span class="cx"> for char in str(self):
</span><span class="cx"> if char not in string.whitespace:
</span><span class="cx"> return False
</span><span class="cx"> return True
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def element(self, document):
</span><span class="cx"> return document.createTextNode(self.data)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def addToDOM(self, document, parent):
</span><span class="cx"> try:
</span><span class="cx"> parent.appendChild(self.element(document))
</span><span class="lines">@@ -481,6 +512,7 @@
</span><span class="cx"> log.error("Invalid PCDATA: %r" % (self.data,))
</span><span class="cx"> raise
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def _writeToStream(self, output, ns, level, pretty):
</span><span class="cx"> # Do escaping/CDATA behavior
</span><span class="cx"> if "\r" in self.data or "\n" in self.data:
</span><span class="lines">@@ -498,38 +530,40 @@
</span><span class="cx"> output.write(cdata)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVOneShotElement (WebDAVElement):
</span><span class="cx"> """
</span><span class="cx"> Element with exactly one WebDAVEmptyElement child and no attributes.
</span><span class="cx"> """
</span><span class="cx"> __singletons = {}
</span><span class="cx">
</span><del>- def __new__(clazz, *children):
</del><ins>+ def __new__(cls, *children):
</ins><span class="cx"> child = None
</span><span class="cx"> for next in children:
</span><span class="cx"> if isinstance(next, WebDAVEmptyElement):
</span><span class="cx"> if child is not None:
</span><span class="cx"> raise ValueError("%s must have exactly one child, not %r"
</span><del>- % (clazz.__name__, children))
</del><ins>+ % (cls.__name__, children))
</ins><span class="cx"> child = next
</span><span class="cx"> elif isinstance(next, PCDATAElement):
</span><span class="cx"> pass
</span><span class="cx"> else:
</span><span class="cx"> raise ValueError("%s child is not a WebDAVEmptyElement instance: %s"
</span><del>- % (clazz.__name__, next))
</del><ins>+ % (cls.__name__, next))
</ins><span class="cx">
</span><del>- if clazz not in WebDAVOneShotElement.__singletons:
- WebDAVOneShotElement.__singletons[clazz] = {
- child: WebDAVElement.__new__(clazz)
</del><ins>+ if cls not in WebDAVOneShotElement.__singletons:
+ WebDAVOneShotElement.__singletons[cls] = {
+ child: WebDAVElement.__new__(cls)
</ins><span class="cx"> }
</span><del>- elif child not in WebDAVOneShotElement.__singletons[clazz]:
- WebDAVOneShotElement.__singletons[clazz][child] = (
- WebDAVElement.__new__(clazz)
</del><ins>+ elif child not in WebDAVOneShotElement.__singletons[cls]:
+ WebDAVOneShotElement.__singletons[cls][child] = (
+ WebDAVElement.__new__(cls)
</ins><span class="cx"> )
</span><span class="cx">
</span><del>- return WebDAVOneShotElement.__singletons[clazz][child]
</del><ins>+ return WebDAVOneShotElement.__singletons[cls][child]
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVUnknownElement (WebDAVElement):
</span><span class="cx"> """
</span><span class="cx"> Placeholder for unknown element tag names.
</span><span class="lines">@@ -546,28 +580,31 @@
</span><span class="cx"> child.name = name
</span><span class="cx"> return child
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def qname(self):
</span><span class="cx"> return (self.namespace, self.name)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def sname(self):
</span><span class="cx"> return encodeXMLName(self.namespace, self.name)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVEmptyElement (WebDAVElement):
</span><span class="cx"> """
</span><span class="cx"> WebDAV element with no contents.
</span><span class="cx"> """
</span><span class="cx"> __singletons = {}
</span><span class="cx">
</span><del>- def __new__(clazz, *args, **kwargs):
</del><ins>+ def __new__(cls, *args, **kwargs):
</ins><span class="cx"> assert not args
</span><span class="cx">
</span><span class="cx"> if kwargs:
</span><del>- return WebDAVElement.__new__(clazz)
</del><ins>+ return WebDAVElement.__new__(cls)
</ins><span class="cx"> else:
</span><del>- if clazz not in WebDAVEmptyElement.__singletons:
- WebDAVEmptyElement.__singletons[clazz] = (WebDAVElement.__new__(clazz))
- return WebDAVEmptyElement.__singletons[clazz]
</del><ins>+ if cls not in WebDAVEmptyElement.__singletons:
+ WebDAVEmptyElement.__singletons[cls] = (WebDAVElement.__new__(cls))
+ return WebDAVEmptyElement.__singletons[cls]
</ins><span class="cx">
</span><span class="cx"> allowed_children = {}
</span><span class="cx"> children = ()
</span><span class="lines">@@ -581,6 +618,7 @@
</span><span class="cx"> return hash((self.name, self.namespace))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVTextElement (WebDAVElement):
</span><span class="cx"> """
</span><span class="cx"> WebDAV element containing PCDATA.
</span><span class="lines">@@ -594,7 +632,7 @@
</span><span class="cx"> else:
</span><span class="cx"> return clazz(PCDATAElement(str(string)))
</span><span class="cx">
</span><del>- allowed_children = { PCDATAElement: (0, None) }
</del><ins>+ allowed_children = {PCDATAElement: (0, None)}
</ins><span class="cx">
</span><span class="cx"> def toString(self):
</span><span class="cx"> """
</span><span class="lines">@@ -602,12 +640,14 @@
</span><span class="cx"> """
</span><span class="cx"> return self.__str__().decode("utf-8")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __str__(self):
</span><span class="cx"> """
</span><span class="cx"> @return: a byte string containing the text in this element.
</span><span class="cx"> """
</span><span class="cx"> return b"".join([c.data for c in self.children])
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __repr__(self):
</span><span class="cx"> content = str(self)
</span><span class="cx"> if content:
</span><span class="lines">@@ -615,6 +655,7 @@
</span><span class="cx"> else:
</span><span class="cx"> return "<%s>" % (self.sname(),)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __eq__(self, other):
</span><span class="cx"> if isinstance(other, self.__class__):
</span><span class="cx"> return str(self) == str(other)
</span><span class="lines">@@ -624,6 +665,7 @@
</span><span class="cx"> return NotImplemented
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVDateTimeElement (WebDAVTextElement):
</span><span class="cx"> """
</span><span class="cx"> WebDAV date-time element. (RFC 2518, section 23.2)
</span><span class="lines">@@ -654,16 +696,19 @@
</span><span class="cx">
</span><span class="cx"> return clazz(PCDATAElement(date))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, *children, **attributes):
</span><span class="cx"> super(WebDAVDateTimeElement, self).__init__(*children, **attributes)
</span><span class="cx"> self.datetime() # Raise ValueError if the format is wrong
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __eq__(self, other):
</span><span class="cx"> if isinstance(other, self.__class__):
</span><span class="cx"> return self.datetime() == other.datetime()
</span><span class="cx"> else:
</span><span class="cx"> return NotImplemented
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def datetime(self):
</span><span class="cx"> s = str(self)
</span><span class="cx"> if not s:
</span><span class="lines">@@ -672,6 +717,7 @@
</span><span class="cx"> return parse_date(s)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class DateTimeHeaderElement (WebDAVDateTimeElement):
</span><span class="cx"> """
</span><span class="cx"> WebDAV date-time element for elements that substitute for HTTP
</span><span class="lines">@@ -707,6 +753,7 @@
</span><span class="cx">
</span><span class="cx"> return clazz(PCDATAElement(date))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def datetime(self):
</span><span class="cx"> s = str(self)
</span><span class="cx"> if not s:
</span><span class="lines">@@ -715,6 +762,7 @@
</span><span class="cx"> return parseDateTime(s)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Utilities
</span><span class="cx"> ##
</span><span class="lines">@@ -727,13 +775,21 @@
</span><span class="cx"> super(FixedOffset, self).__init__()
</span><span class="cx">
</span><span class="cx"> self._offset = datetime.timedelta(minutes=offset)
</span><del>- self._name = name
</del><ins>+ self._name = name
</ins><span class="cx">
</span><del>- def utcoffset(self, dt): return self._offset
- def tzname (self, dt): return self._name
- def dst (self, dt): return datetime.timedelta(0)
</del><span class="cx">
</span><ins>+ def utcoffset(self, dt):
+ return self._offset
</ins><span class="cx">
</span><ins>+
+ def tzname(self, dt):
+ return self._name
+
+
+ def dst(self, dt):
+ return datetime.timedelta(0)
+
+
</ins><span class="cx"> _regex_ISO8601Date = re.compile(
</span><span class="cx"> "^" +
</span><span class="cx"> "(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})T" +
</span><span class="lines">@@ -760,19 +816,21 @@
</span><span class="cx"> if offset_sign is None:
</span><span class="cx"> offset = FixedOffset(0)
</span><span class="cx"> else:
</span><del>- offset_hour = int(match.group("offset_hour" ))
</del><ins>+ offset_hour = int(match.group("offset_hour"))
</ins><span class="cx"> offset_minute = int(match.group("offset_minute"))
</span><span class="cx">
</span><span class="cx"> delta = (offset_hour * 60) + offset_minute
</span><span class="cx">
</span><del>- if offset_sign == "+": offset = FixedOffset(0 - delta)
- elif offset_sign == "-": offset = FixedOffset(0 + delta)
</del><ins>+ if offset_sign == "+":
+ offset = FixedOffset(0 - delta)
+ elif offset_sign == "-":
+ offset = FixedOffset(0 + delta)
</ins><span class="cx">
</span><span class="cx"> return datetime.datetime(
</span><del>- int(match.group("year" )),
- int(match.group("month" )),
- int(match.group("day" )),
- int(match.group("hour" )),
</del><ins>+ int(match.group("year")),
+ int(match.group("month")),
+ int(match.group("day")),
+ int(match.group("hour")),
</ins><span class="cx"> int(match.group("minute")),
</span><span class="cx"> int(match.group("second")),
</span><span class="cx"> subsecond,
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlelementpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/element.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/element.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/element.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -65,19 +65,20 @@
</span><span class="cx"> assert elementClass.name, "Element has no name: %s" % (elementClass,)
</span><span class="cx">
</span><span class="cx"> qname = elementClass.namespace, elementClass.name
</span><del>-
</del><ins>+
</ins><span class="cx"> if qname in _elements_by_qname:
</span><span class="cx"> raise AssertionError(
</span><span class="cx"> "Attempting to register element %s multiple times: (%r, %r)"
</span><span class="cx"> % (elementClass.sname(), _elements_by_qname[qname], elementClass)
</span><span class="cx"> )
</span><del>-
</del><ins>+
</ins><span class="cx"> if not (qname in _elements_by_qname and issubclass(elementClass, _elements_by_qname[qname])):
</span><span class="cx"> _elements_by_qname[qname] = elementClass
</span><span class="cx">
</span><span class="cx"> return elementClass
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def registerElementClass(elementClass):
</span><span class="cx"> """
</span><span class="cx"> Add an XML element class to this module's namespace.
</span><span class="lines">@@ -97,6 +98,7 @@
</span><span class="cx"> return elementClass
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def lookupElement(qname):
</span><span class="cx"> """
</span><span class="cx"> Return the element class for the element with the given qname.
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlparserpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/parser.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/parser.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/parser.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlparser_basepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/parser_base.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/parser_base.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/parser_base.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> def fromStream(cls, source):
</span><span class="cx"> raise NotImplementedError()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @classmethod
</span><span class="cx"> def fromString(cls, source):
</span><span class="cx"> source = StringIO(source)
</span><span class="lines">@@ -45,6 +46,7 @@
</span><span class="cx"> finally:
</span><span class="cx"> source.close()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __init__(self, root_element):
</span><span class="cx"> """
</span><span class="cx"> root_element must be a WebDAVElement instance.
</span><span class="lines">@@ -56,18 +58,22 @@
</span><span class="cx">
</span><span class="cx"> self.root_element = root_element
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __str__(self):
</span><span class="cx"> return self.toxml()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def __eq__(self, other):
</span><span class="cx"> if isinstance(other, AbstractWebDAVDocument):
</span><span class="cx"> return self.root_element == other.root_element
</span><span class="cx"> else:
</span><span class="cx"> return NotImplemented
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def writeXML(self, output):
</span><span class="cx"> raise NotImplementedError()
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def toxml(self):
</span><span class="cx"> output = StringIO()
</span><span class="cx"> self.writeXML(output)
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlparser_etreepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/parser_etree.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/parser_etree.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/parser_etree.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> "WebDAVDocument",
</span><span class="cx"> ]
</span><span class="cx">
</span><del>-from xml.etree.ElementTree import TreeBuilder, XMLParser,\
</del><ins>+from xml.etree.ElementTree import TreeBuilder, XMLParser, \
</ins><span class="cx"> _namespace_map
</span><span class="cx"> from txdav.xml.base import WebDAVUnknownElement, PCDATAElement
</span><span class="cx"> from txdav.xml.base import _elements_by_qname
</span><span class="lines">@@ -39,15 +39,19 @@
</span><span class="cx"> except ImportError:
</span><span class="cx"> from xml.parsers.expat import ExpatError as XMLParseError
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> def QNameSplit(qname):
</span><span class="cx"> return tuple(qname[1:].split("}", 1)) if "}" in qname else ("", qname,)
</span><span class="cx">
</span><ins>+
+
</ins><span class="cx"> class WebDAVContentHandler (TreeBuilder):
</span><span class="cx">
</span><span class="cx"> def __init__(self):
</span><span class="cx"> TreeBuilder.__init__(self)
</span><span class="cx"> self._characterBuffer = None
</span><del>-
</del><ins>+
</ins><span class="cx"> self.startDocument()
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -56,7 +60,6 @@
</span><span class="cx"> Doctype declaration is ignored.
</span><span class="cx"> """
</span><span class="cx">
</span><del>-
</del><span class="cx"> def startDocument(self):
</span><span class="cx"> self.stack = [{
</span><span class="cx"> "name" : None,
</span><span class="lines">@@ -71,6 +74,7 @@
</span><span class="cx"> # multiple times in a document.
</span><span class="cx"> self.unknownElementClasses = {}
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def close(self):
</span><span class="cx"> top = self.stack[-1]
</span><span class="cx">
</span><span class="lines">@@ -83,12 +87,14 @@
</span><span class="cx"> del(self.unknownElementClasses)
</span><span class="cx"> return self.dom
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def data(self, data):
</span><span class="cx"> # Stash character data away in a list that we will "".join() when done
</span><span class="cx"> if self._characterBuffer is None:
</span><span class="cx"> self._characterBuffer = []
</span><span class="cx"> self._characterBuffer.append(data)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def start(self, tag, attrs):
</span><span class="cx"> name = QNameSplit(tag)
</span><span class="cx">
</span><span class="lines">@@ -117,7 +123,7 @@
</span><span class="cx"> def element_class(*args, **kwargs):
</span><span class="cx"> element = WebDAVUnknownElement(*args, **kwargs)
</span><span class="cx"> element.namespace = tag_namespace
</span><del>- element.name = tag_name
</del><ins>+ element.name = tag_name
</ins><span class="cx"> return element
</span><span class="cx"> self.unknownElementClasses[name] = element_class
</span><span class="cx">
</span><span class="lines">@@ -128,6 +134,7 @@
</span><span class="cx"> "children" : [],
</span><span class="cx"> })
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def end(self, tag):
</span><span class="cx"> name = QNameSplit(tag)
</span><span class="cx">
</span><span class="lines">@@ -149,10 +156,11 @@
</span><span class="cx"> self.stack[-1]["children"].append(element)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVDocument(AbstractWebDAVDocument):
</span><span class="cx"> @classmethod
</span><span class="cx"> def fromStream(cls, source):
</span><del>- parser = XMLParser(target=WebDAVContentHandler())
</del><ins>+ parser = XMLParser(target=WebDAVContentHandler())
</ins><span class="cx"> try:
</span><span class="cx"> while 1:
</span><span class="cx"> data = source.read(65536)
</span><span class="lines">@@ -162,6 +170,7 @@
</span><span class="cx"> except XMLParseError, e:
</span><span class="cx"> raise ValueError(e)
</span><span class="cx"> return parser.close()
</span><del>-
</del><ins>+
+
</ins><span class="cx"> def writeXML(self, output):
</span><span class="cx"> self.root_element.writeXML(output)
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlparser_saxpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/parser_sax.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/parser_sax.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/parser_sax.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -33,17 +33,22 @@
</span><span class="cx"> from txdav.xml.xmlext import Print as xmlPrint
</span><span class="cx">
</span><span class="cx">
</span><del>-class WebDAVContentHandler (xml.sax.handler.ContentHandler):
- def setDocumentLocator(self, locator): self.locator = locator
</del><ins>+class WebDAVContentHandler(xml.sax.handler.ContentHandler):
+
+ def setDocumentLocator(self, locator):
+ self.locator = locator
+
</ins><span class="cx"> locator = None
</span><span class="cx">
</span><span class="cx"> def __init__(self):
</span><span class="cx"> xml.sax.handler.ContentHandler.__init__(self)
</span><span class="cx"> self._characterBuffer = None
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def location(self):
</span><span class="cx"> return "line %d, column %d" % (self.locator.getLineNumber(), self.locator.getColumnNumber())
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def startDocument(self):
</span><span class="cx"> self.stack = [{
</span><span class="cx"> "name" : None,
</span><span class="lines">@@ -58,6 +63,7 @@
</span><span class="cx"> # multiple times in a document.
</span><span class="cx"> self.unknownElementClasses = {}
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def endDocument(self):
</span><span class="cx"> top = self.stack[-1]
</span><span class="cx">
</span><span class="lines">@@ -69,6 +75,7 @@
</span><span class="cx"> self.dom = WebDAVDocument(top["children"][0])
</span><span class="cx"> del(self.unknownElementClasses)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def startElementNS(self, name, qname, attributes):
</span><span class="cx"> if self._characterBuffer is not None:
</span><span class="cx"> pcdata = PCDATAElement("".join(self._characterBuffer))
</span><span class="lines">@@ -91,7 +98,7 @@
</span><span class="cx"> def element_class(*args, **kwargs):
</span><span class="cx"> element = WebDAVUnknownElement(*args, **kwargs)
</span><span class="cx"> element.namespace = tag_namespace
</span><del>- element.name = tag_name
</del><ins>+ element.name = tag_name
</ins><span class="cx"> return element
</span><span class="cx"> self.unknownElementClasses[name] = element_class
</span><span class="cx">
</span><span class="lines">@@ -102,6 +109,7 @@
</span><span class="cx"> "children" : [],
</span><span class="cx"> })
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def endElementNS(self, name, qname):
</span><span class="cx"> if self._characterBuffer is not None:
</span><span class="cx"> pcdata = PCDATAElement("".join(self._characterBuffer))
</span><span class="lines">@@ -124,33 +132,41 @@
</span><span class="cx">
</span><span class="cx"> self.stack[-1]["children"].append(element)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def characters(self, content):
</span><span class="cx"> # Stash character data away in a list that we will "".join() when done
</span><span class="cx"> if self._characterBuffer is None:
</span><span class="cx"> self._characterBuffer = []
</span><span class="cx"> self._characterBuffer.append(content)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def ignorableWhitespace(self, whitespace):
</span><span class="cx"> self.characters(self, whitespace)
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def startElement(self, name, attributes):
</span><span class="cx"> raise AssertionError("startElement() should not be called by namespace-aware parser")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def endElement(self, name):
</span><span class="cx"> raise AssertionError("endElement() should not be called by namespace-aware parser")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def processingInstruction(self, target, data):
</span><span class="cx"> raise AssertionError("processing instructions are not allowed")
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def skippedEntity(self, name):
</span><span class="cx"> raise AssertionError("skipped entities are not allowed")
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVDocument(AbstractWebDAVDocument):
</span><ins>+
</ins><span class="cx"> @classmethod
</span><span class="cx"> def fromStream(cls, source):
</span><span class="cx"> handler = WebDAVContentHandler()
</span><del>- parser = xml.sax.make_parser()
</del><ins>+ parser = xml.sax.make_parser()
</ins><span class="cx">
</span><span class="cx"> parser.setContentHandler(handler)
</span><span class="cx"> parser.setFeature(xml.sax.handler.feature_namespaces, True)
</span><span class="lines">@@ -163,7 +179,8 @@
</span><span class="cx"> #handler.dom.root_element.validate()
</span><span class="cx">
</span><span class="cx"> return handler.dom
</span><del>-
</del><ins>+
+
</ins><span class="cx"> def writeXML(self, output):
</span><span class="cx"> document = xml.dom.minidom.Document()
</span><span class="cx"> self.root_element.addToDOM(document, None)
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlrfc2518py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/rfc2518.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/rfc2518.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/rfc2518.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -56,14 +56,15 @@
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><span class="cx"> (dav_namespace, "lockscope"): (1, 1),
</span><del>- (dav_namespace, "locktype" ): (1, 1),
- (dav_namespace, "depth" ): (1, 1),
- (dav_namespace, "owner" ): (0, 1),
- (dav_namespace, "timeout" ): (0, 1),
</del><ins>+ (dav_namespace, "locktype"): (1, 1),
+ (dav_namespace, "depth"): (1, 1),
+ (dav_namespace, "owner"): (0, 1),
+ (dav_namespace, "timeout"): (0, 1),
</ins><span class="cx"> (dav_namespace, "locktoken"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Depth (WebDAVTextElement):
</span><span class="lines">@@ -80,6 +81,7 @@
</span><span class="cx"> raise ValueError("Invalid depth: %s" % (depth,))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class LockToken (WebDAVElement):
</span><span class="lines">@@ -88,9 +90,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "locktoken"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (1, None) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (1, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Timeout (WebDAVTextElement):
</span><span class="lines">@@ -100,6 +103,7 @@
</span><span class="cx"> name = "timeout"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Collection (WebDAVEmptyElement):
</span><span class="lines">@@ -109,6 +113,7 @@
</span><span class="cx"> name = "collection"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class HRef (WebDAVTextElement):
</span><span class="lines">@@ -118,6 +123,7 @@
</span><span class="cx"> name = "href"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Link (WebDAVElement):
</span><span class="lines">@@ -133,6 +139,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class LinkDestination (WebDAVTextElement):
</span><span class="lines">@@ -142,6 +149,7 @@
</span><span class="cx"> name = "dst"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class LinkSource (WebDAVTextElement):
</span><span class="lines">@@ -151,6 +159,7 @@
</span><span class="cx"> name = "src"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class LockEntry (WebDAVElement):
</span><span class="lines">@@ -162,10 +171,11 @@
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><span class="cx"> (dav_namespace, "lockscope"): (1, 1),
</span><del>- (dav_namespace, "locktype" ): (1, 1),
</del><ins>+ (dav_namespace, "locktype"): (1, 1),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class LockInfo (WebDAVElement):
</span><span class="lines">@@ -177,11 +187,12 @@
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><span class="cx"> (dav_namespace, "lockscope"): (1, 1),
</span><del>- (dav_namespace, "locktype" ): (1, 1),
- (dav_namespace, "owner" ): (0, 1),
</del><ins>+ (dav_namespace, "locktype"): (1, 1),
+ (dav_namespace, "owner"): (0, 1),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class LockScope (WebDAVOneShotElement):
</span><span class="lines">@@ -193,10 +204,11 @@
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><span class="cx"> (dav_namespace, "exclusive"): (0, 1),
</span><del>- (dav_namespace, "shared" ): (0, 1),
</del><ins>+ (dav_namespace, "shared"): (0, 1),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Exclusive (WebDAVEmptyElement):
</span><span class="lines">@@ -227,9 +239,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "locktype"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "write"): (0, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "write"): (0, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Write (WebDAVEmptyElement):
</span><span class="lines">@@ -253,11 +266,12 @@
</span><span class="cx"> name = "multistatus"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "response" ): (0, None),
</del><ins>+ (dav_namespace, "response"): (0, None),
</ins><span class="cx"> (dav_namespace, "responsedescription"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Response (WebDAVElement):
</span><span class="lines">@@ -268,46 +282,51 @@
</span><span class="cx"> name = "response"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "href" ): (1, None),
- (dav_namespace, "status" ): (1, 1),
- (dav_namespace, "propstat" ): (1, None),
- (dav_namespace, "error" ): (0, 1), # 2518bis
</del><ins>+ (dav_namespace, "href"): (1, None),
+ (dav_namespace, "status"): (1, 1),
+ (dav_namespace, "propstat"): (1, None),
+ (dav_namespace, "error"): (0, 1), # 2518bis
</ins><span class="cx"> (dav_namespace, "responsedescription"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><del>- def __new__(clazz, *children):
- if clazz is not Response: return WebDAVElement.__new__(clazz)
</del><ins>+ def __new__(cls, *children):
+ if cls is not Response:
+ return WebDAVElement.__new__(cls)
</ins><span class="cx">
</span><span class="cx"> resource_count = 0
</span><del>- status_count = 0
</del><ins>+ status_count = 0
</ins><span class="cx"> propstat_count = 0
</span><span class="cx">
</span><span class="cx"> for child in children:
</span><del>- if isinstance(child, HRef ): resource_count += 1
- elif isinstance(child, Status ): status_count += 1
- elif isinstance(child, PropertyStatus): propstat_count += 1
</del><ins>+ if isinstance(child, HRef):
+ resource_count += 1
+ elif isinstance(child, Status):
+ status_count += 1
+ elif isinstance(child, PropertyStatus):
+ propstat_count += 1
</ins><span class="cx">
</span><span class="cx"> if resource_count < 1:
</span><span class="cx"> raise ValueError("%s element must have at least one %s."
</span><del>- % (clazz.sname(), HRef.sname()))
</del><ins>+ % (cls.sname(), HRef.sname()))
</ins><span class="cx">
</span><span class="cx"> if status_count is 0:
</span><span class="cx"> if propstat_count is 0:
</span><span class="cx"> raise ValueError("%s element must have one of %s or %s"
</span><del>- % (clazz.sname(), Status.sname(), PropertyStatus.sname()))
</del><ins>+ % (cls.sname(), Status.sname(), PropertyStatus.sname()))
</ins><span class="cx">
</span><span class="cx"> if resource_count > 1:
</span><span class="cx"> raise ValueError("%s element with %s may only have one %s"
</span><del>- % (clazz.sname(), PropertyStatus.sname(), HRef.sname()))
</del><ins>+ % (cls.sname(), PropertyStatus.sname(), HRef.sname()))
</ins><span class="cx">
</span><span class="cx"> return PropertyStatusResponse.__new__(PropertyStatusResponse, *children)
</span><span class="cx">
</span><span class="cx"> if status_count > 1:
</span><del>- raise ValueError("%s element may only have one %s" % (clazz.sname(), Status.sname()))
</del><ins>+ raise ValueError("%s element may only have one %s" % (cls.sname(), Status.sname()))
</ins><span class="cx">
</span><span class="cx"> return StatusResponse.__new__(StatusResponse, *children)
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElementClass
</span><span class="cx"> class StatusResponse (Response):
</span><span class="cx"> """
</span><span class="lines">@@ -316,13 +335,14 @@
</span><span class="cx"> unregistered = True
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "href" ): (1, None),
- (dav_namespace, "status" ): (1, 1),
- (dav_namespace, "error" ): (0, 1), # 2518bis
</del><ins>+ (dav_namespace, "href"): (1, None),
+ (dav_namespace, "status"): (1, 1),
+ (dav_namespace, "error"): (0, 1), # 2518bis
</ins><span class="cx"> (dav_namespace, "responsedescription"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertyStatusResponse (Response):
</span><span class="cx"> """
</span><span class="lines">@@ -331,13 +351,14 @@
</span><span class="cx"> unregistered = True
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "href" ): (1, 1),
- (dav_namespace, "propstat" ): (1, None),
- (dav_namespace, "error" ): (0, 1), # 2518bis
</del><ins>+ (dav_namespace, "href"): (1, 1),
+ (dav_namespace, "propstat"): (1, None),
+ (dav_namespace, "error"): (0, 1), # 2518bis
</ins><span class="cx"> (dav_namespace, "responsedescription"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertyStatus (WebDAVElement):
</span><span class="lines">@@ -348,13 +369,14 @@
</span><span class="cx"> name = "propstat"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "prop" ): (1, 1),
- (dav_namespace, "status" ): (1, 1),
- (dav_namespace, "error" ): (0, 1), # 2518bis
</del><ins>+ (dav_namespace, "prop"): (1, 1),
+ (dav_namespace, "status"): (1, 1),
+ (dav_namespace, "error"): (0, 1), # 2518bis
</ins><span class="cx"> (dav_namespace, "responsedescription"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Status (WebDAVTextElement):
</span><span class="lines">@@ -363,6 +385,7 @@
</span><span class="cx"> """
</span><span class="cx"> name = "status"
</span><span class="cx">
</span><ins>+ @classmethod
</ins><span class="cx"> def fromResponseCode(clazz, code):
</span><span class="cx"> """
</span><span class="cx"> code must be an integer response code in
</span><span class="lines">@@ -373,7 +396,6 @@
</span><span class="cx">
</span><span class="cx"> return clazz(PCDATAElement("HTTP/1.1 %d %s" % (code, responsecode.RESPONSES[code])))
</span><span class="cx">
</span><del>- fromResponseCode = classmethod(fromResponseCode)
</del><span class="cx">
</span><span class="cx"> def __init__(self, *children, **attributes):
</span><span class="cx"> super(Status, self).__init__(*children, **attributes)
</span><span class="lines">@@ -389,6 +411,7 @@
</span><span class="cx"> self.code = code
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ResponseDescription (WebDAVTextElement):
</span><span class="lines">@@ -399,6 +422,7 @@
</span><span class="cx"> name = "responsedescription"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Owner (WebDAVElement):
</span><span class="lines">@@ -414,9 +438,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True # may be protected, per RFC 3744, section 5.1
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertyContainer (WebDAVElement):
</span><span class="lines">@@ -425,9 +450,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "prop"
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertyBehavior (WebDAVElement):
</span><span class="lines">@@ -438,7 +464,7 @@
</span><span class="cx"> name = "propertybehavior"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "omit" ): (0, 1),
</del><ins>+ (dav_namespace, "omit"): (0, 1),
</ins><span class="cx"> (dav_namespace, "keepalive"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -454,6 +480,7 @@
</span><span class="cx"> self.behavior = children[0]
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class KeepAlive (WebDAVElement):
</span><span class="lines">@@ -487,6 +514,7 @@
</span><span class="cx"> raise ValueError("Invalid keepalive value: %r", (str(self),))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Omit (WebDAVEmptyElement):
</span><span class="lines">@@ -497,6 +525,7 @@
</span><span class="cx"> name = "omit"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertyUpdate (WebDAVElement):
</span><span class="lines">@@ -508,10 +537,11 @@
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><span class="cx"> (dav_namespace, "remove"): (0, None),
</span><del>- (dav_namespace, "set" ): (0, None),
</del><ins>+ (dav_namespace, "set"): (0, None),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Remove (WebDAVElement):
</span><span class="lines">@@ -521,9 +551,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "remove"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "prop"): (1, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "prop"): (1, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Set (WebDAVElement):
</span><span class="lines">@@ -533,9 +564,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "set"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "prop"): (1, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "prop"): (1, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertyFind (WebDAVElement):
</span><span class="lines">@@ -546,9 +578,9 @@
</span><span class="cx"> name = "propfind"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "allprop" ): (0, 1),
</del><ins>+ (dav_namespace, "allprop"): (0, 1),
</ins><span class="cx"> (dav_namespace, "propname"): (0, 1),
</span><del>- (dav_namespace, "prop" ): (0, 1),
</del><ins>+ (dav_namespace, "prop"): (0, 1),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> def validate(self):
</span><span class="lines">@@ -561,6 +593,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class AllProperties (WebDAVEmptyElement):
</span><span class="lines">@@ -571,6 +604,7 @@
</span><span class="cx"> name = "allprop"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertyName (WebDAVEmptyElement):
</span><span class="lines">@@ -581,6 +615,7 @@
</span><span class="cx"> name = "propname"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Section 13
</span><span class="cx"> ##
</span><span class="lines">@@ -597,6 +632,7 @@
</span><span class="cx"> protected = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class DisplayName (WebDAVTextElement):
</span><span class="lines">@@ -607,6 +643,7 @@
</span><span class="cx"> name = "displayname"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GETContentLanguage (WebDAVTextElement):
</span><span class="lines">@@ -617,6 +654,7 @@
</span><span class="cx"> name = "getcontentlanguage"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GETContentLength (WebDAVTextElement):
</span><span class="lines">@@ -628,6 +666,7 @@
</span><span class="cx"> protected = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GETContentType (WebDAVTextElement):
</span><span class="lines">@@ -641,6 +680,7 @@
</span><span class="cx"> return MimeType.fromString(str(self))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GETETag (WebDAVTextElement):
</span><span class="lines">@@ -652,6 +692,7 @@
</span><span class="cx"> protected = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GETLastModified (DateTimeHeaderElement):
</span><span class="lines">@@ -663,6 +704,7 @@
</span><span class="cx"> protected = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class LockDiscovery (WebDAVElement):
</span><span class="lines">@@ -672,9 +714,10 @@
</span><span class="cx"> name = "lockdiscovery"
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "activelock"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "activelock"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ResourceType (WebDAVElement):
</span><span class="lines">@@ -684,10 +727,10 @@
</span><span class="cx"> name = "resourcetype"
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx"> ResourceType.collection = ResourceType(Collection())
</span><del>-ResourceType.empty = ResourceType()
</del><ins>+ResourceType.empty = ResourceType()
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @registerElement
</span><span class="lines">@@ -700,9 +743,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "source"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "link"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "link"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedLock (WebDAVElement):
</span><span class="lines">@@ -713,12 +757,12 @@
</span><span class="cx"> name = "supportedlock"
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "lockentry"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "lockentry"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # FIXME: Add preconditions codes defined in RFC4918
</span><span class="cx">
</span><del>-
</del><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropfindFiniteDepth (WebDAVEmptyElement):
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlrfc3253py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/rfc3253.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/rfc3253.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/rfc3253.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -49,9 +49,10 @@
</span><span class="cx"> # FIXME: Move when we update to RFC 2518bis
</span><span class="cx"> name = "error"
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Section 3
</span><span class="cx"> ##
</span><span class="lines">@@ -68,6 +69,7 @@
</span><span class="cx"> hidden = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class CreatorDisplayName (WebDAVTextElement):
</span><span class="lines">@@ -79,6 +81,7 @@
</span><span class="cx"> hidden = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedMethod (WebDAVElement):
</span><span class="lines">@@ -92,10 +95,11 @@
</span><span class="cx"> name = "supported-method"
</span><span class="cx"> hidden = True
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
- allowed_attributes = { "name": True }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
+ allowed_attributes = {"name": True}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedMethodSet (WebDAVElement):
</span><span class="lines">@@ -107,9 +111,10 @@
</span><span class="cx"> protected = True
</span><span class="cx"> hidden = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "supported-method"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "supported-method"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedLiveProperty (WebDAVElement):
</span><span class="lines">@@ -124,9 +129,10 @@
</span><span class="cx"> name = "supported-live-property"
</span><span class="cx">
</span><span class="cx"> # FIXME: Where is the name element defined?
</span><del>- allowed_children = { (dav_namespace, "name"): (1, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "name"): (1, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedLivePropertySet (WebDAVElement):
</span><span class="lines">@@ -138,9 +144,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "supported-live-property"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "supported-live-property"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Report (WebDAVElement):
</span><span class="lines">@@ -150,9 +157,10 @@
</span><span class="cx"> # FIXME: Section 3.1.5 is pretty low on information. Where else do we look?
</span><span class="cx"> name = "report"
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedReport (WebDAVElement):
</span><span class="lines">@@ -185,9 +193,10 @@
</span><span class="cx"> # Absent any better guidance, we'll allow no children for this element for
</span><span class="cx"> # the time being.
</span><span class="cx"> #
</span><del>- allowed_children = { (dav_namespace, "report"): (0, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "report"): (0, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedReportSet (WebDAVElement):
</span><span class="lines">@@ -199,9 +208,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "supported-report"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "supported-report"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ExpandProperty (WebDAVElement):
</span><span class="lines">@@ -212,9 +222,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "expand-property"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "property"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "property"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Property (WebDAVElement):
</span><span class="lines">@@ -227,7 +238,7 @@
</span><span class="cx"> """
</span><span class="cx"> name = "property"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "property"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "property"): (0, None)}
</ins><span class="cx"> allowed_attributes = {
</span><span class="cx"> "name" : True,
</span><span class="cx"> "namespace" : False,
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlrfc3744py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/rfc3744.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/rfc3744.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/rfc3744.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> name = "read"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # For DAV:write element (RFC 3744, section 3.2) see Write class in
</span><span class="cx"> # rfc2518.py.
</span><span class="cx">
</span><span class="lines">@@ -65,6 +66,7 @@
</span><span class="cx"> name = "write-properties"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class WriteContent (WebDAVEmptyElement):
</span><span class="lines">@@ -75,6 +77,7 @@
</span><span class="cx"> name = "write-content"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Unlock (WebDAVEmptyElement):
</span><span class="lines">@@ -85,6 +88,7 @@
</span><span class="cx"> name = "unlock"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ReadACL (WebDAVEmptyElement):
</span><span class="lines">@@ -95,6 +99,7 @@
</span><span class="cx"> name = "read-acl"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ReadCurrentUserPrivilegeSet (WebDAVEmptyElement):
</span><span class="lines">@@ -106,6 +111,7 @@
</span><span class="cx"> name = "read-current-user-privilege-set"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class WriteACL (WebDAVEmptyElement):
</span><span class="lines">@@ -116,6 +122,7 @@
</span><span class="cx"> name = "write-acl"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Bind (WebDAVEmptyElement):
</span><span class="lines">@@ -126,6 +133,7 @@
</span><span class="cx"> name = "bind"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Unbind (WebDAVEmptyElement):
</span><span class="lines">@@ -136,6 +144,7 @@
</span><span class="cx"> name = "unbind"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class All (WebDAVEmptyElement):
</span><span class="lines">@@ -147,6 +156,7 @@
</span><span class="cx"> name = "all"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Section 4 (Principal Properties)
</span><span class="cx"> ##
</span><span class="lines">@@ -161,12 +171,12 @@
</span><span class="cx"> name = "principal"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "href" ): (0, 1),
- (dav_namespace, "all" ): (0, 1),
- (dav_namespace, "authenticated" ): (0, 1),
</del><ins>+ (dav_namespace, "href"): (0, 1),
+ (dav_namespace, "all"): (0, 1),
+ (dav_namespace, "authenticated"): (0, 1),
</ins><span class="cx"> (dav_namespace, "unauthenticated"): (0, 1),
</span><del>- (dav_namespace, "property" ): (0, 1),
- (dav_namespace, "self" ): (0, 1),
</del><ins>+ (dav_namespace, "property"): (0, 1),
+ (dav_namespace, "self"): (0, 1),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> def validate(self):
</span><span class="lines">@@ -181,6 +191,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class AlternateURISet (WebDAVElement):
</span><span class="lines">@@ -192,9 +203,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PrincipalURL (WebDAVElement):
</span><span class="lines">@@ -206,9 +218,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GroupMemberSet (WebDAVElement):
</span><span class="lines">@@ -220,9 +233,10 @@
</span><span class="cx"> name = "group-member-set"
</span><span class="cx"> hidden = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GroupMembership (WebDAVElement):
</span><span class="lines">@@ -234,9 +248,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Section 5 (Access Control Properties)
</span><span class="cx"> ##
</span><span class="lines">@@ -256,9 +271,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True # may be protected, per RFC 3744, section 5.2
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedPrivilegeSet (WebDAVElement):
</span><span class="lines">@@ -270,9 +286,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "supported-privilege"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "supported-privilege"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class SupportedPrivilege (WebDAVElement):
</span><span class="lines">@@ -282,13 +299,14 @@
</span><span class="cx"> name = "supported-privilege"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "privilege" ): (1, 1),
- (dav_namespace, "abstract" ): (0, 1),
- (dav_namespace, "description" ): (1, 1),
</del><ins>+ (dav_namespace, "privilege"): (1, 1),
+ (dav_namespace, "abstract"): (0, 1),
+ (dav_namespace, "description"): (1, 1),
</ins><span class="cx"> (dav_namespace, "supported-privilege"): (0, None),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Privilege (WebDAVElement):
</span><span class="lines">@@ -297,7 +315,7 @@
</span><span class="cx"> """
</span><span class="cx"> name = "privilege"
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx"> def isAggregateOf(self, subprivilege, supportedPrivileges):
</span><span class="cx"> """
</span><span class="lines">@@ -339,6 +357,7 @@
</span><span class="cx"> else:
</span><span class="cx"> return False
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def expandAggregate(self, supportedPrivileges):
</span><span class="cx"> """
</span><span class="cx"> Expand this privilege into the set of privileges aggregated under it
</span><span class="lines">@@ -384,6 +403,7 @@
</span><span class="cx"> return aggregates
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Abstract (WebDAVElement):
</span><span class="lines">@@ -393,6 +413,7 @@
</span><span class="cx"> name = "abstract"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Description (WebDAVTextElement):
</span><span class="lines">@@ -401,9 +422,10 @@
</span><span class="cx"> 3744, sections 5.3 and 9.5)
</span><span class="cx"> """
</span><span class="cx"> name = "description"
</span><del>- allowed_attributes = { "xml:lang": True }
</del><ins>+ allowed_attributes = {"xml:lang": True}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class CurrentUserPrivilegeSet (WebDAVElement):
</span><span class="lines">@@ -416,9 +438,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "privilege"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "privilege"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # For DAV:privilege element (RFC 3744, section 5.4) see Privilege class above.
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -434,9 +457,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "ace"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "ace"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ACE (WebDAVElement):
</span><span class="lines">@@ -448,9 +472,9 @@
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><span class="cx"> (dav_namespace, "principal"): (0, 1),
</span><del>- (dav_namespace, "invert" ): (0, 1),
- (dav_namespace, "grant" ): (0, 1),
- (dav_namespace, "deny" ): (0, 1),
</del><ins>+ (dav_namespace, "invert"): (0, 1),
+ (dav_namespace, "grant"): (0, 1),
+ (dav_namespace, "deny"): (0, 1),
</ins><span class="cx"> (dav_namespace, "protected"): (0, 1),
</span><span class="cx"> (dav_namespace, "inherited"): (0, 1),
</span><span class="cx"> }
</span><span class="lines">@@ -458,12 +482,12 @@
</span><span class="cx"> def __init__(self, *children, **attributes):
</span><span class="cx"> super(ACE, self).__init__(*children, **attributes)
</span><span class="cx">
</span><del>- self.principal = None
- self.invert = None
- self.allow = None
</del><ins>+ self.principal = None
+ self.invert = None
+ self.allow = None
</ins><span class="cx"> self.privileges = None
</span><del>- self.inherited = None
- self.protected = False
</del><ins>+ self.inherited = None
+ self.protected = False
</ins><span class="cx">
</span><span class="cx"> my_children = []
</span><span class="cx">
</span><span class="lines">@@ -481,24 +505,24 @@
</span><span class="cx"> % (self.sname(), self.children)
</span><span class="cx"> )
</span><span class="cx"> if name == "invert":
</span><del>- self.invert = True
</del><ins>+ self.invert = True
</ins><span class="cx"> self.principal = child.children[0]
</span><span class="cx"> else:
</span><del>- self.invert = False
</del><ins>+ self.invert = False
</ins><span class="cx"> self.principal = child
</span><del>-
</del><ins>+
</ins><span class="cx"> elif name in ("grant", "deny"):
</span><span class="cx"> if self.allow is not None:
</span><span class="cx"> raise ValueError(
</span><span class="cx"> "Only one of DAV:grant or DAV:deny allowed in %s, got: %s"
</span><span class="cx"> % (self.sname(), self.children)
</span><span class="cx"> )
</span><del>- self.allow = (name == "grant")
</del><ins>+ self.allow = (name == "grant")
</ins><span class="cx"> self.privileges = child.children
</span><del>-
</del><ins>+
</ins><span class="cx"> elif name == "inherited":
</span><span class="cx"> self.inherited = str(child.children[0])
</span><del>-
</del><ins>+
</ins><span class="cx"> elif name == "protected":
</span><span class="cx"> self.protected = True
</span><span class="cx">
</span><span class="lines">@@ -525,6 +549,7 @@
</span><span class="cx"> # class above.
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # For DAV:all element (RFC 3744, section 5.5.1) see All class above.
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -537,6 +562,7 @@
</span><span class="cx"> name = "authenticated"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Unauthenticated (WebDAVEmptyElement):
</span><span class="lines">@@ -546,6 +572,7 @@
</span><span class="cx"> name = "unauthenticated"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # For DAV:property element (RFC 3744, section 5.5.1) see Property
</span><span class="cx"> # class above.
</span><span class="cx">
</span><span class="lines">@@ -560,6 +587,7 @@
</span><span class="cx"> name = "self"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Invert (WebDAVElement):
</span><span class="lines">@@ -569,9 +597,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "invert"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "principal"): (1, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "principal"): (1, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Grant (WebDAVElement):
</span><span class="lines">@@ -580,9 +609,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "grant"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "privilege"): (1, None) }
</del><ins>+ allowed_children = {(dav_namespace, "privilege"): (1, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Deny (WebDAVElement):
</span><span class="lines">@@ -591,9 +621,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "deny"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "privilege"): (1, None) }
</del><ins>+ allowed_children = {(dav_namespace, "privilege"): (1, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # For DAV:privilege element (RFC 3744, section 5.5.2) see Privilege
</span><span class="cx"> # class above.
</span><span class="cx">
</span><span class="lines">@@ -607,18 +638,20 @@
</span><span class="cx"> name = "protected"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Inherited (WebDAVElement):
</span><span class="cx"> """
</span><del>- Indicates that an ACE is inherited from the resource indentified by the
</del><ins>+ Indicates that an ACE is inherited from the resource identified by the
</ins><span class="cx"> contained DAV:href element. (RFC 3744, section 5.5.4)
</span><span class="cx"> """
</span><span class="cx"> name = "inherited"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (1, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (1, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ACLRestrictions (WebDAVElement):
</span><span class="lines">@@ -631,13 +664,14 @@
</span><span class="cx"> protected = True
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "grant-only" ): (0, 1),
- (dav_namespace, "no-invert" ): (0, 1),
- (dav_namespace, "deny-before-grant" ): (0, 1),
</del><ins>+ (dav_namespace, "grant-only"): (0, 1),
+ (dav_namespace, "no-invert"): (0, 1),
+ (dav_namespace, "deny-before-grant"): (0, 1),
</ins><span class="cx"> (dav_namespace, "required-principal"): (0, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class GrantOnly (WebDAVEmptyElement):
</span><span class="lines">@@ -648,6 +682,7 @@
</span><span class="cx"> name = "grant-only"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class NoInvert (WebDAVEmptyElement):
</span><span class="lines">@@ -658,6 +693,7 @@
</span><span class="cx"> name = "no-invert"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class DenyBeforeGrant (WebDAVEmptyElement):
</span><span class="lines">@@ -668,6 +704,7 @@
</span><span class="cx"> name = "deny-before-grant"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class RequiredPrincipal (WebDAVElement):
</span><span class="lines">@@ -678,12 +715,12 @@
</span><span class="cx"> name = "required-principal"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "all" ): (0, 1),
- (dav_namespace, "authenticated" ): (0, 1),
</del><ins>+ (dav_namespace, "all"): (0, 1),
+ (dav_namespace, "authenticated"): (0, 1),
</ins><span class="cx"> (dav_namespace, "unauthenticated"): (0, 1),
</span><del>- (dav_namespace, "self" ): (0, 1),
- (dav_namespace, "href" ): (0, None),
- (dav_namespace, "property" ): (0, None),
</del><ins>+ (dav_namespace, "self"): (0, 1),
+ (dav_namespace, "href"): (0, None),
+ (dav_namespace, "property"): (0, None),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> def validate(self):
</span><span class="lines">@@ -702,6 +739,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class InheritedACLSet (WebDAVElement):
</span><span class="lines">@@ -713,9 +751,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PrincipalCollectionSet (WebDAVElement):
</span><span class="lines">@@ -728,9 +767,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Section 7 (Access Control and existing methods)
</span><span class="cx"> ##
</span><span class="lines">@@ -743,9 +783,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "need-privileges"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "resource"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "resource"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Resource (WebDAVElement):
</span><span class="lines">@@ -756,11 +797,12 @@
</span><span class="cx"> name = "resource"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "href" ): (1, 1),
</del><ins>+ (dav_namespace, "href"): (1, 1),
</ins><span class="cx"> (dav_namespace, "privilege"): (1, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Section 9 (Access Control Reports)
</span><span class="cx"> ##
</span><span class="lines">@@ -776,13 +818,13 @@
</span><span class="cx"> """
</span><span class="cx"> name = "acl-principal-prop-set"
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx"> def validate(self):
</span><span class="cx"> super(ACLPrincipalPropSet, self).validate()
</span><span class="cx">
</span><span class="cx"> prop = False
</span><del>-
</del><ins>+
</ins><span class="cx"> for child in self.children:
</span><span class="cx"> if child.qname() == (dav_namespace, "prop"):
</span><span class="cx"> if prop:
</span><span class="lines">@@ -793,6 +835,7 @@
</span><span class="cx"> prop = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PrincipalMatch (WebDAVElement):
</span><span class="lines">@@ -805,8 +848,8 @@
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><span class="cx"> (dav_namespace, "principal-property"): (0, 1),
</span><del>- (dav_namespace, "self" ): (0, 1),
- (dav_namespace, "prop" ): (0, 1),
</del><ins>+ (dav_namespace, "self"): (0, 1),
+ (dav_namespace, "prop"): (0, 1),
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> def validate(self):
</span><span class="lines">@@ -836,6 +879,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PrincipalProperty (WebDAVElement):
</span><span class="lines">@@ -844,9 +888,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "principal-property"
</span><span class="cx">
</span><del>- allowed_children = { WebDAVElement: (0, None) }
</del><ins>+ allowed_children = {WebDAVElement: (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # For DAV:self element (RFC 3744, section 9.3) see Self class above.
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -861,13 +906,14 @@
</span><span class="cx"> name = "principal-property-search"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "property-search" ): (0, None), # This is required but this element must be empty in supported-report-set
- (dav_namespace, "prop" ): (0, 1),
</del><ins>+ (dav_namespace, "property-search"): (0, None), # This is required but this element must be empty in supported-report-set
+ (dav_namespace, "prop"): (0, 1),
</ins><span class="cx"> (dav_namespace, "apply-to-principal-collection-set"): (0, 1),
</span><span class="cx"> }
</span><del>- allowed_attributes = { "test": False }
</del><ins>+ allowed_attributes = {"test": False}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PropertySearch (WebDAVElement):
</span><span class="lines">@@ -878,11 +924,12 @@
</span><span class="cx"> name = "property-search"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "prop" ): (1, 1),
</del><ins>+ (dav_namespace, "prop"): (1, 1),
</ins><span class="cx"> (dav_namespace, "match"): (1, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Match (WebDAVTextElement):
</span><span class="lines">@@ -892,6 +939,7 @@
</span><span class="cx"> name = "match"
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PrincipalSearchPropertySet (WebDAVElement):
</span><span class="lines">@@ -901,9 +949,10 @@
</span><span class="cx"> """
</span><span class="cx"> name = "principal-search-property-set"
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "principal-search-property"): (0, None) }
</del><ins>+ allowed_children = {(dav_namespace, "principal-search-property"): (0, None)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class PrincipalSearchProperty (WebDAVElement):
</span><span class="lines">@@ -914,11 +963,12 @@
</span><span class="cx"> name = "principal-search-property"
</span><span class="cx">
</span><span class="cx"> allowed_children = {
</span><del>- (dav_namespace, "prop" ): (1, 1),
</del><ins>+ (dav_namespace, "prop"): (1, 1),
</ins><span class="cx"> (dav_namespace, "description"): (1, 1),
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class NumberOfMatchesWithinLimits (WebDAVEmptyElement):
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlrfc4331py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/rfc4331.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/rfc4331.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/rfc4331.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> protected = True
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class QuotaUsedBytes (WebDAVTextElement):
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlrfc5397py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/rfc5397.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/rfc5397.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/rfc5397.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlrfc5842py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/rfc5842.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/rfc5842.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/rfc5842.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -45,9 +45,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class ParentSet (WebDAVElement):
</span><span class="lines">@@ -58,9 +59,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "parent"): (0, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "parent"): (0, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Parent (WebDAVElement):
</span><span class="lines">@@ -73,6 +75,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class Segment (WebDAVTextElement):
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmlrfc5995py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/rfc5995.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/rfc5995.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/rfc5995.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -48,9 +48,10 @@
</span><span class="cx"> hidden = True
</span><span class="cx"> protected = True
</span><span class="cx">
</span><del>- allowed_children = { (dav_namespace, "href"): (0, 1) }
</del><ins>+ allowed_children = {(dav_namespace, "href"): (0, 1)}
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> @registerElement
</span><span class="cx"> @registerElementClass
</span><span class="cx"> class AllowClientDefinedURI (WebDAVElement):
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmltesttest_basepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/test/test_base.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/test/test_base.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/test/test_base.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -37,7 +37,7 @@
</span><span class="cx"> """
</span><span class="cx"> def test_decodeXMLName(self):
</span><span class="cx"> # Empty name
</span><del>- self.assertRaises(ValueError, decodeXMLName, "")
</del><ins>+ self.assertRaises(ValueError, decodeXMLName, "")
</ins><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "{}")
</span><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "{x}")
</span><span class="cx">
</span><span class="lines">@@ -47,18 +47,19 @@
</span><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "{x")
</span><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "}")
</span><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "x}")
</span><del>- self.assertRaises(ValueError, decodeXMLName, "}x")
</del><ins>+ self.assertRaises(ValueError, decodeXMLName, "}x")
</ins><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "{{}")
</span><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "{{}}")
</span><span class="cx"> self.assertRaises(ValueError, decodeXMLName, "x{}")
</span><span class="cx">
</span><span class="cx"> # Empty namespace is OK
</span><del>- self.assertEquals(decodeXMLName( "x"), (None, "x"))
</del><ins>+ self.assertEquals(decodeXMLName("x"), (None, "x"))
</ins><span class="cx"> self.assertEquals(decodeXMLName("{}x"), (None, "x"))
</span><span class="cx">
</span><span class="cx"> # Normal case
</span><span class="cx"> self.assertEquals(decodeXMLName("{namespace}name"), ("namespace", "name"))
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> def test_encodeXMLName(self):
</span><span class="cx"> # No namespace
</span><span class="cx"> self.assertEquals(encodeXMLName(None, "name"), "name")
</span><span class="lines">@@ -68,6 +69,7 @@
</span><span class="cx"> self.assertEquals(encodeXMLName("namespace", "name"), "{namespace}name")
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVElementTestsMixin:
</span><span class="cx"> """
</span><span class="cx"> Mixin for L{TestCase}s which test a L{WebDAVElement} subclass.
</span><span class="lines">@@ -92,6 +94,7 @@
</span><span class="cx"> WebDAVDocument.fromString(document.toxml()))
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class WebDAVUnknownElementTests(WebDAVElementTestsMixin, TestCase):
</span><span class="cx"> """
</span><span class="cx"> Tests for L{WebDAVUnknownElement}.
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmltesttest_xmlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/test/test_xml.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/test/test_xml.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/test/test_xml.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -54,6 +54,7 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> class CurrentUserPrincipalTests(WebDAVElementTestsMixin, TestCase):
</span><span class="cx"> """
</span><span class="cx"> Tests for L{CurrentUserPrincipal}.
</span></span></pre></div>
<a id="CalendarServertrunktxdavxmltesttest_xml_rfc3744py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/xml/test/test_xml_rfc3744.py (12362 => 12363)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/xml/test/test_xml_rfc3744.py        2014-01-16 22:00:09 UTC (rev 12362)
+++ CalendarServer/trunk/txdav/xml/test/test_xml_rfc3744.py        2014-01-16 22:01:41 UTC (rev 12363)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-#
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre>
</div>
</div>
</body>
</html>