From d6fbe51ef59ed87d65b3e8d4c8e2d1fb8c068259 Mon Sep 17 00:00:00 2001 From: RandomJo Date: Wed, 30 Jan 2019 15:58:18 -0600 Subject: [PATCH 1/5] Fix rmtree method of S3BotoStorageMixin The listdir function returns two values, one for directory names and one for file names. These are lists of strings and thus do not have a delete method. Instead of trying to delete each array, we loop through them to build keys that we can delete. --- filebrowser_safe/storage.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/filebrowser_safe/storage.py b/filebrowser_safe/storage.py index 88d1d15..3609355 100644 --- a/filebrowser_safe/storage.py +++ b/filebrowser_safe/storage.py @@ -112,9 +112,13 @@ def makedirs(self, name): def rmtree(self, name): name = self._normalize_name(self._clean_name(name)) - dirlist = self.listdir(self._encode_name(name)) - for item in dirlist: - item.delete() + directories, files = self.listdir(self._encode_name(name)) + + for key in files: + self.delete('/'.join([name, key])) + + for dirname in directories: + self.rmtree('/'.join([name, dirname])) class GoogleStorageMixin(StorageMixin): From 6f23b88f7348d06878198bb63c2392266e7b9fc5 Mon Sep 17 00:00:00 2001 From: Tirso Rodriguez Date: Wed, 6 Mar 2019 14:19:28 +0000 Subject: [PATCH 2/5] Fixes issue with old methods in gcs support --- .gitignore | 1 + filebrowser_safe/storage.py | 31 +++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4d8f39b..994aaf8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ *.pyc *.eggs/ *.egg-info +.idea mezzanine-git/ diff --git a/filebrowser_safe/storage.py b/filebrowser_safe/storage.py index 88d1d15..adc18b8 100644 --- a/filebrowser_safe/storage.py +++ b/filebrowser_safe/storage.py @@ -4,6 +4,7 @@ # PYTHON IMPORTS import os import shutil +import posixpath # DJANGO IMPORTS from django.core.files.move import file_move_safe @@ -133,7 +134,7 @@ def isdir(self, name): return False name = self._normalize_name(self._clean_name(name)) - dirlist = self.bucket.list(self._encode_name(name)) + dirlist = self.listdir(self._encode_name(name)) # Check whether the iterator is empty for item in dirlist: @@ -163,6 +164,32 @@ def makedirs(self, name): def rmtree(self, name): name = self._normalize_name(self._clean_name(name)) - dirlist = self.bucket.list(self._encode_name(name)) + dirlist = self.listdir(self._encode_name(name)) for item in dirlist: item.delete() + + def _clean_name(self, name): + """ + Cleans the name so that Windows style paths work + """ + return clean_name(name) + + +def clean_name(name): + """ + Cleans the name so that Windows style paths work + """ + # Normalize Windows style paths + clean_name = posixpath.normpath(name).replace('\\', '/') + + # os.path.normpath() can strip trailing slashes so we implement + # a workaround here. + if name.endswith('/') and not clean_name.endswith('/'): + # Add a trailing slash as it was stripped. + clean_name = clean_name + '/' + + # Given an empty string, os.path.normpath() will return ., which we don't want + if clean_name == '.': + clean_name = '' + + return clean_name From 3b86e2868b3e0f2e198b7c128ba5ace9058f0038 Mon Sep 17 00:00:00 2001 From: Tirso Rodriguez Date: Sun, 24 Mar 2019 16:03:11 +0000 Subject: [PATCH 3/5] Fix cs specification that is breaking compilemessages command --- filebrowser_safe/locale/cs/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filebrowser_safe/locale/cs/LC_MESSAGES/django.po b/filebrowser_safe/locale/cs/LC_MESSAGES/django.po index ca8b3fc..fb66196 100644 --- a/filebrowser_safe/locale/cs/LC_MESSAGES/django.po +++ b/filebrowser_safe/locale/cs/LC_MESSAGES/django.po @@ -322,7 +322,7 @@ msgstr[1] "%(counter) výsledky" #: templates/filebrowser/include/toolbar.html:9 #, python-format msgid "%(full_result_count)s total" -msgstr "%(full_result_count) celkem" +msgstr "%(full_result_count)s celkem" #: templates/filebrowser/include/search.html:5 msgid "Clear Restrictions" From ee2008f6f11c32abcd3d0e2bc6704f85db9765e0 Mon Sep 17 00:00:00 2001 From: cjh79 Date: Wed, 30 Oct 2019 12:06:28 -0400 Subject: [PATCH 4/5] Allow for use of absolute path in THUMBNAILS_DIR_NAME --- filebrowser_safe/views.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/filebrowser_safe/views.py b/filebrowser_safe/views.py index 69bf1d1..2287b6a 100644 --- a/filebrowser_safe/views.py +++ b/filebrowser_safe/views.py @@ -72,7 +72,11 @@ def remove_thumbnails(file_path): """ from mezzanine.conf import settings dir_name, file_name = os.path.split(file_path) - path = os.path.join(dir_name, settings.THUMBNAILS_DIR_NAME, file_name) + if os.path.isabs(settings.THUMBNAILS_DIR_NAME): + path = os.path.join(settings.THUMBNAILS_DIR_NAME, dir_name, file_name) + else: + path = os.path.join(dir_name, settings.THUMBNAILS_DIR_NAME, file_name) + try: default_storage.rmtree(path) except: From 16ea0453d9b44e8683ebf985322ceb2836a4c3e6 Mon Sep 17 00:00:00 2001 From: cjh79 Date: Wed, 30 Oct 2019 12:07:29 -0400 Subject: [PATCH 5/5] Use default_storage for rename operation so that it works for remote media storage backends --- filebrowser_safe/forms.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/filebrowser_safe/forms.py b/filebrowser_safe/forms.py index 5aa34b5..28d50b4 100644 --- a/filebrowser_safe/forms.py +++ b/filebrowser_safe/forms.py @@ -1,4 +1,7 @@ from __future__ import unicode_literals + +from django.conf import settings +from django.core.files.storage import default_storage from future.builtins import super # coding: utf-8 @@ -52,6 +55,8 @@ class RenameForm(forms.Form): def __init__(self, path, file_extension, *args, **kwargs): self.path = path + if re.match("^https?://", settings.MEDIA_ROOT): + self.path = re.sub("^" + settings.MEDIA_ROOT, "", self.path) self.file_extension = file_extension super(RenameForm, self).__init__(*args, **kwargs) @@ -69,8 +74,8 @@ def clean_name(self): not alnum_name_re.search(self.path)): raise forms.ValidationError(_(u'Only letters, numbers, underscores, spaces and hyphens are allowed.')) # folder/file must not already exist. - if os.path.isdir(os.path.join(self.path, self.cleaned_data['name'])): + if default_storage.isdir(os.path.join(self.path, self.cleaned_data['name'])): raise forms.ValidationError(_(u'The Folder already exists.')) - elif os.path.isfile(os.path.join(self.path, self.cleaned_data['name'] + self.file_extension)): + elif default_storage.isfile(os.path.join(self.path, self.cleaned_data['name'] + self.file_extension)): raise forms.ValidationError(_(u'The File already exists.')) return self.cleaned_data['name']