Skip to content

Commit

Permalink
Dropbox api upgrade (#273)
Browse files Browse the repository at this point in the history
* moved to dropbox v2 api

* replace client.metadata with dropbox v2 call

* replace new dropbox v2 error

* replace dropbox v1 methods with v2 equivalents

* Replace final deprecated dropbox methods, fix the tests, upgrade the required version
  • Loading branch information
jschneier committed Jun 20, 2017
1 parent b70e42c commit e46f306
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 35 deletions.
2 changes: 1 addition & 1 deletion requirements-tests.txt
@@ -1,7 +1,7 @@
boto3>=1.2.3
boto>=2.32.0
dropbox>=7.21
Django>=1.8
dropbox>=3.24
flake8
google-cloud>=0.25.0
mock
Expand Down
28 changes: 14 additions & 14 deletions storages/backends/dropbox.py
Expand Up @@ -22,8 +22,8 @@

from storages.utils import setting

from dropbox.client import DropboxClient
from dropbox.rest import ErrorResponse
from dropbox import Dropbox
from dropbox.exceptions import ApiError

DATE_FORMAT = '%a, %d %b %Y %X +0000'

Expand All @@ -40,7 +40,7 @@ def __init__(self, name, storage):
@property
def file(self):
if not hasattr(self, '_file'):
response = self._storage.client.get_file(self.name)
response = self._storage.client.files_download(self.name)
self._file = SpooledTemporaryFile()
copyfileobj(response, self._file)
self._file.seek(0)
Expand All @@ -57,26 +57,26 @@ def __init__(self, oauth2_access_token=None, root_path=None):
if oauth2_access_token is None:
raise ImproperlyConfigured("You must configure a token auth at"
"'settings.DROPBOX_OAUTH2_TOKEN'.")
self.client = DropboxClient(oauth2_access_token)
self.client = Dropbox(oauth2_access_token)

def _full_path(self, name):
if name == '/':
name = ''
return safe_join(self.root_path, name).replace('\\', '/')

def delete(self, name):
self.client.file_delete(self._full_path(name))
self.client.files_delete(self._full_path(name))

def exists(self, name):
try:
return bool(self.client.metadata(self._full_path(name)))
except ErrorResponse:
return bool(self.client.files_get_metadata(self._full_path(name)))
except ApiError:
return False

def listdir(self, path):
directories, files = [], []
full_path = self._full_path(path)
metadata = self.client.metadata(full_path)
metadata = self.client.files_get_metadata(full_path)
for entry in metadata['contents']:
entry['path'] = entry['path'].replace(full_path, '', 1)
entry['path'] = entry['path'].replace('/', '', 1)
Expand All @@ -87,27 +87,27 @@ def listdir(self, path):
return directories, files

def size(self, name):
metadata = self.client.metadata(self._full_path(name))
metadata = self.client.files_get_metadata(self._full_path(name))
return metadata['bytes']

def modified_time(self, name):
metadata = self.client.metadata(self._full_path(name))
metadata = self.client.files_get_metadata(self._full_path(name))
mod_time = datetime.strptime(metadata['modified'], DATE_FORMAT)
return mod_time

def accessed_time(self, name):
metadata = self.client.metadata(self._full_path(name))
metadata = self.client.files_get_metadata(self._full_path(name))
acc_time = datetime.strptime(metadata['client_mtime'], DATE_FORMAT)
return acc_time

def url(self, name):
media = self.client.media(self._full_path(name))
return media['url']
media = self.client.files_get_temporary_link(self._full_path(name))
return media['link']

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

def _save(self, name, content):
self.client.put_file(self._full_path(name), content)
self.client.files_upload(content, self._full_path(name))
return name
34 changes: 14 additions & 20 deletions tests/test_dropbox.py
Expand Up @@ -8,7 +8,7 @@
from django.test import TestCase
from django.core.files.base import File, ContentFile
from django.core.exceptions import ImproperlyConfigured, \
SuspiciousFileOperation
SuspiciousFileOperation

from storages.backends import dropbox

Expand Down Expand Up @@ -51,7 +51,7 @@
'thumb_exists': False
}
FILE_MEDIA_FIXTURE = {
'url': 'https://dl.dropboxusercontent.com/1/view/foo',
'link': 'https://dl.dropboxusercontent.com/1/view/foo',
'expires': 'Fri, 16 Sep 2011 01:01:25 +0000',
}

