Merge branch 'issue29'

Conflicts:
	tests/storage/test_http.py
	vdirsyncer/storage/dav.py
This commit is contained in:
Markus Unterwaditzer 2014-04-11 15:35:30 +02:00
commit 70b446e673
3 changed files with 49 additions and 24 deletions

View file

@ -16,7 +16,7 @@ from requests import Response
class TestHttpStorage(object): class TestHttpStorage(object):
def test_list(self, monkeypatch): 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 = [ items = [
dedent(b''' dedent(b'''

View file

@ -7,8 +7,8 @@
:license: MIT, see LICENSE for more details. :license: MIT, see LICENSE for more details.
''' '''
from .base import Item from .base import Storage, Item
from .http import HttpStorageBase from .http import prepare_auth, prepare_verify, USERAGENT
from .. import exceptions from .. import exceptions
from .. import log from .. import log
from ..utils import request from ..utils import request
@ -24,7 +24,7 @@ CALDAV_DT_FORMAT = '%Y%m%dT%H%M%SZ'
CONFIG_DT_FORMAT = '%Y-%m-%d' CONFIG_DT_FORMAT = '%Y-%m-%d'
class DavStorage(HttpStorageBase): class DavStorage(Storage):
# the file extension of items. Useful for testing against radicale. # the file extension of items. Useful for testing against radicale.
fileext = None fileext = None
@ -42,11 +42,40 @@ class DavStorage(HttpStorageBase):
leif_class = None leif_class = None
_session = 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) 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 = self._default_headers()
headers['Depth'] = 1 headers['Depth'] = 1
response = self._request( response = self._request(
@ -58,6 +87,12 @@ class DavStorage(HttpStorageBase):
if self.dav_header not in response.headers.get('DAV', ''): if self.dav_header not in response.headers.get('DAV', ''):
raise exceptions.StorageError('URL is not a collection') 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 @classmethod
def discover(cls, url, **kwargs): def discover(cls, url, **kwargs):
if kwargs.pop('collection', None) is not None: if kwargs.pop('collection', None) is not None:

View file

@ -14,6 +14,8 @@ import hashlib
from .base import Storage, Item from .base import Storage, Item
from vdirsyncer.utils import expand_path, get_password, request from vdirsyncer.utils import expand_path, get_password, request
USERAGENT = 'vdirsyncer'
def split_collection(text): def split_collection(text):
item = [] item = []
@ -63,11 +65,11 @@ def prepare_verify(verify):
return verify return verify
class HttpStorageBase(Storage): class HttpStorage(Storage):
_repr_attributes = ('username', 'url') _repr_attributes = ('username', 'url')
def __init__(self, url, username='', password='', collection=None, 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 :param url: Base URL or an URL to a collection. Autodiscovery should be
done via :py:meth:`DavStorage.discover`. done via :py:meth:`DavStorage.discover`.
@ -78,7 +80,7 @@ class HttpStorageBase(Storage):
'basic'. 'basic'.
:param useragent: Default 'vdirsyncer'. :param useragent: Default 'vdirsyncer'.
''' '''
super(HttpStorageBase, self).__init__(**kwargs) super(HttpStorage, self).__init__(**kwargs)
if username and not password: if username and not password:
password = get_password(username, url) password = get_password(username, url)
@ -90,27 +92,15 @@ class HttpStorageBase(Storage):
self.username, self.password = username, password self.username, self.password = username, password
self.useragent = useragent self.useragent = useragent
url = url.rstrip('/') + '/'
if collection is not None: if collection is not None:
url = urlparse.urljoin(url, collection) url = urlparse.urljoin(url, collection)
self.url = url.rstrip('/') + '/' self.url = url
self.parsed_url = urlparse.urlparse(self.url) self.parsed_url = urlparse.urlparse(self.url)
self.collection = collection self.collection = collection
self._items = {}
def _default_headers(self): def _default_headers(self):
return { return {'User-Agent': self.useragent}
'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 = {}
def list(self): def list(self):
r = request('GET', self.url, **self._settings) r = request('GET', self.url, **self._settings)