mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-28 09:25:50 +00:00
Make etags always strings.
This somewhat helps with environments where ducktyping is not an option (e.g. databases)
This commit is contained in:
parent
08d3a6f2e0
commit
3670bed66d
4 changed files with 22 additions and 9 deletions
|
|
@ -41,6 +41,8 @@ class StorageTests(object):
|
|||
hrefs.sort()
|
||||
assert hrefs == sorted(s.list())
|
||||
for href, etag in hrefs:
|
||||
assert isinstance(href, (str, unicode))
|
||||
assert isinstance(etag, (str, unicode))
|
||||
assert s.has(href)
|
||||
obj, etag2 = s.get(href)
|
||||
assert etag == etag2
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ class Storage(object):
|
|||
- ETAG: Checksum of item, or something similar that changes when the
|
||||
object does.
|
||||
|
||||
All of the above properties should be strings. 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
|
||||
to many collections (e.g. a vdir) and the given collection name will be
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ import vdirsyncer.log as log
|
|||
logger = log.get('storage.filesystem')
|
||||
|
||||
|
||||
def _get_etag(fpath):
|
||||
return '{:.9f}'.format(os.path.getmtime(fpath))
|
||||
|
||||
|
||||
class FilesystemStorage(Storage):
|
||||
|
||||
'''Saves data in vdir collection
|
||||
|
|
@ -61,13 +65,13 @@ class FilesystemStorage(Storage):
|
|||
for fname in os.listdir(self.path):
|
||||
fpath = os.path.join(self.path, fname)
|
||||
if os.path.isfile(fpath) and fname.endswith(self.fileext):
|
||||
yield fname, os.path.getmtime(fpath)
|
||||
yield fname, _get_etag(fpath)
|
||||
|
||||
def get(self, href):
|
||||
fpath = self._get_filepath(href)
|
||||
with open(fpath, 'rb') as f:
|
||||
return (Item(f.read().decode(self.encoding)),
|
||||
os.path.getmtime(fpath))
|
||||
_get_etag(fpath))
|
||||
|
||||
def has(self, href):
|
||||
return os.path.isfile(self._get_filepath(href))
|
||||
|
|
@ -79,7 +83,7 @@ class FilesystemStorage(Storage):
|
|||
raise exceptions.AlreadyExistingError(obj.uid)
|
||||
with open(fpath, 'wb+') as f:
|
||||
f.write(obj.raw.encode(self.encoding))
|
||||
return href, os.path.getmtime(fpath)
|
||||
return href, _get_etag(fpath)
|
||||
|
||||
def update(self, href, obj, etag):
|
||||
fpath = self._get_filepath(href)
|
||||
|
|
@ -88,19 +92,19 @@ class FilesystemStorage(Storage):
|
|||
.format(href, obj.uid))
|
||||
if not os.path.exists(fpath):
|
||||
raise exceptions.NotFoundError(obj.uid)
|
||||
actual_etag = os.path.getmtime(fpath)
|
||||
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'))
|
||||
return os.path.getmtime(fpath)
|
||||
return _get_etag(fpath)
|
||||
|
||||
def delete(self, href, etag):
|
||||
fpath = self._get_filepath(href)
|
||||
if not os.path.isfile(fpath):
|
||||
raise exceptions.NotFoundError(href)
|
||||
actual_etag = os.path.getmtime(fpath)
|
||||
actual_etag = _get_etag(fpath)
|
||||
if etag != actual_etag:
|
||||
raise exceptions.WrongEtagError(etag, actual_etag)
|
||||
os.remove(fpath)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,15 @@
|
|||
:license: MIT, see LICENSE for more details.
|
||||
'''
|
||||
|
||||
import datetime
|
||||
import random
|
||||
from vdirsyncer.storage.base import Storage
|
||||
import vdirsyncer.exceptions as exceptions
|
||||
|
||||
|
||||
def _get_etag():
|
||||
return '{:.9f}'.format(random.random())
|
||||
|
||||
|
||||
class MemoryStorage(Storage):
|
||||
|
||||
'''
|
||||
|
|
@ -37,7 +41,7 @@ class MemoryStorage(Storage):
|
|||
href = self._get_href(obj.uid)
|
||||
if href in self.items:
|
||||
raise exceptions.AlreadyExistingError(obj.uid)
|
||||
etag = datetime.datetime.now()
|
||||
etag = _get_etag()
|
||||
self.items[href] = (etag, obj)
|
||||
return href, etag
|
||||
|
||||
|
|
@ -48,7 +52,7 @@ class MemoryStorage(Storage):
|
|||
if etag != actual_etag:
|
||||
raise exceptions.WrongEtagError(etag, actual_etag)
|
||||
|
||||
new_etag = datetime.datetime.now()
|
||||
new_etag = _get_etag()
|
||||
self.items[href] = (new_etag, obj)
|
||||
return new_etag
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue