[CalendarServer-changes] [9945] CalDAVClientLibrary/trunk/caldavclientlibrary
source_changes at macosforge.org
source_changes at macosforge.org
Tue Oct 16 13:05:47 PDT 2012
Revision: 9945
http://trac.calendarserver.org//changeset/9945
Author: cdaboo at apple.com
Date: 2012-10-16 13:05:47 -0700 (Tue, 16 Oct 2012)
Log Message:
-----------
Add calendar-query command to do time-range (possibly expanded) queries.
Modified Paths:
--------------
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/__init__.py
CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py
CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py
Added Paths:
-----------
CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/query.py
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/__init__.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/__init__.py 2012-10-16 16:12:08 UTC (rev 9944)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/__init__.py 2012-10-16 20:05:47 UTC (rev 9945)
@@ -33,6 +33,7 @@
"props",
"proxies",
"put",
+ "query",
"quit",
"quota",
"rm",
Added: CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/query.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/query.py (rev 0)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/browser/commands/query.py 2012-10-16 20:05:47 UTC (rev 9945)
@@ -0,0 +1,110 @@
+##
+# Copyright (c) 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.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from caldavclientlibrary.browser.command import Command
+from caldavclientlibrary.browser.command import WrongOptions
+from caldavclientlibrary.protocol.url import URL
+from caldavclientlibrary.protocol.webdav.definitions import davxml
+import getopt
+import os
+import shlex
+import time
+from caldavclientlibrary.protocol.caldav.definitions import caldavxml
+
+class Cmd(Command):
+
+ def __init__(self):
+ super(Command, self).__init__()
+ self.cmds = ("query",)
+
+
+ def execute(self, name, options):
+
+ timerange = False
+ start = None
+ end = None
+ expand = False
+ data = False
+
+ opts, args = getopt.getopt(shlex.split(options), 'ts:e:xd')
+
+ for name, value in opts:
+
+ if name == "-t":
+ timerange = True
+ elif name == "-s":
+ start = value
+ elif name == "-e":
+ start = value
+ elif name == "-x":
+ expand = True
+ elif name == "-d":
+ data = 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)
+ raise WrongOptions
+
+ path = args[0] if len(args) else self.shell.wd
+ if not path.startswith("/"):
+ path = os.path.join(self.shell.wd, path)
+ if not path.endswith("/"):
+ path += "/"
+
+ resource = URL(url=path)
+
+ now = time.time()
+ if timerange and start is None:
+ now_tm = time.gmtime(now)
+ start = "%04d%02d%02dT000000Z" % (now_tm.tm_year, now_tm.tm_mon, now_tm.tm_mday,)
+ if timerange and end is None:
+ tomorrow_tm = time.gmtime(now + 24 * 60 * 60)
+ end = "%04d%02d%02dT000000Z" % (tomorrow_tm.tm_year, tomorrow_tm.tm_mon, tomorrow_tm.tm_mday,)
+
+ props = (davxml.getetag,)
+ if data and not expand:
+ props += (caldavxml.calendar_data,)
+ results = self.shell.account.session.queryCollection(resource, timerange, start, end, expand, props=props)
+ for href in results:
+ print href
+
+ 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.
+
+Options:
+-t do time-range query
+-s start time [DEFAULT today]
+-e end time [DEFAULT tomorrow]
+-x expand components
+-d return data
+""" % (name,)
+
+
+ def helpDescription(self):
+ return "Query a calendar for data."
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py 2012-10-16 16:12:08 UTC (rev 9944)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/client/clientsession.py 2012-10-16 20:05:47 UTC (rev 9945)
@@ -21,6 +21,7 @@
from caldavclientlibrary.protocol.http.authentication.basic import Basic
from caldavclientlibrary.protocol.http.authentication.digest import Digest
from caldavclientlibrary.protocol.webdav.synccollection import SyncCollection
+from caldavclientlibrary.protocol.caldav.query import QueryVEVENTTimeRange
try:
from caldavclientlibrary.protocol.http.authentication.gssapi import Kerberos
except ImportError:
@@ -560,6 +561,42 @@
return (newsynctoken, changed, removed, other,)
+ def queryCollection(self, rurl, timerange, start, end, expand, props=()):
+
+ assert(isinstance(rurl, URL))
+
+ hrefs = set()
+
+ # Create CalDAV query REPORT
+ if timerange:
+ request = QueryVEVENTTimeRange(self, rurl.relativeURL(), start, end, expand, props=props)
+ else:
+ raise NotImplementedError
+ 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)
+ hrefs.add(name)
+
+ else:
+ self.handleHTTPError(request)
+
+ return hrefs
+
+
def deleteResource(self, rurl):
assert(isinstance(rurl, URL))
Modified: CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py
===================================================================
--- CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py 2012-10-16 16:12:08 UTC (rev 9944)
+++ CalDAVClientLibrary/trunk/caldavclientlibrary/protocol/caldav/query.py 2012-10-16 20:05:47 UTC (rev 9945)
@@ -52,6 +52,21 @@
# <CalDAV:calendar-query> element
query = Element(caldavxml.calendar_query)
+ self.addProps(query)
+
+ # 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 addProps(self, query):
+ """
+ Add properties to the query XML.
+ """
+
if self.props:
# <DAV:prop> element
prop = SubElement(query, davxml.prop)
@@ -61,14 +76,7 @@
# 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.
@@ -80,13 +88,35 @@
class QueryVEVENTTimeRange(Query):
- def __init__(self, session, url, trstart, trend, props=()):
+ def __init__(self, session, url, trstart, trend, expand, props=()):
self.trstart = trstart
self.trend = trend
+ self.expand = expand
+
super(QueryVEVENTTimeRange, self).__init__(session, url, props)
+ def addProps(self, query):
+ """
+ Add properties to the query XML.
+ """
+
+ if self.props or self.expand:
+ # <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 do expand
+ if self.expand:
+ cdata = SubElement(prop, caldavxml.calendar_data)
+ SubElement(cdata, caldavxml.expand, {"start": self.trstart, "end": self.trend})
+
+
def addFilterElement(self, query):
"""
Add a CALDAV:filter element to the specified CALDAV:calendar-query element.
@@ -102,7 +132,7 @@
# </CALDAV:time-range>
# </CALDAV:component-filter>
# </CALDAV:component-filter>
- # </CalDAV:calendar-query>
+ # </CalDAV:filter>
filter = SubElement(query, caldavxml.filter)
calcompfilter = SubElement(filter, caldavxml.comp_filter, {"name": "VCALENDAR"})
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121016/93c17993/attachment-0001.html>
More information about the calendarserver-changes
mailing list