Skip to content
module.py 37.7 KiB
Newer Older
@app.route( baseurl + '/upload', methods = [ 'GET', 'POST' ] )
@login_required
def upload_file():
    upload_type = request.form.get( "upload_type", None )
    
    if upload_type == None:
Marco De Donno's avatar
Marco De Donno committed
        return jsonify( {
            'error': True,
            'msg': 'Must specify a file type to upload a file'
        } )
    
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify( { 'error': True, 'msg': 'No file in the POST request' } )
        elif 'upload_id' not in request.form:
            return jsonify( { 'error': True, 'msg': 'No upload_id' } )
        else:
            try:
                upload_id = request.form.get( "upload_id" )
                sql = "SELECT id FROM submissions WHERE uuid = %s"
                r = config.db.query( sql, ( upload_id, ) )
                upload_id = r.fetchone()[ 'id' ]
                
            except:
                return jsonify( {
                    'error': True
                } )
            
            file = request.files[ 'file' ]
            filename = do_encrypt( file.filename )
            
            fp = StringIO()
            
            file.save( fp )
            file_size = fp.tell()
            
            fp.seek( 0 )
            
            if upload_type in [ 'latent', 'tenprint_card_front', 'tenprint_card_back' ]:
                img = Image.open( fp )
                img_format = img.format
                width, height = img.size
                img = rotate_image_upon_exif( img )
                
                buff = StringIO()
                img.save( buff, format = img_format )
                buff.seek( 0 )
                file_data = buff.getvalue()
            
            else:
                file_data = fp.getvalue()
            
            file_data = base64.b64encode( file_data )
            
            if upload_type == "consent_form":
                file_data = gpg.encrypt( file_data, config.gpg_key )
                file_data = str( file_data )
            
            file_uuid = str( uuid4() )
            
            upload_type_id = {
                'consent_form': 0,
                'tenprint_card_front': 1,
                'tenprint_card_back': 2,
                'latent': 3
            sql = "INSERT INTO files ( folder, creator, filename, type, format, size, width, height, uuid, data ) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )"
            data = ( upload_id, session[ 'user_id' ], filename, upload_type_id, img_format, file_size, width, height, file_uuid, file_data )
            config.db.query( sql, data )
            config.db.commit()
            
            return jsonify( {
                'error': False,
                'filename': filename,
                'filesize': file_size,
                'uuid': file_uuid
            } )
    
    else:
        return abort( 403 )
################################################################################
#    Submission of a new donnor

@app.route( baseurl + '/new_donnor' )
@login_required
def submission_form():
    return render_template( 
        baseurl = baseurl,
        js = config.cdnjs,
        css = config.cdncss,
        session_timeout = config.session_timeout
    )

@app.route( baseurl + '/create_submission', methods = [ "GET", "POST" ] )
@login_required
def create_submission_case():
    email = request.form.get( "email", False )
    
    if email:
        # Check for duplicate base upon the email data
        sql = "SELECT id, email_hash FROM submissions WHERE submitter_id = %s"
        r = config.db.query( sql, ( session[ 'user_id' ], ) )
        for case in r.fetchall():
            if pbkdf2( email, case[ 'email_hash' ] ):
                return jsonify( {
                    'error': True,
                    'msg': "Email already used"
                } )
                
                break
        else:
            # Insert the new donnor
            id = str( uuid4() )
            
            email_aes = do_encrypt( email )
            email_hash = pbkdf2( email, random_data( 50 ), 50000 )
            
            upload_nickname = request.form.get( "upload_nickname", None )
            upload_nickname = do_encrypt( upload_nickname )
            submitter_id = session[ 'user_id' ]
            
            status = "pending"
            
            sql = "INSERT INTO submissions ( uuid, email_aes, email_hash, nickname, status, submitter_id ) VALUES ( %s, %s, %s, %s, %s, %s ) RETURNING id"
            data = ( id, email_aes, email_hash, upload_nickname, status, submitter_id )
            config.db.query( sql, data )
            config.db.commit()
            
            return jsonify( {
                'error': False,
                'id': id
            } )
        
    else:
        return jsonify( {
            'error': True,
            'msg': "Email not provided"
        } )

@app.route( baseurl + '/donnor/<id>' )
@login_required
def update_donnor_folder( id ):
    try:
        sql = "SELECT email_aes as email, nickname, created_time FROM submissions WHERE submitter_id = %s AND uuid = %s"
        r = config.db.query( sql, ( session[ 'user_id' ], id ) )
        user = r.fetchone()
        
        for key in [ 'email', 'nickname' ]:
            user[ key ] = do_decrypt( user[ key ] )
        
        return render_template( 
            baseurl = baseurl,
            js = config.cdnjs,
            css = config.cdncss,
            session_timeout = config.session_timeout,
            upload_id = id,
            **user
        )
    except:
        return jsonify( {
            'error': True,
            'msg': "Case not found"
        } )
@app.route( baseurl + '/submission/<id>/latents' )
@login_required
def update_files_folder( id ):
    sql = "SELECT id FROM submissions WHERE uuid = %s AND submitter_id = %s"
    r = config.db.query( sql, ( id, session[ 'user_id' ], ) )
    id = r.fetchone()[ 'id' ]
    
    sql = "SELECT uuid, filename, size, creation_time FROM files WHERE folder = %s AND type = 2"
    r = config.db.query( sql, ( id, ) )
    files = r.fetchall()
    
    for i, v in enumerate( files ):
        v[ 'filename' ] = do_decrypt( v[ 'filename' ] )
        v[ 'size' ] = round( ( float( v[ 'size' ] ) / ( 1024 * 1024 ) ) * 100 ) / 100
    
    return render_template( 
        "data_update/update_latents.html",
        baseurl = baseurl,
        js = config.cdnjs,
        css = config.cdncss,
        session_timeout = config.session_timeout,
        upload_id = id,
        files = files
    )

################################################################################
#    Image processing

@app.route( baseurl + '/image/preview/<id>' )
@referer_required
@login_required
def img_preview( id ):
    sql = "SELECT size, data FROM files WHERE uuid = %s"
    r = config.db.query( sql, ( id, ) )
    img = r.fetchone()
    
    img = base64.b64decode( img[ 'data' ] )
    buff = StringIO()
    buff.write( img )
    buff.seek( 0 )
    img = Image.open( buff )
    
    img.thumbnail( ( 300, 300 ) )
    
    buff = StringIO()
    img.save( buff, format = 'PNG' )
    buff.seek( 0 )
    
    return send_file( buff, mimetype = "image/png" )

################################################################################
#    Home page

@app.route( baseurl + '/' )
def home():
    return render_template( 
        "index.html",
        baseurl = baseurl,
        admin = int( session[ 'account_type' ] ) == 1,
        js = config.cdnjs,
        css = config.cdncss,
Marco De Donno's avatar
Marco De Donno committed
        session_timeout = config.session_timeout,
        account_type = session.get( "account_type", None )
################################################################################
#    Main startup

if __name__ == '__main__':
    gpg = gnupg.GPG()
    
    for file in os.listdir( config.keys_folder ):
        with open( config.keys_folder + "/" + file, "r" ) as fp:
            gpg.import_keys( fp.read() )
    
    app.run( debug = debug, host = "0.0.0.0", threaded = True )