diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py index 61899a1..fd15dfc 100644 --- a/tests/storage/__init__.py +++ b/tests/storage/__init__.py @@ -44,9 +44,9 @@ class StorageTests(object): assert isinstance(href, (str, unicode)) assert isinstance(etag, (str, unicode)) assert s.has(href) - obj, etag2 = s.get(href) + item, etag2 = s.get(href) assert etag == etag2 - assert 'UID:{}'.format(obj.uid) in obj.raw + assert 'UID:{}'.format(item.uid) in item.raw def test_upload_already_existing(self): s = self._get_storage() @@ -81,10 +81,10 @@ class StorageTests(object): def test_wrong_etag(self): s = self._get_storage() - obj = self._create_bogus_item(1) - href, etag = s.upload(obj) + item = self._create_bogus_item(1) + href, etag = s.upload(item) with pytest.raises(exceptions.PreconditionFailed): - s.update(href, obj, '"lolnope"') + s.update(href, item, '"lolnope"') with pytest.raises(exceptions.PreconditionFailed): s.delete(href, '"lolnope"') diff --git a/tests/test_sync.py b/tests/test_sync.py index 392ccbc..451881b 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -135,10 +135,10 @@ def test_conflict_resolution_both_etags_new(): with pytest.raises(exceptions.SyncConflict): sync(a, b, status) sync(a, b, status, conflict_resolution='a wins') - obj_a, _ = a.get(href_a) - obj_b, _ = b.get(href_b) - assert_item_equals(obj_a, obj_b) - n = normalize_item(obj_a) + item_a, _ = a.get(href_a) + item_b, _ = b.get(href_b) + assert_item_equals(item_a, item_b) + n = normalize_item(item_a) assert u'UID:1' in n assert u'ASDASD' in n diff --git a/vdirsyncer/storage/base.py b/vdirsyncer/storage/base.py index 9785cc4..69e5f58 100644 --- a/vdirsyncer/storage/base.py +++ b/vdirsyncer/storage/base.py @@ -29,15 +29,17 @@ class Storage(object): implement. Terminology: - - UID: Global identifier of the item, across storages. - - HREF: 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. - - ETAG: Checksum of item, or something similar that changes when the - object does. + - 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. + - ETAG: String; Checksum of item, or something similar that changes when the + item does. - All of the above properties should be strings. If bytestrings, an ASCII - encoding is assumed. + Strings can be either unicode strings or bytestrings. If bytestrings, an + ASCII encoding is assumed. :param collection: If None, the given URL or path is already directly referring to a collection. Otherwise it will be treated as a basepath @@ -77,7 +79,7 @@ class Storage(object): def get(self, href): ''' :param href: href to fetch - :returns: (object, etag) + :returns: (item, etag) ''' raise NotImplementedError() @@ -86,11 +88,11 @@ class Storage(object): :param hrefs: list of hrefs to fetch :raises: :exc:`vdirsyncer.exceptions.PreconditionFailed` if one of the items couldn't be found. - :returns: iterable of (href, obj, etag) + :returns: iterable of (href, item, etag) ''' for href in hrefs: - obj, etag = self.get(href) - yield href, obj, etag + item, etag = self.get(href) + yield href, item, etag def has(self, href): ''' @@ -99,17 +101,17 @@ class Storage(object): ''' raise NotImplementedError() - def upload(self, obj): + def upload(self, item): ''' - Upload a new object, raise + Upload a new item, raise :exc:`vdirsyncer.exceptions.PreconditionFailed` if it already exists. :returns: (href, etag) ''' raise NotImplementedError() - def update(self, href, obj, etag): + def update(self, href, item, etag): ''' - Update the object, raise + Update the item, raise :exc:`vdirsyncer.exceptions.PreconditionFailed` if the etag on the server doesn't match the given etag or if the item doesn't exist. @@ -119,7 +121,7 @@ class Storage(object): def delete(self, href, etag): ''' - Delete the object by href, raise + Delete the item by href, raise :exc:`vdirsyncer.exceptions.PreconditionFailed` when item has a different etag or doesn't exist. ''' diff --git a/vdirsyncer/storage/dav.py b/vdirsyncer/storage/dav.py index 5c44a52..9367044 100644 --- a/vdirsyncer/storage/dav.py +++ b/vdirsyncer/storage/dav.py @@ -103,9 +103,9 @@ class DavStorage(HttpStorageBase): response.raise_for_status() def get(self, href): - ((actual_href, obj, etag),) = self.get_multi([href]) + ((actual_href, item, etag),) = self.get_multi([href]) assert href == actual_href - return obj, etag + return item, etag def get_multi(self, hrefs): if not hrefs: @@ -129,7 +129,7 @@ class DavStorage(HttpStorageBase): for element in root.iter('{DAV:}response'): href = self._normalize_href( element.find('{DAV:}href').text.decode(response.encoding)) - obj = element \ + raw = element \ .find('{DAV:}propstat') \ .find('{DAV:}prop') \ .find(self.get_multi_data_query).text @@ -137,11 +137,11 @@ class DavStorage(HttpStorageBase): .find('{DAV:}propstat') \ .find('{DAV:}prop') \ .find('{DAV:}getetag').text - if isinstance(obj, bytes): - obj = obj.decode(response.encoding) + if isinstance(raw, bytes): + raw = raw.decode(response.encoding) if isinstance(etag, bytes): etag = etag.decode(response.encoding) - rv.append((href, Item(obj), etag)) + rv.append((href, Item(raw), etag)) try: hrefs_left.remove(href) except KeyError: @@ -159,7 +159,7 @@ class DavStorage(HttpStorageBase): else: return True - def _put(self, href, obj, etag): + def _put(self, href, item, etag): headers = self._default_headers() headers['Content-Type'] = self.item_mimetype if etag is None: @@ -171,25 +171,25 @@ class DavStorage(HttpStorageBase): response = self._request( 'PUT', href, - data=obj.raw.encode('utf-8'), + data=item.raw.encode('utf-8'), headers=headers ) self._check_response(response) etag = response.headers.get('etag', None) if not etag: - obj2, etag = self.get(href) - assert obj2.uid == obj.uid + item2, etag = self.get(href) + assert item2.uid == item.uid return href, etag - def update(self, href, obj, etag): + def update(self, href, item, etag): href = self._normalize_href(href) if etag is None: raise ValueError('etag must be given and must not be None.') - return self._put(href, obj, etag) + return self._put(href, item, etag) - def upload(self, obj): - href = self._get_href(obj.uid) - return self._put(href, obj, None) + def upload(self, item): + href = self._get_href(item.uid) + return self._put(href, item, None) def delete(self, href, etag): href = self._normalize_href(href) diff --git a/vdirsyncer/storage/filesystem.py b/vdirsyncer/storage/filesystem.py index 860291e..743b0c8 100644 --- a/vdirsyncer/storage/filesystem.py +++ b/vdirsyncer/storage/filesystem.py @@ -76,28 +76,28 @@ class FilesystemStorage(Storage): def has(self, href): return os.path.isfile(self._get_filepath(href)) - def upload(self, obj): - href = self._get_href(obj.uid) + def upload(self, item): + href = self._get_href(item.uid) fpath = self._get_filepath(href) if os.path.exists(fpath): - raise exceptions.AlreadyExistingError(obj.uid) + raise exceptions.AlreadyExistingError(item.uid) with open(fpath, 'wb+') as f: - f.write(obj.raw.encode(self.encoding)) + f.write(item.raw.encode(self.encoding)) return href, _get_etag(fpath) - def update(self, href, obj, etag): + def update(self, href, item, etag): fpath = self._get_filepath(href) - if href != self._get_href(obj.uid): + if href != self._get_href(item.uid): logger.warning('href != uid + fileext: href={}; uid={}' - .format(href, obj.uid)) + .format(href, item.uid)) if not os.path.exists(fpath): - raise exceptions.NotFoundError(obj.uid) + raise exceptions.NotFoundError(item.uid) actual_etag = _get_etag(fpath) if etag != actual_etag: raise exceptions.WrongEtagError(etag, actual_etag) with open(fpath, 'wb') as f: - f.write(obj.raw.encode('utf-8')) + f.write(item.raw.encode('utf-8')) return _get_etag(fpath) def delete(self, href, etag): diff --git a/vdirsyncer/storage/memory.py b/vdirsyncer/storage/memory.py index 93eb331..5748823 100644 --- a/vdirsyncer/storage/memory.py +++ b/vdirsyncer/storage/memory.py @@ -23,37 +23,37 @@ class MemoryStorage(Storage): ''' def __init__(self, **kwargs): - self.items = {} # href => (etag, object) + self.items = {} # href => (etag, item) super(MemoryStorage, self).__init__(**kwargs) def list(self): - for href, (etag, obj) in self.items.items(): + for href, (etag, item) in self.items.items(): yield href, etag def get(self, href): - etag, obj = self.items[href] - return obj, etag + etag, item = self.items[href] + return item, etag def has(self, href): return href in self.items - def upload(self, obj): - href = self._get_href(obj.uid) + def upload(self, item): + href = self._get_href(item.uid) if href in self.items: - raise exceptions.AlreadyExistingError(obj.uid) + raise exceptions.AlreadyExistingError(item.uid) etag = _get_etag() - self.items[href] = (etag, obj) + self.items[href] = (etag, item) return href, etag - def update(self, href, obj, etag): - if href != self._get_href(obj.uid) or href not in self.items: + def update(self, href, item, etag): + if href != self._get_href(item.uid) or href not in self.items: raise exceptions.NotFoundError(href) actual_etag, _ = self.items[href] if etag != actual_etag: raise exceptions.WrongEtagError(etag, actual_etag) new_etag = _get_etag() - self.items[href] = (new_etag, obj) + self.items[href] = (new_etag, item) return new_etag def delete(self, href, etag): diff --git a/vdirsyncer/sync.py b/vdirsyncer/sync.py index 41e320d..f58c375 100644 --- a/vdirsyncer/sync.py +++ b/vdirsyncer/sync.py @@ -23,21 +23,21 @@ def prepare_list(storage, href_to_uid): if href in href_to_uid: props['uid'] = href_to_uid[href] else: - obj, new_etag = storage.get(href) + item, new_etag = storage.get(href) assert etag == new_etag - props['uid'] = obj.uid - props['obj'] = obj + props['uid'] = item.uid + props['item'] = item yield href, props def prefetch(storage, item_list, hrefs): hrefs_to_prefetch = [] for href in hrefs: - if 'obj' not in item_list[href]: + if 'item' not in item_list[href]: hrefs_to_prefetch.append(href) - for href, obj, etag in storage.get_multi(hrefs_to_prefetch): + for href, item, etag in storage.get_multi(hrefs_to_prefetch): assert item_list[href]['etag'] == etag - item_list[href]['obj'] = obj + item_list[href]['item'] = item def sync(storage_a, storage_b, status, conflict_resolution=None): @@ -63,7 +63,7 @@ def sync(storage_a, storage_b, status, conflict_resolution=None): (href_b, uid) for uid, (href_a, etag_a, href_b, etag_b) in status.iteritems() ) - # href => {'etag': etag, 'obj': optional object, 'uid': uid} + # href => {'etag': etag, 'item': optional item, 'uid': uid} list_a = dict(prepare_list(storage_a, a_href_to_uid)) list_b = dict(prepare_list(storage_b, b_href_to_uid)) @@ -97,8 +97,8 @@ def action_upload(uid, source, dest): source_href = source_uid_to_href[uid] source_etag = source_list[source_href]['etag'] - obj = source_list[source_href]['obj'] - dest_href, dest_etag = dest_storage.upload(obj) + item = source_list[source_href]['item'] + dest_href, dest_etag = dest_storage.upload(item) source_status = (source_href, source_etag) dest_status = (dest_href, dest_etag) @@ -119,8 +119,8 @@ def action_update(uid, source, dest): dest_href = dest_uid_to_href[uid] old_etag = dest_list[dest_href]['etag'] - obj = source_list[source_href]['obj'] - dest_etag = dest_storage.update(dest_href, obj, old_etag) + item = source_list[source_href]['item'] + dest_etag = dest_storage.update(dest_href, item, old_etag) source_status = (source_href, source_etag) dest_status = (dest_href, dest_etag) @@ -157,7 +157,7 @@ def action_conflict_resolve(uid): b_href = b_uid_to_href[uid] a_meta = list_a[a_href] b_meta = list_b[b_href] - if a_meta['obj'].raw == b_meta['obj'].raw: + if a_meta['item'].raw == b_meta['item'].raw: sync_logger.info('...same content on both sides.') status[uid] = a_href, a_meta['etag'], b_href, b_meta['etag'] elif conflict_resolution is None: