1. David Larlet
  2. django-storages


django-storages / storages / backends / gs.py

Jannis Leidel fd89bca 

Jannis Leidel 02b9d83 
Jannis Leidel 02c77e7 
Jannis Leidel 02b9d83 
Jannis Leidel 02c77e7 
Jannis Leidel 02b9d83 

Jannis Leidel fd89bca 

Jannis Leidel 02c77e7 

Jannis Leidel 02b9d83 

Jannis Leidel 02c77e7 
Jannis Leidel 813a600 

Jannis Leidel 02b9d83 

Jannis Leidel 813a600 
Jannis Leidel 02b9d83 

Jannis Leidel 813a600 
Jannis Leidel 02b9d83 

Jannis Leidel 813a600 

    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO  # noqa

from django.core.exceptions import ImproperlyConfigured

from storages.backends.s3boto import S3BotoStorage, S3BotoStorageFile, setting

    from boto.gs.connection import GSConnection, SubdomainCallingFormat
    from boto.exception import GSResponseError
    from boto.gs.key import Key as GSKey
except ImportError:
    raise ImproperlyConfigured("Could not load Boto's Google Storage bindings.\n"
                               "See https://github.com/boto/boto")

class GSBotoStorageFile(S3BotoStorageFile):

    def write(self, content):
        if 'w' not in self._mode:
            raise AttributeError("File was not opened in write mode.")
        self.file = StringIO(content)
        self._is_dirty = True

    def close(self):
        if self._is_dirty:
            provider = self.key.bucket.connection.provider
            upload_headers = {provider.acl_header: self._storage.default_acl}
            self._storage._save_content(self.key, self.file, upload_headers)

class GSBotoStorage(S3BotoStorage):
    connection_class = GSConnection
    connection_response_error = GSResponseError
    file_class = GSBotoStorageFile
    key_class = GSKey

    access_key_names = ['GS_ACCESS_KEY_ID']
    secret_key_names = ['GS_SECRET_ACCESS_KEY']

    access_key = setting('GS_ACCESS_KEY_ID')
    secret_key = setting('GS_SECRET_ACCESS_KEY')
    file_overwrite = setting('GS_FILE_OVERWRITE', True)
    headers = setting('GS_HEADERS', {})
    bucket_name = setting('GS_BUCKET_NAME', None)
    auto_create_bucket = setting('GS_AUTO_CREATE_BUCKET', False)
    default_acl = setting('GS_DEFAULT_ACL', 'public-read')
    bucket_acl = setting('GS_BUCKET_ACL', default_acl)
    querystring_auth = setting('GS_QUERYSTRING_AUTH', True)
    querystring_expire = setting('GS_QUERYSTRING_EXPIRE', 3600)
    durable_reduced_availability = setting('GS_DURABLE_REDUCED_AVAILABILITY', False)
    location = setting('GS_LOCATION', '')
    custom_domain = setting('GS_CUSTOM_DOMAIN')
    calling_format = setting('GS_CALLING_FORMAT', SubdomainCallingFormat())
    secure_urls = setting('GS_SECURE_URLS', True)
    file_name_charset = setting('GS_FILE_NAME_CHARSET', 'utf-8')
    is_gzipped = setting('GS_IS_GZIPPED', False)
    preload_metadata = setting('GS_PRELOAD_METADATA', False)
    gzip_content_types = setting('GS_GZIP_CONTENT_TYPES', (
    url_protocol = setting('GS_URL_PROTOCOL', 'http:')

    def _save_content(self, key, content, headers):
        # only pass backwards incompatible arguments if they vary from the default
        options = {}
        if self.encryption:
            options['encrypt_key'] = self.encryption
        key.set_contents_from_file(content, headers=headers,
                                   rewind=True, **options)

    def _get_or_create_bucket(self, name):
        Retrieves a bucket if it exists, otherwise creates it.
        if self.durable_reduced_availability:
            storage_class = 'DURABLE_REDUCED_AVAILABILITY'
            storage_class = 'STANDARD'
            return self.connection.get_bucket(name,
        except self.connection_response_error:
            if self.auto_create_bucket:
                bucket = self.connection.create_bucket(name, storage_class=storage_class)
                return bucket
            raise ImproperlyConfigured("Bucket %s does not exist. Buckets "
                                       "can be automatically created by "
                                       "setting appropriate setting." % name)