Commits

Simone Marzola  committed 6d82916

upload attachedfiles and attachedimages to S3

  • Participants
  • Parent commits 4b13eca

Comments (0)

Files changed (1)

File tgext/datahelpers/remote_attachments.py

+import Image, os
+from cStringIO import StringIO
+from boto.s3.connection import S3Connection
+from boto.s3.key import Key
+from fields import AttachedFile
+from tg.decorators import cached_property
+from tg import config
+
+class S3AttachmentException(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
+class S3AttachedFile(AttachedFile):
+
+    def __init__(self, file, filename, uuid=None):
+        super(S3AttachedFile, self).__init__(file, filename, uuid)
+
+    @cached_property
+    def file(self):
+        if isinstance(self._file, basestring):
+            self._file = self.s3_key.get_file(self._file)
+            self._file.seek(0)
+        return self._file
+
+    @cached_property
+    def s3_bucket(self):
+        bucket = config.get('s3_bucket')
+        if not bucket:
+            return 'tg_attachments'
+        return bucket
+
+    @cached_property
+    def s3_key(self):
+        bucket = self.s3_connection.get_bucket(self.s3_bucket)
+        key = Key(bucket)
+        key.key = self.local_path
+        return key
+
+    @cached_property
+    def s3_connection(self):
+        s3_key = config.get('s3_key')
+        s3_secret = config.get('s3_secret')
+        if not (s3_key and s3_secret):
+            raise S3AttachmentException('Missing s3_key and s3_secret in configuration file')
+        return S3Connection(s3_key, s3_secret)
+
+    @property
+    def attachment_dir(self):
+        return self.uuid
+
+    @cached_property
+    def attachments_url(self):
+        return 'http://%s.s3.amazonaws.com' % self.s3_bucket
+
+    @property
+    def private_url(self):
+        return self.s3_key.generate_url(config.get('s3_expire', 3600))
+
+    def write(self):
+        self.s3_key.set_contents_from_file(self.file, policy='public-read')
+        self.file.seek(0)
+
+    def unlink(self):
+        self.s3_key.delete()
+
+
+class S3AttachedImage(S3AttachedFile):
+    thumbnail_size = (128, 128)
+    thumbnail_format = 'png'
+
+    def __init__(self, file, filename, uuid=None):
+        super(S3AttachedImage, self).__init__(file, filename, uuid)
+
+        thumb_filename = 'thumb.'+self.thumbnail_format.lower()
+        self.thumb_local_path = os.path.join(self.attachment_dir, thumb_filename)
+        self.thumb_url = '/'.join([self.attachments_url, self.uuid, thumb_filename])
+
+    def write(self):
+        super(S3AttachedImage, self).write()
+
+        self.file.seek(0)
+        thumbnail = Image.open(self.file)
+        thumbnail.thumbnail(self.thumbnail_size, Image.BILINEAR)
+        thumbnail = thumbnail.convert('RGBA')
+        thumbnail.format = self.thumbnail_format
+        temp_file = StringIO()
+        thumbnail.save(temp_file)
+        temp_file.seek(0)
+        self.s3_key.set_contents_from_file(temp_file, policy='public-read')