mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Add filesystem storage
This commit is contained in:
parent
be81b48060
commit
34e2c8e9dd
3 changed files with 79 additions and 2 deletions
8
vdirsyncer/exceptions.py
Normal file
8
vdirsyncer/exceptions.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
class Error(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class AlreadyExistingError(Error):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class WrongEtagError(Error):
|
||||||
|
pass
|
||||||
|
|
@ -1,4 +1,21 @@
|
||||||
class Syncer(object):
|
class Item(object):
|
||||||
|
'''wrapper class for VCALENDAR and VCARD'''
|
||||||
|
def __init__(self, raw):
|
||||||
|
self.raw = raw
|
||||||
|
self._uid = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def uid(self):
|
||||||
|
for line in raw.splitlines():
|
||||||
|
if line.startswith(b'UID'):
|
||||||
|
return line.lstrip(b'UID:').strip()
|
||||||
|
|
||||||
|
|
||||||
|
class Storage(object):
|
||||||
|
def __init__(self, fileext, item_class=Item):
|
||||||
|
self.fileext = fileext
|
||||||
|
self.item_class = item_class
|
||||||
|
|
||||||
def list_items(self):
|
def list_items(self):
|
||||||
'''
|
'''
|
||||||
:returns: list of (href, etag)
|
:returns: list of (href, etag)
|
||||||
|
|
@ -15,12 +32,14 @@ class Syncer(object):
|
||||||
def item_exists(self, href):
|
def item_exists(self, href):
|
||||||
'''
|
'''
|
||||||
check if item exists
|
check if item exists
|
||||||
|
:returns: True or False
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def upload(self, obj):
|
def upload(self, obj):
|
||||||
'''
|
'''
|
||||||
Upload a new object, raise error if it already exists.
|
Upload a new object, raise
|
||||||
|
:exc:`vdirsyncer.exceptions.AlreadyExistingError` if it already exists.
|
||||||
:returns: (href, etag)
|
:returns: (href, etag)
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
50
vdirsyncer/storage/filesystem.py
Normal file
50
vdirsyncer/storage/filesystem.py
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import os
|
||||||
|
from vdirsyncer.storage.base import Storage, Item
|
||||||
|
from vdirsyncer.exceptions import AlreadyExistingError
|
||||||
|
|
||||||
|
class FilesystemStorage(Storage):
|
||||||
|
def __init__(self, path, **kwargs):
|
||||||
|
self.path = path
|
||||||
|
super(FilesystemStorage, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
def _get_etag(self, href):
|
||||||
|
return os.path.getmtime(href)
|
||||||
|
|
||||||
|
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 list_items(self):
|
||||||
|
for href in self._get_hrefs():
|
||||||
|
yield href, self._get_etag(href)
|
||||||
|
|
||||||
|
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 item_exists(self, href):
|
||||||
|
return os.path.isfile(path)
|
||||||
|
|
||||||
|
def _get_href(self, obj):
|
||||||
|
return os.path.join(self.path, obj.uid + b'b' + self.fileext)
|
||||||
|
|
||||||
|
def upload(self, obj):
|
||||||
|
href = self._get_href(obj)
|
||||||
|
if os.path.exists(href):
|
||||||
|
raise AlreadyExistingError(href)
|
||||||
|
with open(href, 'wb+') as f:
|
||||||
|
f.write(obj.raw)
|
||||||
|
return href, self._get_etag(href)
|
||||||
|
|
||||||
|
def update(self, obj, etag):
|
||||||
|
href = self._get_href(obj)
|
||||||
|
actual_etag = self._get_etag(href)
|
||||||
|
if etag != actual_etag:
|
||||||
|
raise WrongEtagError(etag, actual_etag)
|
||||||
|
|
||||||
|
with open(href, 'wb') as f:
|
||||||
|
f.write(obj.raw)
|
||||||
|
return self._get_etag(href)
|
||||||
Loading…
Reference in a new issue