From 98a9748392c84dc3ae63e6377ab64bcbe8b0704f Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 14 May 2014 15:13:21 +0200 Subject: [PATCH] Ident is now a property of Item --- tests/storage/test_filesystem.py | 1 + vdirsyncer/storage/base.py | 23 +++++++++++++++++++---- vdirsyncer/storage/dav.py | 2 +- vdirsyncer/sync.py | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/storage/test_filesystem.py b/tests/storage/test_filesystem.py index 6415bc4..941e75f 100644 --- a/tests/storage/test_filesystem.py +++ b/tests/storage/test_filesystem.py @@ -50,6 +50,7 @@ class TestFilesystemStorage(StorageTests): class BrokenItem(object): raw = u'Ц, Ш, Л, ж, Д, З, Ю'.encode('utf-8') uid = 'jeezus' + ident = uid with pytest.raises(TypeError): s.upload(BrokenItem) assert not tmpdir.listdir() diff --git a/vdirsyncer/storage/base.py b/vdirsyncer/storage/base.py index 42cfd58..1f70332 100644 --- a/vdirsyncer/storage/base.py +++ b/vdirsyncer/storage/base.py @@ -15,12 +15,27 @@ from .. import utils class Item(object): - '''should-be-immutable wrapper class for VCALENDAR and VCARD''' + '''should-be-immutable wrapper class for VCALENDAR (VEVENT, VTODO) and + VCARD''' + + uid = None + '''Global identifier of the item, across storages, doesn't change after a + modification of the item.''' + + raw = None + '''Raw content of the item, which vdirsyncer doesn't validate in any + way.''' + + hash = None + '''Hash of self.raw, used for etags.''' + + ident = None + '''Used for generating hrefs and matching up items during synchronization. + This is either the UID or the hash of the item's content.''' def __init__(self, raw): assert isinstance(raw, utils.text_type) raw = raw.splitlines() - self.uid = None for line in raw: if line.startswith(u'UID:'): @@ -30,6 +45,7 @@ class Item(object): self.raw = u'\n'.join(raw) self.hash = hashlib.sha256(self.raw.encode('utf-8')).hexdigest() + self.ident = self.uid or self.hash class Storage(object): @@ -40,7 +56,6 @@ class Storage(object): Terminology: - ITEM: Instance of the Item class, represents a calendar event, task or contact. - - UID: String; Global identifier of the item, across storages. - HREF: String; Per-storage identifier of item, might be UID. The reason items aren't just referenced by their UID is because the CalDAV and CardDAV specifications make this imperformant to implement. @@ -71,7 +86,7 @@ class Storage(object): raise NotImplementedError() def _get_href(self, item): - return (item.uid or item.hash) + self.fileext + return item.ident + self.fileext def __repr__(self): return '<{}(**{})>'.format( diff --git a/vdirsyncer/storage/dav.py b/vdirsyncer/storage/dav.py index cebfc2a..e5467e7 100644 --- a/vdirsyncer/storage/dav.py +++ b/vdirsyncer/storage/dav.py @@ -122,7 +122,7 @@ class DavStorage(Storage): return utils.urlunquote_plus(utils.urlparse.urlsplit(x).path) def _get_href(self, item): - href = utils.urlunquote_plus(item.uid or item.hash) + self.fileext + href = utils.urlunquote_plus(item.ident) + self.fileext return self._normalize_href(href) def _request(self, method, path, data=None, headers=None): diff --git a/vdirsyncer/sync.py b/vdirsyncer/sync.py index 044541a..225235d 100644 --- a/vdirsyncer/sync.py +++ b/vdirsyncer/sync.py @@ -61,7 +61,7 @@ def prepare_list(storage, href_to_status): for href, item, etag in storage.get_multi(download): props = rv[href] props['item'] = item - props['ident'] = item.uid or item.hash + props['ident'] = item.ident if props['etag'] != etag: raise SyncConflict('Etag changed during sync.')