Skip to content

Commit

Permalink
[dropbox] update naming to Dropbox and add backwards compat alias (#1250
Browse files Browse the repository at this point in the history
)
  • Loading branch information
jschneier committed May 20, 2023
1 parent 9791de2 commit 7ebb6f9
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 27 deletions.
10 changes: 5 additions & 5 deletions docs/backends/dropbox.rst
Expand Up @@ -12,13 +12,13 @@ which can be done for you automatically by doing::
Settings
--------

To use DropBoxStorage set::
To use DropboxStorage set::

# django < 4.2
DEFAULT_FILE_STORAGE = 'storages.backends.dropbox.DropBoxStorage'
DEFAULT_FILE_STORAGE = "storages.backends.dropbox.DropboxStorage"

# django >= 4.2
STORAGES = {"default": {"BACKEND": "storages.backends.dropbox.DropBoxStorage"}}
STORAGES = {"default": {"BACKEND": "storages.backends.dropbox.DropboxStorage"}}

Two methods of authenticating are supported:

Expand All @@ -43,14 +43,14 @@ Please set the following variables accordingly:

The refresh token can be obtained using the `commandline-oauth.py`_ example from the `Dropbox SDK for Python`_.

``DROPBOX_ROOT_PATH`` (optional, default ``'/'``)
``DROPBOX_ROOT_PATH`` (optional, default ``"/"``)
Path which will prefix all uploaded files. Must begin with a ``/``.

``DROPBOX_TIMEOUT`` (optional, default ``100``)
Timeout in seconds for requests to the API. If ``None``, the client will wait forever.
The default value matches the SDK at the time of this writing.

``DROPBOX_WRITE_MODE`` (optional, default ``'add'``)
``DROPBOX_WRITE_MODE`` (optional, default ``"add"``)
Sets the Dropbox WriteMode strategy. Read more in the `official docs`_.

Obtain the refresh token manually
Expand Down
21 changes: 15 additions & 6 deletions storages/backends/dropbox.py
Expand Up @@ -35,11 +35,14 @@
_DEFAULT_MODE = 'add'


class DropBoxStorageException(Exception):
class DropboxStorageException(Exception):
pass


class DropBoxFile(File):
DropBoxStorageException = DropboxStorageException


