Ticket #6390: s3.py

File s3.py, 2.8 KB (added by Marty Alchin, 15 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