Skip to content

Commit 020143f

Browse files
committed
Add existing S3Storage
0 parents  commit 020143f

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

FTPStorage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Work in progress

S3BotoStorage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# should not be too hard to adapt S3Storage

S3Storage.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from mimetypes import guess_type
2+
import os
3+
4+
from django.core.exceptions import ImproperlyConfigured
5+
from django.core.filestorage.base import Storage, RemoteFile
6+
from django.core.filestorage.filesystem import FileSystemStorage
7+
from django.utils.functional import curry
8+
from django.conf import settings
9+
10+
ACCESS_KEY_NAME = 'AWS_ACCESS_KEY_ID'
11+
SECRET_KEY_NAME = 'AWS_SECRET_ACCESS_KEY'
12+
AWS_HEADERS = 'AWS_HEADERS'
13+
14+
try:
15+
from S3 import AWSAuthConnection, QueryStringAuthGenerator
16+
except ImportError:
17+
raise ImproperlyConfigured, "Could not load amazon's S3 bindings.\
18+
\nSee http://developer.amazonwebservices.com/connect/entry.jspa?externalID=134"
19+
20+
class S3Storage(Storage):
21+
"""Amazon Simple Storage Service"""
22+
23+
def __init__(self, bucket=settings.AWS_STORAGE_BUCKET_NAME,
24+
access_key=None, secret_key=None, acl='public-read',
25+
calling_format=settings.AWS_CALLING_FORMAT):
26+
self.bucket = bucket
27+
self.acl = acl
28+
29+
if not access_key and not secret_key:
30+
access_key, secret_key = self._get_access_keys()
31+
32+
self.connection = AWSAuthConnection(access_key, secret_key,
33+
calling_format=calling_format)
34+
self.generator = QueryStringAuthGenerator(access_key, secret_key,
35+
calling_format=calling_format, is_secure=False)
36+
37+
self.headers = getattr(settings, AWS_HEADERS, {})
38+
39+
def _get_access_keys(self):
40+
access_key = getattr(settings, ACCESS_KEY_NAME, None)
41+
secret_key = getattr(settings, SECRET_KEY_NAME, None)
42+
if (access_key or secret_key) and (not access_key or not secret_key):
43+
access_key = os.environ.get(ACCESS_KEY_NAME)
44+
secret_key = os.environ.get(SECRET_KEY_NAME)
45+
46+
if access_key and secret_key:
47+
# Both were provided, so use them
48+
return access_key, secret_key
49+
50+
return None, None
51+
52+
def _get_connection(self):
53+
return AWSAuthConnection(*self._get_access_keys())
54+
55+
def _put_file(self, filename, raw_contents):
56+
content_type = guess_type(filename)[0] or "application/x-octet-stream"
57+
self.headers.update({'x-amz-acl': self.acl, 'Content-Type': content_type})
58+
response = self.connection.put(self.bucket, filename, raw_contents, self.headers)
59+
60+
def url(self, filename):
61+
return self.generator.make_bare_url(self.bucket, filename)
62+
63+
path = url
64+
65+
def filesize(self, filename):
66+
response = self.connection.make_request('HEAD', self.bucket, filename)
67+
return int(response.getheader('Content-Length'))
68+
69+
def open(self, filename, mode='rb'):
70+
response = self.connection.get(self.bucket, filename)
71+
writer = curry(self._put_file, filename)
72+
return RemoteFile(self, response.object.data, mode, writer)
73+
74+
def exists(self, filename):
75+
response = self.connection.make_request('HEAD', self.bucket, filename)
76+
return response.status == 200
77+
78+
def save(self, filename, raw_contents):
79+
filename = self.get_available_filename(filename)
80+
self._put_file(filename, raw_contents)
81+
return filename
82+
83+
## UNCOMMENT BELOW IF NECESSARY
84+
85+
#def delete(self, filename):
86+
# """ Do not delete default images. """
87+
# if not filename.endswith('default.jpg') and not filename.endswith('guest.jpg'):
88+
# self.connection.delete(self.bucket, filename)
89+
90+
#def get_available_filename(self, filename):
91+
# """ Overwrite existing file with the same name. """
92+
# return filename

0 commit comments

Comments
 (0)