Created
May 24, 2012 16:04
-
-
Save krusynth/2782431 to your computer and use it in GitHub Desktop.
S3 Uploader for Django
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ######################################################## | |
# s3filefield.py | |
# Extended FileField and ImageField for use with Django and Boto. | |
# | |
# Required settings: | |
# AWS_BUCKET_NAME - String, represents the default bucket name to use if one isn't provided | |
# AWS_ACCESS_KEY - String | |
# AWS_SECRET_KEY - String | |
# | |
# From here: http://djangosnippets.org/snippets/1976/ | |
# | |
# Modified to match existing setting names | |
# | |
# ######################################################## | |
from django.db import models | |
from django.conf import settings | |
from boto.s3.connection import S3Connection | |
from boto.s3.key import Key | |
from django.core.files.storage import FileSystemStorage | |
from django.core.files import File | |
import os | |
class S3Storage(FileSystemStorage): | |
def __init__(self, bucket=None, location=None, base_url=None): | |
assert bucket | |
if location is None: | |
location = settings.MEDIA_ROOT | |
if base_url is None: | |
base_url = settings.MEDIA_URL | |
self.location = os.path.abspath(location) | |
self.bucket = bucket | |
self.base_url = base_url | |
def _open(self, name, mode='rb'): | |
class S3File(File): | |
def __init__(self, key): | |
self.key = key | |
def size(self): | |
return self.key.size | |
def read(self, *args, **kwargs): | |
return self.key.read(*args, **kwargs) | |
def write(self, content): | |
self.key.set_contents_from_string(content) | |
def close(self): | |
self.key.close() | |
return S3File(Key(self.bucket, name)) | |
def _save(self, name, content): | |
key = Key(self.bucket, name) | |
if hasattr(content, 'temporary_file_path'): | |
key.set_contents_from_filename(content.temporary_file_path()) | |
elif isinstance(content, File): | |
key.set_contents_from_file(content) | |
else: | |
key.set_contents_from_string(content) | |
return name | |
def delete(self, name): | |
self.bucket.delete_key(name) | |
def exists(self, name): | |
return Key(self.bucket, name).exists() | |
def listdir(self, path): | |
return [key.name for key in self.bucket.list()] | |
def path(self, name): | |
raise NotImplementedError | |
def size(self, name): | |
return self.bucket.get_key(name).size | |
def url(self, name): | |
return Key(self.bucket, name).generate_url(100000) | |
def get_available_name(self, name): | |
return name | |
class S3EnabledFileField(models.FileField): | |
def __init__(self, upload_to='/', max_length=100, **kwargs): | |
bucket=settings.AWS_BUCKET_NAME | |
self.connection = S3Connection(settings.AWS_ACCESS_KEY, settings.AWS_SECRET_KEY) | |
if not self.connection.lookup(bucket): | |
self.connection.create_bucket(bucket) | |
self.bucket = self.connection.get_bucket(bucket) | |
storage = S3Storage(self.bucket) | |
super(S3EnabledFileField, self).__init__(upload_to, max_length, **kwargs) | |
class S3EnabledImageField(models.ImageField): | |
def __init__(self, upload_to='/', height_field=None, width_field=None, max_length=100, **kwargs): | |
bucket=settings.AWS_BUCKET_NAME | |
self.connection = S3Connection(settings.AWS_ACCESS_KEY, settings.AWS_SECRET_KEY) | |
if not self.connection.lookup(bucket): | |
self.connection.create_bucket(bucket) | |
self.bucket = self.connection.get_bucket(bucket) | |
kwargs['storage'] = S3Storage(self.bucket) | |
super(S3EnabledImageField, self).__init__(upload_to, height_field, width_field, max_length, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment