Share code between dav and http

Adds many features to http
This commit is contained in:
Markus Unterwaditzer 2014-03-26 17:56:21 +01:00
parent 3c55a944a6
commit c7387a17f0
2 changed files with 53 additions and 35 deletions

View file

@ -7,7 +7,8 @@
:license: MIT, see LICENSE for more details. :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.exceptions as exceptions
import vdirsyncer.log as log import vdirsyncer.log as log
import requests import requests
@ -18,7 +19,7 @@ from lxml import etree
dav_logger = log.get('storage.dav') dav_logger = log.get('storage.dav')
class DavStorage(Storage): class DavStorage(HttpStorageBase):
# the file extension of items. Useful for testing against radicale. # the file extension of items. Useful for testing against radicale.
fileext = None fileext = None
@ -38,8 +39,7 @@ class DavStorage(Storage):
_session = None _session = None
_repr_attributes = ('url', 'username') _repr_attributes = ('url', 'username')
def __init__(self, url, username='', password='', collection=None, def __init__(self, **kwargs):
verify=True, auth='basic', useragent='vdirsyncer', **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`.
@ -52,25 +52,6 @@ class DavStorage(Storage):
''' '''
super(DavStorage, self).__init__(**kwargs) 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 = self._default_headers()
headers['Depth'] = 1 headers['Depth'] = 1
response = self._request( response = self._request(
@ -113,12 +94,6 @@ class DavStorage(Storage):
def _get_href(self, uid): def _get_href(self, uid):
return self._normalize_href(super(DavStorage, self)._get_href(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): def _request(self, method, path, data=None, headers=None):
path = path or self.parsed_url.path path = path or self.parsed_url.path
assert path.startswith(self.parsed_url.path) assert path.startswith(self.parsed_url.path)

View file

@ -9,8 +9,10 @@
''' '''
import requests import requests
import urlparse
import hashlib import hashlib
from .base import Storage, Item from .base import Storage, Item
from vdirsyncer.utils import expand_path
def split_collection(text): def split_collection(text):
@ -43,17 +45,58 @@ def split_collection(text):
item.append(line) item.append(line)
class HttpStorage(Storage): def prepare_auth(auth, username, password):
_repr_attributes = ('url',) 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 _items = None
def __init__(self, url, **kwargs): def __init__(self, url, username='', password='', collection=None,
super(HttpStorage, self).__init__(**kwargs) verify=True, auth=None, useragent='vdirsyncer', **kwargs):
self.url = url
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): def list(self):
if self._items is None: if self._items is None:
r = requests.get(self.url) r = requests.get(self.url, **self._settings)
r.raise_on_status() r.raise_on_status()
self._items = {} self._items = {}
for item in split_collection(r.text): for item in split_collection(r.text):