From ded1feb05a7e6749661b1628fe01464e52430397 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 27 Feb 2017 16:06:28 +0100 Subject: [PATCH] Work around Google Contacts discovery bug (#564) * Work around Google Contacts discovery bug * fixup * changelog --- CHANGELOG.rst | 1 + vdirsyncer/storage/dav.py | 25 ++++++++++++++++++------- vdirsyncer/storage/google.py | 4 ++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f64f3a2..eefd50f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,7 @@ Version 0.15 - Deprecated syntax for configuration values is now completely rejected. All values now have to be valid JSON. - A few UX improvements for Google storages, see :gh:`549` and :gh:`552`. +- Fix collection discovery for :storage:`google_contacts`, see :gh:`564`. Version 0.14.1 ============== diff --git a/vdirsyncer/storage/dav.py b/vdirsyncer/storage/dav.py index 5c9cb1a..15fbb7f 100644 --- a/vdirsyncer/storage/dav.py +++ b/vdirsyncer/storage/dav.py @@ -201,6 +201,23 @@ class Discover(object): dav_logger.debug('Given URL is not a homeset URL') return self._find_collections_impl(self.find_home()) + def _check_collection_resource_type(self, response): + if self._resourcetype is None: + return True + + props = _merge_xml(response.findall( + '{DAV:}propstat/{DAV:}prop' + )) + if not props: + dav_logger.debug('Skipping, missing : %s', response) + return False + if props.find('{DAV:}resourcetype/' + self._resourcetype) \ + is None: + dav_logger.debug('Skipping, not of resource type %s: %s', + self._resourcetype, response) + return False + return True + def _find_collections_impl(self, url): headers = self.session.get_default_headers() headers['Depth'] = '1' @@ -209,13 +226,7 @@ class Discover(object): root = _parse_xml(r.content) done = set() for response in root.findall('{DAV:}response'): - props = _merge_xml(response.findall('{DAV:}propstat/{DAV:}prop')) - if not props: - dav_logger.debug('Skipping, missing : %s', response) - continue - if props.find('{DAV:}resourcetype/' + self._resourcetype) is None: - dav_logger.debug('Skipping, not of resource type %s: %s', - self._resourcetype, response) + if not self._check_collection_resource_type(response): continue href = response.find('{DAV:}href') diff --git a/vdirsyncer/storage/google.py b/vdirsyncer/storage/google.py index 4b6088b..951b68f 100644 --- a/vdirsyncer/storage/google.py +++ b/vdirsyncer/storage/google.py @@ -164,6 +164,10 @@ class GoogleContactsStorage(dav.CardDAVStorage): url = 'https://www.googleapis.com/.well-known/carddav' scope = ['https://www.googleapis.com/auth/carddav'] + class discovery_class(dav.CardDAVStorage.discovery_class): + # Google CardDAV doesn't return any resourcetype prop. + _resourcetype = None + storage_name = 'google_contacts' def __init__(self, token_file, client_id, client_secret, **kwargs):