From c7387a17f02e730934f93fd26174edd2799b5d35 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 26 Mar 2014 17:56:21 +0100 Subject: [PATCH] Share code between dav and http Adds many features to http --- vdirsyncer/storage/dav/base.py | 33 +++----------------- vdirsyncer/storage/http.py | 55 ++++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/vdirsyncer/storage/dav/base.py b/vdirsyncer/storage/dav/base.py index 938af81..385da9e 100644 --- a/vdirsyncer/storage/dav/base.py +++ b/vdirsyncer/storage/dav/base.py @@ -7,7 +7,8 @@ :license: MIT, see LICENSE for more details. ''' -from ..base import Storage, Item +from ..base import Item +from ..http import HttpStorageBase import vdirsyncer.exceptions as exceptions import vdirsyncer.log as log import requests @@ -18,7 +19,7 @@ from lxml import etree dav_logger = log.get('storage.dav') -class DavStorage(Storage): +class DavStorage(HttpStorageBase): # the file extension of items. Useful for testing against radicale. fileext = None @@ -38,8 +39,7 @@ class DavStorage(Storage): _session = None _repr_attributes = ('url', 'username') - def __init__(self, url, username='', password='', collection=None, - verify=True, auth='basic', useragent='vdirsyncer', **kwargs): + def __init__(self, **kwargs): ''' :param url: Base URL or an URL to a collection. Autodiscovery should be done via :py:meth:`DavStorage.discover`. @@ -52,25 +52,6 @@ class DavStorage(Storage): ''' super(DavStorage, self).__init__(**kwargs) - self._settings = {'verify': verify} - if auth == 'basic': - self._settings['auth'] = (username, password) - elif auth == 'digest': - from requests.auth import HTTPDigestAuth - self._settings['auth'] = HTTPDigestAuth(username, password) - else: - raise ValueError('Unknown authentication method: {}'.format(auth)) - - self.username, self.password = username, password - self.useragent = useragent - - url = url.rstrip('/') + '/' - if collection is not None: - url = urlparse.urljoin(url, collection) - self.url = url.rstrip('/') + '/' - self.parsed_url = urlparse.urlparse(self.url) - self.collection = collection - headers = self._default_headers() headers['Depth'] = 1 response = self._request( @@ -113,12 +94,6 @@ class DavStorage(Storage): def _get_href(self, uid): return self._normalize_href(super(DavStorage, self)._get_href(uid)) - def _default_headers(self): - return { - 'User-Agent': self.useragent, - 'Content-Type': 'application/xml; charset=UTF-8' - } - def _request(self, method, path, data=None, headers=None): path = path or self.parsed_url.path assert path.startswith(self.parsed_url.path) diff --git a/vdirsyncer/storage/http.py b/vdirsyncer/storage/http.py index 874fd69..70f5cf4 100644 --- a/vdirsyncer/storage/http.py +++ b/vdirsyncer/storage/http.py @@ -9,8 +9,10 @@ ''' import requests +import urlparse import hashlib from .base import Storage, Item +from vdirsyncer.utils import expand_path def split_collection(text): @@ -43,17 +45,58 @@ def split_collection(text): item.append(line) -class HttpStorage(Storage): - _repr_attributes = ('url',) +def prepare_auth(auth, username, password): + if (username and password) or auth == 'basic': + return (username, password) + elif auth == 'digest': + from requests.auth import HTTPDigestAuth + return HTTPDigestAuth(username, password) + elif auth is None: + return None + else: + raise ValueError('Unknown authentication method: {}'.format(auth)) + + +def prepare_verify(verify): + if isinstance(verify, bool): + return verify + return expand_path(verify) + + +class HttpStorageBase(Storage): + _repr_attributes = ('username', 'url') _items = None - def __init__(self, url, **kwargs): - super(HttpStorage, self).__init__(**kwargs) - self.url = url + def __init__(self, url, username='', password='', collection=None, + verify=True, auth=None, useragent='vdirsyncer', **kwargs): + super(HttpStorageBase, self).__init__(**kwargs) + + self._settings = { + 'verify': prepare_verify(verify), + 'auth': prepare_auth(auth, username, password) + } + self.username, self.password = username, password + self.useragent = useragent + + url = url.rstrip('/') + '/' + if collection is not None: + url = urlparse.urljoin(url, collection) + self.url = url.rstrip('/') + '/' + self.parsed_url = urlparse.urlparse(self.url) + self.collection = collection + + def _default_headers(self): + return { + 'User-Agent': self.useragent, + 'Content-Type': 'application/xml; charset=UTF-8' + } + + +class HttpStorage(HttpStorageBase): def list(self): if self._items is None: - r = requests.get(self.url) + r = requests.get(self.url, **self._settings) r.raise_on_status() self._items = {} for item in split_collection(r.text):