diff --git a/docs/vdir.rst b/docs/vdir.rst index 0d510c8..3c5a1e0 100644 --- a/docs/vdir.rst +++ b/docs/vdir.rst @@ -20,7 +20,7 @@ An item is: An item *should* contain a ``UID`` property as described by the vCard and iCalendar standards. -The filename *must* consist of the ``ident``, followed by the file extension. +The filename *should* consist of the ``ident``, followed by the file extension. The ``ident`` is either the ``UID``, if the item has one, else a string with similar properties as the ``UID``: @@ -32,6 +32,9 @@ similar properties as the ``UID``: -- The vCard_ RFC +Character limitations imposed by the filesystem *should* be circumvented by +replacing the offending characters with underscores ``_``. + One reason this format was chosen is due to its compatibility with the CardDAV_ and CalDAV_ standards. diff --git a/tests/storage/test_filesystem.py b/tests/storage/test_filesystem.py index 8921522..5097307 100644 --- a/tests/storage/test_filesystem.py +++ b/tests/storage/test_filesystem.py @@ -12,6 +12,7 @@ import os import pytest +from vdirsyncer.utils.vobject import Item from vdirsyncer.storage.filesystem import FilesystemStorage from . import StorageTests @@ -55,3 +56,9 @@ class TestFilesystemStorage(StorageTests): with pytest.raises(TypeError): s.upload(BrokenItem) assert not tmpdir.listdir() + + def test_ident_with_slash(self, tmpdir): + s = self.storage_class(str(tmpdir), '.txt') + s.upload(Item(u'UID:a/b/c')) + item_file, = tmpdir.listdir() + assert str(item_file).endswith('a_b_c.txt') diff --git a/vdirsyncer/storage/filesystem.py b/vdirsyncer/storage/filesystem.py index e47b7bc..19be94e 100644 --- a/vdirsyncer/storage/filesystem.py +++ b/vdirsyncer/storage/filesystem.py @@ -62,7 +62,9 @@ class FilesystemStorage(Storage): return os.path.join(self.path, href) def _get_href(self, item): - return item.ident + self.fileext + # XXX: POSIX only defines / and \0 as invalid chars, but we should make + # this work crossplatform. + return item.ident.replace('/', '_') + self.fileext def list(self): for fname in os.listdir(self.path):