Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
219 lines (168 sloc) 6.31 KB
from flask import current_app
from ..helpers import get_current_time, get_current_time_plus
from PIL import Image as PIL_IMAGE
import cStringIO
import os
import hashlib
import boto
from boto.s3.connection import S3Connection
from boto.s3.key import Key
import time
Helper functions for dealing with files on disk
def delete_image(image):
Depending on the state of the image, either delete it locally or delete it from s3
if image.on_s3():
def delete_image_on_disk(image):
file_abs_path = get_abs_path(image.file_name)
thumb_abs_path = add_thumb_ext(file_abs_path)
def _delete_file(file):
if os.path.isfile(file):
Helper functions for s3 specific operations
def save_string_to_s3(user_name, key, string_data):
bucket = _get_bucket()
#include user path as prefix
store_key = user_name+'/'+key
#assuming the key is unique (it should be)
k = bucket.new_key(store_key)
k.set_contents_from_string(string_data, \
'Cache-Control': "max-age=31536000, public",\
'Expires' : get_current_time_plus(days=365).strftime("%a, %d %b %Y %H:%M:%S GMT")})
def save_images_to_s3(user, images):
Save an array of images to s3 and delete the local copies from disk
for i in images:
file_abs_path = get_abs_path(i.file_name)
save_file_to_s3(user.user_name, i.file_name, file_abs_path)
#image thumbnail
thumb_name = add_thumb_ext(i.file_name)
thumb_abs_path = add_thumb_ext(file_abs_path)
save_file_to_s3(user.user_name, thumb_name, thumb_abs_path)
#delete the images
def delete_image_from_s3(image):
#generate username
user_name = get_user_name_from_file_name(image.file_name)
file_key = user_name+'/'+ image.file_name
thumb_key = add_thumb_ext(file_key)
def save_file_to_s3(user_name, key, file_abs_path):
bucket = _get_bucket()
#include user path as prefix
store_key = user_name+'/'+key
#assuming the key is unique (it should be)
k = bucket.new_key(store_key)
k.set_contents_from_filename(file_abs_path, \
'Cache-Control': "max-age=31536000, public",\
'Expires' : get_current_time_plus(days=365).strftime("%a, %d %b %Y %H:%M:%S GMT")})
def delete_file_from_s3(key):
bucket = _get_bucket()
k = bucket.get_key(key)
if k:
def _get_bucket():
conn = S3Connection(host = current_app.config['S3_REGION_ENDPOINT'])
#the bucket should exists (notice we skip the request to check)
bucket = conn.get_bucket(current_app.config['S3_BUCKET'], validate=False)
return bucket
Helper function for creating image names, links, and file path
def add_thumb_ext(file_name):
Returns both the image abs path and the thumb abs path
root, ext = os.path.splitext(file_name)
thumb = root+THUMBNAIL_EXTENSION+ext
return thumb
def get_user_name_from_file_name(file_name):
#By convention, image name is [user_name]_[hash]_[day].[ext]
return file_name.split("_")[0]
def get_hash_name(file_data, file_name, user_name):
#construct the file name
today = get_current_time().strftime('_%Y%m%d%H%M%S')
root, ext = os.path.splitext(file_name)
hash_name = user_name + "_" + hashlib.sha1(file_data).hexdigest() + today + ext
return hash_name
def get_abs_path(file_name):
#upload directory (currently, /tmp/instance/upload)
upload_dir = current_app.config['UPLOAD_FOLDER']
return os.path.join(upload_dir, file_name)
def get_s3_link(file_name):
user_name = get_user_name_from_file_name(file_name)
#prefix = [bucket_name].[region_endpoint]/[user_name]/ -> + [file_name]
return 'https://'+current_app.config['S3_BUCKET']+'.'+current_app.config['S3_REGION_ENDPOINT'] +\
'/'+user_name +'/' + file_name
Helper functions for images resizing/cropping, assume thumbnail smaller than image
def save_shrink_and_thumbnail(data, file_name):
shrink_image_path = get_abs_path(file_name)
thumb_image_path = add_thumb_ext(shrink_image_path)
string_io = cStringIO.StringIO(data)
original =
#shrink the image
shrunk = get_shrink_image(original)
#crop and create thumbnail
thumb = get_thumbnail(shrunk)
def get_thumbnail(image, thumb_w = THUMBNAIL_WIDTH, thumb_h = THUMBNAIL_HEIGHT):
Crop the image to the maximum possible thumbnail ratio in the center, then resize to thumbnail size
#Find largest thumbnail ratio that fits in original
width,height = image.size
wratio = width / float(thumb_w)
hratio = height/ float(thumb_h)
if hratio <= wratio:
multiplier = hratio
multiplier = wratio
#Crop the original image based on the ratio
dx = (width - thumb_w * multiplier)/2
dy = (height- thumb_h * multiplier)/2
left = dx
top = dy
right = width-dx
bottom = height-dy
print left, top, right, bottom
thumb = image.crop((int(left), int(top), int(right), int(bottom)))
thumb.thumbnail((thumb_w, thumb_h), PIL_IMAGE.ANTIALIAS)
return thumb
def get_shrink_image(original, max_height=MAX_IMG_HEIGHT, step_two = True):
Perform 2 step shrinking. First step with super low quality(fast) alg then with high quality alg
width, height = original.size
ratio = (1.0*width)/height
new_height = max_height
new_width = int(ratio * new_height)
#Only shrink if height is over MAX
if height > max_height:
#step 1. shrink image to double of target size with fast algorithm
original = original.resize((new_width*2, new_height*2))
if step_two:
#step 2. final shrink with slow (but high quality) algorithm
return original.resize((new_width, new_height), PIL_IMAGE.ANTIALIAS)
return original
You can’t perform that action at this time.