Skip to content
__init__.py 70.7 KiB
Newer Older
#!/usr/bin/python
# -*- coding: UTF-8 -*-

from flask import Blueprint
from flask import current_app, request, jsonify, session, url_for, redirect, abort

import base64
import hashlib
from uuid import uuid4

from cStringIO import StringIO
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import pdf2image
from PIL import Image
from pyzbar import pyzbar

import config
from const import pfsp
from functions import do_encrypt_user_session, do_decrypt_user_session
from functions import do_encrypt_dek, dek_generate, dek_check
from functions import mySMTP

import utils
from utils.decorator import login_required, submission_has_access, admin_required
from utils.images import create_thumbnail
from utils.template import my_render_template

from views.images import do_img_info

from NIST.fingerprint import NISTf_auto
from NIST.fingerprint.labels import FINGER_POSITION_CODE, PALM_POSITION_CODE
segments_position_code = dict( FINGER_POSITION_CODE, **PALM_POSITION_CODE )
submission_view = Blueprint( "submission", __name__, template_folder = "templates" )

@submission_view.route( "/upload", methods = [ "POST" ] )
@login_required
def upload_file():
    """
        Main function dealing with the upload of files (tenprint, mark and consent forms).
        This function accept traditionals images and NIST files for the fingerprint data,
        and PDFs for the consent forms.
    """
    current_app.logger.info( "Processing of the uploaded file" )
    
    upload_type = request.form.get( "upload_type", None )
    current_app.logger.debug( "Upload type: {}".format( upload_type ) )
    
    file_extension = request.form.get( "extension", None )
    if isinstance( file_extension, str ):
        file_extension = file_extension.lower()
    
    current_app.logger.debug( "File extension: {}".format( file_extension ) )
    
    if upload_type == None:
        return jsonify( {
            "error": True,
            "message": "Must specify a file type to upload a file"
        } )
    
    if "file" not in request.files:
        current_app.logger.error( "No file in the upload request" )
        return jsonify( {
            "error": True,
            "message": "No file in the POST request"
        } )
    
    elif "submission_id" not in request.form:
        current_app.logger.error( "No submission identification number" )
        return jsonify( {
            "error": True,
            "message": "No submission_id"
        } )
    
    else:
        try:
            submission_uuid = request.form.get( "submission_id" )
            sql = "SELECT id FROM submissions WHERE uuid = %s"
            submission_id = config.db.query_fetchone( sql, ( submission_uuid, ) )[ "id" ]
            
            current_app.logger.debug( "Submission UUID: {}".format( submission_uuid ) )
            
        except:
            return jsonify( {
                "error": True,
                "message": "upload not related to a submission form"
            } )
        
        uploaded_file = request.files[ "file" ]
        file_name = do_encrypt_user_session( uploaded_file.filename )
        file_uuid = str( uuid4() )
        
        current_app.logger.debug( "File uuid: {}".format( file_uuid ) )
        
        fp = StringIO()
        
        uploaded_file.save( fp )
        file_size = fp.tell()
        
        current_app.logger.debug( "File size: {}".format( file_size ) )
        
        fp.seek( 0 )
        
        if file_extension in config.NIST_file_extensions:
            file_data = fp.getvalue()
            file_data = base64.b64encode( file_data )
            file_data = do_encrypt_dek( file_data, submission_uuid )
            
            try:
                n = NISTf_auto( fp )
                
                if not n.is_initialized():
                    raise
                
                current_app.logger.info( "NIST file loaded correctly" )
                current_app.logger.debug( "Records: " + ", ".join( [ "Type-%02d" % x for x in n.get_ntype() ] ) )
            
            except:
                current_app.logger.error( "Error while loading the NIST file" )
                return jsonify( {
                    "error": True,
                    "message": "Error while loading the NIST file"
                } )
            
            # Save the NIST file in the DB
            current_app.logger.info( "Saving the NIST file to the database" )
            sql = utils.sql.sql_insert_generate( "files", [ "folder", "creator", "filename", "type", "format", "size", "uuid", "data" ] )
            data = ( submission_id, session[ "user_id" ], file_name, 5, "NIST", file_size, file_uuid, file_data, )
            config.db.query( sql, data )
            
            # Segmentation of the NIST file
            current_app.logger.info( "Segmenting the NIST file" )
            fpc_in_file = []
            for fpc in config.all_fpc:
                current_app.logger.debug( "FPC {}".format( fpc ) )
                
                try:
                    try:
                        img = n.get_print( fpc = fpc )
                    except:
                        img = n.get_palmar( fpc = fpc )
                    
                    buff = StringIO()
                    img.save( buff, format = "TIFF" )
                    
                    current_app.logger.debug( str( img ) )
                    
                    buff.seek( 0 )
                    img_data = buff.getvalue()
                    img_data = base64.b64encode( img_data )
                    img_data = do_encrypt_dek( img_data, submission_uuid )
                    
                    sql = utils.sql.sql_insert_generate( "files_segments", [ "tenprint", "uuid", "pc", "data" ] )
                    data = ( file_uuid, str( uuid4() ), fpc, img_data, )
                    config.db.query( sql, data )
                    
                    current_app.logger.info( "Image saved to the database" )
                    
                    fpc_in_file.append( fpc )
                
                except:
                    current_app.logger.debug( "    No data" )
                    pass
            
            current_app.logger.info( "FPC processed ({}): {}".format( len( fpc_in_file ), fpc_in_file ) )
            
            config.db.commit()
            
            return jsonify( {
                "error": False,
                "fpc": fpc_in_file
            } )
                
        else:
            if upload_type in [ "mark_target", "mark_incidental", "tenprint_card_front", "tenprint_card_back" ]:
                current_app.logger.info( "Image file type: {}".format( upload_type ) )
                
                img = Image.open( fp )
                img_format = img.format
                width, height = img.size
                
                current_app.logger.debug( str( img ) )
                
                try:
                    res = int( img.info[ "dpi" ][ 0 ] )
                    current_app.logger.debug( "Resolution: {}".format( res ) )
                except:
                    current_app.logger.error( "No resolution found in the image" )
                    return jsonify( {
                        "error": True,
                        "message": "No resolution found in the image. Upload not possible at the moment."
                    } )
                
                try:
                    img = utils.images.rotate_image_upon_exif( img )
                    current_app.logger.debug( "Rotation of the image" )
Loading
Loading full blame...