class DropboxFile(File):
def __init__(self, name, storage):
self.name = name
self._storage = storage
Expand All @@ -57,7 +60,7 @@ def _get_file(self):
copyfileobj(file_content, self._file)
else:
# JIC the exception isn't catched by the dropbox client
raise DropBoxStorageException(
raise DropboxStorageException(
"Dropbox server returned a {} response when accessing {}"
.format(response.status_code, self.name)
)
Expand All @@ -70,9 +73,12 @@ def _set_file(self, value):
file = property(_get_file, _set_file)


DropBoxFile = DropboxFile


@deconstructible
class DropBoxStorage(Storage):
"""DropBox Storage class for Django pluggable storage system."""
class DropboxStorage(Storage):
"""Dropbox Storage class for Django pluggable storage system."""
location = setting('DROPBOX_ROOT_PATH', '/')
oauth2_access_token = setting('DROPBOX_OAUTH2_TOKEN')
app_key = setting('DROPBOX_APP_KEY')
Expand Down Expand Up @@ -162,7 +168,7 @@ def url(self, name):
return None

def _open(self, name, mode='rb'):
remote_file = DropBoxFile(self._full_path(name), self)
remote_file = DropboxFile(self._full_path(name), self)
return remote_file

def _save(self, name, content):
Expand Down Expand Up @@ -203,3 +209,6 @@ def get_available_name(self, name, max_length=None):
if self.write_mode == 'overwrite':
return get_available_overwrite_name(name, max_length)
return super().get_available_name(name, max_length)


DropBoxStorage = DropboxStorage
32 changes: 16 additions & 16 deletions tests/test_dropbox.py
Expand Up @@ -47,37 +47,37 @@
RESPONSE_500_MOCK.status_code = 500


class DropBoxTest(TestCase):
class DropboxTest(TestCase):
def setUp(self, *args):
self.storage = dropbox.DropBoxStorage('foo')
self.storage = dropbox.DropboxStorage('foo')

def test_no_access_token(self, *args):
with self.assertRaises(ImproperlyConfigured):
dropbox.DropBoxStorage(None)
dropbox.DropboxStorage(None)

def test_refresh_token_app_key_no_app_secret(self, *args):
inputs = {
'oauth2_refresh_token': 'foo',
'app_key': 'bar',
}
with self.assertRaises(ImproperlyConfigured):
dropbox.DropBoxStorage(**inputs)
dropbox.DropboxStorage(**inputs)

def test_refresh_token_app_secret_no_app_key(self, *args):
inputs = {
'oauth2_refresh_token': 'foo',
'app_secret': 'bar',
}
with self.assertRaises(ImproperlyConfigured):
dropbox.DropBoxStorage(**inputs)
dropbox.DropboxStorage(**inputs)

def test_app_key_app_secret_no_refresh_token(self, *args):
inputs = {
'app_key': 'foo',
'app_secret': 'bar',
}
with self.assertRaises(ImproperlyConfigured):
dropbox.DropBoxStorage(**inputs)
dropbox.DropboxStorage(**inputs)

@mock.patch('dropbox.Dropbox.files_delete',
return_value=FILE_METADATA_MOCK)
Expand Down Expand Up @@ -158,18 +158,18 @@ def test_url(self, *args):
self.assertEqual(url, FILE_MEDIA_MOCK.link)

def test_formats(self, *args):
self.storage = dropbox.DropBoxStorage('foo')
self.storage = dropbox.DropboxStorage('foo')
files = self.storage._full_path('')
self.assertEqual(files, self.storage._full_path('/'))
self.assertEqual(files, self.storage._full_path('.'))
self.assertEqual(files, self.storage._full_path('..'))
self.assertEqual(files, self.storage._full_path('../..'))


class DropBoxFileTest(TestCase):
class DropboxFileTest(TestCase):
def setUp(self, *args):
self.storage = dropbox.DropBoxStorage('foo')
self.file = dropbox.DropBoxFile('/foo.txt', self.storage)
self.storage = dropbox.DropboxStorage('foo')
self.file = dropbox.DropboxFile('/foo.txt', self.storage)

@mock.patch('dropbox.Dropbox.files_download',
return_value=(FILE_METADATA_MOCK, RESPONSE_200_MOCK))
Expand All @@ -180,34 +180,34 @@ def test_read(self, *args):
@mock.patch('dropbox.Dropbox.files_download',
return_value=(FILE_METADATA_MOCK, RESPONSE_500_MOCK))
def test_server_bad_response(self, *args):
with self.assertRaises(dropbox.DropBoxStorageException):
with self.assertRaises(dropbox.DropboxStorageException):
file = self.storage._open('foo.txt')
file.read()


@mock.patch('dropbox.Dropbox.files_list_folder',
return_value=FILES_EMPTY_MOCK)
class DropBoxRootPathTest(TestCase):
class DropboxRootPathTest(TestCase):
def test_jailed(self, *args):
self.storage = dropbox.DropBoxStorage('foo', root_path='/bar')
self.storage = dropbox.DropboxStorage('foo', root_path='/bar')
dirs, files = self.storage.listdir('/')
self.assertFalse(dirs)
self.assertFalse(files)

@mock.patch('dropbox.Dropbox.files_upload', return_value='foo')
@mock.patch('dropbox.Dropbox.files_get_metadata', return_value=None)
def test_saves(self, *args):
self.storage = dropbox.DropBoxStorage('foo', root_path='/bar')
self.storage = dropbox.DropboxStorage('foo', root_path='/bar')
name = self.storage.save('xyz', File(io.BytesIO(b'abc'), 'def'))
self.assertEqual(name, 'xyz')

def test_suspicious(self, *args):
self.storage = dropbox.DropBoxStorage('foo', root_path='/bar')
self.storage = dropbox.DropboxStorage('foo', root_path='/bar')
with self.assertRaises((SuspiciousFileOperation, ValueError)):
self.storage._full_path('..')

def test_formats(self, *args):
self.storage = dropbox.DropBoxStorage('foo', root_path='/bar')
self.storage = dropbox.DropboxStorage('foo', root_path='/bar')
files = self.storage._full_path('')
self.assertEqual(files, self.storage._full_path('/'))
self.assertEqual(files, self.storage._full_path('.'))

0 comments on commit 7ebb6f9

Please sign in to comment.