mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
See #29
This commit is contained in:
parent
91c3114b78
commit
0c14b14f17
3 changed files with 51 additions and 25 deletions
|
|
@ -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'''
|
||||||
|
|
@ -44,7 +44,8 @@ class TestHttpStorage(object):
|
||||||
'\n'.join([b'BEGIN:VCALENDAR'] + items + [b'END:VCALENDAR'])
|
'\n'.join([b'BEGIN:VCALENDAR'] + items + [b'END:VCALENDAR'])
|
||||||
] * 2
|
] * 2
|
||||||
|
|
||||||
def get(*a, **kw):
|
def get(url, *a, **kw):
|
||||||
|
assert url == collection_url
|
||||||
r = Response()
|
r = Response()
|
||||||
r.status_code = 200
|
r.status_code = 200
|
||||||
assert responses
|
assert responses
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
import vdirsyncer.exceptions as exceptions
|
import vdirsyncer.exceptions as exceptions
|
||||||
import vdirsyncer.log as log
|
import vdirsyncer.log as log
|
||||||
import requests
|
import requests
|
||||||
|
|
@ -23,7 +23,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
|
||||||
|
|
@ -41,11 +41,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(
|
||||||
|
|
@ -57,6 +86,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:
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import hashlib
|
||||||
from .base import Storage, Item
|
from .base import Storage, Item
|
||||||
from vdirsyncer.utils import expand_path, get_password
|
from vdirsyncer.utils import expand_path, get_password
|
||||||
|
|
||||||
|
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 = requests.get(self.url, **self._settings)
|
r = requests.get(self.url, **self._settings)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue