Skip to content

Commit

Permalink
Implemented compatibility storages for Django 1.8+
Browse files Browse the repository at this point in the history
  • Loading branch information
maryokhin committed Apr 2, 2015
1 parent f1f2341 commit d8943a3
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 31 deletions.
3 changes: 1 addition & 2 deletions storages/backends/apache_libcloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import os

from django.conf import settings
from django.core.files.storage import Storage
from django.core.files.base import File
from django.core.exceptions import ImproperlyConfigured

from storages.compat import BytesIO, deconstructible
from storages.compat import BytesIO, deconstructible, Storage

try:
from libcloud.storage.providers import get_driver
Expand Down
2 changes: 1 addition & 1 deletion storages/backends/azure_storage.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import os.path

from django.core.files.base import ContentFile
from django.core.files.storage import Storage
from django.core.exceptions import ImproperlyConfigured
from storages.compat import Storage

try:
import azure
Expand Down
3 changes: 1 addition & 2 deletions storages/backends/couchdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@

from django.conf import settings
from django.core.files import File
from django.core.files.storage import Storage
from django.core.exceptions import ImproperlyConfigured

from storages.compat import urlparse, BytesIO
from storages.compat import urlparse, BytesIO, Storage

try:
import couchdb
Expand Down
6 changes: 3 additions & 3 deletions storages/backends/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@

from django.conf import settings
from django.core.files import File
from django.core.files.storage import Storage
from django.core.exceptions import ImproperlyConfigured

from storages.compat import urlparse, BytesIO
from storages.compat import urlparse, BytesIO, Storage

try:
import pyodbc
Expand All @@ -16,6 +15,7 @@

REQUIRED_FIELDS = ('db_table', 'fname_column', 'blob_column', 'size_column', 'base_url')


class DatabaseStorage(Storage):
"""
Class DatabaseStorage provides storing files in the database.
Expand Down Expand Up @@ -111,7 +111,7 @@ def exists(self, name):
row = self.cursor.execute("SELECT %s from %s where %s = '%s'"%(self.fname_column,self.db_table,self.fname_column,name)).fetchone()
return row is not None

def get_available_name(self, name):
def get_available_name(self, name, max_length=None):
return name

def delete(self, name):
Expand Down
4 changes: 2 additions & 2 deletions storages/backends/ftp.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

from django.conf import settings
from django.core.files.base import File
from django.core.files.storage import Storage
from django.core.exceptions import ImproperlyConfigured

from storages.compat import urlparse, BytesIO
from storages.compat import urlparse, BytesIO, Storage


class FTPStorageException(Exception):
pass
Expand Down
8 changes: 5 additions & 3 deletions storages/backends/hashpath.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import os, hashlib, errno

from django.core.files.storage import FileSystemStorage
from django.utils.encoding import force_text, force_bytes
from storages.compat import FileSystemStorage


class HashPathStorage(FileSystemStorage):
"""
Creates a hash from the uploaded file to build the path.
"""

def save(self, name, content):
def save(self, name, content, max_length=None):
# Get the content name if name is not given
if name is None: name = content.name
if name is None:
name = content.name

# Get the SHA1 hash of the uploaded file
sha1 = hashlib.sha1()
Expand Down
4 changes: 2 additions & 2 deletions storages/backends/image.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

import os

from django.core.files.storage import FileSystemStorage
from django.core.exceptions import ImproperlyConfigured
from storages.compat import FileSystemStorage

try:
from PIL import ImageFile as PILImageFile
Expand All @@ -27,7 +27,7 @@ def find_extension(self, format):

return format

def save(self, name, content):
def save(self, name, content, max_length=None):
dirname = os.path.dirname(name)
basename = os.path.basename(name)

Expand Down
8 changes: 3 additions & 5 deletions storages/backends/mogile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
from django.conf import settings
from django.core.cache import cache
from django.utils.text import force_text
from django.core.files.storage import Storage
from django.http import HttpResponse, HttpResponseNotFound
from django.core.exceptions import ImproperlyConfigured

from storages.compat import urlparse, BytesIO
from storages.compat import urlparse, BytesIO, Storage

try:
import mogilefs
Expand Down Expand Up @@ -62,8 +61,8 @@ def open(self, filename, mode='rb'):
def exists(self, filename):
return filename in self.client

def save(self, filename, raw_contents):
filename = self.get_available_filename(filename)
def save(self, filename, raw_contents, max_length=None):
filename = self.get_available_name(filename, max_length)

if not hasattr(self, 'mogile_class'):
self.mogile_class = None
Expand All @@ -78,7 +77,6 @@ def save(self, filename, raw_contents):
return force_text(filename.replace('\\', '/'))

def delete(self, filename):

self.client.delete(filename)


Expand Down
4 changes: 3 additions & 1 deletion storages/backends/mongodb.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.base import File
from django.core.files.storage import Storage
from django.db import connections
from django.utils.encoding import force_text
import warnings
from storages.compat import Storage

warnings.warn("The mongodb storage backend will be removed in version 1.3.\n"
"A storage backend is now provided by django-mongodb-engine.",
Expand All @@ -22,6 +22,7 @@
raise ImproperlyConfigured("Could not load pymongo dependency.\
\nSee http://github.com/mongodb/mongo-python-driver")


class GridFSStorage(Storage):
@property
def fs(self):
Expand Down Expand Up @@ -83,6 +84,7 @@ def size(self, name):
def url(self, name):
raise NotImplementedError()


class GridFSFile(File):
def __init__(self, name, storage, mode):
self.name = name
Expand Down
4 changes: 2 additions & 2 deletions storages/backends/overwrite.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.core.files.storage import FileSystemStorage
from storages.compat import FileSystemStorage


class OverwriteStorage(FileSystemStorage):
Expand All @@ -9,7 +9,7 @@ class OverwriteStorage(FileSystemStorage):
See also Django #4339, which might add this functionality to core.
"""

