From 7743372ee430a4e76828d7eb1c7712d18f5c3fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 11 Jan 2016 16:42:05 +0100 Subject: [PATCH] Slugify file names on local storage Just stripping anything non-ASCII leads to errors with UTF-8 only filenames. Closes #1181 --- setup.py | 3 ++- src/octoprint/filemanager/storage.py | 16 ++++++++-------- tests/filemanager/test_localstorage.py | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/setup.py b/setup.py index 86b7837f..911a482a 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,8 @@ INSTALL_REQUIRES = [ "pkginfo==1.2.1", "requests==2.7.0", "semantic_version==2.4.2", - "psutil==3.2.1" + "psutil==3.2.1", + "awesome-slugify>=1.6.5,<1.7" ] # Additional requirements for optional install options diff --git a/src/octoprint/filemanager/storage.py b/src/octoprint/filemanager/storage.py index 6a2378dd..bbbc51aa 100644 --- a/src/octoprint/filemanager/storage.py +++ b/src/octoprint/filemanager/storage.py @@ -311,6 +311,10 @@ class LocalFileStorage(StorageInterface): self._metadata_cache = pylru.lrucache(10) + from slugify import Slugify + self._slugify = Slugify() + self._slugify.safe_chars = "-_.() " + self._old_metadata = None self._initialize_metadata() @@ -609,9 +613,9 @@ class LocalFileStorage(StorageInterface): def sanitize_name(self, name): """ - Raises a :class:`ValueError` for a ``name`` containing ``/`` or ``\``. Otherwise strips any characters from the - given ``name`` that are not any of the ASCII characters, digits, ``-``, ``_``, ``.``, ``(``, ``)`` or space and - replaces and spaces with ``_``. + Raises a :class:`ValueError` for a ``name`` containing ``/`` or ``\``. Otherwise + slugifies the given ``name`` by converting it to ASCII, leaving ``-``, ``_``, ``.``, + ``(``, and ``)`` as is. """ if name is None: return None @@ -619,11 +623,7 @@ class LocalFileStorage(StorageInterface): if "/" in name or "\\" in name: raise ValueError("name must not contain / or \\") - import string - valid_chars = "-_.() {ascii}{digits}".format(ascii=string.ascii_letters, digits=string.digits) - sanitized_name = ''.join(c for c in name if c in valid_chars) - sanitized_name = sanitized_name.replace(" ", "_") - return sanitized_name + return self._slugify(name).replace(" ", "_") def sanitize_path(self, path): """ diff --git a/tests/filemanager/test_localstorage.py b/tests/filemanager/test_localstorage.py index 87bc9b9c..1c61a6e0 100644 --- a/tests/filemanager/test_localstorage.py +++ b/tests/filemanager/test_localstorage.py @@ -309,8 +309,8 @@ class LocalStorageTest(unittest.TestCase): @data( ("some_file.gco", "some_file.gco"), - ("some_file with (parentheses) and ümläuts and digits 123.gco", "some_file_with_(parentheses)_and_mluts_and_digits_123.gco"), - ("pengüino pequeño.stl", "pengino_pequeo.stl") + ("some_file with (parentheses) and ümläuts and digits 123.gco", "some_file_with_(parentheses)_and_umlauts_and_digits_123.gco"), + ("pengüino pequeño.stl", "penguino_pequeno.stl") ) @unpack def test_sanitize_name(self, input, expected):