API change to use only UIDs

This commit is contained in:
Markus Unterwaditzer 2014-02-15 12:10:30 +01:00
parent 32b0ac5a6b
commit e03a677df4
4 changed files with 55 additions and 66 deletions

View file

@ -1,14 +1,16 @@
class Item(object):
'''wrapper class for VCALENDAR and VCARD'''
'''should-be-immutable wrapper class for VCALENDAR and VCARD'''
def __init__(self, raw):
self.raw = raw
self._uid = None
@property
def uid(self):
for line in self.raw.splitlines():
if line.startswith(b'UID'):
return line.lstrip(b'UID:').strip()
if self._uid is None:
for line in self.raw.splitlines():
if line.startswith(b'UID'):
self._uid = line.lstrip(b'UID:').strip()
return self._uid
class Storage(object):
@ -18,18 +20,18 @@ class Storage(object):
def list_items(self):
'''
:returns: list of (href, etag)
:returns: list of (uid, etag)
'''
raise NotImplementedError()
def get_items(self, hrefs):
def get_items(self, uids):
'''
:param hrefs: list of hrefs to fetch
:returns: list of (object, href, etag)
:param uids: list of uids to fetch
:returns: list of (object, uid, etag)
'''
raise NotImplementedError()
def item_exists(self, href):
def item_exists(self, uid):
'''
check if item exists
:returns: True or False
@ -40,7 +42,7 @@ class Storage(object):
'''
Upload a new object, raise
:exc:`vdirsyncer.exceptions.AlreadyExistingError` if it already exists.
:returns: (href, etag)
:returns: (uid, etag)
'''
raise NotImplementedError()

View file

@ -7,46 +7,40 @@ class FilesystemStorage(Storage):
self.path = path
super(FilesystemStorage, self).__init__(**kwargs)
def _get_etag(self, href):
return os.path.getmtime(href)
def _get_href(self, obj):
return os.path.join(self.path, obj.uid + self.fileext)
def _get_hrefs(self):
for fname in os.listdir(self.path):
href = os.path.join(self.path, fname)
if os.path.isfile(href):
yield href
def _get_filepath(self, uid):
return os.path.join(self.path, uid + self.fileext)
def list_items(self):
for href in self._get_hrefs():
yield href, self._get_etag(href)
for fname in os.listdir(self.path):
fpath = os.path.join(self.path, fname)
if os.path.isfile(fpath) and fname.endswith(self.fileext):
uid = fname[:-len(self.fileext)]
yield uid, os.path.getmtime(fpath)
def get_items(self, hrefs):
for href in hrefs:
with open(href, 'rb') as f:
yield Item(f.read()), href, self._get_etag(href)
def get_items(self, uids):
for uid in uids:
fpath = self._get_filepath(uid)
with open(fpath, 'rb') as f:
yield Item(f.read()), uid, os.path.getmtime(fpath)
def item_exists(self, href):
return os.path.isfile(path)
def item_exists(self, uid):
return os.path.isfile(self._get_filepath(uid))
def upload(self, obj):
href = self._get_href(obj)
if os.path.exists(href):
raise exceptions.AlreadyExistingError(href)
with open(href, 'wb+') as f:
fpath = self._get_filepath(obj.uid)
if os.path.exists(fpath):
raise exceptions.AlreadyExistingError(obj.uid)
with open(fpath, 'wb+') as f:
f.write(obj.raw)
return href, self._get_etag(href)
return obj.uid, os.path.getmtime(fpath)
def update(self, obj, etag):
href = self._get_href(obj)
actual_etag = self._get_etag(href)
fpath = self._get_filepath(obj)
if not os.path.exists(fpath):
raise exceptions.NotFoundError(href)
actual_etag = os.path.getmtime(fpath)
if etag != actual_etag:
raise exceptions.WrongEtagError(etag, actual_etag)
if not os.path.exists(href):
raise exceptions.NotFoundError(href)
with open(href, 'wb') as f:
with open(fpath, 'wb') as f:
f.write(obj.raw)
return self._get_etag(href)
return os.path.getmtime(fpath)

View file

@ -4,36 +4,31 @@ import vdirsyncer.exceptions as exceptions
class MemoryStorage(Storage):
def __init__(self, **kwargs):
self.items = {} # href => (etag, object)
self.items = {} # uid => (etag, object)
super(MemoryStorage, self).__init__(**kwargs)
def _get_href(self, obj):
return obj.uid + self.fileext
def list_items(self):
for href, (etag, obj) in self.items.items():
yield href, etag
for uid, (etag, obj) in self.items.items():
yield uid, etag
def get_items(self, hrefs):
for href in hrefs:
etag, obj = self.items[href]
return obj, href, etag
def get_items(self, uids):
for uid in uids:
etag, obj = self.items[uid]
return obj, uid, etag
def item_exists(self, href):
return href in self.items
def item_exists(self, uid):
return uid in self.items
def upload(self, obj):
href = self._get_href(obj)
if href in self.items:
if obj.uid in self.items:
raise exceptions.AlreadyExistingError(obj)
etag = datetime.datetime.now()
self.items[href] = (etag, obj)
return href, etag
self.items[obj.uid] = (etag, obj)
return obj.uid, etag
def update(self, obj, etag):
href = self._get_href(obj)
if href not in self.items:
if obj.uid not in self.items:
raise exceptions.NotFoundError(obj)
etag = datetime.datetime.now()
self.items[href] = (etag, obj)
return href, etag
self.items[obj.uid] = (etag, obj)
return obj.uid, etag

View file

@ -22,14 +22,12 @@ class StorageTests(object):
'UID:8',
'UID:9'
]
fileext = ''
fileext = '.lol'
s = self._get_storage(fileext=fileext)
for item in items:
s.upload(Item(item))
hrefs = [href for href, etag in s.list_items()]
prefix = os.path.commonprefix(hrefs)
a = set(x[len(prefix):] for x in hrefs)
b = set(str(y) + fileext for y in range(1, 10))
a = set(uid for uid, etag in s.list_items())
b = set(str(y) for y in range(1, 10))
assert a == b