soter/soter/views/picture.py

84 lines
2.9 KiB
Python

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