Skip to content

Commit 5844480

Browse files
author
Hugo Osvaldo Barrera
authored
Merge pull request #889 from Intevation/dev-issue881
Implement more flexibility for storage/filesystem
2 parents 5c00cce + b9f5d88 commit 5844480

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

docs/config.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ Local
408408
fileext = "..."
409409
#encoding = "utf-8"
410410
#post_hook = null
411+
#fileignoreext = ".tmp"
411412

412413
Can be used with `khal <http://lostpackets.de/khal/>`_. See :doc:`vdir` for
413414
a more formal description of the format.
@@ -421,11 +422,15 @@ Local
421422
:param fileext: The file extension to use (e.g. ``.txt``). Contained in the
422423
href, so if you change the file extension after a sync, this will
423424
trigger a re-download of everything (but *should* not cause data-loss
424-
of any kind).
425+
of any kind). To be compatible with the ``vset`` format you have
426+
to either use ``.vcf`` or ``.ics``. Note that metasync won't work
427+
if you use an empty string here.
425428
:param encoding: File encoding for items, both content and filename.
426429
:param post_hook: A command to call for each item creation and
427430
modification. The command will be called with the path of the
428431
new/updated file.
432+
:param fileeignoreext: The file extention to ignore. It is only useful
433+
if fileext is set to the empty string. The default is ``.tmp``.
429434

430435
.. storage:: singlefile
431436

tests/storage/test_filesystem.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,36 @@ def test_ident_with_slash(self, tmpdir):
4444
(item_file,) = tmpdir.listdir()
4545
assert "/" not in item_file.basename and item_file.isfile()
4646

47+
def test_ignore_tmp_files(self, tmpdir):
48+
"""Test that files with .tmp suffix beside .ics files are ignored."""
49+
s = self.storage_class(str(tmpdir), '.ics')
50+
s.upload(Item('UID:xyzxyz'))
51+
item_file, = tmpdir.listdir()
52+
item_file.copy(item_file.new(ext='tmp'))
53+
assert len(tmpdir.listdir()) == 2
54+
assert len(list(s.list())) == 1
55+
56+
def test_ignore_tmp_files_empty_fileext(self, tmpdir):
57+
"""Test that files with .tmp suffix are ignored with empty fileext."""
58+
s = self.storage_class(str(tmpdir), '')
59+
s.upload(Item('UID:xyzxyz'))
60+
item_file, = tmpdir.listdir()
61+
item_file.copy(item_file.new(ext='tmp'))
62+
assert len(tmpdir.listdir()) == 2
63+
# assert False, tmpdir.listdir() # enable to see the created filename
64+
assert len(list(s.list())) == 1
65+
66+
def test_ignore_files_typical_backup(self, tmpdir):
67+
"""Test file-name ignorance with typical backup ending ~."""
68+
ignorext = "~" # without dot
69+
s = self.storage_class(str(tmpdir), '', fileignoreext="~")
70+
s.upload(Item('UID:xyzxyz'))
71+
item_file, = tmpdir.listdir()
72+
item_file.copy(item_file.new(basename=item_file.basename+'~'))
73+
assert len(tmpdir.listdir()) == 2
74+
#assert False, tmpdir.listdir() # enable to see the created filename
75+
assert len(list(s.list())) == 1
76+
4777
def test_too_long_uid(self, tmpdir):
4878
s = self.storage_class(str(tmpdir), ".txt")
4979
item = Item("UID:" + "hue" * 600)

vdirsyncer/storage/filesystem.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,22 @@ class FilesystemStorage(Storage):
2222
storage_name = "filesystem"
2323
_repr_attributes = ("path",)
2424

25-
def __init__(self, path, fileext, encoding="utf-8", post_hook=None, **kwargs):
25+
def __init__(
26+
self,
27+
path,
28+
fileext,
29+
encoding="utf-8",
30+
post_hook=None,
31+
fileignoreext=".tmp",
32+
**kwargs
33+
):
2634
super().__init__(**kwargs)
2735
path = expand_path(path)
2836
checkdir(path, create=False)
2937
self.path = path
3038
self.encoding = encoding
3139
self.fileext = fileext
40+
self.fileignoreext = fileignoreext
3241
self.post_hook = post_hook
3342

3443
@classmethod
@@ -80,7 +89,11 @@ def _get_href(self, ident):
8089
def list(self):
8190
for fname in os.listdir(self.path):
8291
fpath = os.path.join(self.path, fname)
83-
if os.path.isfile(fpath) and fname.endswith(self.fileext):
92+
if (
93+
os.path.isfile(fpath)
94+
and fname.endswith(self.fileext)
95+
and (not fname.endswith(self.fileignoreext))
96+
):
8497
yield fname, get_etag_from_file(fpath)
8598

8699
def get(self, href):

0 commit comments

Comments
 (0)