mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Storage API improvements
This commit is contained in:
parent
ca92d9a428
commit
473596a573
3 changed files with 44 additions and 25 deletions
|
|
@ -29,20 +29,28 @@ class Storage(object):
|
||||||
self.fileext = fileext
|
self.fileext = fileext
|
||||||
self.item_class = item_class
|
self.item_class = item_class
|
||||||
|
|
||||||
def list_items(self):
|
def list(self):
|
||||||
'''
|
'''
|
||||||
:returns: list of (uid, etag)
|
:returns: list of (uid, etag)
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_items(self, uids):
|
def get(self, uid):
|
||||||
'''
|
'''
|
||||||
:param uids: list of uids to fetch
|
:param uid: uid to fetch
|
||||||
:returns: list of (object, uid, etag)
|
:returns: (object, uid, etag)
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def item_exists(self, uid):
|
def get_multi(self, uids):
|
||||||
|
'''
|
||||||
|
:param uids: list of uids to fetch
|
||||||
|
:returns: iterable of (object, uid, etag)
|
||||||
|
'''
|
||||||
|
for uid in uids:
|
||||||
|
yield self.get(uid)
|
||||||
|
|
||||||
|
def has(self, uid):
|
||||||
'''
|
'''
|
||||||
check if item exists
|
check if item exists
|
||||||
:returns: True or False
|
:returns: True or False
|
||||||
|
|
@ -67,8 +75,9 @@ class Storage(object):
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def delete(self, uid):
|
def delete(self, uid, etag):
|
||||||
'''
|
'''
|
||||||
Delete the object, raise exceptions on error, no return value
|
Delete the object, raise exceptions when etag doesn't match, no return
|
||||||
|
value
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
||||||
|
|
@ -23,20 +23,19 @@ class FilesystemStorage(Storage):
|
||||||
def _get_filepath(self, uid):
|
def _get_filepath(self, uid):
|
||||||
return os.path.join(self.path, uid + self.fileext)
|
return os.path.join(self.path, uid + self.fileext)
|
||||||
|
|
||||||
def list_items(self):
|
def list(self):
|
||||||
for fname in os.listdir(self.path):
|
for fname in os.listdir(self.path):
|
||||||
fpath = os.path.join(self.path, fname)
|
fpath = os.path.join(self.path, fname)
|
||||||
if os.path.isfile(fpath) and fname.endswith(self.fileext):
|
if os.path.isfile(fpath) and fname.endswith(self.fileext):
|
||||||
uid = fname[:-len(self.fileext)]
|
uid = fname[:-len(self.fileext)]
|
||||||
yield uid, os.path.getmtime(fpath)
|
yield uid, os.path.getmtime(fpath)
|
||||||
|
|
||||||
def get_items(self, uids):
|
def get(self, uid):
|
||||||
for uid in uids:
|
fpath = self._get_filepath(uid)
|
||||||
fpath = self._get_filepath(uid)
|
with open(fpath, 'rb') as f:
|
||||||
with open(fpath, 'rb') as f:
|
return Item(f.read()), uid, os.path.getmtime(fpath)
|
||||||
yield Item(f.read()), uid, os.path.getmtime(fpath)
|
|
||||||
|
|
||||||
def item_exists(self, uid):
|
def has(self, uid):
|
||||||
return os.path.isfile(self._get_filepath(uid))
|
return os.path.isfile(self._get_filepath(uid))
|
||||||
|
|
||||||
def upload(self, obj):
|
def upload(self, obj):
|
||||||
|
|
@ -54,9 +53,13 @@ class FilesystemStorage(Storage):
|
||||||
actual_etag = os.path.getmtime(fpath)
|
actual_etag = os.path.getmtime(fpath)
|
||||||
if etag != actual_etag:
|
if etag != actual_etag:
|
||||||
raise exceptions.WrongEtagError(etag, actual_etag)
|
raise exceptions.WrongEtagError(etag, actual_etag)
|
||||||
|
|
||||||
with open(fpath, 'wb') as f:
|
with open(fpath, 'wb') as f:
|
||||||
f.write(obj.raw)
|
f.write(obj.raw)
|
||||||
return os.path.getmtime(fpath)
|
return os.path.getmtime(fpath)
|
||||||
|
|
||||||
def delete(self, uid):
|
def delete(self, uid, etag):
|
||||||
os.remove(self._get_filepath(uid))
|
fpath = self._get_filepath(uid)
|
||||||
|
if etag != os.path.getmtime(fpath):
|
||||||
|
raise exceptions.WrongEtagError(etag, actual_etag)
|
||||||
|
os.remove(fpath)
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,15 @@ class MemoryStorage(Storage):
|
||||||
self.items = {} # uid => (etag, object)
|
self.items = {} # uid => (etag, object)
|
||||||
super(MemoryStorage, self).__init__(**kwargs)
|
super(MemoryStorage, self).__init__(**kwargs)
|
||||||
|
|
||||||
def list_items(self):
|
def list(self):
|
||||||
for uid, (etag, obj) in self.items.items():
|
for uid, (etag, obj) in self.items.items():
|
||||||
yield uid, etag
|
yield uid, etag
|
||||||
|
|
||||||
def get_items(self, uids):
|
def get(self, uid):
|
||||||
for uid in uids:
|
etag, obj = self.items[uid]
|
||||||
etag, obj = self.items[uid]
|
return obj, uid, etag
|
||||||
yield obj, uid, etag
|
|
||||||
|
|
||||||
def item_exists(self, uid):
|
def has(self, uid):
|
||||||
return uid in self.items
|
return uid in self.items
|
||||||
|
|
||||||
def upload(self, obj):
|
def upload(self, obj):
|
||||||
|
|
@ -41,9 +40,17 @@ class MemoryStorage(Storage):
|
||||||
def update(self, obj, etag):
|
def update(self, obj, etag):
|
||||||
if obj.uid not in self.items:
|
if obj.uid not in self.items:
|
||||||
raise exceptions.NotFoundError(obj)
|
raise exceptions.NotFoundError(obj)
|
||||||
etag = datetime.datetime.now()
|
actual_etag, _ = self.items[obj.uid]
|
||||||
self.items[obj.uid] = (etag, obj)
|
if etag != actual_etag:
|
||||||
|
raise exceptions.WrongEtagError(etag, actual_etag)
|
||||||
|
|
||||||
|
new_etag = datetime.datetime.now()
|
||||||
|
self.items[obj.uid] = (new_etag, obj)
|
||||||
return etag
|
return etag
|
||||||
|
|
||||||
def delete(self, uid):
|
def delete(self, uid, etag):
|
||||||
|
if not self.has(uid):
|
||||||
|
raise exceptions.NotFoundError(uid)
|
||||||
|
if etag != self.items[uid][0]:
|
||||||
|
raise exceptions.WrongEtagError(etag)
|
||||||
del self.items[uid]
|
del self.items[uid]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue