From c83d0e2ca8a70a206cafe42c30493e7909d14448 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Thu, 19 Dec 2019 12:49:48 -0500 Subject: [PATCH] OverwriteStorage was removed from django-storages, so pull it into edx-platform (for now?) --- .../third_party_auth/tests/testutil.py | 2 +- lms/envs/bok_choy.py | 2 +- lms/envs/common.py | 2 +- lms/envs/lms.yml | 2 +- lms/envs/test.py | 2 +- openedx/core/storage.py | 25 ++++++++++++++++++- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/common/djangoapps/third_party_auth/tests/testutil.py b/common/djangoapps/third_party_auth/tests/testutil.py index 616b778bea..bff9d13282 100644 --- a/common/djangoapps/third_party_auth/tests/testutil.py +++ b/common/djangoapps/third_party_auth/tests/testutil.py @@ -18,7 +18,7 @@ from django.contrib.sites.models import Site from mako.template import Template from provider import constants from provider.oauth2.models import Client as OAuth2Client -from storages.backends.overwrite import OverwriteStorage +from openedx.core.storage import OverwriteStorage from third_party_auth.models import ( LTIProviderConfig, diff --git a/lms/envs/bok_choy.py b/lms/envs/bok_choy.py index 6e2adf72d0..42780d6b1d 100644 --- a/lms/envs/bok_choy.py +++ b/lms/envs/bok_choy.py @@ -245,7 +245,7 @@ SECRET_KEY = "very_secret_bok_choy_key" # Set dummy values for profile image settings. PROFILE_IMAGE_BACKEND = { - 'class': 'storages.backends.overwrite.OverwriteStorage', + 'class': 'openedx.core.storage.OverwriteStorage', 'options': { 'location': os.path.join(MEDIA_ROOT, 'profile-images/'), 'base_url': os.path.join(MEDIA_URL, 'profile-images/'), diff --git a/lms/envs/common.py b/lms/envs/common.py index 3264b86120..bffb3f977a 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -3318,7 +3318,7 @@ MODULESTORE_FIELD_OVERRIDE_PROVIDERS = ('openedx.features.content_type_gating.fi # occurring when a user uploads a new profile image to replace an # earlier one (the file will temporarily be deleted). PROFILE_IMAGE_BACKEND = { - 'class': 'storages.backends.overwrite.OverwriteStorage', + 'class': 'openedx.core.storage.OverwriteStorage', 'options': { 'location': os.path.join(MEDIA_ROOT, 'profile-images/'), 'base_url': os.path.join(MEDIA_URL, 'profile-images/'), diff --git a/lms/envs/lms.yml b/lms/envs/lms.yml index a5402e122e..f85771d5c5 100644 --- a/lms/envs/lms.yml +++ b/lms/envs/lms.yml @@ -469,7 +469,7 @@ PROCTORING_BACKENDS: 'null': {} PROCTORING_SETTINGS: {} PROFILE_IMAGE_BACKEND: - class: storages.backends.overwrite.OverwriteStorage + class: openedx.core.storage.OverwriteStorage options: base_url: /media/profile-images/ location: /edx/var/edxapp/media/profile-images/ diff --git a/lms/envs/test.py b/lms/envs/test.py index 812e270c9e..69a0d9cb7f 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -475,7 +475,7 @@ FEATURES['CUSTOM_COURSES_EDX'] = True # Set dummy values for profile image settings. PROFILE_IMAGE_BACKEND = { - 'class': 'storages.backends.overwrite.OverwriteStorage', + 'class': 'openedx.core.storage.OverwriteStorage', 'options': { 'location': MEDIA_ROOT, 'base_url': 'http://example-storage.com/profile-images/', diff --git a/openedx/core/storage.py b/openedx/core/storage.py index c0a60e911b..bfd18d47a9 100644 --- a/openedx/core/storage.py +++ b/openedx/core/storage.py @@ -4,7 +4,8 @@ Django storage backends for Open edX. from __future__ import absolute_import from django.contrib.staticfiles.storage import StaticFilesStorage -from django.core.files.storage import get_storage_class +from django.core.files.storage import get_storage_class, FileSystemStorage +from django.utils.deconstruct import deconstructible from django.utils.lru_cache import lru_cache from pipeline.storage import NonPackagingMixin, PipelineCachedStorage from require.storage import OptimizedFilesMixin @@ -90,6 +91,28 @@ class S3ReportStorage(S3BotoStorage): # pylint: disable=abstract-method super(S3ReportStorage, self).__init__(acl=acl, bucket=bucket, **settings) +@deconstructible +class OverwriteStorage(FileSystemStorage): + """ + FileSystemStorage subclass which automatically overwrites any previous + file with the same name; used in test runs to avoid test file proliferation. + Copied from django-storages when this class was removed in version 1.6. + + Comes from http://www.djangosnippets.org/snippets/976/ + (even if it already exists in S3Storage for ages) + See also Django #4339, which might add this functionality to core. + """ + + def get_available_name(self, name, max_length=None): + """ + Returns a filename that's free on the target storage system, and + available for new content to be written to. + """ + if self.exists(name): + self.delete(name) + return name + + @lru_cache() def get_storage(storage_class=None, **kwargs): """