[CalendarServer-changes] [9879] CalDAVClientLibrary/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Sep 27 19:48:34 PDT 2012
Revision: 9879
http://trac.calendarserver.org//changeset/9879
Author: cdaboo at apple.com
Date: 2012-09-27 19:48:34 -0700 (Thu, 27 Sep 2012)
Log Message:
-----------
Whitespace clean-up.
Modified Paths:
--------------
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/addrecord.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/changepassword.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/command.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/listrecords.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/removerecord.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/directory.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/manage.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/record.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/recordtypes.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tags.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_directory.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_record.py
CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/utils.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/baseshell.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/command.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/acl.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/addressbooks.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/calendars.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cat.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cd.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/help.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/history.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/import.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/logging.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/ls.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkadbk.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkcal.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkdir.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mv.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/principal.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/props.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/proxies.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/put.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quit.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quota.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/rm.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/server.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/sync.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/user.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/whoami.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/shell.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/subshell.py
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/utils.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/account.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/addressbook.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendar.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendaruseraddress.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/httpshandler.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/principal.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/simple.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/caldavxml.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/csxml.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/headers.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/methods.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/makecalendar.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/multiget.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_makecalendar.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_multiget.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/definitions/carddavxml.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/makeaddressbook.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/basic.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/digest.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/gssapi.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/test_basic.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/data.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/file.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/string.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/headers.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/methods.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/requestresponse.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/session.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_requestresponse.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_util.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/util.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/tests/test_url.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/url.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/utils/xmlhelpers.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/ace.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/acl.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/copymovebase.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/csxml.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/davxml.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/methods.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/delete.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/getbase.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/lock.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/multiresponseparser.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/options.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/principalmatch.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propall.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfind.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindbase.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindparser.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propnames.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/proppatch.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/put.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/report.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/requestresponse.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/session.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/synccollection.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_ace.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_acl.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_copy.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_delete.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_get.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_head.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_lock.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_move.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_options.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_principalmatch.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfind.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfindparser.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propnames.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_put.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_report.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_template.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_unlock.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/unlock.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/xmlresponseparser.py
CalDAVClientLibrary/trunk/caldavclientlibrary/ui/WebDAVBrowser.py
CalDAVClientLibrary/trunk/caldavclientlibrary/ui/resource.py
CalDAVClientLibrary/trunk/caldavclientlibrary/ui/session.py
CalDAVClientLibrary/trunk/setup.py
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2007-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2007-2012 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/addrecord.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/addrecord.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/addrecord.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,12 +23,13 @@
"""
Command that adds a record to the directory.
"""
-
+
CMDNAME = "add"
def __init__(self):
super(AddRecord, self).__init__(self.CMDNAME, "Add a record of the specified type.")
+
def doCommand(self):
"""
Run the command.
@@ -36,12 +37,13 @@
if self.doAdd():
return self.writeAccounts()
return 0
-
+
+
def doAdd(self):
"""
Prompts the user for details and then adds a new record to the directory.
"""
-
+
# Prompt for each thing we need in the record
record = XMLRecord()
record.recordType = self.recordType
@@ -61,16 +63,16 @@
while True:
record.guid = raw_input("GUID [leave empty to auto-generate]: ")
if record.guid and self.directory.containsGUID(record.guid):
- print "GUID: '%s' already used in the directory" % (record.guid,)
+ print "GUID: '%s' already used in the directory" % (record.guid,)
else:
break
-
+
# password
record.password = self.promptPassword()
# name
record.name = raw_input("Name: ")
-
+
# members
if self.recordType in (recordtypes.recordType_groups,):
record.members = self.getMemberList("Enter members of this group", "Member", "members")
@@ -82,7 +84,7 @@
record.calendarUserAddresses.add(cuaddr)
else:
break
-
+
# auto-schedule
if self.recordType in (recordtypes.recordType_locations, recordtypes.recordType_resources,):
auto_schedule = raw_input("Turn on automatic scheduling [y/n]?: ")
@@ -101,11 +103,11 @@
except EOFError:
return 0
-
+
# Now validate the record and save it
if not record.guid:
record.guid = str(uuid4())
-
+
self.directory.addRecord(record)
return 1
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/changepassword.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/changepassword.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/changepassword.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,13 +21,14 @@
"""
Command to change the password of an existing directory record.
"""
-
+
CMDNAME = "passwd"
def __init__(self):
super(ChangePassword, self).__init__(self.CMDNAME, "Change the password for a record.")
self.uid = None
+
def usage(self):
print """USAGE: %s TYPE [OPTIONS]
@@ -39,24 +40,25 @@
--uid UID of record to change
""" % (self.cmdname,)
+
def execute(self, argv):
"""
Execute the command specified by the command line arguments.
-
+
@param argv: command line arguments.
@type argv: C{list}
-
+
@return: 1 for success, 0 for failure.
@rtype: C{int}
"""
-
+
# Check first argument for type
argv = self.getTypeArgument(argv)
if argv is None:
return 0
-
- opts, args = getopt.getopt(argv, 'f:h', ["help", "uid=",])
-
+
+ opts, args = getopt.getopt(argv, 'f:h', ["help", "uid=", ])
+
for name, value in opts:
if name == "-f":
self.path = value
@@ -82,11 +84,12 @@
print "Arguments not allowed."
self.usage()
return 0
-
+
if not self.loadAccounts():
return 0
return self.doCommand()
+
def doCommand(self):
"""
Run the command.
@@ -94,18 +97,18 @@
if self.doChangePassword():
return self.writeAccounts()
return 0
-
+
+
def doChangePassword(self):
"""
Prompts the user for details and then changes the password of a record in the directory.
"""
-
+
# First check record exists
record = self.directory.getRecord(self.recordType, self.uid)
if record is None:
print "No '%s' record matching uid '%s'" % (self.recordType, self.uid,)
return 0
-
+
record.password = self.promptPassword()
return 1
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/command.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/command.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/command.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,17 +24,18 @@
import getopt
class Command(object):
-
+
def __init__(self, cmdname, description):
self.path = None
self.cmdname = cmdname
self.description = description
self.recordType = None
+
def usage(self):
if self.allRecordsAllowed():
print """USAGE: %s [TYPE] [OPTIONS]
-
+
TYPE: One of "all", "users", "groups", "locations" or "resources". Also,
"a", "u", "g", "l" or "r" as shortcuts. Invalid or missing type is
treated as "all".
@@ -44,7 +45,7 @@
""" % (self.cmdname,)
else:
print """USAGE: %s TYPE [OPTIONS]
-
+
TYPE: One of "users", "groups", "locations" or "resources". Also,
"u", "g", "l" or "r" as shortcuts.
@@ -52,6 +53,7 @@
-f file path to accounts.xml
""" % (self.cmdname,)
+
def allRecordsAllowed(self):
"""
Indicates whether a command is able to operate on all record types in addition to
@@ -60,24 +62,25 @@
"""
return False
+
def execute(self, argv):
"""
Execute the command specified by the command line arguments.
-
+
@param argv: command line arguments.
@type argv: C{list}
-
+
@return: 1 for success, 0 for failure.
@rtype: C{int}
"""
-
+
# Check first argument for type
argv = self.getTypeArgument(argv)
if argv is None:
return 0
-
+
opts, args = getopt.getopt(argv, 'f:h', ["help", ])
-
+
for name, value in opts:
if name == "-f":
self.path = value
@@ -97,18 +100,19 @@
print "Arguments not allowed."
self.usage()
return 0
-
+
if not self.loadAccounts():
return 0
return self.doCommand()
+
def getTypeArgument(self, argv):
"""
Extract the user specified record type argument from the command line arguments.
@param argv: command line arguments.
@type argv: C{list}
-
+
@return: the modified arguments (if a record type is found the corresponding argument is
removed from the argv passed in).
@rtype: C{list}
@@ -130,13 +134,14 @@
else:
return argv
+
def mapType(self, type):
"""
Map the specified user record type input to the actual record type identifier.
@param type: user input from the command line.
@type type: C{str}
-
+
@return: identifier matching the user input, or C{None} if no match.
@rtype: L{admin.xmlaccounts.recordtypes}
"""
@@ -152,13 +157,13 @@
"all" : recordtypes.recordType_all,
"a" : recordtypes.recordType_all,
}.get(type, None)
-
+
+
def loadAccounts(self):
"""
Load the entire directory from the XML file.
"""
-
-
+
f = open(self.path, "r")
if not f:
print "Could not open file: %s" % (self.path,)
@@ -169,11 +174,12 @@
self.directory.parseXML(XML(xmldata))
return 1
+
def writeAccounts(self):
"""
Write the entire directory to the XML file.
"""
-
+
node = self.directory.writeXML()
os = StringIO()
xmldoc = BetterElementTree(node)
@@ -186,12 +192,14 @@
f.close()
return 1
+
def doCommand(self):
"""
Run the command. Sub-classes must implement this.
"""
raise NotImplementedError
+
def promptPassword(self):
"""
Prompt the user for a password.
@@ -204,6 +212,7 @@
else:
return password
+
def getMemberList(self, prompt, title, type):
"""
Prompt the user for a list of members.
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/listrecords.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/listrecords.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/listrecords.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,12 +19,13 @@
import itertools
class ListRecords(Command):
-
+
CMDNAME = "list"
def __init__(self):
super(ListRecords, self).__init__(self.CMDNAME, "List all records of the specified type.")
+
def allRecordsAllowed(self):
"""
Indicate that this command can list all records in one go as well as each
@@ -32,27 +33,28 @@
"""
return True
+
def doCommand(self):
"""
Run the command.
"""
self.listRecords(self.recordType)
+
def listRecords(self, recordType):
"""
Lists records of the specified record type from the directory.
"""
-
+
if recordType == recordtypes.recordType_all:
users = [l for l in self.directory.records.itervalues()]
print "Full List\n"
else:
users = (self.directory.records[recordType],)
print "%s List\n" % (recordType.capitalize(),)
-
-
+
table = [
- ["UID", "GUID", "Name", "CUADDR",]
+ ["UID", "GUID", "Name", "CUADDR", ]
]
if recordType == recordtypes.recordType_all:
table[0].insert(0, "TYPE")
@@ -100,18 +102,19 @@
elif user.recordType in (recordtypes.recordType_groups, recordtypes.recordType_locations, recordtypes.recordType_resources,):
row += (member,)
table.append(row)
-
+
self.printTable(table)
return 1
-
+
+
def printTable(self, table):
-
+
maxWidths = [0 for _ignore in table[0]]
for row in table:
if row is not None:
for ctr, col in enumerate(row):
maxWidths[ctr] = max(maxWidths[ctr], len(col) if col else 0)
-
+
self.printDivider(maxWidths, False)
for rowctr, row in enumerate(table):
if row is None:
@@ -126,6 +129,7 @@
self.printDivider(maxWidths)
self.printDivider(maxWidths, False)
+
def printDivider(self, maxWidths, intermediate=True):
t = "|" if intermediate else "+"
for widthctr, width in enumerate(maxWidths):
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/removerecord.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/removerecord.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/commands/removerecord.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,13 +18,14 @@
import getopt
class RemoveRecord(Command):
-
+
CMDNAME = "remove"
def __init__(self):
super(RemoveRecord, self).__init__(self.CMDNAME, "Remove a record of the specified type.")
self.uid = None
+
def usage(self):
print """USAGE: %s TYPE [OPTIONS]
@@ -36,24 +37,25 @@
--uid UID to remove
""" % (self.cmdname,)
+
def execute(self, argv):
"""
Execute the command specified by the command line arguments.
-
+
@param argv: command line arguments.
@type argv: C{list}
-
+
@return: 1 for success, 0 for failure.
@rtype: C{int}
"""
-
+
# Check first argument for type
argv = self.getTypeArgument(argv)
if argv is None:
return 0
-
- opts, args = getopt.getopt(argv, 'f:h', ["help", "uid=",])
-
+
+ opts, args = getopt.getopt(argv, 'f:h', ["help", "uid=", ])
+
for name, value in opts:
if name == "-f":
self.path = value
@@ -79,11 +81,12 @@
print "Arguments not allowed."
self.usage()
return 0
-
+
if not self.loadAccounts():
return 0
return self.doCommand()
+
def doCommand(self):
"""
Run the command.
@@ -91,22 +94,22 @@
if self.doRemove():
return self.writeAccounts()
return 0
-
+
+
def doRemove(self):
"""
Removes an existing record from the directory.
"""
-
+
# First check record exists
record = self.directory.getRecord(self.recordType, self.uid)
if record is None:
print "No '%s' record matching uid '%s'" % (self.recordType, self.uid,)
return 0
-
-
+
confirm = raw_input("Really delete the record for '%s' in '%s' [y/n]?" % (self.uid, self.recordType,))
if confirm != "y":
return 0
-
+
self.directory.removeRecord(self.recordType, self.uid)
return 1
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/directory.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/directory.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/directory.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,31 +24,33 @@
"""
Model object for the XML-based directory. This can parse and generate the full XML file.
"""
-
+
def __init__(self):
self.realm = ""
self.records = {}
for type in recordtypes.RECORD_TYPES:
self.records[type] = []
-
+
+
def addRecord(self, record):
"""
Add a new principal record to the directory.
-
+
@param record: the record to add.
@type record: L{admin.xmlaccounts.record.XMLRecord}
"""
self.records[record.recordType].append(record)
-
+
+
def containsRecord(self, recordType, uid):
"""
Test whether the directory contains a record of the specified type and user id.
-
+
@param recordType: a principal record type.
@type recordType: one of L{admin.xmlaccounts.recordtypes.RECORD_TYPES}
@param uid: the user id to check.
@type uid: C{str}
-
+
@return: C{True} if present in the directory, C{False} otherwise.
@rtype: C{boolean}
"""
@@ -57,14 +59,15 @@
return True
else:
return False
-
+
+
def containsGUID(self, guid):
"""
Test whether the directory contains a record with the specified GUID.
-
+
@param guid: the GUID to check.
@type guid: C{str}
-
+
@return: C{True} if present in the directory, C{False} otherwise.
@rtype: C{boolean}
"""
@@ -73,7 +76,8 @@
if record.guid == guid:
return True
return False
-
+
+
def getRecord(self, recordType, uid):
"""
Return the record in the directory with the matching record type and user id.
@@ -82,7 +86,7 @@
@type recordType: one of L{admin.xmlaccounts.recordtypes.RECORD_TYPES}
@param uid: the user id to check.
@type uid: C{str}
-
+
@return: the matching record, or C{None} if not found.
@rtype: L{admin.xmlaccounts.record.XMLRecord}
"""
@@ -91,16 +95,17 @@
return record
else:
return None
-
+
+
def removeRecord(self, recordType, uid):
"""
Remove the record with the matching type and user id from the directory.
-
+
@param recordType: a principal record type.
@type recordType: one of L{admin.xmlaccounts.recordtypes.RECORD_TYPES}
@param uid: the user id to remove.
@type uid: C{str}
-
+
@return: C{True} if found and removed, C{False} otherwise.
@rtype: C{boolean}
"""
@@ -110,7 +115,8 @@
return True
else:
return False
-
+
+
def parseXML(self, node):
"""
Parse an entire XML directory.
@@ -125,17 +131,18 @@
record = XMLRecord()
record.parseXML(child)
self.records[record.recordType].append(record)
-
+
# TODO: Now resolve group and proxy references
+
def writeXML(self):
"""
Generate an entire XML directory.
-
+
@return: the root element for the principal record.
@rtype: C{xml.etree.ElementTree.Element}
"""
-
+
root = Element(tags.ELEMENT_ACCOUNTS)
if self.realm:
root.set(tags.ATTRIBUTE_REALM, self.realm)
@@ -143,6 +150,7 @@
self.writeXMLRecords(root, self.records[type])
return root
+
def writeXMLRecords(self, root, records):
"""
Generate the XML for all records in the specified list.
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/manage.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/manage.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/manage.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -29,11 +29,13 @@
CMD: one of:
%s
-
+
OPTIONS: specific to each command, use --help with the
command to see what options are supported.
""" % ("\n".join(["\t%s" % (cmd,) for cmd in cmds]),)
+
+
def runit():
"""
Run the command based on command line arguments.
@@ -43,8 +45,8 @@
if len(sys.argv) == 1:
usage()
sys.exit(0)
-
- if registered.has_key(sys.argv[1]):
+
+ if sys.argv[1] in registered:
sys.exit(registered[sys.argv[1]]().execute(sys.argv[2:]))
else:
print "No command called '%s' is available." % (sys.argv[1],)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/record.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/record.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/record.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -25,7 +25,7 @@
"""
Represents a single principal record. This class can parse and generate the appropriate XML.
"""
-
+
def __init__(self):
self.recordType = None
self.repeat = 0
@@ -39,7 +39,8 @@
self.enabledForCalendaring = True
self.proxies = set()
self.proxyFor = set()
-
+
+
def parseXML(self, node):
"""
Parse a single principal record from XML.
@@ -80,6 +81,7 @@
else:
raise RuntimeError("Unknown account attribute: %s" % (child.tag,))
+
def _parseMembers(self, node, addto):
"""
Parse an XML <members> or <proxies> element list.
@@ -95,18 +97,19 @@
recordType = child.get(tags.ATTRIBUTE_RECORDTYPE, recordtypes.recordType_users)
addto.add((recordType, child.text))
+
def writeXML(self):
"""
Generate a single XML principal record element.
-
+
@return: the root element for the principal record.
@rtype: C{xml.etree.ElementTree.Element}
"""
-
+
root = Element(recordtypes.RECORD_TYPES_TO_TAGS[self.recordType])
if self.repeat:
root.set(tags.ATTRIBUTE_REPEAT, str(self.repeat))
-
+
SubElementWithData(root, tags.ELEMENT_UID, self.uid)
SubElementWithData(root, tags.ELEMENT_GUID, self.guid)
SubElementWithData(root, tags.ELEMENT_PASSWORD, self.password)
@@ -114,7 +117,7 @@
if self.recordType == recordtypes.recordType_groups:
members = SubElementWithData(root, tags.ELEMENT_MEMBERS)
for member in self.members:
- SubElementWithData(members, tags.ELEMENT_MEMBER, member[1], {tags.ATTRIBUTE_RECORDTYPE:member[0]})
+ SubElementWithData(members, tags.ELEMENT_MEMBER, member[1], {tags.ATTRIBUTE_RECORDTYPE: member[0]})
if self.calendarUserAddresses:
for cuaddr in self.calendarUserAddresses:
SubElementWithData(root, tags.ELEMENT_CUADDR, cuaddr)
@@ -125,6 +128,6 @@
if self.recordType in (recordtypes.recordType_resources, recordtypes.recordType_locations,):
proxies = SubElementWithData(root, tags.ELEMENT_PROXIES)
for proxy in self.proxies:
- SubElementWithData(proxies, tags.ELEMENT_MEMBER, proxy[1], {tags.ATTRIBUTE_RECORDTYPE:proxy[0]})
-
+ SubElementWithData(proxies, tags.ELEMENT_MEMBER, proxy[1], {tags.ATTRIBUTE_RECORDTYPE: proxy[0]})
+
return root
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/recordtypes.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/recordtypes.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/recordtypes.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,17 +20,17 @@
from caldavclientlibrary.admin.xmlaccounts import tags
-recordType_users = "users"
-recordType_groups = "groups"
+recordType_users = "users"
+recordType_groups = "groups"
recordType_locations = "locations"
-recordType_resources = "resources"
-recordType_all = "all"
+recordType_resources = "resources"
+recordType_all = "all"
RECORD_TYPES = (
recordType_users,
recordType_groups,
recordType_locations,
- recordType_resources,
+ recordType_resources,
)
"""Allowed record type identifiers."""
@@ -38,7 +38,7 @@
recordType_users : tags.ELEMENT_USER,
recordType_groups : tags.ELEMENT_GROUP,
recordType_locations : tags.ELEMENT_LOCATION,
- recordType_resources : tags.ELEMENT_RESOURCE,
+ recordType_resources : tags.ELEMENT_RESOURCE,
}
"""Maps between record type identifiers and their corresponding XML element names."""
@@ -46,6 +46,6 @@
tags.ELEMENT_USER : recordType_users,
tags.ELEMENT_GROUP : recordType_groups,
tags.ELEMENT_LOCATION : recordType_locations,
- tags.ELEMENT_RESOURCE : recordType_resources,
+ tags.ELEMENT_RESOURCE : recordType_resources,
}
"""Maps between XML element names and their corresponding record type identifiers."""
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tags.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tags.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tags.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,23 +18,23 @@
XML element names used in the XML directory file.
"""
-ELEMENT_ACCOUNTS = "accounts"
-ELEMENT_USER = "user"
-ELEMENT_GROUP = "group"
-ELEMENT_LOCATION = "location"
-ELEMENT_RESOURCE = "resource"
+ELEMENT_ACCOUNTS = "accounts"
+ELEMENT_USER = "user"
+ELEMENT_GROUP = "group"
+ELEMENT_LOCATION = "location"
+ELEMENT_RESOURCE = "resource"
-ELEMENT_UID = "uid"
-ELEMENT_GUID = "guid"
-ELEMENT_PASSWORD = "password"
-ELEMENT_NAME = "name"
-ELEMENT_MEMBERS = "members"
-ELEMENT_MEMBER = "member"
-ELEMENT_CUADDR = "cuaddr"
-ELEMENT_AUTOSCHEDULE = "auto-schedule"
+ELEMENT_UID = "uid"
+ELEMENT_GUID = "guid"
+ELEMENT_PASSWORD = "password"
+ELEMENT_NAME = "name"
+ELEMENT_MEMBERS = "members"
+ELEMENT_MEMBER = "member"
+ELEMENT_CUADDR = "cuaddr"
+ELEMENT_AUTOSCHEDULE = "auto-schedule"
ELEMENT_DISABLECALENDAR = "disable-calendar"
-ELEMENT_PROXIES = "proxies"
+ELEMENT_PROXIES = "proxies"
-ATTRIBUTE_REALM = "realm"
-ATTRIBUTE_REPEAT = "repeat"
-ATTRIBUTE_RECORDTYPE = "type"
+ATTRIBUTE_REALM = "realm"
+ATTRIBUTE_REPEAT = "repeat"
+ATTRIBUTE_RECORDTYPE = "type"
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_directory.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_directory.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_directory.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,26 +22,27 @@
import unittest
class TestDirectory(unittest.TestCase):
-
+
def checkXML(self, x):
-
+
x = x.replace("\n", "\r\n")
-
+
# Parse the XML data
a = XMLDirectory()
a.parseXML(XML(x))
-
+
# Generate the XML data
node = a.writeXML()
os = StringIO()
xmldoc = BetterElementTree(node)
xmldoc.writeUTF8(os)
-
+
# Verify data
self.assertEqual(os.getvalue(), x)
+
def test_accounts(self):
-
+
self.checkXML("""<?xml version='1.0' encoding='utf-8'?>
<accounts realm="Test Realm">
<user>
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_record.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_record.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/test_record.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,26 +22,27 @@
import unittest
class TestRecord(unittest.TestCase):
-
+
def checkXML(self, x):
-
+
x = x.replace("\n", "\r\n")
-
+
# Parse the XML data
a = XMLRecord()
a.parseXML(XML(x))
-
+
# Generate the XML data
node = a.writeXML()
os = StringIO()
xmldoc = BetterElementTree(node)
xmldoc.writeUTF8(os)
-
+
# Verify data
self.assertEqual(os.getvalue(), x)
+
def test_user(self):
-
+
self.checkXML("""<?xml version='1.0' encoding='utf-8'?>
<user>
<uid>test</uid>
@@ -52,8 +53,9 @@
</user>
""")
+
def test_group(self):
-
+
self.checkXML("""<?xml version='1.0' encoding='utf-8'?>
<group>
<uid>users</uid>
@@ -66,8 +68,9 @@
</group>
""")
+
def test_location(self):
-
+
self.checkXML("""<?xml version='1.0' encoding='utf-8'?>
<location>
<uid>mercury</uid>
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/utils.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/utils.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/admin/xmlaccounts/tests/utils.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,20 +22,20 @@
import unittest
class TestCommon(unittest.TestCase):
-
+
def checkXML(self, x):
-
+
x = x.replace("\n", "\r\n")
-
+
# Parse the XML data
a = XMLRecord()
a.parseXML(XML(x))
-
+
# Generate the XML data
node = a.writeXML()
os = StringIO()
xmldoc = BetterElementTree(node)
xmldoc.writeUTF8(os)
-
+
# Verify data
self.assertEqual(os.getvalue(), x)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/baseshell.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/baseshell.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/baseshell.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,37 +24,42 @@
import traceback
class BaseShell(object):
-
+
def __init__(self, history_name):
-
+
self.prefix = ""
self.commands = {}
self.history = []
self.history_name = history_name
self.preserve_history = False
self.last_wd_complete = ("", ())
-
+
self.readHistory()
+
def readHistory(self):
try:
readline.read_history_file(os.path.expanduser("~/.%s" % (self.history_name,)))
except IOError:
pass
+
def saveHistory(self):
readline.write_history_file(os.path.expanduser("~/.%s" % (self.history_name,)))
+
def registerCommands(self, cmds):
raise NotImplementedError
+
def registerCommand(self, command):
for cmd in command.getCmds():
self.commands[cmd] = command
command.setShell(self)
+
def run(self):
-
+
# Preserve existing history
if self.preserve_history:
old_history = [readline.get_history_item(index) for index in xrange(readline.get_current_history_length())]
@@ -87,8 +92,9 @@
readline.clear_history()
map(readline.add_history, old_history)
+
def execute(self, cmdline):
-
+
# Check for history recall
if cmdline == "!!" and self.history:
cmdline = self.history[-1]
@@ -98,8 +104,8 @@
elif cmdline.startswith("!"):
try:
index = int(cmdline[1:])
- if index> 0 and index <= len(self.history):
- cmdline = self.history[index-1]
+ if index > 0 and index <= len(self.history):
+ cmdline = self.history[index - 1]
print cmdline
if readline.get_current_history_length():
readline.replace_history_item(readline.get_current_history_length() - 1, cmdline)
@@ -108,12 +114,12 @@
except ValueError:
print "%s: event not found" % (cmdline,)
return
-
+
# split the command line into command and options
splits = cmdline.split(" ", 1)
cmd = splits[0]
options = splits[1] if len(splits) == 2 else ""
-
+
# Find matching command
try:
if cmd not in self.commands:
@@ -124,9 +130,10 @@
finally:
# Store in history
self.history.append(cmdline)
-
+
+
def help(self, cmd=None):
-
+
if cmd:
if cmd in self.commands:
cmds = ((cmd, self.commands[cmd]),)
@@ -138,7 +145,7 @@
cmds.sort()
cmds = [(cmd, self.commands[cmd]) for cmd in cmds]
full_help = False
-
+
if full_help:
if self.commands[cmd].hasHelp(cmd):
print self.commands[cmd].help(cmd)
@@ -149,8 +156,9 @@
results.append(cmd.helpListing(name))
utils.printTwoColumnList(results)
+
def complete(self, text, state):
-
+
# If there is no space in the text we complete a command
#print "complete: %s %d" % (text, state)
results = []
@@ -167,8 +175,9 @@
return results[state]
+
def wdcomplete(self, text):
-
+
#print "\nwdcomplete: %s" % (text,)
# Look at cache and return that
@@ -203,6 +212,6 @@
textlen = len(text)
results = [result for result in results if result[:textlen] == text]
#print results
-
+
self.last_wd_complete = (text, results,)
return results
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/command.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/command.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/command.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -15,48 +15,62 @@
##
class Command(object):
-
+
def __init__(self):
-
+
self.shell = None
self.cmds = ()
-
+
+
def execute(self, name, options):
raise NotImplementedError
+
def usage(self, name):
raise NotImplementedError
+
def hasHelp(self, name):
return name in self.cmds
+
def help(self, name):
result = "Command: %s\n" % (name,)
result += "Description: %s\n" % (self.helpDescription(),)
result += self.usage(name)
return result
-
+
+
def helpListing(self, name):
return (name, self.helpDescription())
-
+
+
def helpDescription(self):
return ""
-
+
+
def setShell(self, shell):
self.shell = shell
-
+
+
def getCmds(self):
return self.cmds
+
def complete(self, text):
return ()
+
+
class WrongOptions(Exception):
pass
+
+
class UnknownCommand(Exception):
pass
+
+
class CommandError(Exception):
pass
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/acl.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/acl.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/acl.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -30,14 +30,15 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("acl",)
self.subshell = None
-
+
+
def execute(self, name, options):
-
+
interactive = False
path = None
@@ -47,16 +48,16 @@
print str(e)
print self.usage(name)
raise WrongOptions
-
+
for name, _ignore_value in opts:
-
+
if name == "-i":
interactive = True
else:
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) > 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -80,11 +81,12 @@
else:
aces = ACE.parseFromACL(results[davxml.acl])
print utils.printACEList(aces, self.shell.account)
-
+
return True
+
def doInteractiveMode(self, resource, acls):
-
+
print "Entering ACL edit mode on resource: %s" % (resource.relativeURL(),)
if not self.subshell:
self.subshell = SubShell(self.shell, "ACL", (
@@ -99,7 +101,8 @@
self.subshell.resource = resource
self.subshell.account = self.shell.account
self.subshell.run()
-
+
+
def usage(self, name):
return """Usage: %s [OPTIONS] [PATH]
PATH is a relative or absolute path.
@@ -109,11 +112,14 @@
if not present, existing ACLs will be printed.
""" % (name,)
+
def helpDescription(self):
return "Manage the access privileges of a directory or file."
+
+
class CommonACLCommand(Command):
-
+
def displayACEList(self):
# First list the current set
results, bad = self.shell.shell.account.session.getProperties(self.shell.resource, (davxml.acl,))
@@ -125,6 +131,7 @@
print utils.printACEList(aces, self.shell.shell.account)
return aces
+
def createACE(self, oldace=None):
ace = ACE()
@@ -137,17 +144,17 @@
insert = None
if oldace:
mapper = {
- str(davxml.href): "1",
- str(davxml.all): "2",
- str(davxml.authenticated): "3",
- str(davxml.unauthenticated): "4",
- str(davxml.property): "5",
+ str(davxml.href): "1",
+ str(davxml.all): "2",
+ str(davxml.authenticated): "3",
+ str(davxml.unauthenticated): "4",
+ str(davxml.property): "5",
}
insert = mapper.get(oldace.principal)
choice = utils.numericInput("Select type: ", 1, 5, insert=insert)
if choice == "q":
return None
-
+
if choice == 1:
href = utils.textInput("Enter principal path: ", insert=oldace.data if oldace else None)
principal = self.shell.shell.account.getPrincipal(URL(url=href))
@@ -163,13 +170,13 @@
prop = utils.textInput("Enter property qname: ", insert=str(oldace.data) if oldace else None)
ace.principal = str(davxml.property)
ace.data = QName(prop)
-
+
invert = utils.yesNoInput("Invert principal [y/n]: ", insert=("y" if oldace.invert else "n") if oldace else None)
ace.invert = (invert == "y")
-
+
grant = utils.choiceInput("Grant or Deny privileges [g/d]: ", ("g", "d",), insert=("g" if oldace.grant else "d") if oldace else None)
ace.grant = (grant == "g")
-
+
print "Privileges:"
print " a. {DAV}read"
print " b. {DAV}write"
@@ -190,7 +197,7 @@
)
if "q" in choice:
return None
-
+
mappedPrivs = {
'a': davxml.read,
'b': davxml.write,
@@ -208,16 +215,20 @@
ace.privs = ()
for char in choice:
ace.privs += (mappedPrivs[char],)
-
+
return ace
-
+
+
+
class Add(CommonACLCommand):
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("add",)
-
+
+
def execute(self, name, options):
-
+
# First list the current set
aces = self.displayACEList()
if aces:
@@ -237,7 +248,7 @@
except ValueError:
print "Invalid input, try again."
continue
-
+
# Try and get the new ace
ace = self.createACE()
if not ace:
@@ -246,23 +257,29 @@
# Now remove those that cannot be edited
aces = [ace for ace in aces if ace.canChange()]
-
+
# Now execute
self.shell.shell.account.session.setACL(self.shell.resource, aces)
break
-
+
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Add ACL to existing resource."
+
+
class Change(CommonACLCommand):
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("change",)
-
+
+
def execute(self, name, options):
# First list the current set
@@ -282,12 +299,12 @@
except ValueError:
print "Invalid input, try again."
continue
-
+
# Check that the targeted ace is editable
if not aces[number - 1].canChange():
print "You cannot change a protected or inherited ace."
break
-
+
# Try and get the new ace
ace = self.createACE(oldace=aces[number - 1])
if not ace:
@@ -296,25 +313,31 @@
# Now remove those that cannot be edited
aces = [ace for ace in aces if ace.canChange()]
-
+
# Now execute
self.shell.shell.account.session.setACL(self.shell.resource, aces)
break
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Change ACL on existing resource."
+
+
class Remove(CommonACLCommand):
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("remove",)
-
+
+
def execute(self, name, options):
-
+
# First list the current set
aces = self.displayACEList()
if aces:
@@ -332,42 +355,50 @@
except ValueError:
print "Invalid input, try again."
continue
-
+
# Check that the targeted ace is editable
- if not aces[number-1].canChange():
+ if not aces[number - 1].canChange():
print "You cannot remove a protected or inherited ace."
break
-
+
# Remove the one we are removing
- del aces[number-1]
-
+ del aces[number - 1]
+
# Now remove those that cannot be edited
aces = [ace for ace in aces if ace.canChange()]
-
+
# Now execute
self.shell.shell.account.session.setACL(self.shell.resource, aces)
break
-
+
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Remove ACL on existing resource."
+
+
class List(CommonACLCommand):
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("list",)
-
+
+
def execute(self, name, options):
-
+
self.displayACEList()
return True
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "List current ACLs on existing resource."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/addressbooks.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/addressbooks.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/addressbooks.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,11 +21,12 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("addressbooks",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
if len(opts) != 0:
@@ -52,16 +53,19 @@
if not result:
print "%s: No such directory" % (newpath,)
-
+
return result
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s [PRINCIPAL]
PRINCIPAL is a principal-URL.
""" % (name,)
+
def helpDescription(self):
return "Change working directory to address book home for current or specified principal."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/calendars.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/calendars.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/calendars.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,11 +21,12 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("calendars",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
if len(opts) != 0:
@@ -52,16 +53,19 @@
if not result:
print "%s: No such directory" % (newpath,)
-
+
return result
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s [PRINCIPAL]
PRINCIPAL is a principal-URL.
""" % (name,)
+
def helpDescription(self):
return "Change working directory to calendar home for current or specified principal."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cat.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cat.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cat.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,11 +22,12 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("cat", "more",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
if len(opts) or len(args) != 1:
@@ -44,13 +45,16 @@
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s PATH
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Display contents of a file or directory."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cd.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cd.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/cd.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,11 +21,12 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("cd",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
if len(opts) or len(args) != 1:
@@ -47,16 +48,19 @@
if not result:
print "%s: %s No such directory" % (name, options,)
-
+
return result
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s PATH
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Change working directory."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/help.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/help.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/help.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,26 +20,30 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("help", "?",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
if len(opts) or len(args) > 1:
print self.usage(name)
raise WrongOptions()
- self.shell.help(cmd = (None if len(args) == 0 else args[0]))
+ self.shell.help(cmd=(None if len(args) == 0 else args[0]))
return True
+
def usage(self, name):
return """Usage: %s [CMD]
CMD is the name of a command.
""" % (name,)
+
def hasHelp(self, name):
return name in ("help",)
+
def helpDescription(self):
return "Displays help about a command."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/history.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/history.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/history.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,24 +18,27 @@
from caldavclientlibrary.browser.command import WrongOptions
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
- self.cmds = ("history", )
-
+ self.cmds = ("history",)
+
+
def execute(self, name, options):
if options:
print self.usage(name)
raise WrongOptions()
-
+
format = "%%0%ds %%s" % (len(self.shell.history),)
for ctr, cmd in enumerate(self.shell.history):
- print format % (ctr+1, cmd,)
+ print format % (ctr + 1, cmd,)
return True
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Displays the history of all commands used in this session."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/import.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/import.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/import.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,13 +22,14 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("import",)
-
+
+
def execute(self, name, options):
-
+
fname = None
content_type = None
path = None
@@ -36,7 +37,7 @@
opts, args = getopt.getopt(shlex.split(options), 'acf:')
for name, value in opts:
-
+
if name == "-f":
fname = value
elif name == "-a":
@@ -51,12 +52,12 @@
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if not fname:
print "File name must be provided"
print self.usage(name)
raise WrongOptions
-
+
elif len(args) > 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -87,9 +88,11 @@
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s OPTIONS PATH
PATH is a relative or absolute path.
@@ -102,5 +105,6 @@
One of -c or -a is REQUIRED.
""" % (name,)
+
def helpDescription(self):
return "Import data to a collection on the server."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/logging.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/logging.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/logging.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,11 +20,12 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
- self.cmds = ("logging", )
-
+ self.cmds = ("logging",)
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
if len(opts) or len(args) > 1:
@@ -33,7 +34,7 @@
if args and args[0] not in ("on", "off",):
print self.usage(name)
raise WrongOptions()
-
+
if args:
state = args[0]
else:
@@ -46,6 +47,7 @@
print "HTTP logging turned off"
return True
+
def usage(self, name):
return """Usage: %s [on|off]
on - turn HTTP protocol logging on
@@ -53,5 +55,6 @@
without either argument - toggle the state of logging
""" % (name,)
+
def helpDescription(self):
return "Changes the current state of HTTP logging."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/ls.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/ls.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/ls.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,13 +24,14 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("ls",)
-
+
+
def execute(self, name, options):
-
+
longlist = False
path = None
rtype = False
@@ -43,7 +44,7 @@
opts, args = getopt.getopt(shlex.split(options), 'acdeilrs')
for name, _ignore_value in opts:
-
+
if name == "-a":
pass
elif name == "-c":
@@ -70,7 +71,7 @@
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) > 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -133,14 +134,14 @@
else:
line.append(rurl[len(path):])
lines.append(line)
-
+
if lines:
# Get column widths
- widths = [0] * len(lines[0])
+ widths = [0] * len(lines[0])
for line in lines:
for ctr, col in enumerate(line):
widths[ctr] = max(widths[ctr], len(col))
-
+
# Write out each one
for line in lines:
for ctr, col in enumerate(line):
@@ -151,9 +152,11 @@
print
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s [OPTIONS] [PATH]
PATH is a relative or absolute path.
@@ -168,5 +171,6 @@
-s long listing + DAV:sync-token
""" % (name,)
+
def helpDescription(self):
return "List the contents of a directory."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkadbk.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkadbk.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkadbk.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,21 +22,22 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("mkadbk",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
for name, _ignore_value in opts:
-
+
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) != 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -52,14 +53,17 @@
self.shell.account.session.makeAddressBook(resource)
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s PATH
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Creates an address book collection."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkcal.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkcal.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkcal.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,21 +22,22 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("mkcal",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
for name, _ignore_value in opts:
-
+
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) != 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -52,14 +53,17 @@
self.shell.account.session.makeCalendar(resource)
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s PATH
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Creates a calendar collection."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkdir.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkdir.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mkdir.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,21 +22,22 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("mkdir",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
for name, _ignore_value in opts:
-
+
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) != 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -52,14 +53,17 @@
self.shell.account.session.makeCollection(resource)
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s PATH
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Creates a regular collection."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mv.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mv.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/mv.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,25 +23,26 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("mv", "move",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), 'n')
doURLDecode = False
for name, _ignore_value in opts:
-
+
if name == "-n":
doURLDecode = True
else:
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) != 2:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -57,28 +58,31 @@
return True
elif result[0] == "y":
break
-
+
fromResource = args[0]
if not fromResource.startswith("/"):
fromResource = os.path.join(self.shell.wd, fromResource)
toResource = args[1]
if not toResource.startswith("/"):
toResource = os.path.join(self.shell.wd, toResource)
-
+
resourceFrom = URL(url=fromResource, decode=doURLDecode)
resourceTo = URL(url=self.shell.server + toResource, decode=doURLDecode)
self.shell.account.session.moveResource(resourceFrom, resourceTo)
-
+
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s PATH PATH
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Moves a resource."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/principal.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/principal.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/principal.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,11 +22,12 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
- self.cmds = ("principal", )
-
+ self.cmds = ("principal",)
+
+
def execute(self, name, options):
refresh = False
resolve = True
@@ -36,7 +37,7 @@
opts, args = getopt.getopt(shlex.split(options), 'fnp:x')
for name, value in opts:
-
+
if name == "-f":
refresh = True
elif name == "-n":
@@ -91,6 +92,7 @@
return True
+
def usage(self, name):
return """Usage: %s [OPTIONS]
Options:
@@ -101,5 +103,6 @@
-x print proxy details as well.
""" % (name,)
+
def helpDescription(self):
return "Get details on principals."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/props.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/props.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/props.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,13 +23,14 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("props",)
-
+
+
def execute(self, name, options):
-
+
names = False
all = False
xmllist = False
@@ -38,7 +39,7 @@
opts, args = getopt.getopt(shlex.split(options), 'aln')
for name, _ignore_value in opts:
-
+
if name == "-a":
all = True
elif name == "-l":
@@ -49,7 +50,7 @@
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) > 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -78,12 +79,14 @@
if bad:
print "Failed Properties:"
utils.printProperties(bad)
-
+
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s [OPTIONS] [PATH]
PATH is a relative or absolute path.
@@ -96,5 +99,6 @@
only one of -n and -a can be set.
""" % (name,)
+
def helpDescription(self):
return "List the properties of a directory or file."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/proxies.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/proxies.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/proxies.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,12 +24,13 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
- self.cmds = ("proxies", )
+ self.cmds = ("proxies",)
self.subshell = None
-
+
+
def execute(self, name, options):
interactive = False
@@ -45,7 +46,7 @@
raise WrongOptions
for name, value in opts:
-
+
if name == "-i":
interactive = True
elif name == "-r":
@@ -58,7 +59,7 @@
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) > 0:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -71,8 +72,9 @@
return True
+
def doInteractiveMode(self, principal):
-
+
print "Entering Proxy edit mode on principal: %s (%s)" % (principal.getSmartDisplayName(), principal.principalURL)
if not self.subshell:
self.subshell = SubShell(self.shell, "Proxy", (
@@ -86,24 +88,28 @@
self.subshell.principal = principal
self.subshell.account = self.shell.account
self.subshell.run()
-
+
+
def usage(self, name):
return """Usage: %s [OPTIONS]
PRINCIPAL - principal path to request proxies for.
-
+
Options:
-i interactive mode for adding, changing and deleting proxies.
-r read proxies [OPTIONAL]
-w write proxies [OPTIONAL]
if neither is present, both are displayed.
-
+
-p principal path to request proxies for [OPTIONAL]
if not present, the current user's principal is used.
""" % (name,)
+
def helpDescription(self):
return "Displays the delegates for the chosen user."
+
+
class CommonProxiesCommand(Command):
def parseOptions(self, name, options):
@@ -118,7 +124,7 @@
raise WrongOptions
for name, _ignore_value in opts:
-
+
if name == "-r":
read = True
if write:
@@ -135,7 +141,7 @@
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if not read and not write:
print "One of -r and -w must be specified."
print self.usage(name)
@@ -145,11 +151,12 @@
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
raise WrongOptions
-
+
return read
+
def printProxyList(self, read):
-
+
if read:
principals = self.shell.principal.getReadProxies()
else:
@@ -160,11 +167,15 @@
print "There are no proxies of the specified type."
return principals
+
+
class Add(CommonProxiesCommand):
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("add",)
-
+
+
def execute(self, name, options):
read = self.parseOptions(name, options)
@@ -183,23 +194,29 @@
else:
self.shell.principal.setWriteProxies(principals)
+
def usage(self, name):
return """Usage: %s [OPTIONS]
-
+
Options:
-r add to read-only proxy list
-w add to read-write proxy list
one of -r or -w must be present.
""" % (name,)
+
def helpDescription(self):
return "Add proxies on principal."
-
+
+
+
class Remove(CommonProxiesCommand):
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("remove",)
-
+
+
def execute(self, name, options):
read = self.parseOptions(name, options)
@@ -209,38 +226,46 @@
choice = utils.numericInput("Select principal: ", 1, len(principals), allow_q=True)
if choice == "q":
return None
- del principals[choice-1]
+ del principals[choice - 1]
principals = [principal.principalURL for principal in principals]
if read:
self.shell.principal.setReadProxies(principals)
else:
self.shell.principal.setWriteProxies(principals)
+
def usage(self, name):
return """Usage: %s [OPTIONS]
-
+
Options:
-r remove from read-only proxy list
-w remove from read-write proxy list
one of -r or -w must be present.
""" % (name,)
+
def helpDescription(self):
return "Remove proxies on principal."
-
+
+
+
class List(CommonProxiesCommand):
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("list",)
-
+
+
def execute(self, name, options):
-
+
utils.printProxyPrincipals(self.shell.account, self.shell.principal, True, True, True, True)
return True
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "List current ACLs on existing resource."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/put.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/put.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/put.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,13 +22,14 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("put", "write",)
-
+
+
def execute(self, name, options):
-
+
fname = None
content_type = "text/plain"
path = None
@@ -36,7 +37,7 @@
opts, args = getopt.getopt(shlex.split(options), 'f:t:')
for name, value in opts:
-
+
if name == "-f":
fname = value
elif name == "-t":
@@ -45,12 +46,12 @@
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if not fname:
print "File name must be provided"
print self.usage(name)
raise WrongOptions
-
+
elif len(args) > 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -81,9 +82,11 @@
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s OPTIONS PATH
PATH is a relative or absolute path.
@@ -93,5 +96,6 @@
-t content-type of data being put [DEFAULT: text/plain]
""" % (name,)
+
def helpDescription(self):
return "Write data to a file on the server."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quit.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quit.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quit.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,20 +18,23 @@
from caldavclientlibrary.browser.command import WrongOptions
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("quit", "exit",)
-
+
+
def execute(self, name, options):
if options:
print self.usage(name)
raise WrongOptions()
raise SystemExit("quitting")
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Terminates this session."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quota.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quota.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/quota.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,21 +23,22 @@
from caldavclientlibrary.protocol.webdav.definitions import davxml
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("quota",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
for name, _ignore_value in opts:
-
+
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) > 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -59,8 +60,9 @@
quota_available = int(results[davxml.quota_available_bytes])
quota_used = int(results[davxml.quota_used_bytes])
+
def _printSmartSize(size):
-
+
if size < 1024:
return "%d bytes" % (size,)
elif size < 1024 * 1024:
@@ -69,7 +71,7 @@
return "%.1f MB" % (size / (1024.0 * 1024.0),)
else:
return "%.1f GB" % (size / (1024.0 * 1024.0 * 1024.0),)
-
+
print "Used %s of %s (free: %s)" % (
_printSmartSize(quota_used),
_printSmartSize(quota_used + quota_available),
@@ -78,14 +80,17 @@
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s [PATH]
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Checks quota on the specified PATH."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/rm.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/rm.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/rm.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,21 +23,22 @@
import shlex
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("rm",)
-
+
+
def execute(self, name, options):
opts, args = getopt.getopt(shlex.split(options), '')
for name, _ignore_value in opts:
-
+
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
paths = []
if len(args) == 0:
print "Wrong number of arguments: %d" % (len(args),)
@@ -54,7 +55,7 @@
return True
elif result[0] == "y":
break
-
+
for arg in args:
path = arg
if not path.startswith("/"):
@@ -63,17 +64,20 @@
resource = URL(url=path)
self.shell.account.session.deleteResource(resource)
-
+
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s PATH *[PATH]
PATH is a relative or absolute path.
""" % (name,)
+
def helpDescription(self):
return "Deletes one or more resources."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/server.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/server.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/server.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,11 +18,12 @@
from caldavclientlibrary.browser.command import WrongOptions
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
- self.cmds = ("server", )
-
+ self.cmds = ("server",)
+
+
def execute(self, name, options):
if options:
print self.usage(name)
@@ -30,9 +31,11 @@
print self.shell.server
return True
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Displays the current server."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/sync.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/sync.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/sync.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,26 +24,27 @@
synctokens = {}
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
self.cmds = ("sync",)
-
+
+
def execute(self, name, options):
-
+
force = False
opts, args = getopt.getopt(shlex.split(options), 'f')
for name, _ignore_value in opts:
-
+
if name == "-f":
force = True
else:
print "Unknown option: %s" % (name,)
print self.usage(name)
raise WrongOptions
-
+
if len(args) > 1:
print "Wrong number of arguments: %d" % (len(args),)
print self.usage(name)
@@ -60,7 +61,7 @@
synctoken = synctokens.get(path, "") if not force else ""
newsyctoken, changed, removed, other = self.shell.account.session.syncCollection(resource, synctoken)
synctokens[path] = newsyctoken
-
+
for item in changed:
print "Changed: %s" % (item,)
for item in removed:
@@ -71,9 +72,11 @@
return True
+
def complete(self, text):
return self.shell.wdcomplete(text)
+
def usage(self, name):
return """Usage: %s [OPTIONS] [PATH]
PATH is a relative or absolute path.
@@ -82,5 +85,6 @@
-f force full sync
""" % (name,)
+
def helpDescription(self):
return "Sync the contents of a directory."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/user.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/user.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/user.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,11 +19,12 @@
from getpass import getpass
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
- self.cmds = ("user", )
-
+ self.cmds = ("user",)
+
+
def execute(self, name, options):
if options:
print self.usage(name)
@@ -33,9 +34,11 @@
self.shell.setUserPswd(user, pswd)
return True
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Allows changing the current server login id and password."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/whoami.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/whoami.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/whoami.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,11 +18,12 @@
from caldavclientlibrary.browser.command import WrongOptions
class Cmd(Command):
-
+
def __init__(self):
super(Command, self).__init__()
- self.cmds = ("whoami", )
-
+ self.cmds = ("whoami",)
+
+
def execute(self, name, options):
if options:
print self.usage(name)
@@ -30,9 +31,11 @@
print self.shell.user
return True
+
def usage(self, name):
return """Usage: %s
""" % (name,)
+
def helpDescription(self):
return "Displays the current server login id."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/shell.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/shell.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/shell.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -26,34 +26,36 @@
import urlparse
class Shell(BaseShell):
-
+
def __init__(self, server, path, user, pswd, logging):
-
+
super(Shell, self).__init__("caldav_client")
self.prefix = self.wd = "/"
self.server = server
self.user = user
self.pswd = pswd
-
+
self.registerCommands()
-
+
# Create the account
ssl = server.startswith("https://")
server = server[8:] if ssl else server[7:]
self.account = CalDAVAccount(server, ssl=ssl, user=self.user, pswd=self.pswd, root=path, principal=None, logging=logging)
-
+
atexit.register(self.saveHistory)
+
def registerCommands(self):
module = caldavclientlibrary.browser.commands
for item in module.__all__:
- mod = __import__("caldavclientlibrary.browser.commands." + item, globals(), locals(), ["Cmd",])
+ mod = __import__("caldavclientlibrary.browser.commands." + item, globals(), locals(), ["Cmd", ])
cmd_class = mod.Cmd
if type(cmd_class) is type and issubclass(cmd_class, Command):
self.registerCommand(cmd_class())
+
def setWD(self, newwd):
-
+
# Check that the new one exists
resource = (newwd if newwd.endswith("/") else newwd + "/")
if not self.account.session.testResource(URL(url=resource)):
@@ -61,12 +63,15 @@
self.prefix = self.wd = newwd
return True
+
def setUserPswd(self, user, pswd):
-
+
self.user = user
self.pswd = pswd
self.account.setUserPswd(user, pswd)
+
+
def usage():
return """Usage: shell [OPTIONS]
@@ -77,6 +82,8 @@
--pswd=PSWD password for user - will be prompted if not prsent [OPTIONAL].
"""
+
+
def runit():
logging = False
server = None
@@ -84,9 +91,9 @@
pswd = None
opts, _ignore_args = getopt.getopt(sys.argv[1:], 'lh', ["help", "server=", "user=", "pswd="])
-
+
for name, value in opts:
-
+
if name == "-l":
logging = True
elif name == "--server":
@@ -107,7 +114,7 @@
path = splits.path
if not path:
path = "/"
-
+
if not user:
user = raw_input("User: ")
if not pswd:
@@ -116,6 +123,7 @@
shell = Shell(server, path, user, pswd, logging)
shell.run()
+
if __name__ == '__main__':
runit()
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/subshell.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/subshell.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/subshell.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,17 +18,17 @@
from caldavclientlibrary.browser.baseshell import BaseShell
class SubShell(BaseShell):
-
+
def __init__(self, shell, prefix, cmds):
-
+
super(SubShell, self).__init__("caldav_client.%s" % (prefix,))
self.shell = shell
self.prefix = prefix
self.preserve_history = True
self.registerCommands(cmds)
+
def registerCommands(self, cmds):
for cmd in cmds:
if isinstance(cmd, Command):
self.registerCommand(cmd)
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/utils.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/utils.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/utils.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -26,7 +26,7 @@
if resolve:
results = [account.getPrincipal(item, refresh=refresh) for item in principals]
results.sort(key=lambda x: x.getSmartDisplayName())
- strlen = reduce(lambda x,y: max(x, len(y.getSmartDisplayName()) + 1), results, 0)
+ strlen = reduce(lambda x, y: max(x, len(y.getSmartDisplayName()) + 1), results, 0)
results = ["%- *s (%s)" % (strlen, principal.getSmartDisplayName(), principal.principalURL) for principal in results]
else:
results = [item.relativeURL() for item in principals]
@@ -37,9 +37,11 @@
else:
for item in results:
result += "\n %s" % (item,)
-
+
return result
+
+
def printPrincipals(account, principals, resolve, refresh):
result = ""
@@ -49,7 +51,7 @@
for principal in results:
principal.loadDetails(True)
results.sort(key=lambda x: x.getSmartDisplayName())
- strlen = reduce(lambda x,y: max(x, len(y.getSmartDisplayName()) + 1), results, 0)
+ strlen = reduce(lambda x, y: max(x, len(y.getSmartDisplayName()) + 1), results, 0)
results = ["%- *s (%s)" % (strlen, principal.getSmartDisplayName(), principal.principalURL) for principal in results]
else:
results = [item.principalURL for item in principals]
@@ -60,9 +62,11 @@
else:
for item in results:
result += "\n %s" % (item,)
-
+
return result
+
+
def printProxyPrincipals(account, principal, read=True, write=True, resolve=True, refresh_main=False, refresh=False):
if read:
print " Read-Only Proxies: %s" % printPrincipals(account, principal.getReadProxies(refresh_main), resolve, refresh)
@@ -70,6 +74,8 @@
if write:
print " Read-Write Proxies: %s" % printPrincipals(account, principal.getWriteProxies(refresh_main), resolve, refresh)
+
+
def printProperties(items):
sorted = items.keys()
sorted.sort()
@@ -82,6 +88,8 @@
else:
print " %s: %s" % (key, value,)
+
+
def printList(items):
result = ""
if len(items) == 1:
@@ -93,30 +101,38 @@
result += "\n %s" % (item,)
return result
+
+
def printTwoColumnList(items, indent=0):
-
- strlen = reduce(lambda x,y: max(x, len(y[0]) + 1), items, 0)
+
+ strlen = reduce(lambda x, y: max(x, len(y[0]) + 1), items, 0)
sorted = list(items)
sorted.sort(key=lambda x: x[0])
for col1, col2 in sorted:
- print "%s%- *s - %s" % (" "*indent, strlen, col1, col2,)
+ print "%s%- *s - %s" % (" " * indent, strlen, col1, col2,)
+
+
def printPrincipalList(principals):
-
+
result = ""
for ctr, principal in enumerate(principals):
- result += "\n% 2d. %s (%s)" % (ctr+1, principal.getSmartDisplayName(), principal.principalURL)
+ result += "\n% 2d. %s (%s)" % (ctr + 1, principal.getSmartDisplayName(), principal.principalURL)
return result
+
+
def printACEList(aces, account):
-
+
result = ""
for ctr, ace in enumerate(aces):
- result += "\n% 2d. %s" % (ctr+1, printACE(ace, account))
+ result += "\n% 2d. %s" % (ctr + 1, printACE(ace, account))
return result
+
+
def printACE(ace, account):
-
+
principalText = ace.principal
if principalText == str(davxml.href):
principal = account.getPrincipal(URL(url=ace.data))
@@ -144,6 +160,8 @@
result += "\n"
return result
+
+
def textInput(title, insert=None):
if insert:
title = "%s [%s]:" % (title, insert,)
@@ -153,19 +171,25 @@
if not result:
result = insert
return result
-
-def numericInput(title, low, high, allow_q = False, insert=None):
+
+
+
+def numericInput(title, low, high, allow_q=False, insert=None):
if allow_q:
- result = choiceInput(title, [str(num) for num in range(low, high+1)] + ["q",], insert)
+ result = choiceInput(title, [str(num) for num in range(low, high + 1)] + ["q", ], insert)
if result != "q":
result = int(result)
return result
else:
- return int(choiceInput(title, [str(num) for num in range(low, high+1)], insert))
-
+ return int(choiceInput(title, [str(num) for num in range(low, high + 1)], insert))
+
+
+
def yesNoInput(title, insert=None):
return choiceInput(title, ("y", "n"), insert)
-
+
+
+
def choiceInput(title, choices, insert=None):
while True:
result = textInput(title, insert)
@@ -174,7 +198,9 @@
if result in choices:
return result
print "Invalid input. Try again."
-
+
+
+
def multiChoiceInput(title, choices, insert=None):
while True:
result = textInput(title, insert)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/account.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/account.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/account.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,16 +18,18 @@
from caldavclientlibrary.client.principal import principalCache
class CalDAVAccount(object):
-
+
def __init__(self, server, port=None, ssl=False, user="", pswd="", principal=None, root=None, logging=False):
self.session = CalDAVSession(server, port, ssl, user, pswd, principal, root, logging)
self.principal = principalCache.getPrincipal(self.session, self.session.principalPath)
-
+
+
def setUserPswd(self, user, pswd):
-
+
self.session.setUserPswd(user, pswd)
self.principal = principalCache.getPrincipal(self.session, self.session.principalPath)
+
def getPrincipal(self, path=None, refresh=False):
if path:
return principalCache.getPrincipal(self.session, path, refresh=refresh)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/addressbook.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/addressbook.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/addressbook.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,7 +19,7 @@
from caldavclientlibrary.protocol.webdav.definitions import davxml
class AddressBook(object):
-
+
def __init__(self, path=None, session=None):
self.path = path
if not path.endswith("/"):
@@ -28,38 +28,50 @@
self.displayname = None
self.description = None
+
def __str__(self):
return "AddressBook: %s" % (self.path,)
+
def __repr__(self):
return "AddressBook: %s" % (self.path,)
+
def exists(self):
return self.session.testResource(URL(url=self.path))
+
def readAddressBook(self):
pass
+
+
def writeAddressBook(self, adbk):
pass
+
def readComponent(self, name=None, uid=None):
pass
+
+
def writeComponent(self, component, name=None):
pass
+
def getDisplayName(self):
if self.displayname is None and self.session:
self._getProperties()
return self.displayname
+
def getDescription(self):
if self.description is None and self.session:
self._getProperties()
return self.description
-
+
+
def _getProperties(self):
assert(self.session is not None)
-
+
results, _ignore_bad = self.session.getProperties(URL(url=self.path), (davxml.displayname, carddavxml.addressbook_description,))
self.displayname = results.get(davxml.displayname, "")
self.description = results.get(carddavxml.addressbook_description, "")
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendar.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendar.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendar.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,7 +19,7 @@
from caldavclientlibrary.protocol.caldav.definitions import caldavxml
class Calendar(object):
-
+
def __init__(self, path=None, session=None):
self.path = path
if not path.endswith("/"):
@@ -29,38 +29,50 @@
self.description = None
self.timezone = None
+
def __str__(self):
return "Calendar: %s" % (self.path,)
+
def __repr__(self):
return "Calendar: %s" % (self.path,)
+
def exists(self):
return self.session.testResource(URL(url=self.path))
+
def readCalendar(self):
pass
+
+
def writeCalendar(self, calendar):
pass
+
def readComponent(self, name=None, uid=None):
pass
+
+
def writeComponent(self, component, name=None):
pass
+
def getDisplayName(self):
if self.displayname is None and self.session:
self._getProperties()
return self.displayname
+
def getDescription(self):
if self.description is None and self.session:
self._getProperties()
return self.description
-
+
+
def _getProperties(self):
assert(self.session is not None)
-
+
results, _ignore_bad = self.session.getProperties(URL(url=self.path), (davxml.displayname, caldavxml.calendar_description, caldavxml.calendar_timezone,))
self.displayname = results.get(davxml.displayname, "")
self.description = results.get(caldavxml.calendar_description, "")
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendaruseraddress.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendaruseraddress.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/calendaruseraddress.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -16,30 +16,37 @@
class CalendarUserAddress(object):
-
+
def __init__(self, cuaddr=None, name=None, attendee=None):
self.cuaddr = cuaddr
self.name = name
if attendee:
self.setAttendee(attendee)
+
def getCUAddr(self):
return self.cuaddr
+
def setCUAddr(self, value):
self.cuaddr = value
+
def getName(self):
return self.name
+
def setCn(self, value):
self.name = value
-
+
+
def getFullText(self):
return ("%s <%s>" % (self.name, self.cuaddr,)) if self.name else ("<%s>" % (self.cuaddr,))
-
+
+
def getAttendeeProperty(self):
pass
-
+
+
def setAttendee(self, attendee):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -47,12 +47,13 @@
import types
class CalDAVSession(Session):
-
+
class logger(object):
-
+
def write(self, data):
print data.replace("\r\n", "\n"),
+
def __init__(self, server, port=None, ssl=False, user="", pswd="", principal=None, root=None, logging=False):
super(CalDAVSession, self).__init__(server, port, ssl, log=CalDAVSession.logger())
@@ -60,31 +61,33 @@
self.user = user
self.pswd = pswd
-
+
# Initialize state
self.connect = None
# Paths
self.rootPath = URL(url=root)
self.principalPath = URL(url=principal) if principal else None
-
+
self._initCalDAVState()
+
def _initCalDAVState(self):
# We need to cache the server capabilities and properties
if not self.principalPath:
self._discoverPrincipal()
-
+
+
def _discoverPrincipal(self):
-
+
current = self.getCurrentPrincipalResource(self.rootPath)
if current:
self.principalPath = current
if self.log:
self.log.write("Found current principal path: %s\n" % (self.principalPath.absoluteURL(),))
return
-
+
hrefs = self.getHrefListProperty(self.rootPath, davxml.principal_collection_set)
if not hrefs:
return
@@ -98,25 +101,28 @@
if self.log:
self.log.write("Found principal path: %s\n" % (self.principalPath.absoluteURL(),))
return
-
+
+
def setUserPswd(self, user, pswd):
-
+
self.user = user
self.pswd = pswd
self.authorization = None
self._discoverPrincipal()
+
def testResource(self, rurl):
assert(isinstance(rurl, URL))
request = PropFind(self, rurl.relativeURL(), headers.Depth0, (davxml.resourcetype,))
-
+
# Process it
self.runSession(request)
-
+
return request.getStatusCode() == statuscodes.MultiStatus
+
def getPropertyNames(self, rurl):
assert(isinstance(rurl, URL))
@@ -127,22 +133,22 @@
request = PropNames(self, rurl.relativeURL(), headers.Depth0)
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each propfind result
for item in parser.getResults().itervalues():
# Get child element name (decode URL)
name = URL(url=item.getResource(), decode=True)
-
+
# Must match rurl
if name.equalRelative(rurl):
@@ -150,9 +156,10 @@
else:
self.handleHTTPError(request)
-
+
return results
+
def getProperties(self, rurl, props, xmldata=False):
assert(isinstance(rurl, URL))
@@ -167,22 +174,22 @@
request = PropAll(self, rurl.relativeURL(), headers.Depth0)
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each propfind result
for item in parser.getResults().itervalues():
# Get child element name (decode URL)
name = URL(url=item.getResource(), decode=True)
-
+
# Must match rurl
if name.equalRelative(rurl):
for name, value in item.getTextProperties().iteritems():
@@ -196,9 +203,10 @@
bad = item.getBadProperties()
else:
self.handleHTTPError(request)
-
+
return results, bad
+
def getPropertiesOnHierarchy(self, rurl, props):
assert(isinstance(rurl, URL))
@@ -209,16 +217,16 @@
request = PropFind(self, rurl.relativeURL(), headers.Depth1, props)
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each propfind result
for item in parser.getResults().itervalues():
@@ -226,19 +234,20 @@
name = URL(url=item.getResource(), decode=True)
propresults = {}
results[name.relativeURL()] = propresults
-
+
for prop in props:
- if item.getTextProperties().has_key(str(prop)):
+ if str(prop) in item.getTextProperties():
propresults[prop] = item.getTextProperties().get(str(prop))
- elif item.getNodeProperties().has_key(str(prop)):
+ elif str(prop) in item.getNodeProperties():
propresults[prop] = item.getNodeProperties()[str(prop)]
else:
self.handleHTTPError(request)
-
+
return results
+
def getHrefListProperty(self, rurl, propname):
assert(isinstance(rurl, URL))
@@ -249,76 +258,78 @@
request = PropFind(self, rurl.relativeURL(), headers.Depth0, (propname,))
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each propfind result and extract any Hrefs
for item in parser.getResults().itervalues():
# Get child element name (decode URL)
name = URL(url=item.getResource(), decode=True)
-
+
# Must match rurl
if name.equalRelative(rurl):
- if item.getNodeProperties().has_key(str(propname)):
-
+ if str(propname) in item.getNodeProperties():
+
propnode = item.getNodeProperties()[str(propname)]
results += tuple([URL(url=href.text, decode=True) for href in propnode.findall(str(davxml.href)) if href.text])
else:
self.handleHTTPError(request)
-
+
return results
+
# Do principal-match report with self on the passed in url
def getSelfProperties(self, rurl, props):
-
+
assert(isinstance(rurl, URL))
results = {}
-
+
# Create WebDAV principal-match
request = PrincipalMatch(self, rurl.relativeURL(), props)
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each principal-match result and return first one that is appropriate
for item in parser.getResults().itervalues():
for prop in props:
- if item.getNodeProperties().has_key(str(prop)):
+ if str(prop) in item.getNodeProperties():
href = item.getNodeProperties()[str(prop)].find(str(davxml.href))
-
+
if href is not None:
results[prop] = URL(url=href.text, decode=True)
-
+
# We'll take the first one, whatever that is
break
else:
self.handleHTTPError(request)
return None
-
+
return results
+
# Do principal-match report with self on the passed in url
def getSelfHrefs(self, rurl):
@@ -330,16 +341,16 @@
request = PrincipalMatch(self, rurl.relativeURL(), (davxml.principal_URL,))
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each propfind result and extract any Hrefs
for item in parser.getResults().itervalues():
@@ -350,35 +361,38 @@
else:
self.handleHTTPError(request)
return None
-
+
return results
-
+
+
# Do principal-match report with self on the passed in url
def getSelfPrincipalResource(self, rurl):
-
+
assert(isinstance(rurl, URL))
hrefs = self.getHrefListProperty(rurl, davxml.principal_collection_set)
if not hrefs:
return None
-
+
# For each principal collection find one that matches self
for href in hrefs:
results = self.getSelfHrefs(href)
if results:
return results[0]
-
+
return None
+
# Do current-user-principal property on the passed in url
def getCurrentPrincipalResource(self, rurl):
-
+
assert(isinstance(rurl, URL))
hrefs = self.getHrefListProperty(rurl, davxml.current_user_principal)
return hrefs[0] if hrefs else None
+
def setProperties(self, rurl, props):
assert(isinstance(rurl, URL))
@@ -407,7 +421,7 @@
else:
node = Element(name)
map(node.append, hrefs)
-
+
if node is not None:
converted.append(node)
@@ -415,22 +429,22 @@
request = PropPatch(self, rurl.relativeURL(), converted)
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each propfind result
for item in parser.getResults().itervalues():
# Get child element name (decode URL)
name = URL(url=item.getResource(), decode=True)
-
+
# Must match rurl
if name.equalRelative(rurl):
@@ -439,61 +453,66 @@
else:
self.handleHTTPError(request)
-
+
return results
+
def setACL(self, rurl, aces):
-
+
assert(isinstance(rurl, URL))
# Create WebDAV ACL
request = ACL(self, rurl.relativeURL(), aces)
-
+
# Process it
self.runSession(request)
-
+
if request.getStatusCode() not in (statuscodes.OK, statuscodes.Created, statuscodes.NoContent):
self.handleHTTPError(request)
+
def makeCollection(self, rurl):
-
+
assert(isinstance(rurl, URL))
# Create WebDAV MKCOL
request = MakeCollection(self, rurl.relativeURL())
-
+
# Process it
self.runSession(request)
-
+
if request.getStatusCode() not in (statuscodes.OK, statuscodes.Created, statuscodes.NoContent):
self.handleHTTPError(request)
+
def makeCalendar(self, rurl, displayname=None, description=None):
-
+
assert(isinstance(rurl, URL))
# Create WebDAV MKCALENDAR
request = MakeCalendar(self, rurl.relativeURL(), displayname, description)
-
+
# Process it
self.runSession(request)
-
+
if request.getStatusCode() not in (statuscodes.OK, statuscodes.Created, statuscodes.NoContent):
self.handleHTTPError(request)
+
def makeAddressBook(self, rurl, displayname=None, description=None):
-
+
assert(isinstance(rurl, URL))
# Create WebDAV extended MKCOL
request = MakeAddressBook(self, rurl.relativeURL(), displayname, description)
-
+
# Process it
self.runSession(request)
-
+
if request.getStatusCode() not in (statuscodes.OK, statuscodes.Created, statuscodes.NoContent):
self.handleHTTPError(request)
+
def syncCollection(self, rurl, synctoken, props=()):
assert(isinstance(rurl, URL))
@@ -507,16 +526,16 @@
request = SyncCollection(self, rurl.relativeURL(), davxml.sync_level_1, synctoken, props)
result = ResponseDataString()
request.setOutput(result)
-
+
# Process it
self.runSession(request)
-
+
# If its a 207 we want to parse the XML
if request.getStatusCode() == statuscodes.MultiStatus:
parser = PropFindParser()
parser.parseData(result.getData())
-
+
# Look at each propfind result
for item in parser.getResults().itervalues():
@@ -534,39 +553,42 @@
if node.tag == davxml.sync_token:
newsynctoken = node.text
break
-
+
else:
self.handleHTTPError(request)
-
+
return (newsynctoken, changed, removed, other,)
+
def deleteResource(self, rurl):
-
+
assert(isinstance(rurl, URL))
# Create WebDAV DELETE
request = Delete(self, rurl.relativeURL())
-
+
# Process it
self.runSession(request)
-
+
if request.getStatusCode() not in (statuscodes.OK, statuscodes.NoContent):
self.handleHTTPError(request)
+
def moveResource(self, rurlFrom, rurlTo):
-
+
assert(isinstance(rurlFrom, URL))
assert(isinstance(rurlTo, URL))
# Create WebDAV MOVE
request = Move(self, rurlFrom.relativeURL(), rurlTo.absoluteURL())
-
+
# Process it
self.runSession(request)
-
+
if request.getStatusCode() not in (statuscodes.OK, statuscodes.Created, statuscodes.NoContent):
self.handleHTTPError(request)
+
def readData(self, rurl):
assert(isinstance(rurl, URL))
@@ -575,29 +597,30 @@
request = Get(self, rurl.relativeURL())
dout = ResponseDataString()
request.setData(dout)
-
+
# Process it
self.runSession(request)
-
+
# Check response status
if request.getStatusCode() != statuscodes.OK:
self.handleHTTPError(request)
return None
-
+
# Look for ETag
if request.getNewETag() is not None:
etag = request.getNewETag()
-
+
# Handle server bug: ETag value MUST be quoted per HTTP/1.1 S3.11
if not etag.startswith('"'):
etag = "\"%s\"" % (etag,)
else:
etag = None
-
+
# Return data as a string and etag
return dout.getData(), etag
+
def writeData(self, rurl, data, contentType):
assert(isinstance(rurl, URL))
@@ -606,14 +629,15 @@
request = Put(self, rurl.relativeURL())
dout = RequestDataString(data, contentType)
request.setData(dout, None)
-
+
# Process it
self.runSession(request)
-
+
# Check response status
if request.getStatusCode() not in (statuscodes.OK, statuscodes.Created, statuscodes.NoContent,):
self.handleHTTPError(request)
+
def importData(self, rurl, data, contentType):
assert(isinstance(rurl, URL))
@@ -622,26 +646,29 @@
request = Post(self, rurl.relativeURL())
dout = RequestDataString(data, contentType)
request.setData(dout, None)
-
+
# Process it
self.runSession(request)
-
+
# Check response status
if request.getStatusCode() not in (statuscodes.OK, statuscodes.MultiStatus, statuscodes.NoContent,):
self.handleHTTPError(request)
+
def displayHTTPError(self, request):
print request.status_code
+
def openSession(self):
# Create connection
self.connect = SmartHTTPConnection(self.server, self.port, self.ssl)
-
+
# Write to log file
if self.loghttp and self.log:
self.log.write("\n <-------- BEGIN HTTP CONNECTION -------->\n")
self.log.write("Server: %s\n" % (self.server,))
+
def closeSession(self):
if self.connect:
self.connect.close()
@@ -650,15 +677,16 @@
# Write to log file
if self.loghttp and self.log:
self.log.write("\n <-------- END HTTP CONNECTION -------->\n")
-
+
+
def runSession(self, request):
-
+
ctr = 5
while ctr:
ctr -= 1
-
+
self.doSession(request)
-
+
if request and request.isRedirect():
location = request.getResponseHeader(headers.Location)
if location:
@@ -666,72 +694,72 @@
if not u.scheme or u.scheme in ("http", "https",):
# Get new server and base RURL
different_server = (self.server != u.server) if u.server else False
-
+
# Use new host in this session
if different_server:
self.setServer(u.server)
-
+
# Reset the request with new info
request.setURL(u.relativeURL())
request.clearResponse()
-
+
# Write to log file
if self.loghttp and self.log:
self.log.write("\n <-------- HTTP REDIRECT -------->\n")
self.log.write("Location: %s\n" % (location,))
-
+
# Recyle through loop
continue
# Exit when redirect does not occur
break
-
+
+
def doSession(self, request):
# Do initialisation if not already done
if not self.initialised:
-
+
if not self.initialise(self.server, self.rootPath.relativeURL()):
-
+
# Break connection with server
self.closeConnection()
return
# Do the request if present
if request:
-
+
# Handle delayed authorization
first_time = True
while True:
-
+
# Run the request actions - this will make any connection that is needed
self.sendRequest(request)
-
+
# Check for auth failure if none before
if request.getStatusCode() == statuscodes.Unauthorized:
-
+
# If we had authorization before, then chances are auth details are wrong - so delete and try again with new auth
if self.hasAuthorization():
-
+
self.authorization = None
-
+
# Display error so user knows why the prompt occurs again - but not the first time
# as we might have a digest re-auth.
if not first_time:
self.displayHTTPError(request)
-
-
+
# Get authorization object (prompt the user) and redo the request
self.authorization, cancelled = self.getAuthorizor(first_time, request.getResponseHeaders(headers.WWWAuthenticate))
-
+
# Check for auth cancellation
if cancelled:
self.authorization = None
-
+
else:
first_time = False
-
+
request.clearResponse()
-
+
# Repeat the request loop with new authorization
continue
@@ -739,12 +767,13 @@
break
# Now close it - eventually we will do keep-alive support
-
+
# Break connection with server
self.closeConnection()
+
def doRequest(self, request):
-
+
# Write request headers
self.connect.putrequest(request.method, request.url, skip_host=True, skip_accept_encoding=True)
hdrs = request.getRequestHeaders()
@@ -759,23 +788,23 @@
for header, value in hdrs:
self.log.write("%s: %s\n" % (header, value))
self.log.write("\n")
-
+
# Write the data
self.writeRequestData(request)
-
- # Blank line in log between
+
+ # Blank line in log between
if self.loghttp and self.log:
self.log.write("\n <-------- BEGIN HTTP RESPONSE -------->\n")
# Get response
response = self.connect.getresponse()
-
+
# Get response headers
request.setResponseStatus(response.version, response.status, response.reason)
request.setResponseHeaders(response.msg.headers)
if self.loghttp and self.log:
self.log.write("HTTP/%s %s %s\r\n" % (
- {11:"1.1",10:"1.0",9:"0.9"}.get(response.version, "?"),
+ {11: "1.1", 10: "1.0", 9: "0.9"}.get(response.version, "?"),
response.status,
response.reason
))
@@ -785,19 +814,21 @@
# Now get the data
self.readResponseData(request, response)
-
- # Trailer in log
+
+ # Trailer in log
if self.loghttp and self.log:
self.log.write("\n <-------- END HTTP RESPONSE -------->\n")
+
def handleHTTPError(self, request):
print "Ignoring error: %d" % (request.getStatusCode(),)
+
def getAuthorizor(self, first_time, wwwhdrs):
-
+
for witem in wwwhdrs:
for item in witem.split(","):
- item = item.strip()
+ item = item.strip()
if item.lower().startswith("basic"):
return Basic(self.user, self.pswd), False
elif item.lower().startswith("digest"):
@@ -807,34 +838,36 @@
else:
return None, True
+
def writeRequestData(self, request):
-
+
# Write the data if any present
if request.hasRequestData():
-
+
stream = request.getRequestData()
if stream:
# Tell data we are using it
stream.start()
-
+
# Buffered write from stream
more = True
while more:
data, more = stream.read()
if data:
self.connect.send(data)
-
+
if self.loghttp and self.log:
self.log.write(data)
# Tell data we are done using it
stream.stop()
-
+
+
def readResponseData(self, request, response):
-
+
# Check for data and write it
data = response.read()
-
+
if request.hasResponseData():
stream = request.getResponseData()
stream.start()
@@ -842,16 +875,18 @@
stream.stop()
else:
response.read()
-
+
if self.loghttp and self.log:
- self.log.write(data)
+ self.log.write(data)
+
def setServerType(self, type):
self.type = type
-
+
+
def setServerDescriptor(self, txt):
self.descriptor = txt
-
+
+
def setServerCapability(self, txt):
self.capability = txt
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/httpshandler.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/httpshandler.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/httpshandler.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -30,13 +30,14 @@
https_v23_connects = set()
https_v3_connects = set()
+
def SmartHTTPConnection(host, port, ssl):
-
- def trySSL(cls, ):
+
+ def trySSL(cls,):
connect = cls(host, port)
connect.connect()
return connect
-
+
if ssl:
if (host, port) in https_v3_connects:
try:
@@ -48,22 +49,21 @@
return trySSL(httplib.HTTPSConnection)
except:
https_v23_connects.remove((host, port))
-
+
try:
https_v3_connects.add((host, port))
return trySSL(HTTPSConnection_SSLv3)
except:
https_v3_connects.remove((host, port))
-
+
try:
https_v23_connects.add((host, port))
return trySSL(httplib.HTTPSConnection)
except:
https_v23_connects.remove((host, port))
-
+
raise RuntimeError("Cannot connect via with SSLv23 or SSLv3")
else:
connect = httplib.HTTPConnection(host, port)
connect.connect()
return connect
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/principal.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/principal.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/principal.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,10 +23,11 @@
from caldavclientlibrary.protocol.webdav.definitions import davxml
class PrincipalCache(object):
-
+
def __init__(self):
self.cache = {}
-
+
+
def getPrincipal(self, session, path, refresh=False):
if path and path.toString() not in self.cache:
principal = CalDAVPrincipal(session, path)
@@ -40,26 +41,35 @@
self.cache[path.toString()].loadDetails(refresh=True)
return self.cache[path.toString()] if path else None
+
def invalidate(self, path):
if path.toString() in self.cache:
del self.cache[path.toString()]
principalCache = PrincipalCache()
+
+
def make_tuple(item):
return item if isinstance(item, tuple) else (item,)
-
+
+
+
def make_tuple_from_list(item):
return item if isinstance(item, tuple) else ((item,) if item else ())
+
+
class CalDAVPrincipal(object):
-
+
+
def __init__(self, session, path):
-
+
self.session = session
self.principalPath = path
self._initFields()
+
def __str__(self):
return """
Principal Path : %s
@@ -87,6 +97,7 @@
self.adbkhomeset,
)
+
def _initFields(self):
self.loaded = False
self.valid = False
@@ -100,11 +111,12 @@
self.inboxURL = ""
self.cuaddrs = ()
self.adbkhomeset = ()
-
+
self.proxyFor = None
self.proxyreadURL = ""
self.proxywriteURL = ""
-
+
+
def loadDetails(self, refresh=False):
if self.loaded and not refresh:
return
@@ -135,7 +147,7 @@
type.find(str(caldavxml.calendar_proxy_write)) is not None)):
parentPath = self.principalPath.dirname()
self.proxyFor = principalCache.getPrincipal(self.session, parentPath, refresh)
-
+
if self.valid:
self.displayname = results.get(davxml.displayname, None)
self.principalURL = results.get(davxml.principal_URL, None)
@@ -158,15 +170,17 @@
self.proxyreadURL = URL(url=path)
elif rtype.find(str(caldavxml.calendar_proxy_write)) is not None:
self.proxywriteURL = URL(url=path)
-
+
self.loaded = True
+
def getSmartDisplayName(self):
if self.proxyFor:
return "%s#%s" % (self.proxyFor.displayname, self.displayname,)
else:
return self.displayname
+
def listCalendars(self, root=None):
calendars = []
home = self.homeset[0]
@@ -181,68 +195,78 @@
calendars.append(Calendar(path=path, session=self.session))
return calendars
+
def listFreeBusySet(self):
return self._getFreeBusySet()
-
+
+
def addToFreeBusySet(self, calendars):
current = self._getFreeBusySet()
for calendar in calendars:
current.append(calendar)
self._setFreeBusySet(current)
-
+
+
def removeFromFreeBusySet(self, calendars):
calendar_paths = [calendar.path for calendar in calendars]
current = self._getFreeBusySet()
current = [cal for cal in current if cal.path not in calendar_paths]
self._setFreeBusySet(current)
+
def cleanFreeBusySet(self):
fbset = self.listFreeBusySet()
badfbset = []
for calendar in fbset:
if not calendar.exists():
badfbset.append(calendar)
-
+
if badfbset:
self.removeFromFreeBusySet(badfbset)
+
def _getFreeBusySet(self):
hrefs = self.session.getHrefListProperty(self.inboxURL, caldavxml.calendar_free_busy_set)
return [Calendar(href.relativeURL(), session=self.session) for href in hrefs]
-
+
+
def _setFreeBusySet(self, calendars):
hrefs = [URL(url=calendar.path) for calendar in calendars]
self.session.setProperties(self.inboxURL, ((caldavxml.calendar_free_busy_set, hrefs),))
+
def getReadProxies(self, refresh=True):
if not self.proxyreadURL:
return ()
-
+
principal = principalCache.getPrincipal(self.session, self.proxyreadURL, refresh=refresh)
return [principalCache.getPrincipal(self.session, member) for member in principal.memberset]
-
-
+
+
def setReadProxies(self, principals):
if not self.proxyreadURL:
return ()
-
+
self.session.setProperties(self.proxyreadURL, ((davxml.group_member_set, principals),))
principalCache.invalidate(self.proxyreadURL)
-
+
+
def getWriteProxies(self, refresh=True):
if not self.proxywriteURL:
return ()
-
+
principal = principalCache.getPrincipal(self.session, self.proxywriteURL, refresh=refresh)
return [principalCache.getPrincipal(self.session, member) for member in principal.memberset]
+
def setWriteProxies(self, principals):
if not self.proxywriteURL:
return ()
-
- self.session.setProperties(self.proxywriteURL, ((davxml.group_member_set, principals),))
+
+ self.session.setProperties(self.proxywriteURL, ((davxml.group_member_set, principals),))
principalCache.invalidate(self.proxywriteURL)
-
+
+
def listAddressBooks(self, root=None):
adbks = []
home = self.adbkhomeset[0]
@@ -256,4 +280,3 @@
if rtype.find(str(davxml.collection)) is not None and rtype.find(str(carddavxml.addressbook)) is not None:
adbks.append(AddressBook(path=path, session=self.session))
return adbks
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/simple.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/simple.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/simple.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,7 +19,7 @@
from caldavclientlibrary.protocol.webdav.options import Options
def run(session, request):
-
+
# Create connection
connect = SmartHTTPConnection(session.server, session.port, session.ssl)
connect.set_debuglevel(1)
@@ -30,7 +30,7 @@
for header, value in hdrs.iteritems():
connect.putheader(header, value)
connect.endheaders()
-
+
# Do request body
stream = request.getRequestDataStream()
if stream:
@@ -44,15 +44,16 @@
# Get response
response = connect.getresponse()
-
+
# Get response headers
request.setResponseStatus(response.version, response.status, response.reason)
request.setResponseHeaders(response.getheaders())
-
+
# Get response body
+
if __name__ == '__main__':
session = Session("www.mulberrymail.com")
request = Options(session, "/")
-
+
run(session, request)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/caldavxml.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/caldavxml.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/caldavxml.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,67 +20,67 @@
# RFC4791
-mkcalendar = QName(CalDAVNamespace, "mkcalendar")
-mkcalendar_response = QName(CalDAVNamespace, "mkcalendar-response")
+mkcalendar = QName(CalDAVNamespace, "mkcalendar")
+mkcalendar_response = QName(CalDAVNamespace, "mkcalendar-response")
-calendar = QName(CalDAVNamespace, "calendar")
+calendar = QName(CalDAVNamespace, "calendar")
-calendar_description = QName(CalDAVNamespace, "calendar-description")
-calendar_timezone = QName(CalDAVNamespace, "calendar-timezone")
+calendar_description = QName(CalDAVNamespace, "calendar-description")
+calendar_timezone = QName(CalDAVNamespace, "calendar-timezone")
supported_calendar_component_set = QName(CalDAVNamespace, "supported-calendar-component-set")
-supported_calendar_data = QName(CalDAVNamespace, "supported-calendar-data")
-max_resource_size = QName(CalDAVNamespace, "max-resource-size")
-min_date_time = QName(CalDAVNamespace, "min-date-time")
-max_date_time = QName(CalDAVNamespace, "max-date-time")
-max_instances = QName(CalDAVNamespace, "max-instances")
-max_attendees_per_instance = QName(CalDAVNamespace, "max-attendees-per-instance")
+supported_calendar_data = QName(CalDAVNamespace, "supported-calendar-data")
+max_resource_size = QName(CalDAVNamespace, "max-resource-size")
+min_date_time = QName(CalDAVNamespace, "min-date-time")
+max_date_time = QName(CalDAVNamespace, "max-date-time")
+max_instances = QName(CalDAVNamespace, "max-instances")
+max_attendees_per_instance = QName(CalDAVNamespace, "max-attendees-per-instance")
-read_free_busy = QName(CalDAVNamespace, "read-free-busy")
-calendar_home_set = QName(CalDAVNamespace, "calendar-home-set")
+read_free_busy = QName(CalDAVNamespace, "read-free-busy")
+calendar_home_set = QName(CalDAVNamespace, "calendar-home-set")
-supported_collation = QName(CalDAVNamespace, "supported-collation")
+supported_collation = QName(CalDAVNamespace, "supported-collation")
-calendar_query = QName(CalDAVNamespace, "calendar-query")
-calendar_data = QName(CalDAVNamespace, "calendar-data")
-comp = QName(CalDAVNamespace, "comp")
-allcomp = QName(CalDAVNamespace, "allcomp")
-prop = QName(CalDAVNamespace, "prop")
-expand = QName(CalDAVNamespace, "expand")
+calendar_query = QName(CalDAVNamespace, "calendar-query")
+calendar_data = QName(CalDAVNamespace, "calendar-data")
+comp = QName(CalDAVNamespace, "comp")
+allcomp = QName(CalDAVNamespace, "allcomp")
+prop = QName(CalDAVNamespace, "prop")
+expand = QName(CalDAVNamespace, "expand")
limit_recurrence_set = QName(CalDAVNamespace, "limit-recurrence-set")
-limit_freebusy_set = QName(CalDAVNamespace, "limit-freebusy-set")
-filter = QName(CalDAVNamespace, "filter")
-comp_filter = QName(CalDAVNamespace, "comp-filter")
-prop_filter = QName(CalDAVNamespace, "prop-filter")
-param_filter = QName(CalDAVNamespace, "param-filter")
-is_not_defined = QName(CalDAVNamespace, "is-not-defined")
-text_match = QName(CalDAVNamespace, "text-match")
-timezone = QName(CalDAVNamespace, "timezone")
-time_range = QName(CalDAVNamespace, "time-range")
+limit_freebusy_set = QName(CalDAVNamespace, "limit-freebusy-set")
+filter = QName(CalDAVNamespace, "filter")
+comp_filter = QName(CalDAVNamespace, "comp-filter")
+prop_filter = QName(CalDAVNamespace, "prop-filter")
+param_filter = QName(CalDAVNamespace, "param-filter")
+is_not_defined = QName(CalDAVNamespace, "is-not-defined")
+text_match = QName(CalDAVNamespace, "text-match")
+timezone = QName(CalDAVNamespace, "timezone")
+time_range = QName(CalDAVNamespace, "time-range")
-calendar_multiget = QName(CalDAVNamespace, "calendar-multiget")
+calendar_multiget = QName(CalDAVNamespace, "calendar-multiget")
-free_busy_query = QName(CalDAVNamespace, "free-busy-query")
+free_busy_query = QName(CalDAVNamespace, "free-busy-query")
# draft caldav-schedule
-calendar_free_busy_set = QName(CalDAVNamespace, "calendar-free-busy-set")
-originator = QName(CalDAVNamespace, "originator")
-recipient = QName(CalDAVNamespace, "recipient")
-schedule = QName(CalDAVNamespace, "schedule")
+calendar_free_busy_set = QName(CalDAVNamespace, "calendar-free-busy-set")
+originator = QName(CalDAVNamespace, "originator")
+recipient = QName(CalDAVNamespace, "recipient")
+schedule = QName(CalDAVNamespace, "schedule")
-schedule_tag = QName(CalDAVNamespace, "schedule-tag")
-schedule_inbox = QName(CalDAVNamespace, "schedule-inbox")
-schedule_inbox_URL = QName(CalDAVNamespace, "schedule-inbox-URL")
-schedule_outbox = QName(CalDAVNamespace, "schedule-outbox")
-schedule_outbox_URL = QName(CalDAVNamespace, "schedule-outbox-URL")
+schedule_tag = QName(CalDAVNamespace, "schedule-tag")
+schedule_inbox = QName(CalDAVNamespace, "schedule-inbox")
+schedule_inbox_URL = QName(CalDAVNamespace, "schedule-inbox-URL")
+schedule_outbox = QName(CalDAVNamespace, "schedule-outbox")
+schedule_outbox_URL = QName(CalDAVNamespace, "schedule-outbox-URL")
calendar_user_address_set = QName(CalDAVNamespace, "calendar-user-address-set")
-schedule_response = QName(CalDAVNamespace, "schedule-response")
-response = QName(CalDAVNamespace, "timezone")
-request_status = QName(CalDAVNamespace, "request-status")
+schedule_response = QName(CalDAVNamespace, "schedule-response")
+response = QName(CalDAVNamespace, "timezone")
+request_status = QName(CalDAVNamespace, "request-status")
# Extensions
-CalendarServerNamespace = "http://calendarserver.org/ns/"
+CalendarServerNamespace = "http://calendarserver.org/ns/"
-calendar_proxy_read = QName(CalendarServerNamespace, "calendar-proxy-read")
-calendar_proxy_write = QName(CalendarServerNamespace, "calendar-proxy-write")
+calendar_proxy_read = QName(CalendarServerNamespace, "calendar-proxy-read")
+calendar_proxy_write = QName(CalendarServerNamespace, "calendar-proxy-write")
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/csxml.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/csxml.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/csxml.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,18 +18,18 @@
CSNamespace = "http://calendarserver.org/ns/"
-calendar_proxy_read_for = QName(CSNamespace, "calendar-proxy-read-for")
-calendar_proxy_write_for = QName(CSNamespace, "calendar-proxy-write-for")
-getctag = QName(CSNamespace, "getctag")
+calendar_proxy_read_for = QName(CSNamespace, "calendar-proxy-read-for")
+calendar_proxy_write_for = QName(CSNamespace, "calendar-proxy-write-for")
+getctag = QName(CSNamespace, "getctag")
-notification = QName(CSNamespace, "notification")
-notification_URL = QName(CSNamespace, "notification-URL")
+notification = QName(CSNamespace, "notification")
+notification_URL = QName(CSNamespace, "notification-URL")
# Are these really in this namespace?
-dropbox_home = QName(CSNamespace, "dropbox-home")
-dropbox_home_URL = QName(CSNamespace, "dropbox-home-URL")
+dropbox_home = QName(CSNamespace, "dropbox-home")
+dropbox_home_URL = QName(CSNamespace, "dropbox-home-URL")
# Defined by caldav-pubsubdiscovery
-xmpp_server = QName(CSNamespace, "xmpp-server")
-xmpp_uri = QName(CSNamespace, "xmpp-uri")
-pushkey = QName(CSNamespace, "pushkey")
+xmpp_server = QName(CSNamespace, "xmpp-server")
+xmpp_uri = QName(CSNamespace, "xmpp-uri")
+pushkey = QName(CSNamespace, "pushkey")
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/headers.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/headers.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/headers.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -17,13 +17,13 @@
from caldavclientlibrary.protocol.webdav.definitions.headers import * #@UnusedWildImport
# RFC4791
-CalendarAccess = "calendar-access"
+CalendarAccess = "calendar-access"
# draft caldav-schedule
CalendarSchedule = "calendar-schedule"
Originator = "Originator"
-Recipient = "Recipient"
+Recipient = "Recipient"
# Extensions
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/methods.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/methods.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/definitions/methods.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,4 +18,4 @@
# RFC4791 - CalDAV Request Methods
-MKCALENDAR = "MKCALENDAR";
+MKCALENDAR = "MKCALENDAR"
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/makecalendar.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/makecalendar.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/makecalendar.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -31,16 +31,18 @@
self.displayname = displayname
self.description = description
self.timezone = timezone
-
+
self.initRequestData()
+
def initRequestData(self):
if self.displayname or self.description or self.timezone:
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -55,22 +57,22 @@
# <DAV:prop> element
prop = SubElement(mkcalendar, davxml.prop)
-
+
# <DAV:displayname> element
if self.displayname:
displayname = SubElement(prop, davxml.displayname)
displayname.text = self.displayname
-
+
# <CalDAV:calendar-description> element
if self.description:
description = SubElement(prop, caldavxml.calendar_description)
description.text = self.description
-
+
# <CalDAV:timezone> element
if self.timezone:
timezone = SubElement(prop, caldavxml.calendar_timezone)
timezone.text = self.timezone
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(mkcalendar)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/multiget.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/multiget.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/multiget.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -32,12 +32,14 @@
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -48,24 +50,24 @@
# <DAV:href>...</DAV:href>
# ...
# </CalDAV:calendar-multiget>
-
+
# <CalDAV:calendar-multiget> element
multiget = Element(caldavxml.calendar_multiget)
-
+
if self.props:
# <DAV:prop> element
prop = SubElement(multiget, davxml.prop)
-
+
# Now add each property
for propname in self.props:
# Add property element taking namespace into account
SubElement(prop, propname)
-
+
# Now add each href
for href in self.hrefs:
# Add href elements
SubElement(multiget, davxml.href).text = href
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(multiget)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -28,15 +28,17 @@
def __init__(self, session, url, props=()):
super(Query, self).__init__(session, url)
self.props = props
-
+
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -46,26 +48,27 @@
# </DAV:prop>
# <CALDAV:filter>...</CALDAV:filter>
# </CalDAV:calendar-query>
-
+
# <CalDAV:calendar-query> element
query = Element(caldavxml.calendar_query)
-
+
if self.props:
# <DAV:prop> element
prop = SubElement(query, davxml.prop)
-
+
# Now add each property
for propname in self.props:
# Add property element taking namespace into account
SubElement(prop, propname)
-
+
# Now add each href
self.addFilterElement(query)
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(query)
xmldoc.writeUTF8(os)
+
def addFilterElement(self, query):
"""
Add a CALDAV:filter element to the specified CALDAV:calendar-query element.
@@ -73,14 +76,17 @@
"""
raise NotImplementedError
+
+
class QueryVEVENTTimeRange(Query):
def __init__(self, session, url, trstart, trend, props=()):
-
+
self.trstart = trstart
self.trend = trend
super(QueryVEVENTTimeRange, self).__init__(session, url, props)
+
def addFilterElement(self, query):
"""
Add a CALDAV:filter element to the specified CALDAV:calendar-query element.
@@ -99,8 +105,8 @@
# </CalDAV:calendar-query>
filter = SubElement(query, caldavxml.filter)
- calcompfilter = SubElement(filter, caldavxml.comp_filter, {"name":"VCALENDAR"})
- eventcompfilter = SubElement(calcompfilter, caldavxml.comp_filter, {"name":"VEVENT"})
+ calcompfilter = SubElement(filter, caldavxml.comp_filter, {"name": "VCALENDAR"})
+ eventcompfilter = SubElement(calcompfilter, caldavxml.comp_filter, {"name": "VEVENT"})
tr = {}
if self.trstart:
@@ -108,4 +114,3 @@
if self.trend:
tr["end"] = self.trend
SubElement(eventcompfilter, caldavxml.time_range, tr)
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_makecalendar.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_makecalendar.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_makecalendar.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,20 +20,25 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = MakeCalendar(server, "/")
self.assertEqual(request.getMethod(), "MKCALENDAR")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
pass
+
+
class TestRequestBody(unittest.TestCase):
-
+
def test_GenerateXMLDisplayname(self):
-
+
server = Session("www.example.com")
request = MakeCalendar(server, "/", "home")
os = StringIO()
@@ -47,8 +52,9 @@
""".replace("\n", "\r\n")
)
+
def test_GenerateXMLMultipleProperties(self):
-
+
server = Session("www.example.com")
request = MakeCalendar(server, "/", "home", "my personal calendar")
os = StringIO()
@@ -63,8 +69,9 @@
""".replace("\n", "\r\n")
)
+
def test_GenerateXMLCDATAProperty(self):
-
+
server = Session("www.example.com")
timezone = """BEGIN:VCALENDAR
PRODID:-//Example Corp.//CalDAV Client//EN
@@ -101,11 +108,17 @@
""".replace("\n", "\r\n") % (timezone.replace("&", "&"),)
)
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_multiget.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_multiget.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/tests/test_multiget.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,20 +21,25 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Multiget(server, "/", ())
self.assertEqual(request.getMethod(), "REPORT")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
pass
+
+
class TestRequestBody(unittest.TestCase):
-
+
def test_GenerateXMLOneHrefOnly(self):
-
+
server = Session("www.example.com")
request = Multiget(server, "/", ("/a",))
os = StringIO()
@@ -46,8 +51,9 @@
""".replace("\n", "\r\n")
)
+
def test_GenerateXMLMultipleHrefsOnly(self):
-
+
server = Session("www.example.com")
request = Multiget(server, "/", ("/a", "/b",))
os = StringIO()
@@ -60,8 +66,9 @@
""".replace("\n", "\r\n")
)
+
def test_GenerateXMLMultipleHrefsOneProperty(self):
-
+
server = Session("www.example.com")
request = Multiget(server, "/", ("/a", "/b",), (davxml.getetag,))
os = StringIO()
@@ -77,8 +84,9 @@
""".replace("\n", "\r\n")
)
+
def test_GenerateXMLMultipleHrefsMultipleProperties(self):
-
+
server = Session("www.example.com")
request = Multiget(server, "/", ("/a", "/b",), (davxml.getetag, davxml.displayname,))
os = StringIO()
@@ -95,11 +103,17 @@
""".replace("\n", "\r\n")
)
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/definitions/carddavxml.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/definitions/carddavxml.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/definitions/carddavxml.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,26 +20,26 @@
# draft-
-addressbook = QName(CardDAVNamespace, "addressbook")
+addressbook = QName(CardDAVNamespace, "addressbook")
-addressbook_description = QName(CardDAVNamespace, "addressbook-description")
-supported_addressbook_data = QName(CardDAVNamespace, "supported-addressbook-data")
-max_resource_size = QName(CardDAVNamespace, "max-resource-size")
+addressbook_description = QName(CardDAVNamespace, "addressbook-description")
+supported_addressbook_data = QName(CardDAVNamespace, "supported-addressbook-data")
+max_resource_size = QName(CardDAVNamespace, "max-resource-size")
-addressbook_home_set = QName(CardDAVNamespace, "addressbook-home-set")
+addressbook_home_set = QName(CardDAVNamespace, "addressbook-home-set")
-supported_collation = QName(CardDAVNamespace, "supported-collation")
+supported_collation = QName(CardDAVNamespace, "supported-collation")
-addressbook_query = QName(CardDAVNamespace, "addressbook-query")
-address_data = QName(CardDAVNamespace, "address-data")
-comp = QName(CardDAVNamespace, "comp")
-allcomp = QName(CardDAVNamespace, "allcomp")
-prop = QName(CardDAVNamespace, "prop")
-filter = QName(CardDAVNamespace, "filter")
-comp_filter = QName(CardDAVNamespace, "comp-filter")
-prop_filter = QName(CardDAVNamespace, "prop-filter")
-param_filter = QName(CardDAVNamespace, "param-filter")
-is_not_defined = QName(CardDAVNamespace, "is-not-defined")
-text_match = QName(CardDAVNamespace, "text-match")
+addressbook_query = QName(CardDAVNamespace, "addressbook-query")
+address_data = QName(CardDAVNamespace, "address-data")
+comp = QName(CardDAVNamespace, "comp")
+allcomp = QName(CardDAVNamespace, "allcomp")
+prop = QName(CardDAVNamespace, "prop")
+filter = QName(CardDAVNamespace, "filter")
+comp_filter = QName(CardDAVNamespace, "comp-filter")
+prop_filter = QName(CardDAVNamespace, "prop-filter")
+param_filter = QName(CardDAVNamespace, "param-filter")
+is_not_defined = QName(CardDAVNamespace, "is-not-defined")
+text_match = QName(CardDAVNamespace, "text-match")
addressbook_multiget = QName(CardDAVNamespace, "addressbook-multiget")
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/makeaddressbook.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/makeaddressbook.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/carddav/makeaddressbook.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -29,15 +29,17 @@
super(MakeAddressBook, self).__init__(session, methods.MKCOL, url)
self.displayname = displayname
self.description = description
-
+
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -55,25 +57,25 @@
# <DAV:set> element
set = SubElement(mkcol, davxml.set)
-
+
# <DAV:prop> element
prop = SubElement(set, davxml.prop)
-
+
# <WebDAV:resourcetype> element
resourcetype = SubElement(prop, davxml.resourcetype)
SubElement(resourcetype, davxml.collection)
SubElement(resourcetype, carddavxml.addressbook)
-
+
# <DAV:displayname> element
if self.displayname:
displayname = SubElement(prop, davxml.displayname)
displayname.text = self.displayname
-
+
# <CardDAV:addressbook-description> element
if self.description:
description = SubElement(prop, carddavxml.addressbook_description)
description.text = self.description
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(mkcol)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/basic.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/basic.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/basic.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,14 +23,16 @@
self.user = user
self.pswd = pswd
+
def setDetails(self, user, pswd):
self.user = user
self.pswd = pswd
+
def addHeaders(self, hdrs, request):
# Generate the base64 encoded string
encode = self.user + ":" + self.pswd
base64 = encode.encode("base64").strip()
-
+
# Generate header
hdrs.append((headers.Authorization, "Basic %s" % (base64,)))
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/digest.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/digest.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/digest.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -30,15 +30,17 @@
self.stale = False
self.clientCount = 0
+
def setDetails(self, user, pswd, www_authenticate):
self.fields['username'] = user
self.fields['password'] = pswd
self.parseAuthenticateHeader(www_authenticate)
+
def addHeaders(self, hdrs, request):
# Generate response
self.generateResponse(request)
-
+
# Generate header
os = StringIO()
os.write("Digest username=\"%s\"," % (self.fields['username'],))
@@ -50,26 +52,27 @@
os.write(" nc=\"%s\"" % (self.fields['nc'],))
os.write(" cnonce=\"%s\"" % (self.fields['cnonce'],))
os.write(" response=\"%s\"" % (self.response,))
-
+
if "algorithm" in self.fields:
os.write(", algorithm=\"%s\"" % (self.fields['algorithm'],))
if "opaque" in self.fields:
os.write(", opaque=\"%s\"" % (self.fields['opaque'],))
-
+
hdrs.append((headers.Authorization, os.getvalue()))
+
def parseAuthenticateHeader(self, hdrs):
for hdr in hdrs:
# Strip any space
hdr = hdr.strip()
-
+
# Must have Digest token
if hdr[:7].lower() != "digest ":
continue
else:
hdr = hdr[7:]
-
+
# Get each name/value pair
while True:
name, hdr = parsetoken(hdr, " \t=")
@@ -77,11 +80,11 @@
if not name or not hdr:
return
name = name.lower()
-
+
value, hdr = parsetoken(hdr, ", ")
if not value:
return
-
+
if name in ("realm", "domain", "nonce", "opaque", "algorithm", "qop"):
self.fields[name] = value
@@ -91,10 +94,10 @@
else:
# Unknown token - ignore
pass
-
+
# Punt over space
hdr = hdr.strip()
-
+
break
algorithms = {
@@ -102,7 +105,7 @@
'md5-sess': hashlib.md5,
'sha': hashlib.sha1,
}
-
+
# DigestCalcHA1
@staticmethod
def calcHA1(
@@ -117,22 +120,22 @@
"""
@param pszAlg: The name of the algorithm to use to calculate the Digest.
Currently supported are md5 md5-sess and sha.
-
+
@param pszUserName: The username
@param pszRealm: The realm
@param pszPassword: The password
@param pszNonce: The nonce
@param pszCNonce: The cnonce
-
+
@param preHA1: If available this is a str containing a previously
calculated HA1 as a hex string. If this is given then the values for
pszUserName, pszRealm, and pszPassword are ignored.
"""
-
+
if (preHA1 and (pszUserName or pszRealm or pszPassword)):
raise TypeError(("preHA1 is incompatible with the pszUserName, "
"pszRealm, and pszPassword arguments"))
-
+
if preHA1 is None:
# We need to calculate the HA1 from the username:realm:password
m = Digest.algorithms[pszAlg]()
@@ -145,7 +148,7 @@
else:
# We were given a username:realm:password
HA1 = preHA1.decode('hex')
-
+
if pszAlg == "md5-sess":
m = Digest.algorithms[pszAlg]()
m.update(HA1)
@@ -154,9 +157,10 @@
m.update(":")
m.update(pszCNonce)
HA1 = m.digest()
-
+
return HA1.encode('hex')
-
+
+
# DigestCalcResponse
@staticmethod
def calcResponse(
@@ -178,7 +182,7 @@
m.update(":")
m.update(pszHEntity)
HA2 = m.digest().encode('hex')
-
+
m = Digest.algorithms[algo]()
m.update(HA1)
m.update(":")
@@ -195,6 +199,7 @@
respHash = m.digest().encode('hex')
return respHash
+
def generateResponse(self, request):
self.response = Digest.calcResponse(
Digest.calcHA1(
@@ -214,4 +219,3 @@
request.url,
None,
)
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/gssapi.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/gssapi.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/gssapi.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -33,14 +33,16 @@
self.user = user
self.context = None
+
def addHeaders(self, hdrs, request):
neg_value = self.negotiate_value(hdrs)
header = self.generate_request_header(request, hdrs, neg_value)
-
+
# Generate header
hdrs.append((headers.Authorization, header))
self.clean_context()
-
+
+
def negotiate_value(self, headers):
"""checks for "Negotiate" in proper auth header
taken from urllib2_kerberos, see http://limedav.com/hg/urllib2_kerberos
@@ -64,7 +66,8 @@
# header not found
return None
-
+
+
def generate_request_header(self, req, headers, neg_value):
"""
taken from urllib2_kerberos, see http://limedav.com/hg/urllib2_kerberos
@@ -100,9 +103,10 @@
response = kerberos.authGSSClientResponse(self.context)
# authGSSClientResponse() succeeded
-
+
return "Negotiate %s" % response
-
+
+
def clean_context(self):
"""
taken from urllib2_kerberos, see http://limedav.com/hg/urllib2_kerberos
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/test_basic.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/test_basic.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/authentication/tests/test_basic.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,9 +20,9 @@
import unittest
class TestBasic(unittest.TestCase):
-
+
def testBasic(self):
-
+
auther = Basic("user", "pswd")
hdrs = []
auther.addHeaders(hdrs, None)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/data.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/data.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/data.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -16,31 +16,40 @@
class Data(object):
-
+
def __init__(self):
pass
-
+
+
def start(self):
pass
-
+
+
def stop(self):
pass
+
+
class RequestData(Data):
def getContentLength(self):
return self.content_length
+
def getContentType(self):
return self.content_type
-
+
+
def read(self):
raise NotImplementedError
+
+
class ResponseData(Data):
-
+
def write(self, data):
raise NotImplementedError
+
def clear(self):
raise NotImplementedError
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/file.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/file.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/file.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,25 +20,28 @@
import os
class RequestDataFile(RequestData):
-
+
def __init__(self, fname, content_type):
# Cache file name
self.fname = fname
-
+
# Determine size of stream
self.content_length = os.stat(self.fname)[stat.ST_SIZE]
self.content_type = content_type
+
def start(self):
# Create an input file stream
self.stream = open(self.fname, "r")
+
def stop(self):
self.stream.close()
self.stream = None
+
def read(self):
data = self.stream.read(8192)
if data:
@@ -46,22 +49,28 @@
else:
return data, False
+
+
class ResponseDataFile(ResponseData):
def __init__(self, fname):
self.fname = fname
+
def start(self):
# Create an input file stream
self.stream = open(self.fname, "w")
+
def stop(self):
self.stream.close()
self.stream = None
+
def write(self, data):
self.stream.write(data)
+
def clear(self):
# Throw out existing data and start from scratch
self.stop()
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/string.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/string.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/data/string.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,31 +19,37 @@
from StringIO import StringIO
class RequestDataString(RequestData):
-
+
def __init__(self, text, content_type):
# Cache file name
self.text = text
-
+
# Determine size of stream
self.content_length = len(text)
self.content_type = content_type
+
def read(self):
return self.text, False
-
+
+
+
class ResponseDataString(ResponseData):
def __init__(self):
self.stream = StringIO()
+
def getData(self):
return self.stream.getvalue()
+
def write(self, data):
self.stream.write(data)
+
def clear(self):
# Throw out existing data and start from scratch
self.stream = StringIO()
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/headers.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/headers.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/headers.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,28 +18,28 @@
# RFC2616 4.5 - General Header fields (only the ones we need)
-Connection = "Connection"
-ConnectionClose = "close"
-Date = "Date"
-TransferEncoding = "Transfer-Encoding"
+Connection = "Connection"
+ConnectionClose = "close"
+Date = "Date"
+TransferEncoding = "Transfer-Encoding"
TransferEncodingChunked = "chunked"
# RFC2616 5.3 - Request Header fields (only the ones we need)
Authorization = "Authorization"
-Host = "Host"
-IfMatch = "If-Match"
-IfNoneMatch = "If-None-Match"
+Host = "Host"
+IfMatch = "If-Match"
+IfNoneMatch = "If-None-Match"
# RFC2616 6.2 - Response Header fields (only the ones we need)
-ETag = "ETag"
-Location = "Location"
-Server = "Server"
+ETag = "ETag"
+Location = "Location"
+Server = "Server"
WWWAuthenticate = "WWW-Authenticate"
# RFC2616 7.1 - Entity Header fields (only the ones we need)
-Allow = "Allow"
+Allow = "Allow"
ContentLength = "Content-Length"
-ContentType = "Content-Type"
+ContentType = "Content-Type"
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/methods.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/methods.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/definitions/methods.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,10 +18,10 @@
# RFC2616 5.1.1 - Request Methods
OPTIONS = "OPTIONS"
-GET = "GET"
-HEAD = "HEAD"
-POST = "POST"
-PUT = "PUT"
-DELETE = "DELETE"
-TRACE = "TRACE"
+GET = "GET"
+HEAD = "HEAD"
+POST = "POST"
+PUT = "PUT"
+DELETE = "DELETE"
+TRACE = "TRACE"
CONNECT = "CONNECT"
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/requestresponse.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/requestresponse.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/requestresponse.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,8 +22,10 @@
class ResponseError(Exception):
pass
+
+
class RequestResponse(object):
-
+
def __init__(self, session, method, url, etag=None, etag_match=False):
self._initResponse()
self.session = session
@@ -32,6 +34,7 @@
self.etag = etag
self.etag_match = etag_match
+
def _initResponse(self):
self.session = None
self.request_data = None
@@ -48,51 +51,67 @@
self.chunked = False
self.completed = False
+
def setSession(self, session):
self.session = session
+
+
def getSession(self):
return self.session
+
def getMethod(self):
return self.method
+
def setURL(self, ruri):
self.url = ruri
+
+
def getURL(self):
return self.url
+
def setETag(self, etag, etag_match):
self.etag = etag
self.etag_match = etag_match
+
def queuedForSending(self, session):
self.session = session
-
+
+
def setData(self, request_data, response_data):
self.request_data = request_data
self.response_data = response_data
+
def hasRequestData(self):
return self.request_data != None
+
def hasResponseData(self):
return self.response_data != None
+
def getRequestData(self):
if self.request_data:
return self.request_data
else:
return None
+
def getResponseData(self):
if self.response_data:
return self.response_data
else:
return None
-
+
+
def getRequestStartLine(self):
return "%s %s HTTP/1.1" % (self.method, self.url,)
+
def getRequestHeaders(self):
# This will be overridden by sub-classes that add headers - those classes should
# call this class's implementation to write out the basic set of headers
@@ -100,6 +119,7 @@
self.addHeaders(result)
return tuple(result)
+
def generateRequestHeader(self):
os = StringIO()
os.write("%s\r\n" % (self.getRequestStartLine(),))
@@ -108,34 +128,38 @@
os.write("\r\n")
return os.getvalue()
+
def addHeaders(self, hdrs):
# Write host
hdrs.append((headers.Host, "%s:%s" % (self.session.server, self.session.port,)))
-
+
# Do ETag matching
if self.etag:
if self.etag_match:
hdrs.append((headers.IfMatch, self.etag))
else:
hdrs.append((headers.IfNoneMatch, self.etag))
-
+
# Do session global headers
self.session.addHeaders(hdrs, self)
-
+
# Check for content
self.addContentHeaders(hdrs)
+
def addContentHeaders(self, hdrs):
# Check for content
if self.hasRequestData():
hdrs.append((headers.ContentLength, str(self.request_data.getContentLength())))
hdrs.append((headers.ContentType, self.request_data.getContentType()))
+
def setResponseStatus(self, version, status, reason):
self.status_code = status
self.status_reason = reason
+
def setResponseHeaders(self, hdrs):
for header in hdrs:
splits = header.split(":")
@@ -144,6 +168,7 @@
# Now cache some useful header values
self.cacheHeaders()
+
def clearResponse(self):
self.etag_match = False
self.status_code = statuscodes.Unknown
@@ -153,71 +178,87 @@
self.content_length = 0
self.chunked = False
self.completed = False
-
+
if self.response_data:
self.response_data.clear()
+
def getStatusCode(self):
return self.status_code
+
+
def getStatusReason(self):
return self.status_reason
+
def getConnectionClose(self):
return self.connection_close
+
def getContentLength(self):
return self.content_length
+
+
def getChunked(self):
return self.chunked
+
def setComplete(self):
self.completed = True
+
+
def getCompleted(self):
return self.completed
+
def hasResponseHeader(self, hdr):
- return self.headers.has_key(hdr.lower())
-
+ return hdr.lower() in self.headers
+
+
def getResponseHeader(self, hdr):
- if self.headers.has_key(hdr.lower()):
+ if hdr.lower() in self.headers:
return self.headers[hdr.lower()][0]
else:
return ""
-
+
+
def getResponseHeaders(self, hdr=None):
if hdr:
- if self.headers.has_key(hdr.lower()):
+ if hdr.lower() in self.headers:
return self.headers[hdr.lower()]
else:
return ()
else:
return self.headers
-
+
+
def isRedirect(self):
# Only these are allowed
return self.status_code in (statuscodes.MovedPermanently, statuscodes.Found, statuscodes.TemporaryRedirect)
+
def parseStatusLine(self, line):
-
+
# Must have 'HTTP/' version at start
if line[0:5] != "HTTP/":
raise ResponseError("status line incorrect at start")
-
+
# Must have version '1.1 '
if line[5:9] != "1.1 ":
raise ResponseError("incorrect http version in status line")
-
+
# Must have three digits followed by nothing or one space
if not line[9:12].isdigit() or (len(line) > 12 and line[12] != " "):
raise ResponseError("invalid status response code syntax")
-
+
# Read in the status code
self.status_code = int(line[9:12])
-
+
# Remainder is reason
if len(line) > 13:
self.status_reason = line[13:]
+
def readFoldedLine(self, instream, line1, line2, log):
# If line2 already has data, transfer that into line1
if line2 or line1:
@@ -228,14 +269,14 @@
if not line1:
return False, line1, line2
line1 = line1.rstrip("\r\n")
-
+
if log:
log.write("%s\n" % (line1,))
-
+
# Terminate on blank line which is end of headers
if not line1:
return True, line1, line2
-
+
# Now loop looking ahead at the next line to see if it is folded
while True:
# Get next line
@@ -243,10 +284,10 @@
if not line2:
return True, line1, line2
line2 = line2.rstrip("\r\n")
-
+
if log:
log.write("%s\n" % (line2,))
-
+
# Does it start with a space => folded
if line2 and line2[0].isspace():
# Copy folded line (without space) to current line and cycle for more
@@ -254,21 +295,22 @@
else:
# Not folded - just exit loop
break
-
+
return True, line1, line2
+
def cacheHeaders(self):
# Connection
- if self.headers.has_key(headers.Connection):
+ if headers.Connection in self.headers:
value = self.headers[headers.Connection][0]
self.connection_close = (value.lower() == headers.ConnectionClose)
# Content-Length
- if self.headers.has_key(headers.ContentLength):
+ if headers.ContentLength in self.headers:
value = self.headers[headers.ContentLength][0]
self.content_length = int(value)
-
+
# Transfer encoding
- if self.headers.has_key(headers.TransferEncoding):
+ if headers.TransferEncoding in self.headers:
value = self.headers[headers.TransferEncoding][0]
self.chunked = (value == headers.TransferEncodingChunked)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/session.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/session.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/session.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,12 +18,12 @@
import httplib
class Session(object):
-
- STATE_OPEN = 0
+
+ STATE_OPEN = 0
STATE_CLOSED = 1
-
+
def __init__(self, server, port=None, ssl=False, log=None):
-
+
self.server = server
self.port = port
self.ssl = ssl
@@ -32,27 +32,31 @@
self.authorization = None
self.connection_state = Session.STATE_CLOSED
self.log = log
-
+
+
def hasAuthorization(self):
return self.authorization != None
-
+
+
def getAuthorization(self):
return self.authorization
-
+
+
def addHeaders(self, hdrs, request):
if self.hasAuthorization():
self.getAuthorization().addHeaders(hdrs, request)
-
+
+
def setServer(self, server, port=None):
-
+
if port is None:
i = server.rfind(':')
j = server.rfind(']')
if i > j:
try:
- port = int(server[i+1:])
+ port = int(server[i + 1:])
except ValueError:
- raise InvalidURL("nonnumeric port: '%s'" % server[i+1:])
+ raise InvalidURL("nonnumeric port: '%s'" % server[i + 1:])
server = server[:i]
else:
port = httplib.HTTPS_PORT if self.ssl else httplib.HTTP_PORT
@@ -62,19 +66,20 @@
if self.server != server:
self.server = server
self.port = port
-
+
# Always clear out authorization when host changes
self.authorization = None
-
+
+
def sendRequest(self, request):
try:
# First need a connection
- self.needConnection();
-
+ self.needConnection()
+
# Now do the connection
- self.doRequest(request);
-
+ self.doRequest(request)
+
# Check the final connection state and close if that's what the server wants
if request.getConnectionClose():
self.closeConnection()
@@ -84,39 +89,48 @@
# log.err(e)
self.connection_state = Session.STATE_CLOSED
raise
-
+
+
def handleHTTPError(self, request):
raise NotImplementedError
-
+
+
def displayHTTPError(self, request):
raise NotImplementedError
-
+
+
def isConnectionOpen(self):
return self.connection_state == Session.STATE_OPEN
+
def needConnection(self):
if not self.isConnectionOpen():
self.openConnection()
+
def openConnection(self):
if not self.isConnectionOpen():
self.openSession()
self.connection_state = Session.STATE_OPEN
+
def closeConnection(self):
if self.isConnectionOpen():
- self.closeSession();
+ self.closeSession()
self.connection_state = Session.STATE_CLOSED
+
def openSession(self):
raise NotImplementedError
-
+
+
def closeSession(self):
raise NotImplementedError
-
+
+
def runSession(self, request):
raise NotImplementedError
-
+
+
def doRequest(self, request):
raise NotImplementedError
-
\ No newline at end of file
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/__init__.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/__init__.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -13,4 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_requestresponse.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_requestresponse.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_requestresponse.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,9 +23,9 @@
import unittest
class TestRequestHeaders(unittest.TestCase):
-
+
def test_NoEtag(self):
-
+
server = Session("www.example.com")
request = RequestResponse(server, methods.GET, "/")
self.assertEqual(request.generateRequestHeader(), """GET / HTTP/1.1
@@ -33,9 +33,10 @@
""".replace("\n", "\r\n")
)
-
+
+
def test_EtagMatch(self):
-
+
server = Session("www.example.com")
request = RequestResponse(server, methods.GET, "/", "\"etag\"", True)
self.assertEqual(request.generateRequestHeader(), """GET / HTTP/1.1
@@ -44,9 +45,10 @@
""".replace("\n", "\r\n")
)
-
+
+
def test_EtagNoneMatch(self):
-
+
server = Session("www.example.com")
request = RequestResponse(server, methods.GET, "/", "\"etag\"", False)
self.assertEqual(request.generateRequestHeader(), """GET / HTTP/1.1
@@ -55,9 +57,10 @@
""".replace("\n", "\r\n")
)
-
+
+
def test_Content(self):
-
+
server = Session("www.example.com")
request = RequestResponse(server, methods.GET, "/")
rawdata = "Here is some data\r\non multiple lines."
@@ -71,8 +74,9 @@
""".replace("\n", "\r\n") % (len(rawdata),)
)
+
def test_ContentAndAuthorization(self):
-
+
server = Session("www.example.com")
server.authorization = Basic("user", "pswd")
request = RequestResponse(server, methods.GET, "/")
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_util.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_util.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/tests/test_util.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,87 +21,96 @@
import unittest
class TestParseQuoted(unittest.TestCase):
-
+
def testParseQuotedOK(self):
-
+
data = {
- "\"\"" : ("", ""),
- "\"quoted\"" : ("quoted", ""),
- "\"quoted words\"" : ("quoted words", ""),
- "\"quoting a \\\"word\\\"\"" : ("quoting a \"word\"", ""),
- "\"\" after" : ("", "after"),
- "\"quoted\" after" : ("quoted", "after"),
- "\"quoted words\" after" : ("quoted words", "after"),
- "\"quoting a \\\"word\\\"\" after" : ("quoting a \"word\"", "after"),
+ "\"\"" : ("", ""),
+ "\"quoted\"" : ("quoted", ""),
+ "\"quoted words\"" : ("quoted words", ""),
+ "\"quoting a \\\"word\\\"\"" : ("quoting a \"word\"", ""),
+ "\"\" after" : ("", "after"),
+ "\"quoted\" after" : ("quoted", "after"),
+ "\"quoted words\" after" : ("quoted words", "after"),
+ "\"quoting a \\\"word\\\"\" after" : ("quoting a \"word\"", "after"),
"\"quoting a \\\"word\\\" after\" after": ("quoting a \"word\" after", "after"),
- "\"quoted\"after" : ("quoted", "after"),
- "\"" : ("", ""),
- "\"unterminated" : ("unterminated", ""),
- "\"unterminated words" : ("unterminated words", ""),
- "\"unterminated a \\\"word\\\"" : ("unterminated a \"word\"", ""),
+ "\"quoted\"after" : ("quoted", "after"),
+ "\"" : ("", ""),
+ "\"unterminated" : ("unterminated", ""),
+ "\"unterminated words" : ("unterminated words", ""),
+ "\"unterminated a \\\"word\\\"" : ("unterminated a \"word\"", ""),
}
-
+
for input, result in data.iteritems():
self.assertEqual(parsequoted(input), result)
-
+
+
def testParseQuotedBAD(self):
-
+
data = (
"",
"unquoted",
"unquoted \"quoted\"",
)
-
+
for input in data:
self.assertRaises(AssertionError, parsequoted, input)
+
+
class TestParseToken(unittest.TestCase):
-
+
def testParseTokenOK(self):
-
+
data = {
- "" : ("", ""),
- "unquoted" : ("unquoted", ""),
- "unquoted words" : ("unquoted", "words"),
- "unquoted words" : ("unquoted", "words"),
+ "" : ("", ""),
+ "unquoted" : ("unquoted", ""),
+ "unquoted words" : ("unquoted", "words"),
+ "unquoted words" : ("unquoted", "words"),
"unquoting a \"word\"" : ("unquoting", "a \"word\""),
- "unquoted\twords" : ("unquoted", "words"),
+ "unquoted\twords" : ("unquoted", "words"),
"unquoting\ta \"word\"" : ("unquoting", "a \"word\""),
- "unquoted: words" : ("unquoted", "words"),
+ "unquoted: words" : ("unquoted", "words"),
"unquoting: a \"word\"" : ("unquoting", "a \"word\""),
- "\"\"" : ("", ""),
- "\"quoted\"" : ("quoted", ""),
- "\"quoted words\"" : ("quoted words", ""),
- "\"quoting a \\\"word\\\"\"" : ("quoting a \"word\"", ""),
- "\"\" after" : ("", "after"),
- "\"quoted\" after" : ("quoted", "after"),
- "\"quoted words\" after" : ("quoted words", "after"),
- "\"quoting a \\\"word\\\"\" after" : ("quoting a \"word\"", "after"),
+ "\"\"" : ("", ""),
+ "\"quoted\"" : ("quoted", ""),
+ "\"quoted words\"" : ("quoted words", ""),
+ "\"quoting a \\\"word\\\"\"" : ("quoting a \"word\"", ""),
+ "\"\" after" : ("", "after"),
+ "\"quoted\" after" : ("quoted", "after"),
+ "\"quoted words\" after" : ("quoted words", "after"),
+ "\"quoting a \\\"word\\\"\" after" : ("quoting a \"word\"", "after"),
"\"quoting a \\\"word\\\" after\" after": ("quoting a \"word\" after", "after"),
- "\"quoted\"after" : ("quoted", "after"),
- "\"" : ("", ""),
- "\"unterminated" : ("unterminated", ""),
- "\"unterminated words" : ("unterminated words", ""),
- "\"unterminated a \\\"word\\\"" : ("unterminated a \"word\"", ""),
+ "\"quoted\"after" : ("quoted", "after"),
+ "\"" : ("", ""),
+ "\"unterminated" : ("unterminated", ""),
+ "\"unterminated words" : ("unterminated words", ""),
+ "\"unterminated a \\\"word\\\"" : ("unterminated a \"word\"", ""),
}
-
+
for input, result in data.iteritems():
self.assertEqual(parsetoken(input, " \t:"), result)
+
+
class TestParseStatusLine(unittest.TestCase):
-
+
def testParseTokenOK(self):
self.assertEqual(parseStatusLine("HTTP/1.1 200 OK"), 200)
-
+
+
def testParseTokenBadStatus(self):
self.assertEqual(parseStatusLine("HTTP/1.2 2001 OK"), 0)
-
+
+
def testParseTokenBadVersion(self):
self.assertEqual(parseStatusLine("HTTP/1.2 200 OK"), 0)
-
+
+
def testParseTokenBadNumber(self):
self.assertEqual(parseStatusLine("HTTP/1.1 OK"), 0)
-
+
+
def testParseTokenBad(self):
self.assertEqual(parseStatusLine("HTTP/1.1"), 0)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/util.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/util.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/http/util.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -16,7 +16,7 @@
def parsetoken(text, delimiters=" \t"):
-
+
if not text:
return "", ""
@@ -29,14 +29,16 @@
break
else:
return text, ""
-
+
return token, lstripdelimiters(text[pos:], delimiters)
-
+
+
+
def parsequoted(text, delimiters=" \t"):
-
+
assert(text)
assert(text[0] == '"')
-
+
pos = 1
while True:
next_pos = text.find('"', pos)
@@ -47,9 +49,11 @@
else:
return (
text[1:next_pos].replace("\\\\", "\\").replace("\\\"", "\""),
- lstripdelimiters(text[next_pos+1:], delimiters)
+ lstripdelimiters(text[next_pos + 1:], delimiters)
)
+
+
def lstripdelimiters(text, delimiters):
for pos, c in enumerate(text):
if c not in delimiters:
@@ -57,6 +61,8 @@
else:
return ""
+
+
def parseStatusLine(status):
status = status.strip()
@@ -64,11 +70,10 @@
# Must have 'HTTP/1.1' version at start
if status[0:9] != "HTTP/1.1 ":
return 0
-
+
# Must have three digits followed by nothing or one space
if not status[9:12].isdigit() or (len(status) > 12 and status[12] != " "):
return 0
-
+
# Read in the status code
return int(status[9:12])
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/tests/test_url.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/tests/test_url.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/tests/test_url.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,7 +19,7 @@
import unittest
class TestURLParse(unittest.TestCase):
-
+
def verifyParts(self, u, s, scheme, server, path, extended):
self.assertEqual(u.toString(), s)
self.assertEqual(u.scheme, scheme)
@@ -27,27 +27,30 @@
self.assertEqual(u.path, path)
self.assertEqual(u.extended, extended)
+
def test_ParsePlain(self):
-
+
s = "http://www.example.com"
u = URL(url=s)
self.verifyParts(u, s, "http", "www.example.com", "", "")
+
def test_ParsePlainPath(self):
-
+
s = "http://www.example.com/principals/users"
u = URL(url=s)
self.verifyParts(u, s, "http", "www.example.com", "/principals/users", "")
+
def test_ParsePlainPathExtended(self):
-
+
s = "http://www.example.com/principals/users?test=true"
u = URL(url=s)
self.verifyParts(u, s, "http", "www.example.com", "/principals/users", "?test=true")
+
def test_ParseMailto(self):
-
+
s = "mailto:user at example.com"
u = URL(url=s)
self.verifyParts(u, s, "mailto", "user at example.com", "", "")
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/url.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/url.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/url.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,75 +18,75 @@
import urllib
class URL(object):
-
+
eAbsolute = 0
eRelative = 1
eLastPath = 2
URLEscape = '%'
URLReserved = "/?:@&="
- URLUnreserved = ( # Allowable URL chars
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0 - 15
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 16 - 31
- 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, # 32 - 47
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, # 48 - 63
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 64 - 79
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, # 80 - 95
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 96 - 111
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, # 112 - 127
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 128 - 143
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 144 - 159
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 160 - 175
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 176 - 191
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 192 - 207
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 208 - 223
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 224 - 239
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 240 - 255
+ URLUnreserved = (# Allowable URL chars
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0 - 15
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 16 - 31
+ 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, # 32 - 47
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, # 48 - 63
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 64 - 79
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, # 80 - 95
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 96 - 111
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, # 112 - 127
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 128 - 143
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 144 - 159
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 160 - 175
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 176 - 191
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 192 - 207
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 208 - 223
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 224 - 239
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 240 - 255
)
-
- URLCharacter = ( # Allowable URL chars -- all
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0 - 15
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 16 - 31
- 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 32 - 47
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, # 48 - 63
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 64 - 79
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, # 80 - 95
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 96 - 111
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, # 112 - 127
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 128 - 143
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 144 - 159
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 160 - 175
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 176 - 191
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 192 - 207
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 208 - 223
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 224 - 239
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 240 - 255
+
+ URLCharacter = (# Allowable URL chars -- all
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0 - 15
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 16 - 31
+ 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 32 - 47
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, # 48 - 63
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 64 - 79
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, # 80 - 95
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 96 - 111
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, # 112 - 127
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 128 - 143
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 144 - 159
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 160 - 175
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 176 - 191
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 192 - 207
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 208 - 223
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 224 - 239
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 240 - 255
)
-
- URLXCharacter = ( # Allowable URL chars (all)
+
+ URLXCharacter = (# Allowable URL chars (all)
# RFC2732 uses '[...]' for IPv6 addressing - [] are now allowed
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0 - 15
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 16 - 31
- 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 32 - 47
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, # 48 - 63
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 64 - 79
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, # 80 - 95
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 96 - 111
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, # 112 - 127
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 128 - 143
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 144 - 159
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 160 - 175
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 176 - 191
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 192 - 207
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 208 - 223
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 224 - 239
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 240 - 255
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0 - 15
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 16 - 31
+ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 32 - 47
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, # 48 - 63
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 64 - 79
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, # 80 - 95
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 96 - 111
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, # 112 - 127
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 128 - 143
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 144 - 159
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 160 - 175
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 176 - 191
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 192 - 207
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 208 - 223
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 224 - 239
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 240 - 255
)
URLSchemeDoubleSlash = ("http", "https", "webcal",)
def __init__(self, url=None, scheme=None, server=None, path=None, extended=None, decode=False):
-
+
self.scheme = ""
self.server = ""
self.path = ""
@@ -103,82 +103,92 @@
self.extended = urllib.unquote_plus(self.extended)
else:
self._parse(url, decode)
-
+
+
def __str__(self):
return "URL: %s" % (self.toString(),)
+
def __repr__(self):
return "URL: %s" % (self.toString(),)
+
def __cmp__(self, other):
return cmp(self.toString(), other.toString())
+
def absoluteURL(self):
return self.toString()
-
+
+
def relativeURL(self):
return self.toString(conversion=URL.eRelative)
+
def toString(self, conversion=eAbsolute, encode=True):
result = ""
-
+
# Add scheme & host if not relative
if conversion == URL.eAbsolute and self.scheme and self.server:
result += self.scheme + ":"
if self.scheme in URL.URLSchemeDoubleSlash:
result += "//"
result += self.server
-
+
# Get path (or last part of it if required)
if self.path and conversion == URL.eLastPath:
path = self.path[self.path.rfind("/"):]
else:
path = self.path
-
+
# Now encode if required
if path:
result += (urllib.quote(path) if encode else path)
-
+
if self.extended:
result += (urllib.quote_plus(self.extended, "?=") if encode else self.extended)
-
+
return result
+
def equal(self, comp):
# Compare each component
if self.scheme != comp.scheme:
return False
-
+
if self.server != comp.server:
return False
-
+
# Ignore trailing slash
if self.path.rstrip("/") != comp.path.rstrip("/"):
return False
return True
+
def equalRelative(self, comp):
# Must be relative
if comp.server:
return False
-
+
# Just compare paths, ignore trailing slash
return self.path.rstrip("/") == comp.path.rstrip("/")
-
+
+
def dirname(self):
if self.path:
newpath = os.path.dirname(self.path.rstrip("/")) + "/"
return URL(scheme=self.scheme, server=self.server, path=newpath)
+
def _parse(self, url, decode=False):
-
+
# Strip off main scheme
if url.lower().startswith("url:"):
url = url[4:]
-
+
# Special - if it starts with "/" its a relative HTTP url
if url[0] == '/':
self.scheme = "http"
@@ -188,26 +198,27 @@
# Get protocol scheme
self.scheme = url[:url.find(":")].lower()
url = url[len(self.scheme):]
-
+
if self.scheme in URL.URLSchemeDoubleSlash:
-
+
assert(url.startswith("://"))
-
+
# Look for server
splits = url[3:].split("/", 1)
self.server = splits[0]
if len(splits) == 2:
self._parsePath("/" + splits[1], decode)
-
+
elif self.scheme in ("mailto", "urn",):
-
+
assert(url.startswith(":"))
-
+
# Look for server
self.server = url[1:]
+
def _parsePath(self, path, decode=False):
-
+
# Look for extended bits
splits = path.split("?", 1)
self.path = splits[0]
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/utils/xmlhelpers.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/utils/xmlhelpers.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/utils/xmlhelpers.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -32,6 +32,8 @@
element.text = data
return element
+
+
def myfixtag(tag, namespaces):
# given a decorated tag (of the form {uri}tag), return prefixed
# tag and namespace declaration, if any
@@ -52,8 +54,10 @@
xmlns = None
return "%s:%s" % (prefix, tag), xmlns
+
+
class BetterElementTree(ElementTree):
-
+
def writeUTF8(self, file):
assert self._root is not None
if not hasattr(file, "write"):
@@ -63,6 +67,7 @@
self._prettywrite(file, self._root, encoding, {})
file.write("\r\n")
+
def _prettywrite(self, file, node, encoding, namespaces, depth=0):
# write XML to file
tag = node.tag
@@ -78,7 +83,8 @@
try:
if isinstance(tag, QName) or tag[:1] == "{":
tag, xmlns = myfixtag(tag, namespaces)
- if xmlns: xmlns_items.append(xmlns)
+ if xmlns:
+ xmlns_items.append(xmlns)
except TypeError:
_raise_serialization_error(tag)
file.write("\r\n" + " " * depth)
@@ -89,13 +95,15 @@
try:
if isinstance(k, QName) or k[:1] == "{":
k, xmlns = myfixtag(k, namespaces)
- if xmlns: xmlns_items.append(xmlns)
+ if xmlns:
+ xmlns_items.append(xmlns)
except TypeError:
_raise_serialization_error(k)
try:
if isinstance(v, QName):
v, xmlns = myfixtag(v, namespaces)
- if xmlns: xmlns_items.append(xmlns)
+ if xmlns:
+ xmlns_items.append(xmlns)
except TypeError:
_raise_serialization_error(v)
file.write(" %s=\"%s\"" % (_encode(k, encoding),
@@ -108,7 +116,7 @@
if node.text:
file.write(_escape_cdata(node.text, encoding))
for n in node:
- self._prettywrite(file, n, encoding, namespaces, depth=depth+1)
+ self._prettywrite(file, n, encoding, namespaces, depth=depth + 1)
if not node.text or len(node):
file.write("\r\n" + " " * depth)
file.write("</" + _encode(tag, encoding) + ">")
@@ -119,9 +127,10 @@
if node.tail:
file.write(_escape_cdata(node.tail, encoding))
+
+
def elementToString(element):
os = StringIO()
xmldoc = BetterElementTree(element)
xmldoc.writeUTF8(os)
return os.getvalue()
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/ace.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/ace.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/ace.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -30,16 +30,20 @@
self.protected = False
self.inherited = False
+
def getPrincipal(self):
return self.principal
+
def setPrincipal(self, principal, data=None):
self.principal = principal
self.data = data
+
def canChange(self):
return not self.protected and not self.inherited
+
@staticmethod
def parseFromACL(aclnode):
@@ -50,9 +54,10 @@
newace.parseACE(node)
aces.append(newace)
return aces
-
+
+
def parseACE(self, acenode):
-
+
assert(acenode and acenode.tag == davxml.ace)
# Get invert
@@ -67,7 +72,7 @@
principal = principal_parent.find(str(davxml.principal))
if not principal or len(principal.getchildren()) != 1:
return False
-
+
# Determine principal info
child = principal.getchildren()[0]
if child.tag == davxml.href:
@@ -81,7 +86,7 @@
self.setPrincipal(child.tag, QName(child.getchildren()[0].tag))
else:
self.setPrincipal(child.tag)
-
+
# Determine rights
self.grant = True
child = acenode.find(str(davxml.grant))
@@ -91,17 +96,18 @@
self.grant = False
if child:
self.parsePrivileges(child)
-
+
# Determine protected/inherited state
self.protected = acenode.find(str(davxml.protected)) is not None
self.inherited = acenode.find(str(davxml.inherited)) is not None
-
+
return True
+
def parsePrivileges(self, parent):
-
+
assert(parent.tag in (davxml.grant, davxml.deny,))
-
+
# Parent node contains one of more privilege nodes which we parse
self.privs = ()
for privilege in parent.getchildren():
@@ -112,6 +118,7 @@
# Now get rights within the privilege
self.privs += (privilege.getchildren()[0].tag,)
+
def generateACE(self, aclnode):
# Structure of ace is:
#
@@ -119,16 +126,16 @@
# <DAV:principal>...</DAV:principal>
# <DAV:grant>...</DAV:grant>
# </DAV:ace>
-
+
# <DAV:ace> element
ace = SubElement(aclnode, davxml.ace)
-
+
if self.invert:
invert = SubElement(ace, davxml.invert)
# <DAV:principal> element
principal = SubElement(invert if self.invert else ace, davxml.principal)
-
+
# Principal type
if self.principal == davxml.href:
@@ -146,17 +153,17 @@
# <DAV:property> element - the UID is the property element name
property = SubElement(principal, davxml.property)
SubElement(property, self.data)
-
+
# Do grant rights for each one set
if self.grant:
# <DAV:grant> element
privs = SubElement(ace, davxml.grant)
-
+
# Do deny rights for each one set
else:
# <DAV:deny> element
privs = SubElement(ace, davxml.deny)
-
+
for item in self.privs:
priv = SubElement(privs, davxml.privilege)
SubElement(priv, item)
@@ -166,4 +173,3 @@
SubElement(ace, davxml.protected)
if self.inherited:
SubElement(ace, davxml.inherited)
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/acl.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/acl.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/acl.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -27,15 +27,17 @@
def __init__(self, session, url, acls):
super(ACL, self).__init__(session, methods.ACL, url)
self.acls = acls
-
+
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -47,10 +49,10 @@
# </DAV:ace>
# ...
# </DAV:acl>
-
+
# <DAV:acl> element
acl = Element(davxml.acl)
-
+
# Do for each ACL
if self.acls:
@@ -58,10 +60,10 @@
# Cannot do if change not allowed
if not ace.canChange():
continue
-
+
# <DAV:ace> element
ace.generateACE(acl)
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(acl)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/copymovebase.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/copymovebase.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/copymovebase.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -25,6 +25,7 @@
self.absurl_new = absurl_new
self.overwrite = overwrite
+
def setData(self, etag):
self.request_data = None
self.response_data = None
@@ -34,12 +35,13 @@
self.etag = etag
self.etag_match = True
+
def addHeaders(self, hdrs):
# Do default
super(CopyMoveBase, self).addHeaders(hdrs)
-
+
# Add Destination header
hdrs.append((headers.Destination, self.absurl_new))
-
+
# Add Overwrite header
hdrs.append((headers.Overwrite, headers.OverwriteTrue if self.overwrite else headers.OverwriteFalse))
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/csxml.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/csxml.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/csxml.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,5 +18,5 @@
CSNamespace = "http://calendarserver.org/ns/"
-expanded_group_member_set = QName(CSNamespace, "expanded-group-member-set")
-expanded_group_membership = QName(CSNamespace, "expanded-group-membership")
+expanded_group_member_set = QName(CSNamespace, "expanded-group-member-set")
+expanded_group_membership = QName(CSNamespace, "expanded-group-membership")
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/davxml.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/davxml.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/davxml.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,90 +18,89 @@
DAVNamespace = "DAV:"
-propfind = QName(DAVNamespace, "propfind")
-propname = QName(DAVNamespace, "propname")
-allprop = QName(DAVNamespace, "allprop")
-prop = QName(DAVNamespace, "prop")
-propstat = QName(DAVNamespace, "propstat")
+propfind = QName(DAVNamespace, "propfind")
+propname = QName(DAVNamespace, "propname")
+allprop = QName(DAVNamespace, "allprop")
+prop = QName(DAVNamespace, "prop")
+propstat = QName(DAVNamespace, "propstat")
propertyupdate = QName(DAVNamespace, "propertyupdate")
-remove = QName(DAVNamespace, "remove")
-set = QName(DAVNamespace, "set")
+remove = QName(DAVNamespace, "remove")
+set = QName(DAVNamespace, "set")
-getetag = QName(DAVNamespace, "getetag")
-creationdate = QName(DAVNamespace, "creationdate")
-displayname = QName(DAVNamespace, "displayname")
+getetag = QName(DAVNamespace, "getetag")
+creationdate = QName(DAVNamespace, "creationdate")
+displayname = QName(DAVNamespace, "displayname")
getcontentlanguage = QName(DAVNamespace, "getcontentlanguage")
-getcontentlength = QName(DAVNamespace, "getcontentlength")
-getcontenttype = QName(DAVNamespace, "getcontenttype")
-getlastmodified = QName(DAVNamespace, "getlastmodified")
-resourcetype = QName(DAVNamespace, "resourcetype")
-collection = QName(DAVNamespace, "collection")
-synctoken = QName(DAVNamespace, "sync-token")
+getcontentlength = QName(DAVNamespace, "getcontentlength")
+getcontenttype = QName(DAVNamespace, "getcontenttype")
+getlastmodified = QName(DAVNamespace, "getlastmodified")
+resourcetype = QName(DAVNamespace, "resourcetype")
+collection = QName(DAVNamespace, "collection")
+synctoken = QName(DAVNamespace, "sync-token")
-lockinfo = QName(DAVNamespace, "lockinfo")
-lockscope = QName(DAVNamespace, "lockscope")
-locktype = QName(DAVNamespace, "locktype")
-owner = QName(DAVNamespace, "owner")
-exclusive = QName(DAVNamespace, "exclusive")
-shared = QName(DAVNamespace, "shared")
-write = QName(DAVNamespace, "write")
+lockinfo = QName(DAVNamespace, "lockinfo")
+lockscope = QName(DAVNamespace, "lockscope")
+locktype = QName(DAVNamespace, "locktype")
+owner = QName(DAVNamespace, "owner")
+exclusive = QName(DAVNamespace, "exclusive")
+shared = QName(DAVNamespace, "shared")
+write = QName(DAVNamespace, "write")
-acl = QName(DAVNamespace, "acl")
-ace = QName(DAVNamespace, "ace")
-invert = QName(DAVNamespace, "invert")
-principal = QName(DAVNamespace, "principal")
-privilege = QName(DAVNamespace, "privilege")
-grant = QName(DAVNamespace, "grant")
-deny = QName(DAVNamespace, "deny")
-protected = QName(DAVNamespace, "protected")
-inherited = QName(DAVNamespace, "inherited")
+acl = QName(DAVNamespace, "acl")
+ace = QName(DAVNamespace, "ace")
+invert = QName(DAVNamespace, "invert")
+principal = QName(DAVNamespace, "principal")
+privilege = QName(DAVNamespace, "privilege")
+grant = QName(DAVNamespace, "grant")
+deny = QName(DAVNamespace, "deny")
+protected = QName(DAVNamespace, "protected")
+inherited = QName(DAVNamespace, "inherited")
-href = QName(DAVNamespace, "href")
-all = QName(DAVNamespace, "all")
-authenticated = QName(DAVNamespace, "authenticated")
-unauthenticated = QName(DAVNamespace, "unauthenticated")
-property = QName(DAVNamespace, "property")
-self = QName(DAVNamespace, "self")
-read = QName(DAVNamespace, "read")
-write = QName(DAVNamespace, "write")
-write_properties = QName(DAVNamespace, "write-properties")
-write_content = QName(DAVNamespace, "write-content")
-read_acl = QName(DAVNamespace, "read-acl")
+href = QName(DAVNamespace, "href")
+all = QName(DAVNamespace, "all")
+authenticated = QName(DAVNamespace, "authenticated")
+unauthenticated = QName(DAVNamespace, "unauthenticated")
+property = QName(DAVNamespace, "property")
+self = QName(DAVNamespace, "self")
+read = QName(DAVNamespace, "read")
+write = QName(DAVNamespace, "write")
+write_properties = QName(DAVNamespace, "write-properties")
+write_content = QName(DAVNamespace, "write-content")
+read_acl = QName(DAVNamespace, "read-acl")
read_current_user_privilege_set = QName(DAVNamespace, "read-current-user-privilege-set")
-write_acl = QName(DAVNamespace, "write-acl")
-bind = QName(DAVNamespace, "bind")
-unbind = QName(DAVNamespace, "unbind")
-all = QName(DAVNamespace, "all")
+write_acl = QName(DAVNamespace, "write-acl")
+bind = QName(DAVNamespace, "bind")
+unbind = QName(DAVNamespace, "unbind")
+all = QName(DAVNamespace, "all")
-multistatus = QName(DAVNamespace, "multistatus")
-response = QName(DAVNamespace, "response")
+multistatus = QName(DAVNamespace, "multistatus")
+response = QName(DAVNamespace, "response")
responsedescription = QName(DAVNamespace, "responsedescription")
-status = QName(DAVNamespace, "status")
+status = QName(DAVNamespace, "status")
-principal_match = QName(DAVNamespace, "principal-match")
+principal_match = QName(DAVNamespace, "principal-match")
principal_collection_set = QName(DAVNamespace, "principal-collection-set")
-alternate_URI_set = QName(DAVNamespace, "alternate-URI-set")
-principal_URL = QName(DAVNamespace, "principal-URL")
-group_member_set = QName(DAVNamespace, "group-member-set")
-group_membership = QName(DAVNamespace, "group-membership")
+alternate_URI_set = QName(DAVNamespace, "alternate-URI-set")
+principal_URL = QName(DAVNamespace, "principal-URL")
+group_member_set = QName(DAVNamespace, "group-member-set")
+group_membership = QName(DAVNamespace, "group-membership")
supported_report_set = QName(DAVNamespace, "supported-report-set")
-supported_report = QName(DAVNamespace, "supported-report")
-report = QName(DAVNamespace, "report")
+supported_report = QName(DAVNamespace, "supported-report")
+report = QName(DAVNamespace, "report")
quota_available_bytes = QName(DAVNamespace, "quota-available-bytes")
-quota_used_bytes = QName(DAVNamespace, "quota-used-bytes")
+quota_used_bytes = QName(DAVNamespace, "quota-used-bytes")
current_user_principal = QName(DAVNamespace, "current-user-principal")
-mkcol = QName(DAVNamespace, "mkcol")
+mkcol = QName(DAVNamespace, "mkcol")
mkcol_response = QName(DAVNamespace, "mkcol-response")
sync_collection = QName(DAVNamespace, "sync-collection")
-sync_token = QName(DAVNamespace, "sync-token")
-sync_level = QName(DAVNamespace, "sync-level")
-sync_level_1 = "1"
+sync_token = QName(DAVNamespace, "sync-token")
+sync_level = QName(DAVNamespace, "sync-level")
+sync_level_1 = "1"
sync_level_infinite = "infinite"
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/methods.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/methods.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/definitions/methods.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,12 +18,12 @@
# RFC2518 - WebDAV Request Methods
-MKCOL = "MKCOL"
-MOVE = "MOVE"
-COPY = "COPY"
-PROPFIND = "PROPFIND"
+MKCOL = "MKCOL"
+MOVE = "MOVE"
+COPY = "COPY"
+PROPFIND = "PROPFIND"
PROPPATCH = "PROPPATCH"
-LOCK = "LOCK"
-UNLOCK = "UNLOCK"
-REPORT = "REPORT" # RFC3253
-ACL = "ACL" # RFC3744
+LOCK = "LOCK"
+UNLOCK = "UNLOCK"
+REPORT = "REPORT" # RFC3253
+ACL = "ACL" # RFC3744
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/delete.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/delete.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/delete.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,6 +22,7 @@
def __init__(self, session, url):
super(Delete, self).__init__(session, methods.DELETE, url)
+
def setData(self, etag=None):
self.request_data = None
self.response_data = None
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/getbase.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/getbase.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/getbase.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -25,6 +25,7 @@
super(GetBase, self).__init__(session, methods.HEAD if head else methods.GET, url, lock=lock)
self.head = head
+
def setData(self, response_data, etag=None):
self.request_data = None
self.response_data = response_data
@@ -34,6 +35,7 @@
self.etag = etag
self.etag_match = True
+
def getNewETag(self):
# Get the ETag header from response headers
if self.hasResponseHeader(headers.ETag):
@@ -41,10 +43,12 @@
else:
return None
+
def getContentLength(self):
# Always zero to prevent attempt to read response
return 0 if self.head else self.content_length
-
+
+
def getChunked(self):
# Always false to prevent attempt to read response
return False if self.head else self.chunked
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/lock.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/lock.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/lock.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -26,14 +26,14 @@
class Lock(RequestResponse):
eExclusive = 0
- eShared = 1
+ eShared = 1
- eResourceMustExist = 0
- eResourceMustNotExist = 1
- eResourceMayExist = 2
+ eResourceMustExist = 0
+ eResourceMustNotExist = 1
+ eResourceMayExist = 2
def __init__(self, session, url, depth, scope, owner, timeout, exists=eResourceMustExist):
-
+
assert(depth in (headers.Depth0, headers.Depth1, headers.DepthInfinity))
assert(scope in (Lock.eExclusive, Lock.eShared,))
assert(exists in (Lock.eResourceMustExist, Lock.eResourceMustNotExist, Lock.eResourceMayExist))
@@ -44,7 +44,7 @@
self.scope = scope
self.owner = owner
self.timeout = timeout
-
+
# Do appropriate etag based on exists
if exists == Lock.eResourceMustExist:
self.etag = "*"
@@ -54,28 +54,31 @@
self.etag_match = False
elif exists == Lock.eResourceMayExist:
pass
-
+
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
+
def addHeaders(self, hdrs):
# Do default
super(Lock, self).addHeaders(hdrs)
-
+
# Add depth header
hdrs.append((headers.Depth, self.depth))
-
+
# Add timeout header
if self.timeout == -1:
hdrs.append((headers.Timeout, headers.TimeoutInfinite))
elif self.timeout > 0:
hdrs.append((headers.Timeout, "%s%d" % (headers.TimeoutSeconds, self.timeout)))
+
def generateXML(self, os):
# Structure of document is:
#
@@ -90,43 +93,44 @@
# <<owner>>
# </DAV:owner>
# </DAV:lockinfo>
-
+
# <DAV:lockinfo> element
lockinfo = Element(davxml.lockinfo)
-
+
# <DAV:lockscope> element
lockscope = Element(davxml.lockscope)
lockinfo.append(lockscope)
-
+
# <DAV:exclusive/> | <DAV:shared/> element
lockscope.append(Element(davxml.exclusive if self.scope == Lock.eExclusive else davxml.shared))
-
+
# <DAV:locktype> element
locktype = Element(davxml.locktype)
lockinfo.append(locktype)
-
+
# <DAV:write/> element
locktype.append(Element(davxml.write))
-
+
# <DAV:owner> element is optional
if self.owner:
# <DAV:owner> element
owner = Element(davxml.owner)
owner.text = self.owner
lockinfo.append(owner)
-
+
# Now we have the complete document, so write it out (no indentation)
BetterElementTree(lockinfo).writeUTF8(os)
+
def getLockToken(self):
-
+
# Get the Lock-Token header from response headers
result = ""
if self.hasResponseHeader(headers.LockToken):
# Get Coded-URL
codedurl = self.getResponseHeader(headers.LockToken)
-
+
# Strip leading/trailing <>
codeurl = codedurl.strip()
if codeurl.startswith("<") and codeurl.endswith(">"):
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/multiresponseparser.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/multiresponseparser.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/multiresponseparser.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,14 +23,15 @@
# Must have a node
if multistatus_node is None:
return
-
+
# Verify that the node is the correct element <DAV:multistatus>
if multistatus_node.tag != davxml.multistatus:
return
-
+
# Node is the right type, so iterator over all child response nodes and process each one
for response in multistatus_node.getchildren():
self.parseResponse(response)
-
+
+
def parseResponse(self, response):
raise NotImplementedError
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/options.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/options.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/options.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,6 +24,7 @@
def __init__(self, session, url):
super(Options, self).__init__(session, methods.OPTIONS, url)
+
def getAllowed(self):
methods = ()
@@ -34,9 +35,10 @@
while value:
token, value = parsetoken(value, ", \t")
methods += (token,)
-
+
return methods
+
def isAllowed(self, method):
methods = ()
if self.hasResponseHeader(headers.Allow):
@@ -47,5 +49,5 @@
token, value = parsetoken(value, ", \t")
if method == token:
return True
-
+
return False
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/principalmatch.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/principalmatch.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/principalmatch.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -30,15 +30,17 @@
super(PrincipalMatch, self).__init__(session, url, headers.Depth0)
self.props = props
self.method = methods.REPORT
-
+
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -48,26 +50,26 @@
# <<names of each property as elements>>
# </DAV:prop>
# </DAV:principal-match>
-
+
# <DAV:principal-match> element
principalmatch = Element(davxml.principal_match)
-
+
# <DAV:self> element
SubElement(principalmatch, davxml.self)
-
+
if self.props:
# <DAV:prop> element
prop = SubElement(principalmatch, davxml.prop)
-
+
# Now add each property
for item in self.props:
# Add property element taking namespace into account
-
+
# Look for DAV namespace and reuse that one
SubElement(prop, item)
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(principalmatch)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propall.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propall.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propall.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -25,19 +25,20 @@
super(PropAll, self).__init__(session, url, depth)
self.initRequestData()
+
def generateXML(self, os):
# Structure of document is:
#
# <DAV:propfind>
# <DAV:allprop/>
# </DAV:propfind>
-
+
# <DAV:propfind> element
propfind = Element(davxml.propfind)
-
+
# <DAV:propname> element
propfind.append(Element(davxml.allprop))
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(propfind)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfind.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfind.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfind.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,9 +24,10 @@
def __init__(self, session, url, depth, props):
super(PropFind, self).__init__(session, url, depth)
self.props = props
-
+
self.initRequestData()
+
def generateXML(self, os):
# Structure of document is:
#
@@ -35,19 +36,19 @@
# <<names of each property as elements>>
# </DAV:prop>
# </DAV:propfind>
-
+
# <DAV:propfind> element
propfind = Element(davxml.propfind)
-
+
# <DAV:prop> element
prop = Element(davxml.prop)
propfind.append(prop)
-
+
# Now add each property
for propname in self.props:
# Add property element taking namespace into account
prop.append(Element(propname))
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(propfind)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindbase.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindbase.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindbase.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -28,25 +28,29 @@
super(PropFindBase, self).__init__(session, methods.PROPFIND, url)
self.depth = depth
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
- self.generateXML(os);
- self.request_data = RequestDataString(os.getvalue(), "text/xml; charset=utf-8");
-
+ self.generateXML(os)
+ self.request_data = RequestDataString(os.getvalue(), "text/xml; charset=utf-8")
+
+
def setOutput(self, response_data):
self.response_data = response_data
+
def addHeaders(self, hdrs):
# Do default
super(PropFindBase, self).addHeaders(hdrs)
-
+
# Add depth header
hdrs.append((headers.Depth, self.depth))
-
+
# Optional ones
if self.session.useBriefHeader:
hdrs.append((headers.Brief, "t"))
-
+
+
def generateXML(self, os):
raise NotImplementedError
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindparser.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindparser.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propfindparser.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -27,7 +27,7 @@
hrefListProperties = set()
class PropFindResult(object):
-
+
def __init__(self):
self.status = 200
self.textProperties = {}
@@ -44,7 +44,7 @@
self.status = status
def getStatus(self):
return self.status
-
+
def addTextProperty(self, name, value):
self.textProperties[name] = value
def getTextProperties(self):
@@ -65,23 +65,27 @@
def getBadProperties(self):
return self.badProperties
+
def __init__(self):
self.results = {}
self.others = set()
-
+
+
def getResults(self):
return self.results
+
def getOthers(self):
return self.others
+
# Parse the response element down to the properties
def parseResponse(self, response):
# Verify that the node is the correct element <DAV:response>
if response.tag != davxml.response:
self.others.add(response)
return
-
+
# Node is the right type, so iterate over all child response nodes and process each one
result = PropFindParser.PropFindResult()
for child in response.getchildren():
@@ -89,24 +93,25 @@
# Is it the href
if child.tag == davxml.href:
result.setResource(child.text)
-
+
# Is it propstat
elif child.tag == davxml.propstat:
self.parsePropStat(child, result)
elif child.tag == davxml.status:
result.setStatus(child.text)
-
+
# Add the resource only if we got one
if result.getResource():
self.results[result.getResource()] = result
+
def parsePropStat(self, propstat, result):
# Scan the propstat node the status - we only process OK status
-
+
# Now look for a <DAV:status> element in its children
status = propstat.find(str(davxml.status))
-
+
# Now parse the response and dispatch accordingly
if status is not None:
@@ -115,13 +120,15 @@
# Now look for a <DAV:prop> element in its children
for item in propstat.findall(str(davxml.prop)):
- self.parseProp(item, result, badstatus)
+ self.parseProp(item, result, badstatus)
+
def parseProp(self, property, result, badstatus):
# Scan the prop node - each child is processed
for item in property.getchildren():
self.parsePropElement(item, result, badstatus)
-
+
+
# Parsing of property elements
def parsePropElement(self, prop, result, badstatus):
# Here we need to detect the type of element and dispatch accordingly
@@ -152,11 +159,13 @@
else:
self.parsePropElementUnknown(prop, result)
+
def parsePropElementText(self, prop, result):
# Grab the element data
result.addTextProperty(QName(prop.tag), prop.text if prop.text else "")
result.addNodeProperty(QName(prop.tag), prop)
+
def parsePropElementHref(self, prop, result, is_list):
# Grab the element data
hrefs = tuple([URL(url=href.text, decode=True) for href in prop.findall(str(davxml.href))])
@@ -168,6 +177,7 @@
result.addHrefProperty(QName(prop.tag), hrefs)
result.addNodeProperty(QName(prop.tag), prop)
+
def parsePropElementUnknown(self, prop, result):
# Just add the node
result.addNodeProperty(QName(prop.tag), prop)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propnames.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propnames.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/propnames.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -25,19 +25,20 @@
super(PropNames, self).__init__(session, url, depth)
self.initRequestData()
+
def generateXML(self, os):
# Structure of document is:
#
# <DAV:propfind>
# <DAV:propname/>
# </DAV:propfind>
-
+
# <DAV:propfind> element
propfind = Element(davxml.propfind)
-
+
# <DAV:propname> element
propfind.append(Element(davxml.propname))
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(propfind)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/proppatch.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/proppatch.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/proppatch.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -29,26 +29,30 @@
super(PropPatch, self).__init__(session, methods.PROPPATCH, url)
self.setprops = setprops
self.delprops = delprops
-
+
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
- self.generateXML(os);
- self.request_data = RequestDataString(os.getvalue(), "text/xml; charset=utf-8");
-
+ self.generateXML(os)
+ self.request_data = RequestDataString(os.getvalue(), "text/xml; charset=utf-8")
+
+
def setOutput(self, response_data):
self.response_data = response_data
+
def addHeaders(self, hdrs):
# Do default
super(PropPatch, self).addHeaders(hdrs)
-
+
# Optional ones
if self.session.useBriefHeader:
hdrs.append((headers.Brief, "t"))
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -60,10 +64,10 @@
# <<names of each property as elements>>
# </DAV:remove>
# </DAV:propertyupdate>
-
+
# <DAV:propertyupdate> element
propertyupdate = Element(davxml.propertyupdate)
-
+
# <DAV:set> element
if self.setprops:
set = SubElement(propertyupdate, davxml.set)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/put.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/put.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/put.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,11 +23,12 @@
def __init__(self, session, url, lock=None):
super(Put, self).__init__(session, methods.PUT, url, lock=lock)
+
def setData(self, request_data, response_data, etag=None, new_item=False):
assert(not (etag and new_item))
self.request_data = request_data
self.response_data = response_data
-
+
# Must have matching ETag
if etag:
self.etag = etag
@@ -38,6 +39,7 @@
self.etag = "*"
self.etag_match = False
+
def getNewETag(self):
# Get the ETag header from response headers
if self.hasResponseHeader(headers.ETag):
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/report.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/report.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/report.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,14 +22,15 @@
def __init__(self, session, url):
super(Report, self).__init__(session, methods.REPORT, url)
+
def setOutput(self, response_data):
- self.response_data = response_data;
+ self.response_data = response_data
+
def addHeaders(self, hdrs):
# Do default
super(RequestResponse, self).addHeaders(hdrs)
-
+
# Optional ones
if self.session.useBriefHeader:
hdrs.append((headers.Brief, "t"))
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/requestresponse.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/requestresponse.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/requestresponse.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,9 +24,11 @@
super(RequestResponse, self).__init__(session, method, ruri, etag, etag_match)
self.lock = lock
+
def setLock(self, lock):
self.lock = lock
+
def addHeaders(self, hdrs):
# Do inherited
super(RequestResponse, self).addHeaders(hdrs)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/session.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/session.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/session.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,19 +22,20 @@
from caldavclientlibrary.protocol.webdav.definitions import headers
class Session(HTTPSession):
-
+
def __init__(self, server, port=None, ssl=False, log=None):
super(Session, self).__init__(server, port, ssl, log)
self.initialised = False
self.version = ()
-
+
# Features for entire session
self.useBriefHeader = True
+
def initialise(self, host, base_uri):
# Set host change
self.setServer(host)
-
+
# Loop repeating until we can do it or get a fatal error
first_time = True
while True:
@@ -44,10 +45,10 @@
request.setSession(self)
sout = ResponseDataString()
request.setData(None, sout)
-
+
# Add request and process it
self.sendRequest(request)
-
+
# Check response
if request.getStatusCode() == statuscodes.Unauthorized:
@@ -55,35 +56,35 @@
if self.hasAuthorization():
self.authorization = None
-
+
# Display error so user knows why the prompt occurs again
self.displayHTTPError(request)
-
+
# Get authorization object (prompt the user) and redo the request
self.authorization, cancelled = self.getAuthorizor(first_time, request.getResponseHeaders(headers.WWWAuthenticate))
-
+
# Check for auth cancellation
if cancelled:
self.authorization = None
return False
-
+
first_time = False
-
+
# Repeat the request loop with new authorization
continue
-
+
# Look for success and exit loop for further processing
if request.getStatusCode() in (statuscodes.OK, statuscodes.NoContent):
# Grab the server string
if request.hasResponseHeader(headers.Server):
self.setServerDescriptor = self.setServerDescriptor(request.getResponseHeader(headers.Server))
-
+
# Now check the response headers for a DAV version (may be more than one)
self.version = ()
for dav_version in request.getResponseHeaders(headers.DAV):
-
+
# Tokenize on commas
for token in dav_version.split(","):
@@ -91,7 +92,7 @@
self.addVersion(token)
self.setServerType(self.version)
-
+
# Put other strings into capability
capa = ""
for name, value in request.getResponseHeaders().iteritems():
@@ -103,42 +104,50 @@
capa += "%s: %s\n" % (name, value,)
self.setServerCapability(capa)
-
+
# Just assume any version is fine for now
break
-
+
# If we get here we had some kind of fatal error
self.handleHTTPError(request)
return False
-
+
self.initialised = True
-
+
return True
+
def addVersion(self, token):
self.version += (token,)
+
def hasDAVVersion(self, version):
return version in self.version
+
def hasDAV(self):
return self.hasDAVVersion(headers.DAV1)
+
def hasDAVLocking(self):
return self.hasDAVVersion(headers.DAV2) or self.hasDAVVersion(headers.DAVbis)
+
def hasDAVACL(self):
return self.hasDAVVersion(headers.DAVACL)
+
def getAuthorizor(self, first_time, www_authenticate):
raise NotImplementedError
-
+
+
def setServerType(self, type):
raise NotImplementedError
-
+
+
def setServerDescriptor(self, txt):
raise NotImplementedError
-
+
+
def setServerCapability(self, txt):
raise NotImplementedError
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/synccollection.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/synccollection.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/synccollection.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -31,22 +31,25 @@
self.level = level
self.synctoken = synctoken
self.props = props
-
+
self.initRequestData()
+
def initRequestData(self):
# Write XML info to a string
os = StringIO()
self.generateXML(os)
self.request_data = RequestDataString(os.getvalue(), "text/xml charset=utf-8")
+
def addHeaders(self, hdrs):
# Do default
super(SyncCollection, self).addHeaders(hdrs)
-
+
# Add depth header
hdrs.append((headers.Depth, headers.Depth0))
-
+
+
def generateXML(self, os):
# Structure of document is:
#
@@ -57,10 +60,10 @@
# <<names of each property as elements>>
# </DAV:prop>
# </DAV:sync-collection>
-
+
# <DAV:sync-collection> element
synccollection = Element(davxml.sync_collection)
-
+
# Add sync-token element
SubElement(synccollection, davxml.sync_token).text = self.synctoken
@@ -75,7 +78,7 @@
for propname in self.props:
# Add property element taking namespace into account
SubElement(prop, propname)
-
+
# Now we have the complete document, so write it out (no indentation)
xmldoc = BetterElementTree(synccollection)
xmldoc.writeUTF8(os)
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_ace.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_ace.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_ace.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -24,29 +24,30 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def verifyXML(self, x, y=None):
-
+
x = x.replace("\n", "\r\n")
if y:
y = y.replace("\n", "\r\n")
-
+
# Parse the XML data
a = ACE()
a.parseACE(XML(x))
-
+
# Generate the XML data
aclnode = Element(davxml.acl)
a.generateACE(aclnode)
os = StringIO()
xmldoc = BetterElementTree(aclnode.getchildren()[0])
xmldoc.writeUTF8(os)
-
+
# Verify data
self.assertEqual(os.getvalue(), y if y else x)
+
def test_XML1(self):
-
+
self.verifyXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:ace xmlns:ns0="DAV:">
<ns0:principal>
@@ -60,8 +61,9 @@
</ns0:ace>
""")
+
def test_XML2(self):
-
+
self.verifyXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:ace xmlns:ns0="DAV:">
<ns0:principal>
@@ -78,8 +80,9 @@
</ns0:ace>
""")
+
def test_XML3(self):
-
+
self.verifyXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:ace xmlns:ns0="DAV:">
<ns0:principal>
@@ -95,8 +98,9 @@
</ns0:ace>
""")
+
def test_XML4(self):
-
+
self.verifyXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:ace xmlns:ns0="DAV:">
<ns0:invert>
@@ -114,8 +118,9 @@
</ns0:ace>
""")
+
def test_XML5(self):
-
+
self.verifyXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:ace xmlns:ns0="DAV:">
<ns0:principal>
@@ -130,5 +135,3 @@
</ns0:grant>
</ns0:ace>
""")
-
-
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_acl.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_acl.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_acl.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,24 +20,34 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = ACL(server, "/", ())
self.assertEqual(request.getMethod(), "ACL")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
pass
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_copy.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_copy.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_copy.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,16 +20,19 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Copy(server, "/a", "http://www.example.com/b")
self.assertEqual(request.getMethod(), "COPY")
+
+
class TestRequestHeaders(unittest.TestCase):
+
def test_NoSpecialHeaders(self):
-
+
server = Session("www.example.com")
request = Copy(server, "/a", "http://www.example.com/b")
hdrs = request.generateRequestHeader()
@@ -37,9 +40,10 @@
self.assertFalse("If-Match:" in hdrs)
self.assertTrue("Overwrite: F" in hdrs)
self.assertTrue("Destination: http://www.example.com/b" in hdrs)
-
+
+
def test_IfMatchHeader(self):
-
+
server = Session("www.example.com")
request = Copy(server, "/a", "http://www.example.com/b")
request.setData(etag="\"12345\"")
@@ -48,9 +52,10 @@
self.assertTrue("If-Match: \"12345\"" in hdrs)
self.assertTrue("Overwrite: F" in hdrs)
self.assertTrue("Destination: http://www.example.com/b" in hdrs)
-
+
+
def test_OverwriteHeader(self):
-
+
server = Session("www.example.com")
request = Copy(server, "/a", "http://www.example.com/b", overwrite=True)
hdrs = request.generateRequestHeader()
@@ -59,14 +64,22 @@
self.assertTrue("Overwrite: T" in hdrs)
self.assertTrue("Destination: http://www.example.com/b" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_delete.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_delete.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_delete.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,24 +20,28 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Delete(server, "/")
self.assertEqual(request.getMethod(), "DELETE")
+
+
class TestRequestHeaders(unittest.TestCase):
+
def test_NoSpecialHeaders(self):
-
+
server = Session("www.example.com")
request = Delete(server, "/")
hdrs = request.generateRequestHeader()
self.assertFalse("If-None-Match:" in hdrs)
self.assertFalse("If-Match:" in hdrs)
-
+
+
def test_IfMatchHeader(self):
-
+
server = Session("www.example.com")
request = Delete(server, "/")
request.setData(etag="\"12345\"")
@@ -45,14 +49,22 @@
self.assertFalse("If-None-Match:" in hdrs)
self.assertTrue("If-Match: \"12345\"" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_get.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_get.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_get.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,24 +20,28 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Get(server, "/")
self.assertEqual(request.getMethod(), "GET")
+
+
class TestRequestHeaders(unittest.TestCase):
+
def test_NoSpecialHeaders(self):
-
+
server = Session("www.example.com")
request = Get(server, "/")
hdrs = request.generateRequestHeader()
self.assertFalse("If-None-Match:" in hdrs)
self.assertFalse("If-Match:" in hdrs)
-
+
+
def test_IfMatchHeader(self):
-
+
server = Session("www.example.com")
request = Get(server, "/")
request.setData(None, etag="\"12345\"")
@@ -45,14 +49,22 @@
self.assertFalse("If-None-Match:" in hdrs)
self.assertTrue("If-Match: \"12345\"" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_head.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_head.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_head.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,24 +20,28 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Head(server, "/")
self.assertEqual(request.getMethod(), "HEAD")
+
+
class TestRequestHeaders(unittest.TestCase):
+
def test_NoSpecialHeaders(self):
-
+
server = Session("www.example.com")
request = Head(server, "/")
hdrs = request.generateRequestHeader()
self.assertFalse("If-None-Match:" in hdrs)
self.assertFalse("If-Match:" in hdrs)
-
+
+
def test_IfMatchHeader(self):
-
+
server = Session("www.example.com")
request = Head(server, "/")
request.setData(None, etag="\"12345\"")
@@ -45,14 +49,22 @@
self.assertFalse("If-None-Match:" in hdrs)
self.assertTrue("If-Match: \"12345\"" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_lock.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_lock.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_lock.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,41 +22,46 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth0, Lock.eExclusive, "user at example.com", -1)
self.assertEqual(request.getMethod(), "LOCK")
+
+
class TestRequestHeaders(unittest.TestCase):
def test_NoSpecialHeaders(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth0, Lock.eExclusive, "user at example.com", -1, exists=Lock.eResourceMayExist)
hdrs = request.generateRequestHeader()
self.assertFalse("If-None-Match:" in hdrs)
self.assertFalse("If-Match:" in hdrs)
-
+
+
def test_IfMatchHeader(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth0, Lock.eExclusive, "user at example.com", -1, exists=Lock.eResourceMustExist)
hdrs = request.generateRequestHeader()
self.assertFalse("If-None-Match:" in hdrs)
self.assertTrue("If-Match: *" in hdrs)
-
+
+
def test_IfNoneMatchHeader(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth0, Lock.eExclusive, "user at example.com", -1, exists=Lock.eResourceMustNotExist)
hdrs = request.generateRequestHeader()
self.assertTrue("If-None-Match: *" in hdrs)
self.assertFalse("If-Match:" in hdrs)
+
def test_Depth0Headers(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth0, Lock.eExclusive, "user at example.com", -1, exists=Lock.eResourceMustNotExist)
hdrs = request.generateRequestHeader()
@@ -64,8 +69,9 @@
self.assertFalse("Depth: 1" in hdrs)
self.assertFalse("Depth: infinity" in hdrs)
+
def test_Depth1Headers(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth1, Lock.eExclusive, "user at example.com", -1, exists=Lock.eResourceMustNotExist)
hdrs = request.generateRequestHeader()
@@ -73,8 +79,9 @@
self.assertTrue("Depth: 1" in hdrs)
self.assertFalse("Depth: infinity" in hdrs)
+
def test_DepthInfinityHeaders(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.DepthInfinity, Lock.eExclusive, "user at example.com", -1, exists=Lock.eResourceMustNotExist)
hdrs = request.generateRequestHeader()
@@ -83,10 +90,11 @@
self.assertTrue("Depth: infinity" in hdrs)
+
class TestRequestBody(unittest.TestCase):
-
+
def test_GenerateXML(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth0, Lock.eExclusive, "user at example.com", -1)
os = StringIO()
@@ -104,13 +112,17 @@
""".replace("\n", "\r\n")
)
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
def test_OneHeader(self):
-
+
server = Session("www.example.com")
request = Lock(server, "/", headers.Depth0, Lock.eExclusive, "user at example.com", -1)
request.getResponseHeaders().update({
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_move.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_move.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_move.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,16 +20,19 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Move(server, "/a", "http://www.example.com/b")
self.assertEqual(request.getMethod(), "MOVE")
+
+
class TestRequestHeaders(unittest.TestCase):
+
def test_NoSpecialHeaders(self):
-
+
server = Session("www.example.com")
request = Move(server, "/a", "http://www.example.com/b")
hdrs = request.generateRequestHeader()
@@ -37,9 +40,10 @@
self.assertFalse("If-Match:" in hdrs)
self.assertTrue("Overwrite: F" in hdrs)
self.assertTrue("Destination: http://www.example.com/b" in hdrs)
-
+
+
def test_IfMatchHeader(self):
-
+
server = Session("www.example.com")
request = Move(server, "/a", "http://www.example.com/b")
request.setData(etag="\"12345\"")
@@ -48,9 +52,10 @@
self.assertTrue("If-Match: \"12345\"" in hdrs)
self.assertTrue("Overwrite: F" in hdrs)
self.assertTrue("Destination: http://www.example.com/b" in hdrs)
-
+
+
def test_OverwriteHeader(self):
-
+
server = Session("www.example.com")
request = Move(server, "/a", "http://www.example.com/b", overwrite=True)
hdrs = request.generateRequestHeader()
@@ -59,14 +64,22 @@
self.assertTrue("Overwrite: T" in hdrs)
self.assertTrue("Destination: http://www.example.com/b" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_options.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_options.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_options.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,26 +20,34 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Options(server, "/")
self.assertEqual(request.getMethod(), "OPTIONS")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
pass
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
def test_OneHeader(self):
-
+
server = Session("www.example.com")
request = Options(server, "/")
request.getResponseHeaders().update({
@@ -50,9 +58,10 @@
self.assertTrue(request.isAllowed("PUT"))
self.assertTrue(request.isAllowed("OPTIONS"))
self.assertTrue(request.isAllowed("HEAD"))
-
+
+
def test_MultipleHeader(self):
-
+
server = Session("www.example.com")
request = Options(server, "/")
request.getResponseHeaders().update({
@@ -64,5 +73,7 @@
self.assertTrue(request.isAllowed("OPTIONS"))
self.assertTrue(request.isAllowed("HEAD"))
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_principalmatch.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_principalmatch.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_principalmatch.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,17 +21,19 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = PrincipalMatch(server, "/", ())
self.assertEqual(request.getMethod(), "REPORT")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
-
+
def test_Depth0Headers(self):
-
+
server = Session("www.example.com")
request = PrincipalMatch(server, "/", ())
hdrs = request.generateRequestHeader()
@@ -39,10 +41,12 @@
self.assertFalse("Depth: 1" in hdrs)
self.assertFalse("Depth: infinity" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
-
+
def test_GenerateXMLOneProperty(self):
-
+
server = Session("www.example.com")
request = PrincipalMatch(server, "/", (davxml.getetag,))
os = StringIO()
@@ -57,8 +61,9 @@
""".replace("\n", "\r\n")
)
+
def test_GenerateXMLMultipleProperties(self):
-
+
server = Session("www.example.com")
request = PrincipalMatch(server, "/", (davxml.getetag, davxml.displayname,))
os = StringIO()
@@ -74,11 +79,17 @@
""".replace("\n", "\r\n")
)
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfind.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfind.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfind.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -23,17 +23,19 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = PropFind(server, "/", headers.Depth0, (davxml.getetag, QName("http://example.com/ns/", "taggy")))
self.assertEqual(request.getMethod(), "PROPFIND")
+
+
class TestRequestHeaders(unittest.TestCase):
-
+
def test_Depth0Headers(self):
-
+
server = Session("www.example.com")
request = PropFind(server, "/", headers.Depth0, (davxml.getetag, QName("http://example.com/ns/", "taggy")))
hdrs = request.generateRequestHeader()
@@ -41,8 +43,9 @@
self.assertFalse("Depth: 1" in hdrs)
self.assertFalse("Depth: infinity" in hdrs)
+
def test_Depth1Headers(self):
-
+
server = Session("www.example.com")
request = PropFind(server, "/", headers.Depth1, (davxml.getetag, QName("http://example.com/ns/", "taggy")))
hdrs = request.generateRequestHeader()
@@ -50,8 +53,9 @@
self.assertTrue("Depth: 1" in hdrs)
self.assertFalse("Depth: infinity" in hdrs)
+
def test_DepthInfinityHeaders(self):
-
+
server = Session("www.example.com")
request = PropFind(server, "/", headers.DepthInfinity, (davxml.getetag, QName("http://example.com/ns/", "taggy")))
hdrs = request.generateRequestHeader()
@@ -59,10 +63,12 @@
self.assertFalse("Depth: 1" in hdrs)
self.assertTrue("Depth: infinity" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
-
+
def test_GenerateXML(self):
-
+
server = Session("www.example.com")
request = PropFind(server, "/", headers.Depth0, (davxml.getetag, QName("http://example.com/ns/", "taggy")))
os = StringIO()
@@ -77,11 +83,17 @@
""".replace("\n", "\r\n")
)
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfindparser.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfindparser.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propfindparser.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,24 +20,26 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def parseXML(self, x):
-
+
x = x.replace("\n", "\r\n")
-
+
# Parse the XML data
p = PropFindParser()
p.parse(XML(x))
return p
+
def checkResource(self, parser, resource, properties):
result = parser.getResults().get(resource, None)
self.assertTrue(result is not None)
for prop, value in properties:
self.assertEqual(result.getTextProperties().get(prop, None), value)
+
def test_SinglePropSingleResource(self):
-
+
parser = self.parseXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:multistatus xmlns:ns0="DAV:">
<ns0:response>
@@ -51,13 +53,14 @@
</ns0:response>
</ns0:multistatus>
""")
-
+
self.checkResource(parser, "/principals/users/a", (
(davxml.getetag, "12345",),
))
+
def test_MultiplePropsSingleResource(self):
-
+
parser = self.parseXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:multistatus xmlns:ns0="DAV:">
<ns0:response>
@@ -72,19 +75,20 @@
</ns0:response>
</ns0:multistatus>
""")
-
+
result = parser.getResults().get("/principals/users/a", None)
self.assertTrue(result is not None)
self.assertEqual(result.getTextProperties().get(davxml.getetag, None), "12345")
self.assertEqual(result.getTextProperties().get(davxml.displayname, None), "Name")
self.checkResource(parser, "/principals/users/a", (
- (davxml.getetag, "12345",),
+ (davxml.getetag, "12345",),
(davxml.displayname, "Name",),
))
+
def test_MultiplePropsSingleMultipleResources(self):
-
+
parser = self.parseXML("""<?xml version='1.0' encoding='utf-8'?>
<ns0:multistatus xmlns:ns0="DAV:">
<ns0:response>
@@ -111,12 +115,12 @@
""")
self.checkResource(parser, "/principals/users/a", (
- (davxml.getetag, "1",),
+ (davxml.getetag, "1",),
(davxml.displayname, "Name1",),
))
self.checkResource(parser, "/principals/users/b", (
- (davxml.getetag, "2",),
+ (davxml.getetag, "2",),
(davxml.displayname, "Name2",),
))
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propnames.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propnames.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_propnames.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,17 +21,19 @@
import unittest
class TestPropNames(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = PropNames(server, "/", headers.Depth0)
self.assertEqual(request.getMethod(), "PROPFIND")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
-
+
def test_Depth0Headers(self):
-
+
server = Session("www.example.com")
request = PropNames(server, "/", headers.Depth0)
hdrs = request.generateRequestHeader()
@@ -39,8 +41,9 @@
self.assertFalse("Depth: 1" in hdrs)
self.assertFalse("Depth: infinity" in hdrs)
+
def test_Depth1Headers(self):
-
+
server = Session("www.example.com")
request = PropNames(server, "/", headers.Depth1)
hdrs = request.generateRequestHeader()
@@ -48,8 +51,9 @@
self.assertTrue("Depth: 1" in hdrs)
self.assertFalse("Depth: infinity" in hdrs)
+
def test_DepthInfinityHeaders(self):
-
+
server = Session("www.example.com")
request = PropNames(server, "/", headers.DepthInfinity)
hdrs = request.generateRequestHeader()
@@ -57,10 +61,12 @@
self.assertFalse("Depth: 1" in hdrs)
self.assertTrue("Depth: infinity" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
-
+
def test_GenerateXML(self):
-
+
server = Session("www.example.com")
request = PropNames(server, "/", headers.Depth0)
os = StringIO()
@@ -72,11 +78,17 @@
""".replace("\n", "\r\n")
)
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_put.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_put.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_put.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,56 +20,69 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Put(server, "/")
self.assertEqual(request.getMethod(), "PUT")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
def test_NoSpecialHeaders(self):
-
+
server = Session("www.example.com")
request = Put(server, "/")
request.setData(None, None)
hdrs = request.generateRequestHeader()
self.assertFalse("If-None-Match:" in hdrs)
self.assertFalse("If-Match:" in hdrs)
-
+
+
def test_IfMatchHeader(self):
-
+
server = Session("www.example.com")
request = Put(server, "/")
request.setData(None, None, etag="\"12345\"")
hdrs = request.generateRequestHeader()
self.assertFalse("If-None-Match:" in hdrs)
self.assertTrue("If-Match: \"12345\"" in hdrs)
-
+
+
def test_IfNoneMatchHeader(self):
-
+
server = Session("www.example.com")
request = Put(server, "/")
request.setData(None, None, new_item=True)
hdrs = request.generateRequestHeader()
self.assertTrue("If-None-Match: *" in hdrs)
self.assertFalse("If-Match:" in hdrs)
-
+
+
def test_Bad(self):
-
+
server = Session("www.example.com")
request = Put(server, "/")
self.assertRaises(AssertionError, request.setData, None, None, **{"etag": "\"12345\"", "new_item": True})
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_report.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_report.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_report.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,24 +20,34 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Report(server, "/")
self.assertEqual(request.getMethod(), "REPORT")
-
+
+
+
class TestRequestHeaders(unittest.TestCase):
pass
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_template.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_template.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_template.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,17 +19,27 @@
class TestRequest(unittest.TestCase):
pass
+
+
class TestRequestHeaders(unittest.TestCase):
pass
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_unlock.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_unlock.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/tests/test_unlock.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -20,30 +20,40 @@
import unittest
class TestRequest(unittest.TestCase):
-
+
def test_Method(self):
-
+
server = Session("www.example.com")
request = Unlock(server, "/", "locked-up-in-chains")
self.assertEqual(request.getMethod(), "UNLOCK")
+
+
class TestRequestHeaders(unittest.TestCase):
def test_LockTokenHeaders(self):
-
+
server = Session("www.example.com")
request = Unlock(server, "/", "locked-up-in-chains")
hdrs = request.generateRequestHeader()
self.assertTrue("Lock-Token: <locked-up-in-chains>" in hdrs)
+
+
class TestRequestBody(unittest.TestCase):
pass
+
+
class TestResponse(unittest.TestCase):
pass
+
+
class TestResponseHeaders(unittest.TestCase):
pass
+
+
class TestResponseBody(unittest.TestCase):
pass
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/unlock.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/unlock.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/unlock.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -21,14 +21,15 @@
class Unlock(RequestResponse):
def __init__(self, session, url, lock_token):
-
+
super(Unlock, self).__init__(session, methods.UNLOCK, url)
self.lock_token = lock_token
+
def addHeaders(self, hdrs):
# Do default
super(Unlock, self).addHeaders(hdrs)
-
+
# Add lock-token header
hdrs.append((headers.LockToken, "<%s>" % (self.lock_token,)))
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/xmlresponseparser.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/xmlresponseparser.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/webdav/xmlresponseparser.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -22,10 +22,12 @@
# XML parse the data
self.parse(XML(data))
+
def parseFile(self, fpath):
fp = open(fpath, "r")
self.parse(XML(fp.read()))
fp.close()
+
def parse(self, root_node):
raise NotImplementedError
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/ui/WebDAVBrowser.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/ui/WebDAVBrowser.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/ui/WebDAVBrowser.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -18,7 +18,9 @@
Code based on PyObjC examples included with Apple Developer tools.
"""
-import Foundation, AppKit, WebKit #@UnusedImport
+import Foundation #@UnusedImport
+import AppKit #@UnusedImport
+import WebKit #@UnusedImport
from AppKit import * #@UnusedWildImport
from AppKit import NSApplication #@UnresolvedImport
@@ -77,18 +79,18 @@
bounds = anItemContent.bounds()
minSize = (bounds[1][0], bounds[1][1])
maxSize = (bounds[1][0], bounds[1][1])
- toolbarItem.setMinSize_( minSize )
- toolbarItem.setMaxSize_( maxSize )
+ toolbarItem.setMinSize_(minSize)
+ toolbarItem.setMaxSize_(maxSize)
if aMenu:
menuItem = NSMenuItem.alloc().init()
menuItem.setSubmenu_(aMenu)
- menuItem.setTitle_( aMenu.title() )
+ menuItem.setTitle_(aMenu.title())
toolbarItem.setMenuFormRepresentation_(menuItem)
aController._toolbarItems[anIdentifier] = toolbarItem
-WRAPPED={}
+WRAPPED = {}
class Wrapper(NSObject):
"""
NSOutlineView doesn't retain values, which means we cannot use normal
@@ -98,24 +100,32 @@
self.value = value
return self
+
def __str__(self):
return '<Wrapper for %s>' % self.value
+
def description(self):
return str(self)
+
+
def wrap_object(obj):
- if WRAPPED.has_key(obj):
+ if obj in WRAPPED:
return WRAPPED[obj]
else:
WRAPPED[obj] = Wrapper.alloc().init_(obj)
return WRAPPED[obj]
+
+
def unwrap_object(obj):
if obj is None:
return obj
return obj.value
+
+
class WebDAVBrowserDelegate(NibClassBuilder.AutoBaseClass):
"""
Class defined in NIB file. This acts as the delegate and responder
@@ -163,10 +173,10 @@
dataView = objc.IBOutlet()
BROWSERVIEW_COLUMNS = 0
- BROWSERVIEW_LIST = 1
+ BROWSERVIEW_LIST = 1
DATAVIEW_PROPERTIES = 0
- DATAVIEW_DATA = 1
+ DATAVIEW_DATA = 1
#DATAVIEW_DELEGATES = 2
#DATAVIEW_ACLS = 3
@@ -207,10 +217,10 @@
container.addSubview_(self.dataView)
self.currentDataView = None
self.setDataView(self.DATAVIEW_PROPERTIES)
- self.text.setString_("")
-
+ self.text.setString_("")
+
self.pathLabel.setStringValue_("No server specified")
-
+
# Get preferences
lastServer = NSUserDefaults.standardUserDefaults().stringForKey_("LastServer")
if lastServer and len(lastServer):
@@ -224,6 +234,7 @@
if lastUser and len(lastUser):
self.userText.setStringValue_(lastUser)
+
def createToolbar(self):
"""
Create the toolbar for our app.
@@ -237,6 +248,7 @@
self.window.setToolbar_(toolbar)
+
def createToolbarItems(self):
"""
Create the toolbar item and define the default and allowed set.
@@ -277,18 +289,21 @@
NSToolbarCustomizeToolbarItemIdentifier,
]
+
def toolbarDefaultItemIdentifiers_(self, anIdentifier):
"""
Return the default set of toolbar items.
"""
return self._toolbarDefaultItemIdentifiers
+
def toolbarAllowedItemIdentifiers_(self, anIdentifier):
"""
Return the allowed set of toolbar items.
"""
return self._toolbarAllowedItemIdentifiers
+
def toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_(self,
toolbar,
itemIdentifier, flag):
@@ -302,24 +317,25 @@
newItem = NSToolbarItem.alloc().initWithItemIdentifier_(itemIdentifier)
item = self._toolbarItems[itemIdentifier]
- newItem.setLabel_( item.label() )
- newItem.setPaletteLabel_( item.paletteLabel() )
+ newItem.setLabel_(item.label())
+ newItem.setPaletteLabel_(item.paletteLabel())
if item.view():
- newItem.setView_( item.view() )
+ newItem.setView_(item.view())
else:
- newItem.setImage_( item.image() )
+ newItem.setImage_(item.image())
- newItem.setToolTip_( item.toolTip() )
- newItem.setTarget_( item.target() )
- newItem.setAction_( item.action() )
- newItem.setMenuFormRepresentation_( item.menuFormRepresentation() )
+ newItem.setToolTip_(item.toolTip())
+ newItem.setTarget_(item.target())
+ newItem.setAction_(item.action())
+ newItem.setMenuFormRepresentation_(item.menuFormRepresentation())
if newItem.view():
- newItem.setMinSize_( item.minSize() )
- newItem.setMaxSize_( item.maxSize() )
+ newItem.setMinSize_(item.minSize())
+ newItem.setMaxSize_(item.maxSize())
return newItem
+
def setBrowserView(self, view):
"""
Change the browser view pane to the specified list type.
@@ -336,7 +352,8 @@
self.currentBrowserView.setHidden_(NO)
self.browserview = view
self.refreshView()
-
+
+
@objc.IBAction
def changeBrowserView_(self, sender):
"""
@@ -344,6 +361,7 @@
"""
self.setBrowserView(sender.selectedSegment())
+
def setDataView(self, view):
"""
Change the data view pane to the specified type.
@@ -360,14 +378,16 @@
self.currentDataView.setHidden_(NO)
self.dataview = view
self.refreshView()
-
+
+
@objc.IBAction
def changeDataView_(self, sender):
"""
User clicked a view toolbar button.
"""
self.setDataView(sender.selectedSegment())
-
+
+
@objc.IBAction
def resetServer_(self, sender):
"""
@@ -378,21 +398,23 @@
self.window,
None, None, 0
)
-
+
+
def refreshData_(self, sender):
"""
Force a refresh of the data for the current selected resource.
"""
if self.selectedResource:
self.selectedResource.clear()
-
+
self.progress.startAnimation_(self)
resources = self.selectedResource.listChildren()
self.columns[-1] = resources
self.progress.stopAnimation_(self)
-
+
self.refreshView()
+
def refreshView(self):
"""
Refresh the actual data view for the selected resource.
@@ -410,12 +432,13 @@
self.webView.mainFrame().loadHTMLString_baseURL_(self.selectedData, url)
self.progress.stopAnimation_(self)
+
@objc.IBAction
def startupOKAction_(self, btn):
"""
User clicked OK in the server setup sheet.
"""
-
+
# Create the actual session.
server = self.serverText.stringValue()
path = self.pathText.stringValue()
@@ -427,7 +450,7 @@
NSUserDefaults.standardUserDefaults().setObject_forKey_(server, "LastServer")
NSUserDefaults.standardUserDefaults().setObject_forKey_(path, "LastPath")
NSUserDefaults.standardUserDefaults().setObject_forKey_(user, "LastUser")
-
+
# List the root resource.
self.progress.startAnimation_(self)
resources = self.session.getRoot().listChildren()
@@ -437,11 +460,12 @@
# Done with the sheet.
self.startupSheet.close()
NSApplication.sharedApplication().endSheet_(self.startupSheet)
-
+
# Force reload of browser pane views.
self.browser.loadColumnZero()
self.list.reloadItem_(None)
+
@objc.IBAction
def startupCancelAction_(self, btn):
"""
@@ -450,12 +474,13 @@
self.startupSheet.close()
NSApplication.sharedApplication().endSheet_(self.startupSheet)
+
@objc.IBAction
def browserAction_(self, browser):
"""
Something changed in the column browser.
"""
-
+
# Update current path.
self.pathLabel.setStringValue_((self.session.path if len(self.session.path) > 1 else "") + browser.path())
@@ -471,9 +496,10 @@
row = self.browser.selectedRowInColumn_(col)
if row >= 0:
self.selectedResource = self.columns[col][row]
-
+
self.refreshView()
+
def browser_willDisplayCell_atRow_column_(self, browser, cell, row, col):
"""
Delegate method to set the actual stuff displayed in a column view row.
@@ -483,6 +509,7 @@
cell.setStringValue_(self.columns[col][row].getName())
cell.setImage_(self.fileImage if isLeaf else self.directoryImage)
+
def browser_numberOfRowsInColumn_(self, browser, col):
"""
Delegate method that returns the number of rows in a column view column.
@@ -497,11 +524,12 @@
self.columns.append(resources)
return len(resources)
+
def outlineViewSelectionDidChange_(self, notification):
"""
Delegate method called when the selection in the outline view changes.
"""
-
+
# Get the new selected resource and refresh the data view.
row = self.list.selectedRow()
if row == -1:
@@ -510,9 +538,10 @@
else:
self.selectedResource = unwrap_object(self.list.itemAtRow_(row))
self.pathLabel.setStringValue_(self.selectedResource.getPath())
-
+
self.refreshView()
+
def outlineView_numberOfChildrenOfItem_(self, outlineView, item):
"""
Delegate method to return the number of children of an item in the outline view.
@@ -527,7 +556,8 @@
resources = resource.listChildren()
self.progress.stopAnimation_(self)
return len(resources)
-
+
+
def outlineView_isItemExpandable_(self, outlineView, item):
"""
Delegate method to return the whether an item in the outline view is expandable.
@@ -538,6 +568,7 @@
resource = unwrap_object(item)
return YES if resource.isCollection() else NO
+
def outlineView_child_ofItem_(self, outlineView, index, item):
"""
Delegate method to return the item associated with a row in the outline view.
@@ -551,6 +582,7 @@
self.progress.stopAnimation_(self)
return wrap_object(resources[index])
+
def outlineView_objectValueForTableColumn_byItem_(self, outlineView, tableColumn, item):
"""
Delegate method to return the data displayed in the outline view.
@@ -565,12 +597,13 @@
"Modified": resource.getLastMod(),
}[tableColumn.identifier()]
+
@objc.IBAction
def tableAction_(self, table):
"""
Called when the selection in the properties list changes.
"""
-
+
# Get the selected property and display its value.
row = self.table.selectedRow()
if row >= 0:
@@ -586,8 +619,9 @@
text = self.propValueToText(value)
else:
text = ""
- self.text.setString_(text)
+ self.text.setString_(text)
+
def numberOfRowsInTableView_(self, tableView):
"""
Delegate method to return the number of rows in the list.
@@ -598,18 +632,21 @@
return 0
return len(self.selectedDetails)
+
def tableView_objectValueForTableColumn_row_(self, tableView, col, row):
"""
Delegate method to return the text for a list cell.
"""
return str(self.selectedDetails[row][0])
+
def tableView_shouldEditTableColumn_row_(self, tableView, col, row):
"""
Delegate method to indicate whether a cell can be edited.
"""
return 0
+
def propValueToText(self, value):
"""
Do a sensible print of a property value taking type into account.
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/ui/resource.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/ui/resource.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/ui/resource.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2007-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2007-2012 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -23,9 +23,9 @@
Maintains data for a WebDAV resource, including list of properties,
child resources and actual data.
"""
-
+
def __init__(self, session, path, lastmod="", size="", type=""):
-
+
self.session = session
self.path = path.rstrip("/")
self.iscollection = path.endswith("/")
@@ -36,24 +36,31 @@
self.details = None
self.data = None
+
def getPath(self):
return self.path
+
def getName(self):
return os.path.basename(self.path)
+
def getLastMod(self):
return self.lastmod
+
def getSize(self):
return self.size
+
def getType(self):
return self.type
+
def isCollection(self):
return self.iscollection
+
def findPath(self, path=None, elements=None):
if path:
elements = path.lstrip("/").rstrip("/").split("/")
@@ -67,6 +74,7 @@
return child
return None
+
def findChild(self, name):
if self.children:
for child in self.children:
@@ -74,9 +82,10 @@
return child
return None
+
def listChildren(self):
if self.children is None:
- resource = URL(url=self.path+"/")
+ resource = URL(url=self.path + "/")
props = (
davxml.resourcetype,
davxml.getlastmodified,
@@ -95,8 +104,9 @@
) for rurl in items if rurl != self.path + "/"]
return self.children
+
def getDetails(self):
- resource = URL(url=self.path+"/")
+ resource = URL(url=self.path + "/")
props = (davxml.resourcetype,)
props += (davxml.getcontentlength, davxml.getlastmodified,)
props, _ignore_bad = self.session.account.session.getProperties(resource, props)
@@ -106,9 +116,10 @@
modtime = props.get(davxml.getlastmodified, "-")
return ["Size: %s" % (size,), "Modtime: %s" % (modtime,)]
+
def getAllDetails(self):
if self.details is None:
- resource = URL(url=self.path+"/")
+ resource = URL(url=self.path + "/")
props = self.session.account.session.getPropertyNames(resource)
results, _ignore_bad = self.session.account.session.getProperties(resource, props)
sorted = results.keys()
@@ -116,18 +127,21 @@
self.details = [(key, results[key],) for key in sorted]
return self.details
+
def getData(self):
if self.data is None:
- resource = URL(url=self.path+"/")
+ resource = URL(url=self.path + "/")
self.data, _ignore_etag = self.session.account.session.readData(resource)
return self.data
+
def getDataAsHTML(self):
data = self.getData()
if not self.type.startswith("text/html"):
data = "<HTML><BODY>%s</BODY></HTML>" % (data.replace("\r\n", "\n").replace("\r", "\n").replace("\n", "<br>\n"),)
return data
+
def clear(self):
self.children = None
self.details = None
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/ui/session.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/ui/session.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/ui/session.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2007-2010 Apple Inc. All rights reserved.
+# Copyright (c) 2007-2012 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -21,19 +21,20 @@
"""
Maintains the basic information for a session and the root resource.
"""
-
+
def __init__(self, server, path, user, pswd, logging):
-
+
self.server = server
self.path = path
self.user = user
self.pswd = pswd
-
+
# Create the account
ssl = server.startswith("https://")
server = server[8:] if ssl else server[7:]
paths = "/principals/users/%s/" % (self.user,)
self.account = CalDAVAccount(server, ssl=ssl, user=self.user, pswd=self.pswd, root=paths, principal=paths, logging=logging)
-
+
+
def getRoot(self):
return Resource(self, self.path)
Modified: CalDAVClientLibrary/trunk/setup.py
===================================================================
--- CalDAVClientLibrary/trunk/setup.py 2012-09-28 00:11:01 UTC (rev 9878)
+++ CalDAVClientLibrary/trunk/setup.py 2012-09-28 02:48:34 UTC (rev 9879)
@@ -19,14 +19,14 @@
Usage:
python setup.py py2app
-"""
+"""
import os
from distutils.core import setup
data_files = []
package_data = {}
try:
- import py2app
+ import py2app #@UnusedImport
except ImportError:
pass
else:
@@ -47,7 +47,7 @@
data_files=data_files,
package_data=package_data,
scripts=['runshell.py', 'runadmin.py'],
- options=dict(py2app=dict(plist=plist, includes=["urllib", "sha", "md5",],
+ options=dict(py2app=dict(plist=plist, includes=["urllib", "sha", "md5", ],
packages=["caldavclientlibrary/client",
"caldavclientlibrary/protocol",
"caldavclientlibrary/ui",
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120927/a6c51d64/attachment-0001.html>
More information about the calendarserver-changes
mailing list