mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Make CaldavStorage.list faster
This commit is contained in:
parent
b5f42457bd
commit
fadff19752
3 changed files with 48 additions and 34 deletions
|
|
@ -15,18 +15,25 @@ take a look at `vfix <https://github.com/geier/vfix>`_.
|
||||||
Radicale
|
Radicale
|
||||||
========
|
========
|
||||||
|
|
||||||
vdirsyncer is tested against the git version and the latest PyPI release of
|
Vdirsyncer is tested against the git version and the latest PyPI release of
|
||||||
Radicale.
|
Radicale.
|
||||||
|
|
||||||
Radicale doesn't `support time ranges in the calendar-query of CalDAV
|
- Radicale doesn't `support time ranges in the calendar-query of CalDAV
|
||||||
<https://github.com/Kozea/Radicale/issues/146>`_, so setting ``start_date`` and
|
<https://github.com/Kozea/Radicale/issues/146>`_, so setting ``start_date``
|
||||||
``end_date`` for :py:class:`vdirsyncer.storage.CaldavStorage` will have no or
|
and ``end_date`` for :py:class:`vdirsyncer.storage.CaldavStorage` will have
|
||||||
unpredicted consequences.
|
no or unpredicted consequences.
|
||||||
|
|
||||||
|
- Versions of Radicale older than 0.9b1 don't support the necessary
|
||||||
|
functionality for efficient querying for all items of a collection.
|
||||||
|
Vdirsyncer's defaults are supposed to deal with this situation, but if you're
|
||||||
|
using :py:class:`vdirsyncer.storage.CaldavStorage` and set ``item_types`` to
|
||||||
|
an empty value (``item_types =``), these versions of Radicale will not work
|
||||||
|
properly.
|
||||||
|
|
||||||
ownCloud
|
ownCloud
|
||||||
========
|
========
|
||||||
|
|
||||||
vdirsyncer is tested against the latest version of ownCloud.
|
Vdirsyncer is tested against the latest version of ownCloud.
|
||||||
|
|
||||||
ownCloud uses SabreDAV, which had problems detecting collisions and
|
ownCloud uses SabreDAV, which had problems detecting collisions and
|
||||||
race-conditions. The problems were reported and are fixed in SabreDAV's repo.
|
race-conditions. The problems were reported and are fixed in SabreDAV's repo.
|
||||||
|
|
|
||||||
|
|
@ -111,11 +111,14 @@ class TestCaldavStorage(DavStorageTests):
|
||||||
('VTODO',),
|
('VTODO',),
|
||||||
('VEVENT',),
|
('VEVENT',),
|
||||||
('VTODO', 'VEVENT'),
|
('VTODO', 'VEVENT'),
|
||||||
('VTODO', 'VEVENT', 'VJOURNAL')
|
('VTODO', 'VEVENT', 'VJOURNAL'),
|
||||||
|
()
|
||||||
])
|
])
|
||||||
def test_item_types_performance(self, item_types, monkeypatch):
|
def test_item_types_performance(self, item_types, monkeypatch):
|
||||||
kw = self.get_storage_args()
|
kw = self.get_storage_args()
|
||||||
s = self.storage_class(item_types=item_types, **kw)
|
s = self.storage_class(item_types=item_types, **kw)
|
||||||
|
item = self._create_bogus_item()
|
||||||
|
href, etag = s.upload(item)
|
||||||
|
|
||||||
old_list = s._list
|
old_list = s._list
|
||||||
calls = []
|
calls = []
|
||||||
|
|
@ -126,8 +129,10 @@ class TestCaldavStorage(DavStorageTests):
|
||||||
|
|
||||||
monkeypatch.setattr(s, '_list', _list)
|
monkeypatch.setattr(s, '_list', _list)
|
||||||
|
|
||||||
list(s.list())
|
rv = list(s.list())
|
||||||
assert len(calls) == len(item_types)
|
if dav_server != 'radicale' or item.parsed.name in s.item_types:
|
||||||
|
assert rv == [(href, etag)]
|
||||||
|
assert len(calls) == (len(item_types) or 1)
|
||||||
|
|
||||||
@pytest.mark.xfail(dav_server == 'radicale',
|
@pytest.mark.xfail(dav_server == 'radicale',
|
||||||
reason='Radicale doesn\'t support timeranges.')
|
reason='Radicale doesn\'t support timeranges.')
|
||||||
|
|
|
||||||
|
|
@ -440,11 +440,8 @@ class CaldavStorage(DavStorage):
|
||||||
:param start_date: Start date of timerange to show, default -inf.
|
:param start_date: Start date of timerange to show, default -inf.
|
||||||
:param end_date: End date of timerange to show, default +inf.
|
:param end_date: End date of timerange to show, default +inf.
|
||||||
:param item_types: A tuple of collection types to show from the server.
|
:param item_types: A tuple of collection types to show from the server.
|
||||||
For example, if you want to only get VEVENTs, pass ``('VEVENT',)``.
|
For example, if you want to only get VEVENTs, pass ``VEVENT``.
|
||||||
Falsy values mean "get all types". Dependent on server
|
Dependent on server functionality, no clientside validation of results.
|
||||||
functionality, no clientside validation of results. This currently
|
|
||||||
only affects the `list` method, but this shouldn't cause problems
|
|
||||||
in the normal usecase.
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
storage_name = 'caldav'
|
storage_name = 'caldav'
|
||||||
|
|
@ -469,7 +466,7 @@ class CaldavStorage(DavStorage):
|
||||||
get_multi_data_query = '{urn:ietf:params:xml:ns:caldav}calendar-data'
|
get_multi_data_query = '{urn:ietf:params:xml:ns:caldav}calendar-data'
|
||||||
|
|
||||||
def __init__(self, start_date=None, end_date=None,
|
def __init__(self, start_date=None, end_date=None,
|
||||||
item_types=(), **kwargs):
|
item_types='VTODO, VEVENT', **kwargs):
|
||||||
super(CaldavStorage, self).__init__(**kwargs)
|
super(CaldavStorage, self).__init__(**kwargs)
|
||||||
if isinstance(item_types, str):
|
if isinstance(item_types, str):
|
||||||
item_types = [x.strip() for x in item_types.split(',')]
|
item_types = [x.strip() for x in item_types.split(',')]
|
||||||
|
|
@ -489,9 +486,7 @@ class CaldavStorage(DavStorage):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_list_filters(components, start, end):
|
def _get_list_filters(components, start, end):
|
||||||
|
|
||||||
if not components:
|
if components:
|
||||||
components = ('VTODO', 'VEVENT')
|
|
||||||
|
|
||||||
caldavfilter = '''
|
caldavfilter = '''
|
||||||
<C:comp-filter name="VCALENDAR">
|
<C:comp-filter name="VCALENDAR">
|
||||||
<C:comp-filter name="{component}">
|
<C:comp-filter name="{component}">
|
||||||
|
|
@ -512,6 +507,13 @@ class CaldavStorage(DavStorage):
|
||||||
for component in components:
|
for component in components:
|
||||||
yield caldavfilter.format(component=component,
|
yield caldavfilter.format(component=component,
|
||||||
timefilter=timefilter)
|
timefilter=timefilter)
|
||||||
|
else:
|
||||||
|
if start is not None and end is not None:
|
||||||
|
for x in CaldavStorage._get_list_filters(('VTODO', 'VEVENT'),
|
||||||
|
start, end):
|
||||||
|
yield x
|
||||||
|
else:
|
||||||
|
yield '<C:comp-filter name="VCALENDAR"/>'
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
data = '''<?xml version="1.0" encoding="utf-8" ?>
|
data = '''<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue