mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Less files
This commit is contained in:
parent
47d3b1917d
commit
475671f437
8 changed files with 190 additions and 240 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
vdirsyncer.tests.storage.dav
|
vdirsyncer.tests.storage.dav
|
||||||
|
|
@ -7,43 +6,3 @@
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer
|
:copyright: (c) 2014 Markus Unterwaditzer
|
||||||
:license: MIT, see LICENSE for more details.
|
:license: MIT, see LICENSE for more details.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from .. import StorageTests
|
|
||||||
import vdirsyncer.exceptions as exceptions
|
|
||||||
from vdirsyncer.storage.base import Item
|
|
||||||
import requests.exceptions
|
|
||||||
|
|
||||||
|
|
||||||
dav_server = os.environ.get('DAV_SERVER', '').strip() or 'radicale_filesystem'
|
|
||||||
if dav_server.startswith('radicale_'):
|
|
||||||
from ._radicale import ServerMixin
|
|
||||||
elif dav_server == 'owncloud':
|
|
||||||
from ._owncloud import ServerMixin
|
|
||||||
else:
|
|
||||||
raise RuntimeError('{} is not a known DAV server.'.format(dav_server))
|
|
||||||
|
|
||||||
try:
|
|
||||||
import radicale
|
|
||||||
radicale_version = radicale.VERSION
|
|
||||||
del radicale
|
|
||||||
except ImportError:
|
|
||||||
radicale_version = None
|
|
||||||
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.xfail(
|
|
||||||
dav_server == 'radicale_database' and radicale_version == '0.8',
|
|
||||||
reason='Database storage of Radicale 0.8 is broken.')
|
|
||||||
|
|
||||||
|
|
||||||
class DavStorageTests(ServerMixin, StorageTests):
|
|
||||||
def test_dav_broken_item(self):
|
|
||||||
item = Item(u'UID:1')
|
|
||||||
s = self._get_storage()
|
|
||||||
try:
|
|
||||||
s.upload(item)
|
|
||||||
except (exceptions.Error, requests.exceptions.HTTPError):
|
|
||||||
pass
|
|
||||||
assert not list(s.list())
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
'''
|
|
||||||
vdirsyncer.tests.storage.test_carddav
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
'''
|
|
||||||
|
|
||||||
from vdirsyncer.storage.dav.carddav import CarddavStorage
|
|
||||||
from . import DavStorageTests, pytestmark
|
|
||||||
|
|
||||||
|
|
||||||
VCARD_TEMPLATE = u'''BEGIN:VCARD
|
|
||||||
VERSION:3.0
|
|
||||||
FN:Cyrus Daboo
|
|
||||||
N:Daboo;Cyrus
|
|
||||||
ADR;TYPE=POSTAL:;2822 Email HQ;Suite 2821;RFCVille;PA;15213;USA
|
|
||||||
EMAIL;TYPE=INTERNET;TYPE=PREF:cyrus@example.com
|
|
||||||
NICKNAME:me
|
|
||||||
NOTE:Example VCard.
|
|
||||||
ORG:Self Employed
|
|
||||||
TEL;TYPE=WORK;TYPE=VOICE:412 605 0499
|
|
||||||
TEL;TYPE=FAX:412 605 0705
|
|
||||||
URL:http://www.example.com
|
|
||||||
UID:{uid}
|
|
||||||
X-SOMETHING:{r}
|
|
||||||
END:VCARD'''
|
|
||||||
|
|
||||||
|
|
||||||
class TestCarddavStorage(DavStorageTests):
|
|
||||||
storage_class = CarddavStorage
|
|
||||||
item_template = VCARD_TEMPLATE
|
|
||||||
|
|
@ -1,19 +1,59 @@
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
vdirsyncer.tests.storage.test_caldav
|
vdirsyncer.tests.storage.dav.test_main
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer
|
:copyright: (c) 2014 Markus Unterwaditzer
|
||||||
:license: MIT, see LICENSE for more details.
|
:license: MIT, see LICENSE for more details.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
import requests.exceptions
|
|
||||||
from vdirsyncer.storage.dav.caldav import CaldavStorage
|
from .. import StorageTests
|
||||||
import vdirsyncer.exceptions as exceptions
|
import vdirsyncer.exceptions as exceptions
|
||||||
from . import DavStorageTests, pytestmark
|
from vdirsyncer.storage.base import Item
|
||||||
|
from vdirsyncer.storage.dav import CaldavStorage, CarddavStorage
|
||||||
|
import requests.exceptions
|
||||||
|
|
||||||
|
|
||||||
|
dav_server = os.environ.get('DAV_SERVER', '').strip() or 'radicale_filesystem'
|
||||||
|
if dav_server.startswith('radicale_'):
|
||||||
|
from ._radicale import ServerMixin
|
||||||
|
elif dav_server == 'owncloud':
|
||||||
|
from ._owncloud import ServerMixin
|
||||||
|
else:
|
||||||
|
raise RuntimeError('{} is not a known DAV server.'.format(dav_server))
|
||||||
|
|
||||||
|
try:
|
||||||
|
import radicale
|
||||||
|
radicale_version = radicale.VERSION
|
||||||
|
del radicale
|
||||||
|
except ImportError:
|
||||||
|
radicale_version = None
|
||||||
|
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.xfail(
|
||||||
|
dav_server == 'radicale_database' and radicale_version == '0.8',
|
||||||
|
reason='Database storage of Radicale 0.8 is broken.')
|
||||||
|
|
||||||
|
|
||||||
|
VCARD_TEMPLATE = u'''BEGIN:VCARD
|
||||||
|
VERSION:3.0
|
||||||
|
FN:Cyrus Daboo
|
||||||
|
N:Daboo;Cyrus
|
||||||
|
ADR;TYPE=POSTAL:;2822 Email HQ;Suite 2821;RFCVille;PA;15213;USA
|
||||||
|
EMAIL;TYPE=INTERNET;TYPE=PREF:cyrus@example.com
|
||||||
|
NICKNAME:me
|
||||||
|
NOTE:Example VCard.
|
||||||
|
ORG:Self Employed
|
||||||
|
TEL;TYPE=WORK;TYPE=VOICE:412 605 0499
|
||||||
|
TEL;TYPE=FAX:412 605 0705
|
||||||
|
URL:http://www.example.com
|
||||||
|
UID:{uid}
|
||||||
|
X-SOMETHING:{r}
|
||||||
|
END:VCARD'''
|
||||||
|
|
||||||
|
|
||||||
TASK_TEMPLATE = u'''BEGIN:VCALENDAR
|
TASK_TEMPLATE = u'''BEGIN:VCALENDAR
|
||||||
|
|
@ -43,13 +83,24 @@ UID:{uid}
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
END:VCALENDAR'''
|
END:VCALENDAR'''
|
||||||
|
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
|
'VCARD': VCARD_TEMPLATE,
|
||||||
'VEVENT': EVENT_TEMPLATE,
|
'VEVENT': EVENT_TEMPLATE,
|
||||||
'VTODO': TASK_TEMPLATE
|
'VTODO': TASK_TEMPLATE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DavStorageTests(ServerMixin, StorageTests):
|
||||||
|
def test_dav_broken_item(self):
|
||||||
|
item = Item(u'UID:1')
|
||||||
|
s = self._get_storage()
|
||||||
|
try:
|
||||||
|
s.upload(item)
|
||||||
|
except (exceptions.Error, requests.exceptions.HTTPError):
|
||||||
|
pass
|
||||||
|
assert not list(s.list())
|
||||||
|
|
||||||
|
|
||||||
class TestCaldavStorage(DavStorageTests):
|
class TestCaldavStorage(DavStorageTests):
|
||||||
storage_class = CaldavStorage
|
storage_class = CaldavStorage
|
||||||
|
|
||||||
|
|
@ -90,3 +141,8 @@ class TestCaldavStorage(DavStorageTests):
|
||||||
a = self.storage_class(item_types='VTODO,VEVENT', **kw)
|
a = self.storage_class(item_types='VTODO,VEVENT', **kw)
|
||||||
b = self.storage_class(item_types=('VTODO', 'VEVENT'), **kw)
|
b = self.storage_class(item_types=('VTODO', 'VEVENT'), **kw)
|
||||||
assert a.item_types == b.item_types == ('VTODO', 'VEVENT')
|
assert a.item_types == b.item_types == ('VTODO', 'VEVENT')
|
||||||
|
|
||||||
|
|
||||||
|
class TestCarddavStorage(DavStorageTests):
|
||||||
|
storage_class = CarddavStorage
|
||||||
|
item_template = VCARD_TEMPLATE
|
||||||
|
|
@ -12,8 +12,8 @@
|
||||||
:license: MIT, see LICENSE for more details.
|
:license: MIT, see LICENSE for more details.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from .dav.caldav import CaldavStorage
|
from .dav import CaldavStorage
|
||||||
from .dav.carddav import CarddavStorage
|
from .dav import CarddavStorage
|
||||||
from .filesystem import FilesystemStorage
|
from .filesystem import FilesystemStorage
|
||||||
from .http import HttpStorage
|
from .http import HttpStorage
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
vdirsyncer.storage.dav.base
|
vdirsyncer.storage.dav
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer, Christian Geier and contributors
|
:copyright: (c) 2014 Markus Unterwaditzer, Christian Geier and contributors
|
||||||
:license: MIT, see LICENSE for more details.
|
:license: MIT, see LICENSE for more details.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ..base import Item
|
from .base import Item
|
||||||
from ..http import HttpStorageBase
|
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,6 +18,9 @@ from lxml import etree
|
||||||
|
|
||||||
dav_logger = log.get('storage.dav')
|
dav_logger = log.get('storage.dav')
|
||||||
|
|
||||||
|
CALDAV_DT_FORMAT = '%Y%m%dT%H%M%SZ'
|
||||||
|
CONFIG_DT_FORMAT = '%Y-%m-%d'
|
||||||
|
|
||||||
|
|
||||||
class DavStorage(HttpStorageBase):
|
class DavStorage(HttpStorageBase):
|
||||||
|
|
||||||
|
|
@ -228,3 +231,122 @@ class DavStorage(HttpStorageBase):
|
||||||
'{DAV:}prop').find('{DAV:}getetag').text
|
'{DAV:}prop').find('{DAV:}getetag').text
|
||||||
href = self._normalize_href(element.find('{DAV:}href').text)
|
href = self._normalize_href(element.find('{DAV:}href').text)
|
||||||
yield href, etag
|
yield href, etag
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CaldavStorage(DavStorage):
|
||||||
|
|
||||||
|
fileext = '.ics'
|
||||||
|
item_mimetype = 'text/calendar'
|
||||||
|
dav_header = 'calendar-access'
|
||||||
|
leif_class = 'CalDiscover'
|
||||||
|
|
||||||
|
start_date = None
|
||||||
|
end_date = None
|
||||||
|
|
||||||
|
get_multi_template = '''<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<C:calendar-multiget xmlns:D="DAV:"
|
||||||
|
xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<D:prop>
|
||||||
|
<D:getetag/>
|
||||||
|
<C:calendar-data/>
|
||||||
|
</D:prop>
|
||||||
|
{hrefs}
|
||||||
|
</C:calendar-multiget>'''
|
||||||
|
|
||||||
|
get_multi_data_query = '{urn:ietf:params:xml:ns:caldav}calendar-data'
|
||||||
|
|
||||||
|
def __init__(self, start_date=None, end_date=None,
|
||||||
|
item_types=('VTODO', 'VEVENT'), **kwargs):
|
||||||
|
'''
|
||||||
|
:param start_date: Start date of timerange to show, default -inf.
|
||||||
|
:param end_date: End date of timerange to show, default +inf.
|
||||||
|
:param item_types: The item types to show from the server. Dependent on
|
||||||
|
server functionality, no clientside validation of results. This
|
||||||
|
currently only affects the `list` method, but this shouldn't cause
|
||||||
|
problems in the normal usecase.
|
||||||
|
'''
|
||||||
|
super(CaldavStorage, self).__init__(**kwargs)
|
||||||
|
if isinstance(item_types, str):
|
||||||
|
item_types = [x.strip() for x in item_types.split(',')]
|
||||||
|
self.item_types = tuple(item_types)
|
||||||
|
if (start_date is None) != (end_date is None):
|
||||||
|
raise ValueError('If start_date is given, '
|
||||||
|
'end_date has to be given too.')
|
||||||
|
elif start_date is not None and end_date is not None:
|
||||||
|
namespace = dict(datetime.__dict__)
|
||||||
|
namespace['start_date'] = self.start_date = \
|
||||||
|
(eval(start_date, namespace) if isinstance(start_date, str)
|
||||||
|
else start_date)
|
||||||
|
self.end_date = \
|
||||||
|
(eval(end_date, namespace) if isinstance(end_date, str)
|
||||||
|
else end_date)
|
||||||
|
|
||||||
|
self._list_template = self._get_list_template()
|
||||||
|
|
||||||
|
def _get_list_template(self):
|
||||||
|
data = '''<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<C:calendar-query xmlns:D="DAV:"
|
||||||
|
xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<D:prop>
|
||||||
|
<D:getetag/>
|
||||||
|
</D:prop>
|
||||||
|
<C:filter>
|
||||||
|
<C:comp-filter name="VCALENDAR">
|
||||||
|
<C:comp-filter name="{component}">
|
||||||
|
{caldavfilter}
|
||||||
|
</C:comp-filter>
|
||||||
|
</C:comp-filter>
|
||||||
|
</C:filter>
|
||||||
|
</C:calendar-query>'''
|
||||||
|
start = self.start_date
|
||||||
|
end = self.end_date
|
||||||
|
caldavfilter = ''
|
||||||
|
if start is not None and end is not None:
|
||||||
|
start = start.strftime(CALDAV_DT_FORMAT)
|
||||||
|
end = end.strftime(CALDAV_DT_FORMAT)
|
||||||
|
caldavfilter = ('<C:time-range start="{start}" end="{end}"/>'
|
||||||
|
.format(start=start, end=end))
|
||||||
|
return data.format(caldavfilter=caldavfilter, component='{item_type}')
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
hrefs = set()
|
||||||
|
for t in self.item_types:
|
||||||
|
xml = self._list_template.format(item_type=t)
|
||||||
|
for href, etag in self._list(xml):
|
||||||
|
assert href not in hrefs
|
||||||
|
hrefs.add(href)
|
||||||
|
yield href, etag
|
||||||
|
|
||||||
|
|
||||||
|
class CarddavStorage(DavStorage):
|
||||||
|
|
||||||
|
fileext = '.vcf'
|
||||||
|
item_mimetype = 'text/vcard'
|
||||||
|
dav_header = 'addressbook'
|
||||||
|
leif_class = 'CardDiscover'
|
||||||
|
|
||||||
|
get_multi_template = '''<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<C:addressbook-multiget xmlns:D="DAV:"
|
||||||
|
xmlns:C="urn:ietf:params:xml:ns:carddav">
|
||||||
|
<D:prop>
|
||||||
|
<D:getetag/>
|
||||||
|
<C:address-data/>
|
||||||
|
</D:prop>
|
||||||
|
{hrefs}
|
||||||
|
</C:addressbook-multiget>'''
|
||||||
|
|
||||||
|
get_multi_data_query = '{urn:ietf:params:xml:ns:carddav}address-data'
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
return self._list('''<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<C:addressbook-query xmlns:D="DAV:"
|
||||||
|
xmlns:C="urn:ietf:params:xml:ns:carddav">
|
||||||
|
<D:prop>
|
||||||
|
<D:getetag/>
|
||||||
|
</D:prop>
|
||||||
|
<C:filter>
|
||||||
|
<C:comp-filter name="VCARD"/>
|
||||||
|
</C:filter>
|
||||||
|
</C:addressbook-query>''')
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
'''
|
|
||||||
vdirsyncer.storage.dav
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
'''
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
'''
|
|
||||||
vdirsyncer.storage.dav.caldav
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Original version from khal: https://github.com/geier/khal
|
|
||||||
|
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer, Christian Geier and contributors
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
'''
|
|
||||||
|
|
||||||
from .base import DavStorage
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
CALDAV_DT_FORMAT = '%Y%m%dT%H%M%SZ'
|
|
||||||
CONFIG_DT_FORMAT = '%Y-%m-%d'
|
|
||||||
|
|
||||||
|
|
||||||
class CaldavStorage(DavStorage):
|
|
||||||
|
|
||||||
fileext = '.ics'
|
|
||||||
item_mimetype = 'text/calendar'
|
|
||||||
dav_header = 'calendar-access'
|
|
||||||
leif_class = 'CalDiscover'
|
|
||||||
|
|
||||||
start_date = None
|
|
||||||
end_date = None
|
|
||||||
|
|
||||||
get_multi_template = '''<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<C:calendar-multiget xmlns:D="DAV:"
|
|
||||||
xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
||||||
<D:prop>
|
|
||||||
<D:getetag/>
|
|
||||||
<C:calendar-data/>
|
|
||||||
</D:prop>
|
|
||||||
{hrefs}
|
|
||||||
</C:calendar-multiget>'''
|
|
||||||
|
|
||||||
get_multi_data_query = '{urn:ietf:params:xml:ns:caldav}calendar-data'
|
|
||||||
|
|
||||||
def __init__(self, start_date=None, end_date=None,
|
|
||||||
item_types=('VTODO', 'VEVENT'), **kwargs):
|
|
||||||
'''
|
|
||||||
:param start_date: Start date of timerange to show, default -inf.
|
|
||||||
:param end_date: End date of timerange to show, default +inf.
|
|
||||||
:param item_types: The item types to show from the server. Dependent on
|
|
||||||
server functionality, no clientside validation of results. This
|
|
||||||
currently only affects the `list` method, but this shouldn't cause
|
|
||||||
problems in the normal usecase.
|
|
||||||
'''
|
|
||||||
super(CaldavStorage, self).__init__(**kwargs)
|
|
||||||
if isinstance(item_types, str):
|
|
||||||
item_types = [x.strip() for x in item_types.split(',')]
|
|
||||||
self.item_types = tuple(item_types)
|
|
||||||
if (start_date is None) != (end_date is None):
|
|
||||||
raise ValueError('If start_date is given, '
|
|
||||||
'end_date has to be given too.')
|
|
||||||
elif start_date is not None and end_date is not None:
|
|
||||||
namespace = dict(datetime.__dict__)
|
|
||||||
namespace['start_date'] = self.start_date = \
|
|
||||||
(eval(start_date, namespace) if isinstance(start_date, str)
|
|
||||||
else start_date)
|
|
||||||
self.end_date = \
|
|
||||||
(eval(end_date, namespace) if isinstance(end_date, str)
|
|
||||||
else end_date)
|
|
||||||
|
|
||||||
self._list_template = self._get_list_template()
|
|
||||||
|
|
||||||
def _get_list_template(self):
|
|
||||||
data = '''<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<C:calendar-query xmlns:D="DAV:"
|
|
||||||
xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
||||||
<D:prop>
|
|
||||||
<D:getetag/>
|
|
||||||
</D:prop>
|
|
||||||
<C:filter>
|
|
||||||
<C:comp-filter name="VCALENDAR">
|
|
||||||
<C:comp-filter name="{component}">
|
|
||||||
{caldavfilter}
|
|
||||||
</C:comp-filter>
|
|
||||||
</C:comp-filter>
|
|
||||||
</C:filter>
|
|
||||||
</C:calendar-query>'''
|
|
||||||
start = self.start_date
|
|
||||||
end = self.end_date
|
|
||||||
caldavfilter = ''
|
|
||||||
if start is not None and end is not None:
|
|
||||||
start = start.strftime(CALDAV_DT_FORMAT)
|
|
||||||
end = end.strftime(CALDAV_DT_FORMAT)
|
|
||||||
caldavfilter = ('<C:time-range start="{start}" end="{end}"/>'
|
|
||||||
.format(start=start, end=end))
|
|
||||||
return data.format(caldavfilter=caldavfilter, component='{item_type}')
|
|
||||||
|
|
||||||
def list(self):
|
|
||||||
hrefs = set()
|
|
||||||
for t in self.item_types:
|
|
||||||
xml = self._list_template.format(item_type=t)
|
|
||||||
for href, etag in self._list(xml):
|
|
||||||
assert href not in hrefs
|
|
||||||
hrefs.add(href)
|
|
||||||
yield href, etag
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
'''
|
|
||||||
vdirsyncer.storage.dav.carddav
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Original version from pycarddav: https://github.com/geier/pycarddav
|
|
||||||
|
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer, Christian Geier and contributors
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
'''
|
|
||||||
|
|
||||||
from .base import DavStorage
|
|
||||||
|
|
||||||
|
|
||||||
class CarddavStorage(DavStorage):
|
|
||||||
|
|
||||||
fileext = '.vcf'
|
|
||||||
item_mimetype = 'text/vcard'
|
|
||||||
dav_header = 'addressbook'
|
|
||||||
leif_class = 'CardDiscover'
|
|
||||||
|
|
||||||
get_multi_template = '''<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<C:addressbook-multiget xmlns:D="DAV:"
|
|
||||||
xmlns:C="urn:ietf:params:xml:ns:carddav">
|
|
||||||
<D:prop>
|
|
||||||
<D:getetag/>
|
|
||||||
<C:address-data/>
|
|
||||||
</D:prop>
|
|
||||||
{hrefs}
|
|
||||||
</C:addressbook-multiget>'''
|
|
||||||
|
|
||||||
get_multi_data_query = '{urn:ietf:params:xml:ns:carddav}address-data'
|
|
||||||
|
|
||||||
def list(self):
|
|
||||||
return self._list('''<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<C:addressbook-query xmlns:D="DAV:"
|
|
||||||
xmlns:C="urn:ietf:params:xml:ns:carddav">
|
|
||||||
<D:prop>
|
|
||||||
<D:getetag/>
|
|
||||||
</D:prop>
|
|
||||||
<C:filter>
|
|
||||||
<C:comp-filter name="VCARD"/>
|
|
||||||
</C:filter>
|
|
||||||
</C:addressbook-query>''')
|
|
||||||
Loading…
Reference in a new issue