import os import shutil import uuid from PIL import Image, ExifTags import pkg_resources from pyramid.response import FileResponse from pyramid.security import authenticated_userid from pyramid.view import view_config import transaction import numpy from soter.models import DBSession from soter.models.master import Picture @view_config(request_method='GET', route_name='upload', permission='Albums') def html(request): package, resource = 'soter:static/index.html'.split(':', 1) file = pkg_resources.resource_filename(package, resource) return FileResponse(file, request=request) @view_config(request_method='POST', route_name='api_upload', renderer='json', permission='Albums') def upload(request): input_file = request.POST['file'].file file_id = uuid.uuid4() file_path = pkg_resources.resource_filename('soter', 'upload/' + str(file_id) + '.jpg') album = request.POST['album'] temp_file_path = file_path + '~' input_file.seek(0) with open(temp_file_path, 'wb') as output_file: shutil.copyfileobj(input_file, output_file) os.rename(temp_file_path, file_path) # Process picture here to get the hash and the exif tags to be added to the database pic = Picture(file_id, str(file_id), uuid.UUID(authenticated_userid(request)), uuid.UUID(album), True, file_id) DBSession.add(pic) transaction.commit() return {'location': file_path} def process_picture(path): image = get_image(path) Picture(file_id, str(file_id), uuid.UUID(authenticated_userid(request)), uuid.UUID(album), True, file_id) def get_image(path): image = Image.open(path) orientation = [tag for tag in ExifTags.TAGS.keys() if ExifTags.TAGS[tag] == 'Orientation'][0] exif = dict(image._getexif().items()) if exif[orientation] == 3: image = image.rotate(180, expand=True) elif exif[orientation] == 6: image = image.rotate(270, expand=True) elif exif[orientation] == 8: image = image.rotate(90, expand=True) img = numpy.array(image) # CONVERT RGB TO BGR return img[:, :, ::-1].copy() @view_config(request_method='GET', route_name='picture_raw', permission='Albums') def show_raw(request): package, resource = ('soter:upload/' + request.matchdict['id'] + '.jpg').split(':', 1) file = pkg_resources.resource_filename(package, resource) return FileResponse(file, request=request) @view_config(request_method='GET', route_name='api_album_id', renderer='json', request_param='pictures', permission='Albums') def show_id(request): return picture_info(request.matchdict['id'], request) def picture_info(id, request): if not isinstance(id, Picture): picture = Picture.by_id(id) else: picture = id album = {'id': picture.id, 'name': picture.name, 'imageUrl': request.route_url('picture_raw', id=picture.id), 'user': {'id': picture.user_id, 'name': picture.user.name}} return album