Ident is now a property of Item

This commit is contained in:
Markus Unterwaditzer 2014-05-14 15:13:21 +02:00
parent b87abfa4c0
commit 98a9748392
4 changed files with 22 additions and 6 deletions

View file

@ -50,6 +50,7 @@ class TestFilesystemStorage(StorageTests):
class BrokenItem(object): class BrokenItem(object):
raw = u'Ц, Ш, Л, ж, Д, З, Ю'.encode('utf-8') raw = u'Ц, Ш, Л, ж, Д, З, Ю'.encode('utf-8')
uid = 'jeezus' uid = 'jeezus'
ident = uid
with pytest.raises(TypeError): with pytest.raises(TypeError):
s.upload(BrokenItem) s.upload(BrokenItem)
assert not tmpdir.listdir() assert not tmpdir.listdir()

View file

@ -15,12 +15,27 @@ from .. import utils
class Item(object): 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): def __init__(self, raw):
assert isinstance(raw, utils.text_type) assert isinstance(raw, utils.text_type)
raw = raw.splitlines() raw = raw.splitlines()
self.uid = None
for line in raw: for line in raw:
if line.startswith(u'UID:'): if line.startswith(u'UID:'):
@ -30,6 +45,7 @@ class Item(object):
self.raw = u'\n'.join(raw) self.raw = u'\n'.join(raw)
self.hash = hashlib.sha256(self.raw.encode('utf-8')).hexdigest() self.hash = hashlib.sha256(self.raw.encode('utf-8')).hexdigest()
self.ident = self.uid or self.hash
class Storage(object): class Storage(object):
@ -40,7 +56,6 @@ class Storage(object):
Terminology: Terminology:
- ITEM: Instance of the Item class, represents a calendar event, task or - ITEM: Instance of the Item class, represents a calendar event, task or
contact. contact.
- UID: String; Global identifier of the item, across storages.
- HREF: String; Per-storage identifier of item, might be UID. The reason - 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 items aren't just referenced by their UID is because the CalDAV and
CardDAV specifications make this imperformant to implement. CardDAV specifications make this imperformant to implement.
@ -71,7 +86,7 @@ class Storage(object):
raise NotImplementedError() raise NotImplementedError()
def _get_href(self, item): def _get_href(self, item):
return (item.uid or item.hash) + self.fileext return item.ident + self.fileext
def __repr__(self): def __repr__(self):
return '<{}(**{})>'.format( return '<{}(**{})>'.format(

View file

@ -122,7 +122,7 @@ class DavStorage(Storage):
return utils.urlunquote_plus(utils.urlparse.urlsplit(x).path) return utils.urlunquote_plus(utils.urlparse.urlsplit(x).path)
def _get_href(self, item): 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) return self._normalize_href(href)
def _request(self, method, path, data=None, headers=None): def _request(self, method, path, data=None, headers=None):

View file

@ -61,7 +61,7 @@ def prepare_list(storage, href_to_status):
for href, item, etag in storage.get_multi(download): for href, item, etag in storage.get_multi(download):
props = rv[href] props = rv[href]
props['item'] = item props['item'] = item
props['ident'] = item.uid or item.hash props['ident'] = item.ident
if props['etag'] != etag: if props['etag'] != etag:
raise SyncConflict('Etag changed during sync.') raise SyncConflict('Etag changed during sync.')