Ticket #6390: s3.py

File s3.py, 2.8 KB (added by Marty Alchin, 16 years ago)

Broken first draft

Line 
1from mimetypes import guess_type
2from StringIO import StringIO
3import urlparse
4import os
5
6from django.core.exceptions import ImproperlyConfigured
7from django.core.filestorage.base import Backend, RemoteFile
8from django.utils.functional import curry
9
10ACCESS_KEY_NAME = 'AWS_ACCESS_KEY_ID'
11SECRET_KEY_NAME = 'AWS_SECRET_ACCESS_KEY'
12
13try:
14 from boto.s3.connection import S3Connection
15except ImportError:
16 raise ImproperlyConfigured, "Could not load boto's S3 bindings."
17
18class S3Backend(Backend):
19 """Amazon Simple Storage Service"""
20
21 def __init__(self, bucket, access_key=None, secret_key=None, acl='public-read'):
22 self.bucket = bucket
23
24 if not access_key and not secret_key:
25 access_key, secret_key = self._get_access_keys()
26
27 self.connection = S3Connection(access_key, secret_key)
28 self.generator = S3.QueryStringAuthGenerator(access_key, secret_key)
29
30 def _get_access_keys(self):
31 access_key = getattr(settings, ACCESS_KEY_NAME, None)
32 secret_key = getattr(settings, SECRET_KEY_NAME, None)
33 if (access_key or secret_key) and (not access_key or not secret_key):
34 access_key = os.environ.get(ACCESS_KEY_NAME)
35 secret_key = os.environ.get(SECRET_KEY_NAME)
36
37 if access_key and secret_key:
38 # Both were provided, so use them
39 return access_key, secret_key
40
41 return None, None
42
43 def _get_connection(self):
44 return S3Connection(*self._get_access_keys())
45
46 def _put_file(self, filename, raw_contents):
47 content_type = guess_type(filename)[0] or "application/x-octet-stream"
48 headers = {'x-amz-acl': self.acl, 'Content-Type': content_type}
49 self.connection.put(self.bucket, self.filename, raw_contents, headers)
50
51 def get_filename(self, filename):
52 return urlparse.urljoin('/%s/' % self.bucket, filename)
53
54 def get_absolute_url(self, filename):
55 return self.generator.make_bare_url(self.bucket, filename)
56
57 def get_filesize(self, filename):
58 response = self.connection.make_request('HEAD', self.bucket, filename)
59 return int(response.getheader('Content-Length'))
60
61 def open_file(self, filename, mode='rb'):
62 response = self.connection.get(self.bucket, filename)
63 writer = curry(self._put_file, filename)
64 return RemoteFile(self, response.object.data, mode, writer)
65
66 def file_exists(self, filename):
67 response = self.connection.make_request('HEAD', self.bucket, filename)
68 return response.status == 200
69
70 def save_file(self, filename, raw_contents):
71 filename = self.get_available_filename(filename)
72 self._put_file(filename, raw_contents)
73 return filename
74
75 def delete_file(self, filename):
76 self.connection.delete(self.bucket, self.key)
Back to Top