From e3ded59e5303610951579cf6b71b14703b903bf8 Mon Sep 17 00:00:00 2001 From: tanshu Date: Mon, 29 Jun 2015 15:22:15 +0530 Subject: [PATCH] Added a picture property table to store an array of picture properties Now upload also saves the name and the lastModifiedDate as reported by the browser --- soter/models/master.py | 50 +++++++++++++++++++ soter/static/app/album/album.controller.js | 2 +- .../static/app/picture/picture.controller.js | 1 + soter/views/picture.py | 30 ++++++----- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/soter/models/master.py b/soter/models/master.py index 49a275a..56b09f8 100644 --- a/soter/models/master.py +++ b/soter/models/master.py @@ -2,6 +2,7 @@ import uuid import re from sqlalchemy import Column, PickleType, Unicode, ForeignKey, Boolean, Table, UniqueConstraint, LargeBinary + from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import relationship @@ -180,3 +181,52 @@ class Tag(Base): @classmethod def list(cls): return DBSession.query(cls).all() + + +class Property(Base): + __tablename__ = 'pic_properties' + + id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) + name = Column('name', Unicode(100), unique=True, nullable=False) + + def __init__(self, name=None): + self.name = name + + @classmethod + def by_id(cls, id): + return DBSession.query(cls).filter(cls.id == id).first() + + @classmethod + def by_name(cls, name): + prop = DBSession.query(cls).filter(cls.name == name).first() + if prop is None: + prop = Property(name) + DBSession.add(prop) + return prop + + @classmethod + def list(cls): + return DBSession.query(cls).all() + + +class PictureProperty(Base): + __tablename__ = 'picture_properties' + __table_args__ = (UniqueConstraint('picture_id', 'property_id'),) + id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) + picture_id = Column('picture_id', GUID(), ForeignKey('pictures.id'), nullable=False) + property_id = Column('property_id', GUID(), ForeignKey('pic_properties.id'), nullable=False) + data = Column('data', PickleType, nullable=False) + + picture = relationship(Picture, backref="properties") + property = relationship(Property, backref="pictures") + + def __init__(self, picture_id=None, property_id=None, picture=None, property=None, data=None): + if picture_id is not None: + self.picture_id = picture_id + if property_id is not None: + self.property_id = property_id + if picture is not None: + self.picture = picture + if property is not None: + self.property = property + self.data = data diff --git a/soter/static/app/album/album.controller.js b/soter/static/app/album/album.controller.js index 1b874f6..86b5a94 100644 --- a/soter/static/app/album/album.controller.js +++ b/soter/static/app/album/album.controller.js @@ -42,7 +42,7 @@ var file = files[i]; Upload.upload({ url: '/v1/upload', - fields: {'album': info.id}, + fields: {'album': info.id, name: file.name, lastModifiedDate: file.lastModifiedDate}, file: file }).progress(function (evt) { var progressPercentage = parseInt(100.0 * evt.loaded / evt.total); diff --git a/soter/static/app/picture/picture.controller.js b/soter/static/app/picture/picture.controller.js index 5a67c6c..73cef95 100644 --- a/soter/static/app/picture/picture.controller.js +++ b/soter/static/app/picture/picture.controller.js @@ -12,6 +12,7 @@ var file = files[i]; Upload.upload({ url: '/v1/upload', + fields: {name: file.name, lastModifiedDate: file.lastModifiedDate}, file: file }).progress(function (evt) { var progressPercentage = parseInt(100.0 * evt.loaded / evt.total); diff --git a/soter/views/picture.py b/soter/views/picture.py index 17393ac..7269396 100644 --- a/soter/views/picture.py +++ b/soter/views/picture.py @@ -14,7 +14,7 @@ import transaction import numpy from soter.models import DBSession -from soter.models.master import Picture, Album +from soter.models.master import Picture, Album, Property, PictureProperty @view_config(request_method='GET', route_name='upload', permission='Albums') @@ -28,15 +28,25 @@ def html(request): @view_config(request_method='POST', route_name='api_upload', renderer='json', permission='Albums') def upload(request): input_file = request.POST['file'].file + name = request.POST['name'] + last_modified_date = request.POST['lastModifiedDate'] + album_id = uuid.UUID(request.POST['album']) + upload_file(input_file, name, last_modified_date, album_id, uuid.UUID(authenticated_userid(request))) + return {'Status': 'OK'} + + +def upload_file(file, name, last_modified_date, album_id, user_id): + last_modified_date_prop = Property.by_name('last_modified_date') file_id = uuid.uuid4() file_path = pkg_resources.resource_filename('soter', 'upload/o/' + str(file_id) + '.jpg') - album = request.POST['album'] temp_file_path = file_path + '~' - input_file.seek(0) + file.seek(0) with open(temp_file_path, 'wb') as output_file: - shutil.copyfileobj(input_file, output_file) - pic = process_picture(temp_file_path, str(file_id), uuid.UUID(authenticated_userid(request)), file_id, - uuid.UUID(album)) + shutil.copyfileobj(file, output_file) + pic_hash = get_hash(temp_file_path) + pic = Picture(name, pic_hash, user_id, True, file_id) + pic.albums.append(Album.by_id(album_id)) + pic.properties.append(PictureProperty(property= last_modified_date_prop, data = last_modified_date)) DBSession.add(pic) try: transaction.commit() @@ -51,15 +61,11 @@ def upload(request): return {'location': file_path} -def process_picture(path, name, user_id, file_id, album_id): +def get_hash(path): image = get_image(path) img = numpy.array(image) img = img[:, :, ::-1].copy() - - hash = hashlib.sha512(numpy.array(img)).digest() - picture = Picture(name, hash, user_id, True, file_id) - picture.albums.append(Album.by_id(album_id)) - return picture + return hashlib.sha512(numpy.array(img)).digest() def get_image(path):