Django

Code

Ticket #6390: s3.py

File s3.py, 2.8 kB (added by Gulopine, 8 months ago)

Broken first draft

Line 
1 from mimetypes import guess_type
2 from StringIO import StringIO
3 import urlparse
4 import os
5
6 from django.core.exceptions import ImproperlyConfigured
7 from django.core.filestorage.base import Backend, RemoteFile
8 from django.utils.functional import curry
9
10 ACCESS_KEY_NAME = 'AWS_ACCESS_KEY_ID'
11 SECRET_KEY_NAME = 'AWS_SECRET_ACCESS_KEY'
12
13 try:
14     from boto.s3.connection import S3Connection
15 except ImportError:
16     raise ImproperlyConfigured, "Could not load boto's S3 bindings."
17
18 class 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)