def get_available_name(self, name):
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.
Expand Down
7 changes: 3 additions & 4 deletions storages/backends/s3boto.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import warnings

from django.core.files.base import File
from django.core.files.storage import Storage
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
from django.utils.encoding import force_text, smart_str, filepath_to_uri, force_bytes

Expand All @@ -22,7 +21,7 @@
"See https://github.com/boto/boto")

from storages.utils import setting
from storages.compat import urlparse, BytesIO, deconstructible
from storages.compat import urlparse, BytesIO, deconstructible, Storage

boto_version_info = tuple([int(i) for i in boto_version.split('-')[0].split('.')])

Expand Down Expand Up @@ -491,9 +490,9 @@ def url(self, name, headers=None, response_headers=None):
query_auth=self.querystring_auth, force_http=not self.secure_urls,
response_headers=response_headers)

def get_available_name(self, name):
def get_available_name(self, name, max_length=None):
""" Overwrite existing file with the same name. """
if self.file_overwrite:
name = self._clean_name(name)
return name
return super(S3BotoStorage, self).get_available_name(name)
return super(S3BotoStorage, self).get_available_name(name, max_length)
4 changes: 2 additions & 2 deletions storages/backends/sftpstorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@

from django.conf import settings
from django.core.files.base import File
from django.core.files.storage import Storage

from storages.compat import urlparse, BytesIO
from storages.compat import urlparse, BytesIO, Storage


class SFTPStorage(Storage):

Expand Down
3 changes: 2 additions & 1 deletion storages/backends/symlinkorcopy.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os

from django.conf import settings
from django.core.files.storage import FileSystemStorage
from storages.compat import FileSystemStorage

__doc__ = """
I needed to efficiently create a mirror of a directory tree (so that
Expand All @@ -25,6 +25,7 @@
a temporary directory, e.g. /tmp/image.jpg.
"""


class SymlinkOrCopyStorage(FileSystemStorage):
"""Stores symlinks to files instead of actual files whenever possible
Expand Down
23 changes: 22 additions & 1 deletion storages/compat.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
from django.utils.six.moves.urllib import parse as urlparse
from django.utils.six import BytesIO
import django

try:
from django.utils.deconstruct import deconstructible
except ImportError: # Django 1.7+ migrations
except ImportError: # Django 1.7+ migrations
deconstructible = lambda klass, *args, **kwargs: klass

# Storage only accepts `max_length` in 1.8+
if django.VERSION >= (1, 8):
from django.core.files.storage import Storage, FileSystemStorage
else:
from django.core.files.storage import Storage as DjangoStorage
from django.core.files.storage import FileSystemStorage as DjangoFileSystemStorage

class StorageMixin(object):
def save(self, name, content, max_length=None):
return super().save(name, content)

def get_available_name(self, name, max_length=None):
return super().get_available_name(name)

class Storage(DjangoStorage, StorageMixin):
pass

class FileSystemStorage(DjangoFileSystemStorage, StorageMixin):
pass

0 comments on commit d8943a3

Please sign in to comment.