<!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>[12992] CalendarServer/branches/users/sagen/move2who-4</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/12992">12992</a></dd>
<dt>Author</dt> <dd>sagen@apple.com</dd>
<dt>Date</dt> <dd>2014-03-24 12:36:48 -0700 (Mon, 24 Mar 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Get gateway working</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServerbranchesuserssagenmove2who4calendarservertoolsgatewaypy">CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/gateway.py</a></li>
<li><a href="#CalendarServerbranchesuserssagenmove2who4calendarservertoolstestgatewaycaldavdplist">CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/gateway/caldavd.plist</a></li>
<li><a href="#CalendarServerbranchesuserssagenmove2who4calendarservertoolstesttest_gatewaypy">CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/test_gateway.py</a></li>
<li><a href="#CalendarServerbranchesuserssagenmove2who4requirementspy_developtxt">CalendarServer/branches/users/sagen/move2who-4/requirements/py_develop.txt</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServerbranchesuserssagenmove2who4calendarservertoolsgatewaypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/gateway.py (12991 => 12992)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/gateway.py        2014-03-22 02:56:09 UTC (rev 12991)
+++ CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/gateway.py        2014-03-24 19:36:48 UTC (rev 12992)
</span><span class="lines">@@ -30,17 +30,19 @@
</span><span class="cx"> )
</span><span class="cx"> from calendarserver.tools.purge import WorkerService, PurgeOldEventsService, DEFAULT_BATCH_SIZE, DEFAULT_RETAIN_DAYS
</span><span class="cx"> from calendarserver.tools.util import (
</span><del>- principalForPrincipalID, proxySubprincipal, addProxy, removeProxy,
- ProxyError, ProxyWarning, autoDisableMemcached
</del><ins>+ recordForPrincipalID, autoDisableMemcached
</ins><span class="cx"> )
</span><span class="cx"> from pycalendar.datetime import DateTime
</span><span class="cx"> from twext.who.directory import DirectoryRecord
</span><del>-from twisted.internet.defer import inlineCallbacks, succeed
</del><ins>+from twisted.internet.defer import inlineCallbacks, succeed, returnValue
</ins><span class="cx"> from twistedcaldav.config import config, ConfigDict
</span><del>-from txdav.xml import element as davxml
</del><span class="cx">
</span><span class="cx"> from txdav.who.idirectory import RecordType as CalRecordType
</span><span class="cx"> from twext.who.idirectory import FieldName
</span><ins>+from twisted.python.constants import Names, NamedConstant
+from txdav.who.delegates import (
+ addDelegate, removeDelegate, RecordType as DelegateRecordType
+)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> attrMap = {
</span><span class="lines">@@ -227,23 +229,50 @@
</span><span class="cx"> def command_getLocationList(self, command):
</span><span class="cx"> return self.respondWithRecordsOfTypes(self.dir, command, ["locations"])
</span><span class="cx">
</span><del>-
</del><span class="cx"> @inlineCallbacks
</span><del>- def command_createLocation(self, command):
</del><ins>+ def _saveRecord(self, typeName, recordType, command, oldFields=None):
+ """
+ Save a record using the values in the command plist, starting with
+ any fields in the optional oldFields.
</ins><span class="cx">
</span><del>- fields = {
- FieldName.recordType: CalRecordType.location
- }
</del><ins>+ @param typeName: one of "locations", "resources", "addresses"; used
+ to return the appropriate list of records afterwards.
+ @param recordType: the type of record to save
+ @param command: the command containing values
+ @type command: C{dict}
+ @param oldFields: the optional fields to start with, which will be
+ overridden by values from command
+ @type oldFiles: C{dict}
+ """
+
+ if oldFields is None:
+ fields = {
+ FieldName.recordType: recordType
+ }
+ create = True
+ else:
+ fields = oldFields.copy()
+ create = False
+
</ins><span class="cx"> for key, info in attrMap.iteritems():
</span><span class="cx"> if key in command:
</span><span class="cx"> attrName = info['attr']
</span><span class="cx"> field = self.dir.fieldName.lookupByName(attrName)
</span><span class="cx"> valueType = self.dir.fieldName.valueType(field)
</span><span class="cx"> value = command[key]
</span><del>- if self.dir.fieldName.isMultiValue(field) and not isinstance(value, list):
</del><ins>+
+ # For backwards compatibility, convert to a list if needed
+ if (
+ self.dir.fieldName.isMultiValue(field) and
+ not isinstance(value, list)
+ ):
</ins><span class="cx"> value = [value]
</span><ins>+
</ins><span class="cx"> if valueType == int:
</span><span class="cx"> value = int(value)
</span><ins>+ elif issubclass(valueType, Names):
+ if value is not None:
+ value = valueType.lookupByName(value)
</ins><span class="cx"> else:
</span><span class="cx"> if isinstance(value, list):
</span><span class="cx"> newList = []
</span><span class="lines">@@ -259,9 +288,8 @@
</span><span class="cx"> fields[field] = value
</span><span class="cx">
</span><span class="cx"> record = DirectoryRecord(self.dir, fields)
</span><del>- yield self.dir.updateRecords([record], create=True)
</del><ins>+ yield self.dir.updateRecords([record], create=create)
</ins><span class="cx">
</span><del>-
</del><span class="cx"> readProxies = command.get("ReadProxies", None)
</span><span class="cx"> if readProxies:
</span><span class="cx"> proxyRecords = []
</span><span class="lines">@@ -282,15 +310,62 @@
</span><span class="cx">
</span><span class="cx"> yield setProxies(record, readProxies, writeProxies)
</span><span class="cx">
</span><del>- yield self.respondWithRecordsOfTypes(self.dir, command, ["locations"])
</del><ins>+ yield self.respondWithRecordsOfTypes(self.dir, command, [typeName])
</ins><span class="cx">
</span><span class="cx">
</span><ins>+ def command_createLocation(self, command):
+ return self._saveRecord("locations", CalRecordType.location, command)
+
+
+ def command_createResource(self, command):
+ return self._saveRecord("resources", CalRecordType.resource, command)
+
+
+ def command_createAddress(self, command):
+ return self._saveRecord("addresses", CalRecordType.address, command)
+
+
</ins><span class="cx"> @inlineCallbacks
</span><ins>+ def command_setLocationAttributes(self, command):
+ uid = command['GeneratedUID']
+ record = yield self.dir.recordWithUID(uid)
+ yield self._saveRecord(
+ "locations",
+ CalRecordType.location,
+ command,
+ oldFields=record.fields
+ )
+
+ @inlineCallbacks
+ def command_setResourceAttributes(self, command):
+ uid = command['GeneratedUID']
+ record = yield self.dir.recordWithUID(uid)
+ yield self._saveRecord(
+ "resources",
+ CalRecordType.resource,
+ command,
+ oldFields=record.fields
+ )
+
+
+ @inlineCallbacks
+ def command_setAddressAttributes(self, command):
+ uid = command['GeneratedUID']
+ record = yield self.dir.recordWithUID(uid)
+ yield self._saveRecord(
+ "addresses",
+ CalRecordType.address,
+ command,
+ oldFields=record.fields
+ )
+
+
+ @inlineCallbacks
</ins><span class="cx"> def command_getLocationAttributes(self, command):
</span><span class="cx"> uid = command['GeneratedUID']
</span><span class="cx"> record = yield self.dir.recordWithUID(uid)
</span><span class="cx"> if record is None:
</span><del>- self.respondWithError("Location not found: %s" % (uid,))
</del><ins>+ self.respondWithError("Principal not found: %s" % (uid,))
</ins><span class="cx"> return
</span><span class="cx"> recordDict = recordToDict(record)
</span><span class="cx"> # recordDict['AutoSchedule'] = principal.getAutoSchedule()
</span><span class="lines">@@ -305,117 +380,95 @@
</span><span class="cx"> self.respond(command, recordDict)
</span><span class="cx">
</span><span class="cx"> command_getResourceAttributes = command_getLocationAttributes
</span><ins>+ command_getAddressAttributes = command_getLocationAttributes
</ins><span class="cx">
</span><span class="cx">
</span><del>- @inlineCallbacks
- def command_setLocationAttributes(self, command):
</del><span class="cx">
</span><del>- # Set autoSchedule prior to the updateRecord so that the right
- # value ends up in memcached
- principal = principalForPrincipalID(command['GeneratedUID'],
- directory=self.dir)
- (yield principal.setAutoSchedule(command.get('AutoSchedule', False)))
- (yield principal.setAutoAcceptGroup(command.get('AutoAcceptGroup', "")))
</del><span class="cx">
</span><del>- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
- try:
- record = (yield updateRecord(False, self.dir, "locations", **kwargs))
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
</del><span class="cx">
</span><del>- readProxies = command.get("ReadProxies", None)
- writeProxies = command.get("WriteProxies", None)
- principal = principalForPrincipalID(record.guid, directory=self.dir)
- (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
</del><ins>+ # @inlineCallbacks
+ # def _setAttributes(self, )
+ # # Set autoSchedule prior to the updateRecord so that the right
+ # # value ends up in memcached
+ # principal = principalForPrincipalID(command['GeneratedUID'],
+ # directory=self.dir)
+ # (yield principal.setAutoSchedule(command.get('AutoSchedule', False)))
+ # (yield principal.setAutoAcceptGroup(command.get('AutoAcceptGroup', "")))
</ins><span class="cx">
</span><del>- yield self.command_getLocationAttributes(command)
</del><ins>+ # kwargs = {}
+ # for key, info in attrMap.iteritems():
+ # if key in command:
+ # kwargs[info['attr']] = command[key]
+ # try:
+ # record = (yield updateRecord(False, self.dir, "locations", **kwargs))
+ # except DirectoryError, e:
+ # self.respondWithError(str(e))
+ # return
</ins><span class="cx">
</span><ins>+ # readProxies = command.get("ReadProxies", None)
+ # writeProxies = command.get("WriteProxies", None)
+ # principal = principalForPrincipalID(record.guid, directory=self.dir)
+ # (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
</ins><span class="cx">
</span><del>- def command_deleteLocation(self, command):
- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
- try:
- self.dir.destroyRecord("locations", **kwargs)
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
- self.respondWithRecordsOfTypes(self.dir, command, ["locations"])
</del><ins>+ # yield self.command_getLocationAttributes(command)
</ins><span class="cx">
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> # Resources
</span><span class="cx">
</span><span class="cx"> def command_getResourceList(self, command):
</span><span class="cx"> self.respondWithRecordsOfTypes(self.dir, command, ["resources"])
</span><span class="cx">
</span><span class="cx">
</span><del>- @inlineCallbacks
- def command_createResource(self, command):
- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
</del><ins>+ # @inlineCallbacks
+ # def command_createResource(self, command):
+ # kwargs = {}
+ # for key, info in attrMap.iteritems():
+ # if key in command:
+ # kwargs[info['attr']] = command[key]
</ins><span class="cx">
</span><del>- try:
- record = (yield updateRecord(True, self.dir, "resources", **kwargs))
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
</del><ins>+ # try:
+ # record = (yield updateRecord(True, self.dir, "resources", **kwargs))
+ # except DirectoryError, e:
+ # self.respondWithError(str(e))
+ # return
</ins><span class="cx">
</span><del>- readProxies = command.get("ReadProxies", None)
- writeProxies = command.get("WriteProxies", None)
- principal = principalForPrincipalID(record.guid, directory=self.dir)
- (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
</del><ins>+ # readProxies = command.get("ReadProxies", None)
+ # writeProxies = command.get("WriteProxies", None)
+ # principal = principalForPrincipalID(record.guid, directory=self.dir)
+ # (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
</ins><span class="cx">
</span><del>- self.respondWithRecordsOfTypes(self.dir, command, ["resources"])
</del><ins>+ # self.respondWithRecordsOfTypes(self.dir, command, ["resources"])
</ins><span class="cx">
</span><span class="cx">
</span><del>- @inlineCallbacks
- def command_setResourceAttributes(self, command):
</del><ins>+ # @inlineCallbacks
+ # def command_setResourceAttributes(self, command):
</ins><span class="cx">
</span><del>- # Set autoSchedule prior to the updateRecord so that the right
- # value ends up in memcached
- principal = principalForPrincipalID(command['GeneratedUID'],
- directory=self.dir)
- (yield principal.setAutoSchedule(command.get('AutoSchedule', False)))
- (yield principal.setAutoAcceptGroup(command.get('AutoAcceptGroup', "")))
</del><ins>+ # # Set autoSchedule prior to the updateRecord so that the right
+ # # value ends up in memcached
+ # principal = principalForPrincipalID(command['GeneratedUID'],
+ # directory=self.dir)
+ # (yield principal.setAutoSchedule(command.get('AutoSchedule', False)))
+ # (yield principal.setAutoAcceptGroup(command.get('AutoAcceptGroup', "")))
</ins><span class="cx">
</span><del>- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
- try:
- record = (yield updateRecord(False, self.dir, "resources", **kwargs))
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
</del><ins>+ # kwargs = {}
+ # for key, info in attrMap.iteritems():
+ # if key in command:
+ # kwargs[info['attr']] = command[key]
+ # try:
+ # record = (yield updateRecord(False, self.dir, "resources", **kwargs))
+ # except DirectoryError, e:
+ # self.respondWithError(str(e))
+ # return
</ins><span class="cx">
</span><del>- readProxies = command.get("ReadProxies", None)
- writeProxies = command.get("WriteProxies", None)
- principal = principalForPrincipalID(record.guid, directory=self.dir)
- (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
</del><ins>+ # readProxies = command.get("ReadProxies", None)
+ # writeProxies = command.get("WriteProxies", None)
+ # principal = principalForPrincipalID(record.guid, directory=self.dir)
+ # (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
</ins><span class="cx">
</span><del>- yield self.command_getResourceAttributes(command)
</del><ins>+ # yield self.command_getResourceAttributes(command)
</ins><span class="cx">
</span><span class="cx">
</span><del>- def command_deleteResource(self, command):
- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
- try:
- self.dir.destroyRecord("resources", **kwargs)
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
- self.respondWithRecordsOfTypes(self.dir, command, ["resources"])
-
-
</del><span class="cx"> # deferred
</span><span class="cx"> def command_getLocationAndResourceList(self, command):
</span><span class="cx"> return self.respondWithRecordsOfTypes(self.dir, command, ["locations", "resources"])
</span><span class="lines">@@ -424,62 +477,60 @@
</span><span class="cx"> # Addresses
</span><span class="cx">
</span><span class="cx"> def command_getAddressList(self, command):
</span><del>- self.respondWithRecordsOfTypes(self.dir, command, ["addresses"])
</del><ins>+ return self.respondWithRecordsOfTypes(self.dir, command, ["addresses"])
</ins><span class="cx">
</span><span class="cx">
</span><del>- @inlineCallbacks
- def command_createAddress(self, command):
- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
</del><ins>+ # @inlineCallbacks
+ # def command_createAddress(self, command):
+ # kwargs = {}
+ # for key, info in attrMap.iteritems():
+ # if key in command:
+ # kwargs[info['attr']] = command[key]
</ins><span class="cx">
</span><del>- try:
- yield updateRecord(True, self.dir, "addresses", **kwargs)
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
</del><ins>+ # try:
+ # yield updateRecord(True, self.dir, "addresses", **kwargs)
+ # except DirectoryError, e:
+ # self.respondWithError(str(e))
+ # return
</ins><span class="cx">
</span><del>- self.respondWithRecordsOfTypes(self.dir, command, ["addresses"])
</del><ins>+ # self.respondWithRecordsOfTypes(self.dir, command, ["addresses"])
</ins><span class="cx">
</span><span class="cx">
</span><del>- def command_getAddressAttributes(self, command):
- guid = command['GeneratedUID']
- record = self.dir.recordWithGUID(guid)
- if record is None:
- self.respondWithError("Principal not found: %s" % (guid,))
- return
- recordDict = recordToDict(record)
- self.respond(command, recordDict)
- return succeed(None)
</del><span class="cx">
</span><span class="cx">
</span><ins>+ # @inlineCallbacks
+ # def command_setAddressAttributes(self, command):
+ # kwargs = {}
+ # for key, info in attrMap.iteritems():
+ # if key in command:
+ # kwargs[info['attr']] = command[key]
+ # try:
+ # yield updateRecord(False, self.dir, "addresses", **kwargs)
+ # except DirectoryError, e:
+ # self.respondWithError(str(e))
+ # return
+
+ # yield self.command_getAddressAttributes(command)
+
+
+
</ins><span class="cx"> @inlineCallbacks
</span><del>- def command_setAddressAttributes(self, command):
- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
- try:
- yield updateRecord(False, self.dir, "addresses", **kwargs)
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
</del><ins>+ def _delete(self, typeName, command):
+ uid = command['GeneratedUID']
+ yield self.dir.removeRecords([uid])
+ self.respondWithRecordsOfTypes(self.dir, command, [typeName])
</ins><span class="cx">
</span><del>- yield self.command_getAddressAttributes(command)
</del><span class="cx">
</span><ins>+ def command_deleteLocation(self, command):
+ return self._delete("locations", command)
</ins><span class="cx">
</span><ins>+
+ def command_deleteResource(self, command):
+ return self._delete("resources", command)
+
+
</ins><span class="cx"> def command_deleteAddress(self, command):
</span><del>- kwargs = {}
- for key, info in attrMap.iteritems():
- if key in command:
- kwargs[info['attr']] = command[key]
- try:
- self.dir.destroyRecord("addresses", **kwargs)
- except DirectoryError, e:
- self.respondWithError(str(e))
- return
- self.respondWithRecordsOfTypes(self.dir, command, ["addresses"])
</del><ins>+ return self._delete("addresses", command)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> # Config
</span><span class="lines">@@ -530,106 +581,144 @@
</span><span class="cx">
</span><span class="cx"> # Proxies
</span><span class="cx">
</span><del>- @inlineCallbacks
</del><span class="cx"> def command_listWriteProxies(self, command):
</span><del>- principal = principalForPrincipalID(command['Principal'], directory=self.dir)
- if principal is None:
- self.respondWithError("Principal not found: %s" % (command['Principal'],))
- return
- (yield self.respondWithProxies(self.dir, command, principal, "write"))
</del><ins>+ return self._listProxies(command, "write")
</ins><span class="cx">
</span><span class="cx">
</span><ins>+ def command_listReadProxies(self, command):
+ return self._listProxies(command, "read")
+
</ins><span class="cx"> @inlineCallbacks
</span><del>- def command_addWriteProxy(self, command):
- principal = principalForPrincipalID(command['Principal'],
- directory=self.dir)
- if principal is None:
</del><ins>+ def _listProxies(self, command, proxyType):
+ record = yield recordForPrincipalID(self.dir, command['Principal'])
+ if record is None:
</ins><span class="cx"> self.respondWithError("Principal not found: %s" % (command['Principal'],))
</span><del>- return
</del><ins>+ returnValue(None)
+ yield self.respondWithProxies(command, record, proxyType)
</ins><span class="cx">
</span><del>- proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
- if proxy is None:
- self.respondWithError("Proxy not found: %s" % (command['Proxy'],))
- return
- try:
- (yield addProxy(self.root, self.dir, self.store, principal, "write", proxy))
- except ProxyError, e:
- self.respondWithError(str(e))
- return
- except ProxyWarning, e:
- pass
- (yield self.respondWithProxies(self.dir, command, principal, "write"))
</del><span class="cx">
</span><ins>+ def command_addReadProxy(self, command):
+ return self._addProxy(command, "read")
</ins><span class="cx">
</span><ins>+
+ def command_addWriteProxy(self, command):
+ return self._addProxy(command, "write")
+
+
</ins><span class="cx"> @inlineCallbacks
</span><del>- def command_removeWriteProxy(self, command):
- principal = principalForPrincipalID(command['Principal'], directory=self.dir)
- if principal is None:
</del><ins>+ def _addProxy(self, command, proxyType):
+ record = yield recordForPrincipalID(self.dir, command['Principal'])
+ if record is None:
</ins><span class="cx"> self.respondWithError("Principal not found: %s" % (command['Principal'],))
</span><del>- return
- proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
- if proxy is None:
</del><ins>+ returnValue(None)
+
+ proxyRecord = yield recordForPrincipalID(self.dir, command['Proxy'])
+ if proxyRecord is None:
</ins><span class="cx"> self.respondWithError("Proxy not found: %s" % (command['Proxy'],))
</span><del>- return
- try:
- (yield removeProxy(self.root, self.dir, self.store, principal, proxy, proxyTypes=("write",)))
- except ProxyError, e:
- self.respondWithError(str(e))
- return
- except ProxyWarning, e:
- pass
- (yield self.respondWithProxies(self.dir, command, principal, "write"))
</del><ins>+ returnValue(None)
</ins><span class="cx">
</span><ins>+ txn = self.store.newTransaction()
+ yield addDelegate(txn, record, proxyRecord, (proxyType == "write"))
+ yield txn.commit()
+ yield self.respondWithProxies(command, record, proxyType)
</ins><span class="cx">
</span><del>- @inlineCallbacks
- def command_listReadProxies(self, command):
- principal = principalForPrincipalID(command['Principal'], directory=self.dir)
- if principal is None:
- self.respondWithError("Principal not found: %s" % (command['Principal'],))
- return
- (yield self.respondWithProxies(self.dir, command, principal, "read"))
</del><span class="cx">
</span><ins>+ def command_removeReadProxy(self, command):
+ return self._removeProxy(command, "read")
</ins><span class="cx">
</span><del>- @inlineCallbacks
- def command_addReadProxy(self, command):
- principal = principalForPrincipalID(command['Principal'], directory=self.dir)
- if principal is None:
- self.respondWithError("Principal not found: %s" % (command['Principal'],))
- return
- proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
- if proxy is None:
- self.respondWithError("Proxy not found: %s" % (command['Proxy'],))
- return
- try:
- (yield addProxy(self.root, self.dir, self.store, principal, "read", proxy))
- except ProxyError, e:
- self.respondWithError(str(e))
- return
- except ProxyWarning, e:
- pass
- (yield self.respondWithProxies(self.dir, command, principal, "read"))
</del><span class="cx">
</span><ins>+ def command_removeWriteProxy(self, command):
+ return self._removeProxy(command, "write")
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><del>- def command_removeReadProxy(self, command):
- principal = principalForPrincipalID(command['Principal'], directory=self.dir)
- if principal is None:
</del><ins>+ def _removeProxy(self, command, proxyType):
+ record = yield recordForPrincipalID(self.dir, command['Principal'])
+ if record is None:
</ins><span class="cx"> self.respondWithError("Principal not found: %s" % (command['Principal'],))
</span><del>- return
- proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
- if proxy is None:
</del><ins>+ returnValue(None)
+
+ proxyRecord = yield recordForPrincipalID(self.dir, command['Proxy'])
+ if proxyRecord is None:
</ins><span class="cx"> self.respondWithError("Proxy not found: %s" % (command['Proxy'],))
</span><del>- return
- try:
- (yield removeProxy(self.root, self.dir, self.store, principal, proxy, proxyTypes=("read",)))
- except ProxyError, e:
- self.respondWithError(str(e))
- return
- except ProxyWarning, e:
- pass
- (yield self.respondWithProxies(self.dir, command, principal, "read"))
</del><ins>+ returnValue(None)
</ins><span class="cx">
</span><ins>+ txn = self.store.newTransaction()
+ yield removeDelegate(txn, record, proxyRecord, (proxyType == "write"))
+ yield txn.commit()
+ yield self.respondWithProxies(command, record, proxyType)
</ins><span class="cx">
</span><ins>+
+
+ # @inlineCallbacks
+ # def command_removeWriteProxy(self, command):
+ # principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+ # if principal is None:
+ # self.respondWithError("Principal not found: %s" % (command['Principal'],))
+ # return
+ # proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
+ # if proxy is None:
+ # self.respondWithError("Proxy not found: %s" % (command['Proxy'],))
+ # return
+ # try:
+ # (yield removeProxy(self.root, self.dir, self.store, principal, proxy, proxyTypes=("write",)))
+ # except ProxyError, e:
+ # self.respondWithError(str(e))
+ # return
+ # except ProxyWarning, e:
+ # pass
+ # (yield self.respondWithProxies(self.dir, command, principal, "write"))
+
+
+ # @inlineCallbacks
+ # def command_listReadProxies(self, command):
+ # principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+ # if principal is None:
+ # self.respondWithError("Principal not found: %s" % (command['Principal'],))
+ # return
+ # (yield self.respondWithProxies(self.dir, command, principal, "read"))
+
+
+ # @inlineCallbacks
+ # def command_addReadProxy(self, command):
+ # principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+ # if principal is None:
+ # self.respondWithError("Principal not found: %s" % (command['Principal'],))
+ # return
+ # proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
+ # if proxy is None:
+ # self.respondWithError("Proxy not found: %s" % (command['Proxy'],))
+ # return
+ # try:
+ # (yield addProxy(self.root, self.dir, self.store, principal, "read", proxy))
+ # except ProxyError, e:
+ # self.respondWithError(str(e))
+ # return
+ # except ProxyWarning, e:
+ # pass
+ # (yield self.respondWithProxies(self.dir, command, principal, "read"))
+
+
+ # @inlineCallbacks
+ # def command_removeReadProxy(self, command):
+ # principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+ # if principal is None:
+ # self.respondWithError("Principal not found: %s" % (command['Principal'],))
+ # return
+ # proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
+ # if proxy is None:
+ # self.respondWithError("Proxy not found: %s" % (command['Proxy'],))
+ # return
+ # try:
+ # (yield removeProxy(self.root, self.dir, self.store, principal, proxy, proxyTypes=("read",)))
+ # except ProxyError, e:
+ # self.respondWithError(str(e))
+ # return
+ # except ProxyWarning, e:
+ # pass
+ # (yield self.respondWithProxies(self.dir, command, principal, "read"))
+
+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def command_purgeOldEvents(self, command):
</span><span class="cx"> """
</span><span class="lines">@@ -644,22 +733,22 @@
</span><span class="cx"> cutoff.setDateOnly(False)
</span><span class="cx"> cutoff.offsetDay(-retainDays)
</span><span class="cx"> eventCount = (yield PurgeOldEventsService.purgeOldEvents(self.store, cutoff, DEFAULT_BATCH_SIZE))
</span><del>- self.respond(command, {'EventsRemoved' : eventCount, "RetainDays" : retainDays})
</del><ins>+ self.respond(command, {'EventsRemoved': eventCount, "RetainDays": retainDays})
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><del>- def respondWithProxies(self, directory, command, principal, proxyType):
</del><ins>+ def respondWithProxies(self, command, record, proxyType):
</ins><span class="cx"> proxies = []
</span><del>- subPrincipal = proxySubprincipal(principal, proxyType)
- if subPrincipal is not None:
- membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
- if membersProperty.children:
- for member in membersProperty.children:
- proxyPrincipal = principalForPrincipalID(str(member), directory=directory)
- proxies.append(proxyPrincipal.record.guid)
</del><ins>+ recordType = {
+ "read": DelegateRecordType.readDelegateGroup,
+ "write": DelegateRecordType.writeDelegateGroup,
+ }[proxyType]
+ proxyGroup = yield self.dir.recordWithShortName(recordType, record.uid)
+ for member in (yield proxyGroup.members()):
+ proxies.append(member.uid)
</ins><span class="cx">
</span><span class="cx"> self.respond(command, {
</span><del>- 'Principal' : principal.record.guid, 'Proxies' : proxies
</del><ins>+ 'Principal': record.uid, 'Proxies': proxies
</ins><span class="cx"> })
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -675,11 +764,11 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def respond(self, command, result):
</span><del>- self.output.write(writePlistToString({'command' : command['command'], 'result' : result}))
</del><ins>+ self.output.write(writePlistToString({'command': command['command'], 'result': result}))
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> def respondWithError(self, msg, status=1):
</span><del>- self.output.write(writePlistToString({'error' : msg, }))
</del><ins>+ self.output.write(writePlistToString({'error': msg, }))
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -690,8 +779,14 @@
</span><span class="cx"> value = record.fields[record.service.fieldName.lookupByName(info['attr'])]
</span><span class="cx"> if value is None:
</span><span class="cx"> continue
</span><del>- elif isinstance(value, str):
</del><ins>+ # For backwards compatibility, present fullName/RealName as single
+ # value even though twext.who now has it as multiValue
+ if key == "RealName":
+ value = value[0]
+ if isinstance(value, str):
</ins><span class="cx"> value = value.decode("utf-8")
</span><ins>+ elif isinstance(value, NamedConstant):
+ value = value.name
</ins><span class="cx"> recordDict[key] = value
</span><span class="cx"> except KeyError:
</span><span class="cx"> pass
</span><span class="lines">@@ -700,7 +795,7 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def respondWithError(msg, status=1):
</span><del>- sys.stdout.write(writePlistToString({'error' : msg, }))
</del><ins>+ sys.stdout.write(writePlistToString({'error': msg, }))
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServerbranchesuserssagenmove2who4calendarservertoolstestgatewaycaldavdplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/gateway/caldavd.plist (12991 => 12992)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/gateway/caldavd.plist        2014-03-22 02:56:09 UTC (rev 12991)
+++ CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/gateway/caldavd.plist        2014-03-24 19:36:48 UTC (rev 12992)
</span><span class="lines">@@ -34,6 +34,14 @@
</span><span class="cx"> <key>ServerHostName</key>
</span><span class="cx"> <string></string> <!-- The hostname clients use when connecting -->
</span><span class="cx">
</span><ins>+ <!-- Enable Calendars -->
+ <key>EnableCalDAV</key>
+ <true/>
+
+ <!-- Enable AddressBooks -->
+ <key>EnableCardDAV</key>
+ <true/>
+
</ins><span class="cx"> <!-- HTTP port [0 = disable HTTP] -->
</span><span class="cx"> <key>HTTPPort</key>
</span><span class="cx"> <integer>8008</integer>
</span><span class="lines">@@ -482,6 +490,31 @@
</span><span class="cx">
</span><span class="cx"> <key>Services</key>
</span><span class="cx"> <dict>
</span><ins>+
+ <key>APNS</key>
+ <dict>
+ <key>Enabled</key>
+ <false/>
+ <key>EnableStaggering</key>
+ <true/>
+ <key>StaggerSeconds</key>
+ <integer>5</integer>
+ <key>CalDAV</key>
+ <dict>
+ <key>CertificatePath</key>
+ <string>/example/calendar.cer</string>
+ <key>PrivateKeyPath</key>
+ <string>/example/calendar.pem</string>
+ </dict>
+ <key>CardDAV</key>
+ <dict>
+ <key>CertificatePath</key>
+ <string>/example/contacts.cer</string>
+ <key>PrivateKeyPath</key>
+ <string>/example/contacts.pem</string>
+ </dict>
+ </dict>
+
</ins><span class="cx"> <key>SimpleLineNotifier</key>
</span><span class="cx"> <dict>
</span><span class="cx"> <!-- Simple line notification service (for testing) -->
</span><span class="lines">@@ -756,5 +789,12 @@
</span><span class="cx"> </dict>
</span><span class="cx">
</span><span class="cx">
</span><ins>+ <key>Includes</key>
+ <array>
+ <string>%(WritablePlist)s</string>
+ </array>
+ <key>WritableConfigFile</key>
+ <string>%(WritablePlist)s</string>
+
</ins><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span></span></pre></div>
<a id="CalendarServerbranchesuserssagenmove2who4calendarservertoolstesttest_gatewaypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/test_gateway.py (12991 => 12992)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/test_gateway.py        2014-03-22 02:56:09 UTC (rev 12991)
+++ CalendarServer/branches/users/sagen/move2who-4/calendarserver/tools/test/test_gateway.py        2014-03-24 19:36:48 UTC (rev 12992)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> import plistlib
</span><span class="cx"> from twistedcaldav.memcacheclient import ClientFactory
</span><span class="cx"> from twistedcaldav import memcacher
</span><ins>+from txdav.who.idirectory import AutoScheduleMode
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> class RunCommandTestCase(StoreTestCase):
</span><span class="lines">@@ -183,6 +184,12 @@
</span><span class="cx">
</span><span class="cx"> class GatewayTestCase(RunCommandTestCase):
</span><span class="cx">
</span><ins>+ def _flush(self):
+ # Flush both XML directories
+ self.directory._directory.services[0].flush()
+ self.directory._directory.services[1].flush()
+
+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_getLocationAndResourceList(self):
</span><span class="cx"> results = yield self.runCommand(command_getLocationAndResourceList)
</span><span class="lines">@@ -198,14 +205,18 @@
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_getLocationAttributes(self):
</span><span class="cx"> yield self.runCommand(command_createLocation)
</span><ins>+
+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
+
</ins><span class="cx"> results = yield self.runCommand(command_getLocationAttributes)
</span><del>- self.assertEquals(results["result"]["Capacity"], "40")
- self.assertEquals(results["result"]["Description"], "Test Description")
</del><ins>+ # self.assertEquals(results["result"]["Capacity"], "40")
+ # self.assertEquals(results["result"]["Description"], "Test Description")
</ins><span class="cx"> self.assertEquals(results["result"]["RecordName"], ["createdlocation01"])
</span><span class="cx"> self.assertEquals(results["result"]["RealName"],
</span><span class="cx"> "Created Location 01 %s %s" % (unichr(208), u"\ud83d\udca3"))
</span><del>- self.assertEquals(results["result"]["Comment"], "Test Comment")
- self.assertEquals(results["result"]["AutoSchedule"], True)
</del><ins>+ # self.assertEquals(results["result"]["Comment"], "Test Comment")
+ self.assertEquals(results["result"]["AutoScheduleMode"], u"acceptIfFree")
</ins><span class="cx"> self.assertEquals(results["result"]["AutoAcceptGroup"], "E5A6142C-4189-4E9E-90B0-9CD0268B314B")
</span><span class="cx"> self.assertEquals(set(results["result"]["ReadProxies"]), set(['user03', 'user04']))
</span><span class="cx"> self.assertEquals(set(results["result"]["WriteProxies"]), set(['user05', 'user06']))
</span><span class="lines">@@ -220,9 +231,13 @@
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_getResourceAttributes(self):
</span><span class="cx"> yield self.runCommand(command_createResource)
</span><ins>+
+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
+
</ins><span class="cx"> results = yield self.runCommand(command_getResourceAttributes)
</span><del>- self.assertEquals(results["result"]["Comment"], "Test Comment")
- self.assertEquals(results["result"]["Type"], "Computer")
</del><ins>+ # self.assertEquals(results["result"]["Comment"], "Test Comment")
+ # self.assertEquals(results["result"]["Type"], "Computer")
</ins><span class="cx"> self.assertEquals(set(results["result"]["ReadProxies"]), set(['user03', 'user04']))
</span><span class="cx"> self.assertEquals(set(results["result"]["WriteProxies"]), set(['user05', 'user06']))
</span><span class="cx">
</span><span class="lines">@@ -234,17 +249,19 @@
</span><span class="cx"> self.assertEquals(record, None)
</span><span class="cx"> yield self.runCommand(command_createAddress)
</span><span class="cx">
</span><del>- # directory.flushCaches()
</del><ins>+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
</ins><span class="cx">
</span><span class="cx"> record = yield self.directory.recordWithUID("C701069D-9CA1-4925-A1A9-5CD94767B74B")
</span><del>- self.assertEquals(record.fullName.decode("utf-8"),
- "Created Address 01 %s %s" % (unichr(208), u"\ud83d\udca3"))
</del><ins>+ self.assertEquals(
+ record.displayName,
+ "Created Address 01 %s %s" % (unichr(208), u"\ud83d\udca3")
+ )
</ins><span class="cx">
</span><del>- self.assertNotEquals(record, None)
</del><span class="cx">
</span><del>- self.assertEquals(record.extras["abbreviatedName"], "Addr1")
- self.assertEquals(record.extras["streetAddress"], "1 Infinite Loop\nCupertino, 95014\nCA")
- self.assertEquals(record.extras["geo"], "geo:37.331,-122.030")
</del><ins>+ self.assertEquals(record.abbreviatedName, "Addr1")
+ self.assertEquals(record.streetAddress, "1 Infinite Loop\nCupertino, 95014\nCA")
+ self.assertEquals(record.geographicLocation, "geo:37.331,-122.030")
</ins><span class="cx">
</span><span class="cx"> results = yield self.runCommand(command_getAddressList)
</span><span class="cx"> self.assertEquals(len(results["result"]), 1)
</span><span class="lines">@@ -257,7 +274,7 @@
</span><span class="cx"> results = yield self.runCommand(command_getAddressAttributes)
</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><del>- self.assertEquals(results["result"]["Geo"], u'Updated Geo')
</del><ins>+ self.assertEquals(results["result"]["GeographicLocation"], u'Updated Geo')
</ins><span class="cx">
</span><span class="cx"> results = yield self.runCommand(command_deleteAddress)
</span><span class="cx">
</span><span class="lines">@@ -272,13 +289,9 @@
</span><span class="cx"> self.assertEquals(record, None)
</span><span class="cx"> yield self.runCommand(command_createLocation)
</span><span class="cx">
</span><del>- # directory.flushCaches()
</del><ins>+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
</ins><span class="cx">
</span><del>- # This appears to be necessary in order for record.autoSchedule to
- # reflect the change prior to the directory record expiration
- # augmentService = directory.serviceForRecordType(directory.recordType_locations).augmentService
- # augmentService.refresh()
-
</del><span class="cx"> record = yield self.directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
</span><span class="cx"> self.assertEquals(record.fullNames[0],
</span><span class="cx"> u"Created Location 01 %s %s" % (unichr(208), u"\ud83d\udca3"))
</span><span class="lines">@@ -296,28 +309,24 @@
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_setLocationAttributes(self):
</span><del>- directory = getDirectory()
</del><span class="cx">
</span><span class="cx"> yield self.runCommand(command_createLocation)
</span><span class="cx"> yield self.runCommand(command_setLocationAttributes)
</span><del>- directory.flushCaches()
</del><span class="cx">
</span><del>- # This appears to be necessary in order for record.autoSchedule to
- # reflect the change
- augmentService = directory.serviceForRecordType(directory.recordType_locations).augmentService
- augmentService.refresh()
</del><ins>+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
</ins><span class="cx">
</span><del>- record = directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
</del><ins>+ record = yield self.directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
</ins><span class="cx">
</span><del>- self.assertEquals(record.extras["comment"], "Updated Test Comment")
- self.assertEquals(record.extras["floor"], "Second")
- self.assertEquals(record.extras["capacity"], "41")
- self.assertEquals(record.extras["streetAddress"], "2 Infinite Loop\nCupertino, 95014\nCA")
- self.assertEquals(record.autoSchedule, True)
</del><ins>+ # self.assertEquals(record.extras["comment"], "Updated Test Comment")
+ self.assertEquals(record.floor, "Second")
+ # self.assertEquals(record.extras["capacity"], "41")
+ self.assertEquals(record.streetAddress, "2 Infinite Loop\nCupertino, 95014\nCA")
+ self.assertEquals(record.autoScheduleMode, AutoScheduleMode.acceptIfFree)
</ins><span class="cx"> self.assertEquals(record.autoAcceptGroup, "F5A6142C-4189-4E9E-90B0-9CD0268B314B")
</span><span class="cx">
</span><span class="cx"> results = yield self.runCommand(command_getLocationAttributes)
</span><del>- self.assertEquals(results["result"]["AutoSchedule"], True)
</del><ins>+ self.assertEquals(results["result"]["AutoScheduleMode"], "acceptIfFree")
</ins><span class="cx"> self.assertEquals(results["result"]["AutoAcceptGroup"], "F5A6142C-4189-4E9E-90B0-9CD0268B314B")
</span><span class="cx"> self.assertEquals(set(results["result"]["ReadProxies"]), set(['user03']))
</span><span class="cx"> self.assertEquals(set(results["result"]["WriteProxies"]), set(['user05', 'user06', 'user07']))
</span><span class="lines">@@ -325,59 +334,62 @@
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_destroyLocation(self):
</span><del>- directory = getDirectory()
</del><span class="cx">
</span><del>- record = directory.recordWithUID("location01")
</del><ins>+ record = yield self.directory.recordWithUID("location01")
</ins><span class="cx"> self.assertNotEquals(record, None)
</span><span class="cx">
</span><span class="cx"> yield self.runCommand(command_deleteLocation)
</span><span class="cx">
</span><del>- directory.flushCaches()
- record = directory.recordWithUID("location01")
</del><ins>+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
+
+ record = yield self.directory.recordWithUID("location01")
</ins><span class="cx"> self.assertEquals(record, None)
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_createResource(self):
</span><del>- directory = getDirectory()
</del><span class="cx">
</span><del>- record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
</del><ins>+ record = yield self.directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
</ins><span class="cx"> self.assertEquals(record, None)
</span><span class="cx">
</span><span class="cx"> yield self.runCommand(command_createResource)
</span><span class="cx">
</span><del>- directory.flushCaches()
- record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
</del><ins>+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
+
+ record = yield self.directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
</ins><span class="cx"> self.assertNotEquals(record, None)
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_setResourceAttributes(self):
</span><del>- directory = getDirectory()
</del><span class="cx">
</span><span class="cx"> yield self.runCommand(command_createResource)
</span><del>- directory.flushCaches()
- record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
- self.assertEquals(record.fullName, "Laptop 1")
</del><ins>+ record = yield self.directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
+ self.assertEquals(record.displayName, "Laptop 1")
</ins><span class="cx">
</span><span class="cx"> yield self.runCommand(command_setResourceAttributes)
</span><span class="cx">
</span><del>- directory.flushCaches()
- record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
- self.assertEquals(record.fullName, "Updated Laptop 1")
</del><ins>+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
</ins><span class="cx">
</span><ins>+ record = yield self.directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
+ self.assertEquals(record.displayName, "Updated Laptop 1")
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_destroyResource(self):
</span><del>- directory = getDirectory()
</del><span class="cx">
</span><del>- record = directory.recordWithUID("resource01")
</del><ins>+ record = yield self.directory.recordWithUID("resource01")
</ins><span class="cx"> self.assertNotEquals(record, None)
</span><span class="cx">
</span><span class="cx"> yield self.runCommand(command_deleteResource)
</span><span class="cx">
</span><del>- directory.flushCaches()
- record = directory.recordWithUID("resource01")
</del><ins>+ # Tell the resources services to flush its cache and re-read XML
+ self._flush()
+
+ record = yield self.directory.recordWithUID("resource01")
</ins><span class="cx"> self.assertEquals(record, None)
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -408,9 +420,10 @@
</span><span class="cx"> """
</span><span class="cx"> Verify readConfig returns with only the writable keys
</span><span class="cx"> """
</span><del>- results = yield self.runCommand(command_readConfig,
- script="calendarserver_config")
-
</del><ins>+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config"
+ )
</ins><span class="cx"> self.assertEquals(results["result"]["RedirectHTTPToHTTPS"], False)
</span><span class="cx"> self.assertEquals(results["result"]["EnableSearchAddressBook"], False)
</span><span class="cx"> self.assertEquals(results["result"]["EnableCalDAV"], True)
</span><span class="lines">@@ -430,8 +443,10 @@
</span><span class="cx"> """
</span><span class="cx"> Verify writeConfig updates the writable plist file only
</span><span class="cx"> """
</span><del>- results = yield self.runCommand(command_writeConfig,
- script="calendarserver_config")
</del><ins>+ results = yield self.runCommand(
+ command_writeConfig,
+ script="calendarserver_config"
+ )
</ins><span class="cx">
</span><span class="cx"> self.assertEquals(results["result"]["EnableCalDAV"], False)
</span><span class="cx"> self.assertEquals(results["result"]["EnableCardDAV"], False)
</span><span class="lines">@@ -453,9 +468,9 @@
</span><span class="cx"> <key>command</key>
</span><span class="cx"> <string>addReadProxy</string>
</span><span class="cx"> <key>Principal</key>
</span><del>- <string>locations:location01</string>
</del><ins>+ <string>location01</string>
</ins><span class="cx"> <key>Proxy</key>
</span><del>- <string>users:user03</string>
</del><ins>+ <string>user03</string>
</ins><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span><span class="cx"> """
</span><span class="lines">@@ -467,9 +482,9 @@
</span><span class="cx"> <key>command</key>
</span><span class="cx"> <string>addWriteProxy</string>
</span><span class="cx"> <key>Principal</key>
</span><del>- <string>locations:location01</string>
</del><ins>+ <string>location01</string>
</ins><span class="cx"> <key>Proxy</key>
</span><del>- <string>users:user01</string>
</del><ins>+ <string>user01</string>
</ins><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span><span class="cx"> """
</span><span class="lines">@@ -492,7 +507,7 @@
</span><span class="cx"> </array>
</span><span class="cx"> <key>StreetAddress</key>
</span><span class="cx"> <string>1 Infinite Loop\nCupertino, 95014\nCA</string>
</span><del>- <key>Geo</key>
</del><ins>+ <key>GeographicLocation</key>
</ins><span class="cx"> <string>geo:37.331,-122.030</string>
</span><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span><span class="lines">@@ -505,10 +520,8 @@
</span><span class="cx"> <dict>
</span><span class="cx"> <key>command</key>
</span><span class="cx"> <string>createLocation</string>
</span><del>- <!--
</del><span class="cx"> <key>AutoScheduleMode</key>
</span><del>- <string></string>
- -->
</del><ins>+ <string>acceptIfFree</string>
</ins><span class="cx"> <key>AutoAcceptGroup</key>
</span><span class="cx"> <string>E5A6142C-4189-4E9E-90B0-9CD0268B314B</string>
</span><span class="cx"> <key>GeneratedUID</key>
</span><span class="lines">@@ -552,31 +565,33 @@
</span><span class="cx"> <dict>
</span><span class="cx"> <key>command</key>
</span><span class="cx"> <string>createResource</string>
</span><del>- <key>AutoSchedule</key>
- <true/>
</del><ins>+ <key>AutoScheduleMode</key>
+ <string>declineIfBusy</string>
</ins><span class="cx"> <key>GeneratedUID</key>
</span><span class="cx"> <string>AF575A61-CFA6-49E1-A0F6-B5662C9D9801</string>
</span><span class="cx"> <key>RealName</key>
</span><span class="cx"> <string>Laptop 1</string>
</span><ins>+ <!--
</ins><span class="cx"> <key>Comment</key>
</span><span class="cx"> <string>Test Comment</string>
</span><span class="cx"> <key>Description</key>
</span><span class="cx"> <string>Test Description</string>
</span><span class="cx"> <key>Type</key>
</span><span class="cx"> <string>Computer</string>
</span><ins>+ -->
</ins><span class="cx"> <key>RecordName</key>
</span><span class="cx"> <array>
</span><span class="cx"> <string>laptop1</string>
</span><span class="cx"> </array>
</span><span class="cx"> <key>ReadProxies</key>
</span><span class="cx"> <array>
</span><del>- <string>users:user03</string>
- <string>users:user04</string>
</del><ins>+ <string>user03</string>
+ <string>user04</string>
</ins><span class="cx"> </array>
</span><span class="cx"> <key>WriteProxies</key>
</span><span class="cx"> <array>
</span><del>- <string>users:user05</string>
- <string>users:user06</string>
</del><ins>+ <string>user05</string>
+ <string>user06</string>
</ins><span class="cx"> </array>
</span><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span><span class="lines">@@ -691,9 +706,9 @@
</span><span class="cx"> <key>command</key>
</span><span class="cx"> <string>removeReadProxy</string>
</span><span class="cx"> <key>Principal</key>
</span><del>- <string>locations:location01</string>
</del><ins>+ <string>location01</string>
</ins><span class="cx"> <key>Proxy</key>
</span><del>- <string>users:user03</string>
</del><ins>+ <string>user03</string>
</ins><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span><span class="cx"> """
</span><span class="lines">@@ -705,9 +720,9 @@
</span><span class="cx"> <key>command</key>
</span><span class="cx"> <string>removeWriteProxy</string>
</span><span class="cx"> <key>Principal</key>
</span><del>- <string>locations:location01</string>
</del><ins>+ <string>location01</string>
</ins><span class="cx"> <key>Proxy</key>
</span><del>- <string>users:user01</string>
</del><ins>+ <string>user01</string>
</ins><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span><span class="cx"> """
</span><span class="lines">@@ -736,19 +751,21 @@
</span><span class="cx"> <string>Updated Test Description</string>
</span><span class="cx"> <key>Floor</key>
</span><span class="cx"> <string>Second</string>
</span><ins>+ <!--
</ins><span class="cx"> <key>Capacity</key>
</span><span class="cx"> <string>41</string>
</span><ins>+ -->
</ins><span class="cx"> <key>StreetAddress</key>
</span><span class="cx"> <string>2 Infinite Loop\nCupertino, 95014\nCA</string>
</span><span class="cx"> <key>ReadProxies</key>
</span><span class="cx"> <array>
</span><del>- <string>users:user03</string>
</del><ins>+ <string>user03</string>
</ins><span class="cx"> </array>
</span><span class="cx"> <key>WriteProxies</key>
</span><span class="cx"> <array>
</span><del>- <string>users:user05</string>
- <string>users:user06</string>
- <string>users:user07</string>
</del><ins>+ <string>user05</string>
+ <string>user06</string>
+ <string>user07</string>
</ins><span class="cx"> </array>
</span><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span><span class="lines">@@ -790,7 +807,7 @@
</span><span class="cx"> <string>Updated Address</string>
</span><span class="cx"> <key>StreetAddress</key>
</span><span class="cx"> <string>Updated Street Address</string>
</span><del>- <key>Geo</key>
</del><ins>+ <key>GeographicLocation</key>
</ins><span class="cx"> <string>Updated Geo</string>
</span><span class="cx">
</span><span class="cx"> </dict>
</span><span class="lines">@@ -804,8 +821,8 @@
</span><span class="cx"> <dict>
</span><span class="cx"> <key>command</key>
</span><span class="cx"> <string>setResourceAttributes</string>
</span><del>- <key>AutoSchedule</key>
- <false/>
</del><ins>+ <key>AutoScheduleMode</key>
+ <string>acceptIfFree</string>
</ins><span class="cx"> <key>GeneratedUID</key>
</span><span class="cx"> <string>AF575A61-CFA6-49E1-A0F6-B5662C9D9801</string>
</span><span class="cx"> <key>RealName</key>
</span></span></pre></div>
<a id="CalendarServerbranchesuserssagenmove2who4requirementspy_developtxt"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/sagen/move2who-4/requirements/py_develop.txt (12991 => 12992)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/sagen/move2who-4/requirements/py_develop.txt        2014-03-22 02:56:09 UTC (rev 12991)
+++ CalendarServer/branches/users/sagen/move2who-4/requirements/py_develop.txt        2014-03-24 19:36:48 UTC (rev 12992)
</span><span class="lines">@@ -5,6 +5,7 @@
</span><span class="cx"> pyflakes
</span><span class="cx"> docutils>=0.11
</span><span class="cx"> mockldap>=0.1.4
</span><ins>+q
</ins><span class="cx">
</span><span class="cx"> -e svn+http://svn.calendarserver.org/repository/calendarserver/CalDAVClientLibrary/trunk#egg=CalDAVClientLibrary
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>