#!/usr/bin/python # -*- coding: UTF-8 -*- import base64 from cStringIO import StringIO from uuid import uuid4 from flask import Blueprint from flask import jsonify, request, send_file, current_app from PIL import Image import utils from utils.decorator import admin_required from utils.template import my_render_template import config from utils.sql import sql_insert_generate from functions import do_encrypt_dek, do_decrypt_dek from NIST.fingerprint.labels import FINGER_POSITION_CODE, PALM_POSITION_CODE segments_position_code = dict( FINGER_POSITION_CODE, **PALM_POSITION_CODE ) afis_view = Blueprint( "afis", __name__, template_folder = "templates" ) @afis_view.route( "/afis/get/list" ) def download_list(): return my_render_template( "afis/search_list.html" ) @afis_view.route( "/admin/afis/list" ) @admin_required def admin_list(): sql = """ SELECT cnm_folder.uuid, users.username FROM cnm_folder INNER JOIN submissions ON submissions.uuid = cnm_folder.donor INNER JOIN users ON submissions.donor_id = users.id """ folders = config.db.query_fetchall( sql ) sql = """ SELECT submissions.uuid, users.username FROM submissions LEFT JOIN users ON submissions.donor_id = users.id LEFT JOIN cnm_folder ON submissions.uuid = cnm_folder.donor WHERE cnm_folder.uuid IS NULL ORDER BY users.id ASC """ donors = config.db.query_fetchall( sql ) return my_render_template( "afis/admin/list.html", folders = folders, donors = donors ) @afis_view.route( "/admin/afis/new_folder", methods = [ "POST" ] ) @admin_required def admin_add_new_folder(): try: donor_uuid = request.form.get( "donor_uuid", False ) sql = "SELECT count( * ) AS nb FROM cnm_folder WHERE donor = %s" nb = config.db.query_fetchone( sql, ( donor_uuid, ) )[ "nb" ] if nb == 0: sql = sql_insert_generate( "cnm_folder", [ "donor", "uuid" ], "id" ) config.db.query_fetchone( sql, ( donor_uuid, str( uuid4() ) ) ) config.db.commit() return jsonify( { "error": False } ) except: return jsonify( { "error": True } ) @afis_view.route( "/admin/afis//delete" ) @admin_required def admin_delete_folder( folder_id ): try: sql = "DELETE FROM cnm_annotation WHERE folder = %s" config.db.query( sql, ( folder_id, ) ) sql = "DELETE FROM cnm_segments WHERE folder_uuid = %s" config.db.query( sql, ( folder_id, ) ) sql = "DELETE FROM cnm_folder WHERE uuid = %s" config.db.query( sql, ( folder_id, ) ) config.db.commit() return jsonify( { "error": False } ) except: return jsonify( { "error": True } ) @afis_view.route( "/admin/afis/" ) @admin_required def admin_folder_show( folder_id ): sql = """ SELECT segments_locations.fpc FROM segments_locations INNER JOIN files ON segments_locations.tenprint_id = files.uuid INNER JOIN submissions ON files.folder = submissions.id INNER JOIN cnm_folder ON submissions.uuid = cnm_folder.donor WHERE cnm_folder.uuid = %s ORDER BY fpc ASC """ segment_list = config.db.query_fetchall( sql, ( folder_id, ) ) sql = """ SELECT * FROM cnm_segments WHERE folder_uuid = %s ORDER BY fpc ASC """ segment_list_in_folder = config.db.query_fetchall( sql, ( folder_id, ) ) sql = """ SELECT files_segments.tenprint, files_segments.pc FROM cnm_folder INNER JOIN submissions ON cnm_folder.donor = submissions.uuid INNER JOIN files ON submissions.id = files.folder INNER JOIN files_segments ON files.uuid = files_segments.tenprint WHERE cnm_folder.uuid = %s """ tpid = config.db.query_fetchall( sql, ( folder_id, ) ) sql = """ SELECT username FROM users INNER JOIN submissions ON users.id = submissions.donor_id INNER JOIN cnm_folder ON submissions.uuid = cnm_folder.donor WHERE cnm_folder.uuid = %s """ username = config.db.query_fetchone( sql, ( folder_id, ) )[ "username" ] return my_render_template( "afis/admin/folder.html", segment_list = segment_list, segment_list_in_folder = segment_list_in_folder, tpid = tpid, username = username, folder_id = folder_id, segments_position_code = segments_position_code ) @afis_view.route( "/admin/afis//add/segment", methods = [ "POST" ] ) @admin_required def admin_add_segment_to_cnmfolder( folder_id ): try: fpc = request.form.get( "fpc" ) sql = "SELECT count( * ) AS nb FROM cnm_segments WHERE folder_uuid = %s AND fpc = %s" nb = config.db.query_fetchone( sql, ( folder_id, fpc, ) )[ "nb" ] if nb == 0: sql = sql_insert_generate( "cnm_segments", [ "uuid", "folder_uuid", "fpc" ], "uuid" ) config.db.query_fetchone( sql, ( str( uuid4() ), folder_id, fpc, ) ) config.db.commit() return jsonify( { "error": False } ) except: return jsonify( { "error": True } ) @afis_view.route( "/admin/afis//segment/" ) @admin_required def admin_view_segment( folder_id, fpc ): sql = """ SELECT files_segments.tenprint, files.uuid as file_uuid FROM cnm_folder INNER JOIN submissions ON cnm_folder.donor = submissions.uuid INNER JOIN files ON submissions.id = files.folder INNER JOIN files_segments ON files.uuid = files_segments.tenprint WHERE cnm_folder.uuid = %s AND files_segments.pc = %s """ tenprints_list = config.db.query_fetchall( sql, ( folder_id, fpc, ) ) sql = """ SELECT username FROM users INNER JOIN submissions ON users.id = submissions.donor_id INNER JOIN cnm_folder ON submissions.uuid = cnm_folder.donor WHERE cnm_folder.uuid = %s """ username = config.db.query_fetchone( sql, ( folder_id, ) )[ "username" ] sql = """ SELECT id, uuid FROM cnm_annotation WHERE folder = %s AND fpc = %s """ annotations = config.db.query_fetchall( sql, ( folder_id, fpc, ) ) return my_render_template( "afis/admin/segment.html", folder_id = folder_id, fpc = fpc, tenprints_list = tenprints_list, username = username, annotations = annotations, segments_position_code = segments_position_code ) @afis_view.route( "/admin/afis//segment//add/illustration", methods = [ "POST" ] ) @admin_required def admin_add_illustration( folder_id, fpc ): try: sql = """ SELECT donor FROM cnm_folder WHERE uuid = %s """ donor_uuid = config.db.query_fetchone( sql, ( folder_id, ) )[ "donor" ] uploaded_file = request.files[ "file" ] fp = StringIO() uploaded_file.save( fp ) fp.seek( 0 ) file_data = fp.getvalue() file_data = base64.b64encode( file_data ) file_data = do_encrypt_dek( file_data, donor_uuid ) sql = sql_insert_generate( "cnm_annotation", [ "uuid", "folder", "fpc", "annotation_data" ], "id" ) annotation_id = config.db.query_fetchone( sql, ( str( uuid4() ), folder_id, fpc, file_data, ) ) config.db.commit() return jsonify( { "error": False } ) except: return jsonify( { "error": True } ) @afis_view.route( "/admin/afis//segment//remove/illustration", methods = [ "POST" ] ) @admin_required def admin_remove_illustration( folder_id, fpc ): try: illustration_uuid = request.form.get( "uuid" ) sql = "DELETE FROM cnm_annotation WHERE folder = %s AND fpc = %s AND uuid = %s" config.db.query( sql, ( folder_id, fpc, illustration_uuid, ) ) config.db.commit() return jsonify( { "error": False } ) except: return jsonify( { "error": True } ) @afis_view.route( "/admin/afis//remove/segment", methods = [ "POST" ] ) @admin_required def admin_remove_segment( folder_id ): try: fpc = request.form.get( "fpc" ) sql = "DELETE FROM cnm_segments WHERE folder_uuid = %s AND fpc = %s" config.db.query( sql, ( folder_id, fpc, ) ) sql = "DELETE FROM cnm_annotation WHERE folder = %s AND fpc = %s" config.db.query( sql, ( folder_id, fpc, ) ) config.db.commit() return jsonify( { "error": False } ) except: return jsonify( { "error": True } ) @afis_view.route( "/admin/afis//annotation/" ) @admin_required def admin_get_annotation_image( folder_id, a_uuid ): sql = "SELECT donor FROM cnm_folder WHERE uuid = %s" donor_uuid = config.db.query_fetchone( sql, ( folder_id, ) )[ "donor" ] sql = """ SELECT annotation_data FROM cnm_annotation WHERE uuid = %s """ data = config.db.query_fetchone( sql, ( a_uuid, ) )[ "annotation_data" ] data = do_decrypt_dek( data, donor_uuid ) img = base64.b64decode( data ) buff = StringIO() buff.write( img ) buff.seek( 0 ) img = Image.open( buff ) buff = utils.images.pil2buffer( img, "PNG" ) return send_file( buff, mimetype = "image/png" )