zcash-grant-system/backend/grant/utils/upload.py

64 lines
1.9 KiB
Python

import re
import uuid
import boto3
from flask import current_app
IMAGE_MIME_TYPES = set(['image/png', 'image/jpg', 'image/gif'])
AVATAR_MAX_SIZE = 2 * 1024 * 1024 # 2MB
class AvatarException(Exception):
pass
def allowed_avatar_type(mimetype):
if mimetype not in IMAGE_MIME_TYPES:
raise AvatarException("Unacceptable file type: {0}".format(mimetype))
return True
def extract_avatar_filename(url):
match = re.search(r'avatars/(\d+\.\w+\.\w+)$', url)
if match:
return match.group(1)
else:
raise AvatarException("Unable to extract avatar filename from %s" % url)
def construct_avatar_url(filename):
S3_BUCKET = current_app.config['S3_BUCKET']
return "https://%s.s3.amazonaws.com/avatars/%s" % (S3_BUCKET, filename)
def remove_avatar(url, user_id):
S3_BUCKET = current_app.config['S3_BUCKET']
filename = extract_avatar_filename(url)
user_match = re.search(r'^(\d+)\.\w+\.\w+$', filename)
if user_match and user_match.group(1) == str(user_id):
s3 = boto3.resource('s3')
s3.Object(S3_BUCKET, 'avatars/' + filename).delete()
def sign_avatar_upload(mimetype, user_id):
S3_BUCKET = current_app.config['S3_BUCKET']
if mimetype and allowed_avatar_type(mimetype):
ext = mimetype.replace('image/', '')
filename = "{0}.{1}.{2}".format(user_id, uuid.uuid4().hex, ext)
key = "avatars/" + filename
s3 = boto3.client('s3')
presigned_post = s3.generate_presigned_post(
Bucket=S3_BUCKET,
Key=key,
Fields={"acl": "public-read", "Content-Type": mimetype},
Conditions=[
{"acl": "public-read"},
{"Content-Type": mimetype},
["content-length-range", 0, AVATAR_MAX_SIZE]
],
ExpiresIn=3600
)
return {
"data": presigned_post,
"url": construct_avatar_url(filename)
}