calcurse-caldav: Use calendar-multiget to obtain ETag

Some CalDAV servers do not support calendar-query with a UID filter. Use
a calendar-multiget request to obtain the ETag of submitted objects
instead.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
Lukas Fleischer 2016-01-26 17:33:49 +01:00
parent 304ff81836
commit 3dbfc7c1f5

View File

@ -118,19 +118,21 @@ def remote_query(cmd, path, additional_headers, body):
return (headers, body) return (headers, body)
def get_hrefmap(conn, uid=None): def get_hrefmap(conn, hrefs=[]):
if uid: if len(hrefs) > 0:
propfilter = ('<C:prop-filter name="UID">' + body = '<?xml version="1.0" encoding="utf-8" ?>' +\
'<C:text-match collation="i;octet" >%s</C:text-match>' + '<C:calendar-multiget xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">' +\
'</C:prop-filter>') % (uid) '<D:prop><D:getetag /></D:prop>'
for href in hrefs:
body += '<D:href>{}</D:href>'.format(href)
body += '</C:calendar-multiget>'
else: else:
propfilter = '' body = '<?xml version="1.0" encoding="utf-8" ?>' +\
'<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">' +\
'<D:prop><D:getetag /></D:prop><C:filter>' +\
'<C:comp-filter name="VCALENDAR"></C:comp-filter>' +\
'</C:filter></C:calendar-query>'
body = '<?xml version="1.0" encoding="utf-8" ?>' +\
'<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">' +\
'<D:prop><D:getetag /></D:prop><C:filter>' +\
'<C:comp-filter name="VCALENDAR">' + propfilter + '</C:comp-filter>' +\
'</C:filter></C:calendar-query>'
headers, body = remote_query("REPORT", path, {}, body) headers, body = remote_query("REPORT", path, {}, body)
if not headers: if not headers:
return {} return {}
@ -186,8 +188,9 @@ def save_syncdb(fn, syncdb):
print("%s %s" % (etag, objhash), file=f) print("%s %s" % (etag, objhash), file=f)
def push_object(conn, objhash): def push_object(conn, objhash):
href = path + objhash + ".ics"
body = calcurse_export(objhash) body = calcurse_export(objhash)
headers, body = remote_query("PUT", path + objhash + ".ics", {}, body) headers, body = remote_query("PUT", href, {}, body)
if not headers: if not headers:
return None return None
@ -197,9 +200,9 @@ def push_object(conn, objhash):
if 'etag' in headerdict: if 'etag' in headerdict:
etag = headerdict['etag'] etag = headerdict['etag']
while not etag: while not etag:
hrefmap = get_hrefmap(conn, objhash) hrefmap = get_hrefmap(conn, [href])
if len(hrefmap.keys()) > 0: if len(hrefmap.keys()) > 0:
etag = hrefmap.keys()[0] etag = next(iter(hrefmap.keys()))
etag = etag.strip('"') etag = etag.strip('"')
return etag return etag