diff --git a/tests/storage/test_http.py b/tests/storage/test_http.py index 3737a00..d7ce961 100644 --- a/tests/storage/test_http.py +++ b/tests/storage/test_http.py @@ -16,7 +16,7 @@ from requests import Response class TestHttpStorage(object): def test_list(self, monkeypatch): - collection_url = 'http://127.0.0.1/calendar/collection/' + collection_url = 'http://127.0.0.1/calendar/collection.ics' items = [ dedent(b''' @@ -44,7 +44,8 @@ class TestHttpStorage(object): '\n'.join([b'BEGIN:VCALENDAR'] + items + [b'END:VCALENDAR']) ] * 2 - def get(*a, **kw): + def get(url, *a, **kw): + assert url == collection_url r = Response() r.status_code = 200 assert responses diff --git a/vdirsyncer/storage/dav.py b/vdirsyncer/storage/dav.py index 9367044..0c26162 100644 --- a/vdirsyncer/storage/dav.py +++ b/vdirsyncer/storage/dav.py @@ -7,8 +7,8 @@ :license: MIT, see LICENSE for more details. ''' -from .base import Item -from .http import HttpStorageBase +from .base import Storage, Item +from .http import prepare_auth, prepare_verify, USERAGENT import vdirsyncer.exceptions as exceptions import vdirsyncer.log as log import requests @@ -23,7 +23,7 @@ CALDAV_DT_FORMAT = '%Y%m%dT%H%M%SZ' CONFIG_DT_FORMAT = '%Y-%m-%d' -class DavStorage(HttpStorageBase): +class DavStorage(Storage): # the file extension of items. Useful for testing against radicale. fileext = None @@ -41,11 +41,40 @@ class DavStorage(HttpStorageBase): leif_class = None _session = None - _repr_attributes = ('url', 'username') + _repr_attributes = ('username', 'url') + + def __init__(self, url, username='', password='', collection=None, + verify=True, auth=None, useragent=USERAGENT, **kwargs): + ''' + :param url: Base URL or an URL to a collection. Autodiscovery should be + done via :py:meth:`DavStorage.discover`. + :param username: Username for authentication. + :param password: Password for authentication. + :param verify: Verify SSL certificate, default True. + :param auth: Authentication method, from {'basic', 'digest'}, default + 'basic'. + :param useragent: Default 'vdirsyncer'. + ''' - def __init__(self, **kwargs): super(DavStorage, self).__init__(**kwargs) + if username and not password: + password = get_password(username, url) + + 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 + headers = self._default_headers() headers['Depth'] = 1 response = self._request( @@ -57,6 +86,12 @@ class DavStorage(HttpStorageBase): if self.dav_header not in response.headers.get('DAV', ''): raise exceptions.StorageError('URL is not a collection') + def _default_headers(self): + return { + 'User-Agent': self.useragent, + 'Content-Type': 'application/xml; charset=UTF-8' + } + @classmethod def discover(cls, url, **kwargs): if kwargs.pop('collection', None) is not None: diff --git a/vdirsyncer/storage/http.py b/vdirsyncer/storage/http.py index af30a3e..b9e5852 100644 --- a/vdirsyncer/storage/http.py +++ b/vdirsyncer/storage/http.py @@ -14,6 +14,8 @@ import hashlib from .base import Storage, Item from vdirsyncer.utils import expand_path, get_password +USERAGENT = 'vdirsyncer' + def split_collection(text): item = [] @@ -63,11 +65,11 @@ def prepare_verify(verify): return verify -class HttpStorageBase(Storage): +class HttpStorage(Storage): _repr_attributes = ('username', 'url') def __init__(self, url, username='', password='', collection=None, - verify=True, auth=None, useragent='vdirsyncer', **kwargs): + verify=True, auth=None, useragent=USERAGENT, **kwargs): ''' :param url: Base URL or an URL to a collection. Autodiscovery should be done via :py:meth:`DavStorage.discover`. @@ -78,7 +80,7 @@ class HttpStorageBase(Storage): 'basic'. :param useragent: Default 'vdirsyncer'. ''' - super(HttpStorageBase, self).__init__(**kwargs) + super(HttpStorage, self).__init__(**kwargs) if username and not password: password = get_password(username, url) @@ -90,27 +92,15 @@ class HttpStorageBase(Storage): 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.url = url self.parsed_url = urlparse.urlparse(self.url) self.collection = collection + self._items = {} def _default_headers(self): - return { - 'User-Agent': self.useragent, - 'Content-Type': 'application/xml; charset=UTF-8' - } - - -class HttpStorage(HttpStorageBase): - - _items = None - - def __init__(self, **kwargs): - super(HttpStorage, self).__init__(**kwargs) - self._items = {} + return {'User-Agent': self.useragent} def list(self): r = requests.get(self.url, **self._settings)