Expand All @@ -67,24 +67,24 @@ def test_no_access_token(self, *args):
with self.assertRaises(ImproperlyConfigured):
dropbox.DropBoxStorage(None)

@mock.patch('dropbox.client.DropboxClient.file_delete',
@mock.patch('dropbox.Dropbox.files_delete',
return_value=FILE_FIXTURE)
def test_delete(self, *args):
self.storage.delete('foo')

@mock.patch('dropbox.client.DropboxClient.metadata',
@mock.patch('dropbox.Dropbox.files_get_metadata',
return_value=[FILE_FIXTURE])
def test_exists(self, *args):
exists = self.storage.exists('foo')
self.assertTrue(exists)

@mock.patch('dropbox.client.DropboxClient.metadata',
@mock.patch('dropbox.Dropbox.files_get_metadata',
return_value=[])
def test_not_exists(self, *args):
exists = self.storage.exists('bar')
self.assertFalse(exists)

@mock.patch('dropbox.client.DropboxClient.metadata',
@mock.patch('dropbox.Dropbox.files_get_metadata',
return_value=FILES_FIXTURE)
def test_listdir(self, *args):
dirs, files = self.storage.listdir('/')
Expand All @@ -93,19 +93,19 @@ def test_listdir(self, *args):
self.assertEqual(dirs[0], 'bar')
self.assertEqual(files[0], 'foo.txt')

@mock.patch('dropbox.client.DropboxClient.metadata',
@mock.patch('dropbox.Dropbox.files_get_metadata',
return_value=FILE_FIXTURE)
def test_size(self, *args):
size = self.storage.size('foo')
self.assertEqual(size, FILE_FIXTURE['bytes'])

@mock.patch('dropbox.client.DropboxClient.metadata',
@mock.patch('dropbox.Dropbox.files_get_metadata',
return_value=FILE_FIXTURE)
def test_modified_time(self, *args):
mtime = self.storage.modified_time('foo')
self.assertEqual(mtime, FILE_DATE)

@mock.patch('dropbox.client.DropboxClient.metadata',
@mock.patch('dropbox.Dropbox.files_get_metadata',
return_value=FILE_FIXTURE)
def test_accessed_time(self, *args):
mtime = self.storage.accessed_time('foo')
Expand All @@ -115,16 +115,16 @@ def test_open(self, *args):
obj = self.storage._open('foo')
self.assertIsInstance(obj, File)

@mock.patch('dropbox.client.DropboxClient.put_file',
@mock.patch('dropbox.Dropbox.files_upload',
return_value='foo')
def test_save(self, *args):
self.storage._save('foo', b'bar')

@mock.patch('dropbox.client.DropboxClient.media',
@mock.patch('dropbox.Dropbox.files_get_temporary_link',
return_value=FILE_MEDIA_FIXTURE)
def test_url(self, *args):
url = self.storage.url('foo')
self.assertEqual(url, FILE_MEDIA_FIXTURE['url'])
self.assertEqual(url, FILE_MEDIA_FIXTURE['link'])

def test_formats(self, *args):
self.storage = dropbox.DropBoxStorage('foo')
Expand All @@ -136,24 +136,18 @@ def test_formats(self, *args):


class DropBoxFileTest(TestCase):
@mock.patch('dropbox.client._OAUTH2_ACCESS_TOKEN_PATTERN',
re.compile(r'.*'))
@mock.patch('dropbox.client.DropboxOAuth2Session')
def setUp(self, *args):
self.storage = dropbox.DropBoxStorage('foo')
self.file = dropbox.DropBoxFile('/foo.txt', self.storage)

@mock.patch('dropbox.client.DropboxClient.get_file',
@mock.patch('dropbox.Dropbox.files_download',
return_value=ContentFile(b'bar'))
def test_read(self, *args):
file = self.storage._open(b'foo')
self.assertEqual(file.read(), b'bar')


@mock.patch('dropbox.client._OAUTH2_ACCESS_TOKEN_PATTERN',
re.compile(r'.*'))
@mock.patch('dropbox.client.DropboxOAuth2Session')
@mock.patch('dropbox.client.DropboxClient.metadata',
@mock.patch('dropbox.Dropbox.files_get_metadata',
return_value={'contents': []})
class DropBoxRootPathTest(TestCase):
def test_jailed(self, *args):
Expand Down

0 comments on commit e46f306

Please sign in to comment.