Skip to content
__init__.py 64 KiB
Newer Older
@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>" )
@submission_has_access
def submission_tenprint( submission_id, tenprint_id ):
    """
        Serve the page to see and edit a tenprint file.
    """
    current_app.logger.info( "Serve tenprint edit page for '{}', submission '{}'".format( tenprint_id, submission_id ) )
    sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
    submission_folder_id, nickname = config.db.query_fetchone( sql, ( submission_id, ) )
    nickname = do_decrypt_user_session( nickname )
    
    sql = """
        SELECT
            files.uuid, files.filename, files.note,
            files.format, files.resolution, files.width, files.height, files.size,
            files.creation_time, files.type,
        FROM files
        WHERE
            folder = %s AND
            files.uuid = %s
    """
    
    tenprint_file = config.db.query_fetchone( sql, ( submission_folder_id, tenprint_id, ) )
    
    current_app.logger.debug( "tenprint type: {}".format( tenprint_file[ "type" ] ) )
    
    if tenprint_file[ "type" ] == 5:
        current_app.logger.debug( "Redirect to the segments list page" )
        return redirect( url_for( "submission.tenprint_segments_list", submission_id = submission_id, tenprint_id = tenprint_id ) )
    
    else:
        tenprint_file[ "size" ] = round( 100 * float( tenprint_file[ "size" ] ) / ( 1024 * 1024 ) ) / 100
        tenprint_file[ "filename" ] = do_decrypt_user_session( tenprint_file[ "filename" ] )
        tenprint_file[ "note" ] = do_decrypt_user_session( tenprint_file[ "note" ] )
        
        if tenprint_file[ "type" ] == 1:
            side = "front"
        elif tenprint_file[ "type" ] == 2:
            side = "back"
        
        ############################################################################
        
        sql = "SELECT id, name FROM quality_type"
        quality_type = config.db.query_fetchall( sql )
        
        ############################################################################
        
        sql = "SELECT width, height, resolution FROM files WHERE uuid = %s LIMIT 1"
        img_info = config.db.query_fetchone( sql, ( tenprint_id, ) )
        svg_hw_factor = float( img_info[ "width" ] ) / float( img_info[ "height" ] )
        
        ############################################################################
        
        sql = "SELECT * FROM segments_locations WHERE tenprint_id = %s ORDER BY fpc ASC"
        zones_raw = config.db.query_fetchall( sql, ( tenprint_id, ) )
        zones = []
        
        for z in zones_raw:
            tmp = {}
            for k in [ "fpc", "orientation" ]:
                tmp[ k ] = z[ k ]
            
            for k in [ "x", "width" ]:
                tmp[ k ] = z[ k ] / img_info[ "width" ]
            for k in [ "y", "height" ]:
                tmp[ k ] = z[ k ] / img_info[ "height" ]
            
            zones.append( tmp )
        
        ############################################################################
        
        if side == "front":
            to_annotate = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
        else:
            to_annotate = [ 25, 27, 22, 24 ]
        
        ############################################################################
        
            "shared/tenprint.html",
            admin = False,
            segments_position_code = segments_position_code,
            to_annotate = to_annotate,
            submission_id = submission_id,
            file = tenprint_file,
            nickname = nickname,
            img_info = img_info,
            zones = zones,
            svg_hw_factor = svg_hw_factor,
            quality_type = quality_type
        )

@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>/delete" )
@submission_has_access
def submission_tenprint_delete( submission_id, tenprint_id ):
    """
        Endpoint to delete a tenprint image.
    """
    current_app.logger.info( "Delete tenprint '{}' from submission '{}'".format( tenprint_id, submission_id ) )
    
    try:
        sql = "DELETE FROM files WHERE uuid = %s"
        config.db.query( sql, ( tenprint_id, ) )
        
        sql = "DELETE FROM files_segments WHERE tenprint = %s"
        config.db.query( sql, ( tenprint_id, ) )
        
        config.db.commit()
        
        return jsonify( {
            "error": False
        } )
    
    except:
        return jsonify( {
            "error": True
        } )

@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>/set/template", methods = [ "POST" ] )
@submission_has_access
def submission_tenprint_set_template( submission_id, tenprint_id ):
    """
        Set the template id for a tenprint image.
    """
    try:
        template = request.form.get( "template" )
        current_app.logger.info( "Set tenprint template id to '{}' for '{}', submission id '{}'".format( template, tenprint_id, submission_id ) )
        
        sql = "SELECT id FROM file_template WHERE file = %s"
        q = config.db.query_fetchone( sql, ( tenprint_id, ) )
        
        if q == None:
            sql = utils.sql.sql_insert_generate( "file_template", [ "file", "template" ] )
            config.db.query( sql, ( tenprint_id, template, ) )
            config.db.commit()
        
        else:
            sql = "UPDATE file_template SET template = %s WHERE file = %s"
            config.db.query( sql, ( template, tenprint_id, ) )
            config.db.commit()
        
        return jsonify( {
            "error": False
        } )
    
    except:
        return jsonify( {
            "error": True
        } )

@submission_view.route( "/submission/<submission_id>/<file_type>/<tenprint_id>/set/note", methods = [ "POST" ] )
@submission_has_access
def submission_file_set_note( submission_id, file_type, tenprint_id ):
    """
        Store the user encrypted notes for a tenprint image.
    """
    try:
        current_app.logger.info( "Add note for tenprint '{}', '{}', submission id '{}'".format( tenprint_id, file_type, submission_id ) )
        note = request.form.get( "note" )
        
        sql = "UPDATE files SET note = %s WHERE uuid = %s RETURNING id"
        config.db.query( sql, ( note, tenprint_id, ) )
        config.db.commit()
        
        return jsonify( {
            "error": False
        } )
    
    except:
        return jsonify( {
            "error": True
        } )

@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>/set/quality", methods = [ "POST" ] )
@submission_has_access
def submission_tenprint_set_quality( submission_id, tenprint_id ):
    """
        Store the quality for a tenprint image.
    """
    try:
        quality = request.form.get( "quality" )
        current_app.logger.info( "Set the quality to '{}' for tenprint '{}', submission id '{}'".format( quality, tenprint_id, submission_id ) )
        
        sql = "UPDATE files SET quality = %s WHERE uuid = %s RETURNING id"
        config.db.query( sql, ( quality, tenprint_id, ) )
        config.db.commit()
        
        return jsonify( {
            "error": False
        } )
    
    except:
        return jsonify( {
            "error": True
        } )

################################################################################
#    Tenprint segments

@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>/segment/list" )
@submission_has_access
def submission_tenprint_segments_list( submission_id, tenprint_id ):
    """
        Serve the page with the list of segments for a tenprint image.
    """
    current_app.logger.info( "Get the list of segments for tenprint '{}', submission id '{}'".format( tenprint_id, submission_id ) )
    sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
    submission_folder_id, nickname = config.db.query_fetchone( sql, ( submission_id, ) )
    nickname = do_decrypt_user_session( nickname )
    
    sql = "SELECT uuid, filename FROM files WHERE folder = %s AND files.uuid = %s"
    
    tenprint_file = config.db.query_fetchone( sql, ( submission_folder_id, tenprint_id, ) )
    filename = do_decrypt_user_session( tenprint_file[ "filename" ] )
    tenprint_id = tenprint_file[ "uuid" ]
    
    ############################################################################
    
    sql = """
        SELECT files_segments.pc, files_segments.data, pc.name
        FROM files_segments
        LEFT JOIN pc ON pc.id = files_segments.pc
        WHERE tenprint = %s
    """
    segments = config.db.query_fetchall( sql, ( tenprint_id, ) )
    nb_segments = len( segments )
    
    current_app.logger.debug( "{} segments stored in database".format( nb_segments ) )
    
    ############################################################################
    
    return my_render_template( 
        "submission/segment_list.html",
        submission_id = submission_id,
        tenprint_id = tenprint_id,
        nickname = nickname,
        filename = filename,
        segments = segments,
        nb_segments = nb_segments
    )

@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>/segment/<pc>" )
@submission_has_access
def submission_segment( submission_id, tenprint_id, pc ):
    """
        Serve the page to edit the information relative to a segment image.
    """
    current_app.logger.info( "Serve the edit page for segment '{}'".format( pc ) )
    
    pc = int( pc )
    
    if not pc in config.all_fpc:
        current_app.logger.error( "'{}' not in the pc_list".format( pc ) )
        return redirect( url_for( "submission.tenprint_segments_list", submission_id = submission_id, tenprint_id = tenprint_id ) )
    
    else:
        current_app.logger.debug( "Retrieving data for submission '{}', pc '{}'".format( submission_id, pc ) )
        
        sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
        submission_folder_id, nickname = config.db.query_fetchone( sql, ( submission_id, ) )
        nickname = do_decrypt_user_session( nickname )
        
        sql = "SELECT uuid, filename, type FROM files WHERE folder = %s AND files.uuid = %s"
        tp_file = config.db.query_fetchone( sql, ( submission_folder_id, tenprint_id, ) )
        tp_filename = do_decrypt_user_session( tp_file[ "filename" ] )
        
        sql = "SELECT name FROM pc WHERE id = %s"
        pc_name = config.db.query_fetchone( sql, ( pc, ) )[ "name" ]
        
        sql = """
            SELECT gp.div_name
            FROM donor_fingers_gp
            LEFT JOIN submissions ON donor_fingers_gp.donor_id = submissions.donor_id
            LEFT JOIN gp ON donor_fingers_gp.gp = gp.id
            WHERE submissions.uuid = %s AND donor_fingers_gp.fpc = %s
        """
        try:
            current_gp = config.db.query_fetchone( sql, ( submission_id, pc, ) )[ "div_name" ]
        except:
            current_gp = None
        
        if pc in xrange( 1, 10 ):
            next_pc = pc + 1
            tp_type = "finger"
        elif pc == 10:
            next_pc = None
            tp_type = "finger"
        elif pc == 25:
            next_pc = 27
            tp_type = "palm"
        elif pc == 27:
            next_pc = None
            tp_type = "palm"
        else:
            return abort( 404 )
        
        current_app.logger.debug( "pc: {}".format( pc ) )
        current_app.logger.debug( "tp_type: {}".format( tp_type ) )
        current_app.logger.debug( "next pc: {}".format( next_pc ) )
        
        return my_render_template( 
            "submission/segment.html",
            submission_id = submission_id,
            nickname = nickname,
            pc_name = pc_name,
            tp_filename = tp_filename,
            tenprint_id = tenprint_id,
            pc = pc,
            next_pc = next_pc,
            current_gp = current_gp,
            tp_type = tp_type
        )

@submission_view.route( "/submission/<submission_id>/tenprint/segment/<pc>/set/gp", methods = [ "POST" ] )
@submission_has_access
def submission_segment_set_gp( submission_id, pc ):
    """
        Set the general pattern of a fingerprint segment image (FPC 1-10).
    """
    try:
        pc = int( pc )
        
        gp = request.form.get( "gp" )
        
        current_app.logger.info( "Set general pattern for '{}', pc '{}' to '{}'".format( submission_id, pc, gp ) )
        
        sql = "SELECT id FROM gp WHERE name = %s OR div_name = %s"
        r = config.db.query_fetchone( sql, ( gp, gp, ) )
        if r == None:
            current_app.logger.error( "General pattern not recognized" )
            return jsonify( {
                "error": True,
                "message": "General pattern not recognized"
            } )
        
        gp_id = r[ "id" ]
        
        sql = """
            SELECT count( * )
            FROM donor_fingers_gp
            LEFT JOIN submissions ON donor_fingers_gp.donor_id = submissions.donor_id
            WHERE submissions.uuid = %s AND donor_fingers_gp.fpc = %s
            GROUP BY donor_fingers_gp.id
        """
        nb = config.db.query_fetchone( sql, ( submission_id, pc, ) )
        
        sql = "SELECT donor_id FROM submissions WHERE uuid = %s"
        donor_id = config.db.query_fetchone( sql, ( submission_id, ) )[ "donor_id" ]
        
        if nb == 0 or nb == None:
            current_app.logger.debug( "Insert general pattern in database" )
            sql = utils.sql.sql_insert_generate( "donor_fingers_gp", [ "donor_id", "fpc", "gp" ] )
            config.db.query( sql, ( donor_id, pc, gp_id, ) )
        
        else:
            current_app.logger.debug( "Update general patern in database" )
            sql = "UPDATE donor_fingers_gp SET gp = %s WHERE donor_id = %s AND fpc = %s"
            config.db.query( sql, ( gp_id, donor_id, pc, ) )
        
        config.db.commit()
        
        return jsonify( {
            "error": False
        } )
    
    except:
        return jsonify( {
            "error": True
        } )

@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>/segment/set_coordinates", methods = [ "POST" ] )
@submission_has_access
def submission_segment_setcoordinates( submission_id, tenprint_id ):
    """
        Add the segment location data to the database.
    """
    try:
        fpc = request.form.get( "fpc" )
        x = float( request.form.get( "x" ) )
        y = float( request.form.get( "y" ) )
        w = float( request.form.get( "w" ) )
        h = float( request.form.get( "h" ) )
        img_width = float( request.form.get( "img_width" ) )
        img_height = float( request.form.get( "img_height" ) )
        orientation = int( request.form.get( "orientation" ) )
        
        img_data = do_img_info( tenprint_id )
        
        fpc = int( fpc )
        
        x_seg = int( x / img_width * img_data[ "width" ] )
        y_seg = int( y / img_height * img_data[ "height" ] )
        
        width_seg = int( w / img_width * img_data[ "width" ] )
        height_seg = int( h / img_height * img_data[ "height" ] )
        
        count = config.db.query_fetchone( "SELECT count( * ) FROM segments_locations WHERE tenprint_id = %s AND fpc = %s", ( tenprint_id, fpc, ) )[ "count" ]
        
        if count == 0:
            sql = utils.sql.sql_insert_generate( "segments_locations", [ "tenprint_id", "fpc", "x", "y", "width", "height", "orientation" ], "id" )
            seg_data_id = config.db.query_fetchone( sql, ( tenprint_id, fpc, x_seg, y_seg, width_seg, height_seg, orientation, ) )[ "id" ]
            sql = "UPDATE segments_locations SET x = %s, y = %s, width = %s, height = %s, orientation = %s WHERE tenprint_id = %s AND fpc = %s RETURNING id"
            data = ( x_seg, y_seg, width_seg, height_seg, orientation, tenprint_id, fpc, )
            seg_data_id = config.db.query_fetchone( sql, data )[ "id" ]
        
        config.db.commit()
        
        return jsonify( {
            "error": False,
            "id": seg_data_id,
        } )
    
    except Exception as e:
        print e
        from traceback import print_exc
        print_exc()
        
@submission_view.route( "/submission/<submission_id>/tenprint/<tenprint_id>/segment/delete_coordinates" )
@submission_has_access
def submission_segment_deletecoordinates( submission_id, tenprint_id ):
    sql = "DELETE FROM segments_locations WHERE tenprint_id = %s"
    data = ( tenprint_id, )
    
    config.db.query( sql, data )
    config.db.commit()
    
    return jsonify( {
        "error": False
    } )

################################################################################
#    Admin review

@submission_view.route( "/admin/<submission_id>" )
@admin_required
def admin_submission_home( submission_id ):
    sql = """
        SELECT submissions.id, submissions.uuid, users.username
        FROM submissions
        LEFT JOIN users ON submissions.donor_id = users.id
        WHERE submissions.uuid = %s
    """
    donor = config.db.query_fetchone( sql, ( submission_id, ) )
    
    return my_render_template( 
        "admin/submission_home.html",
        donor = donor
    )
    
@submission_view.route( "/admin/submission/list" )
@admin_required
def admin_submission_list():
    """
        Get the list of all submissions folder.
    """
    current_app.logger.info( "Get all submissions" )
    
    sql = """
        SELECT submissions.id, submissions.uuid, users.username
        FROM submissions
        LEFT JOIN users ON submissions.donor_id = users.id
        ORDER BY created_time DESC
    """
    q = config.db.query_fetchall( sql )
    
    donors = []
    for donor in q:
        donors.append( donor )
        current_app.logger.debug( "uuid: {}".format( donor[ "uuid" ] ) )
    
    current_app.logger.info( "{} submissions found".format( len( donors ) ) )
    
    return my_render_template( 
        "admin/submission_list.html",
        donors = donors
    )

@submission_view.route( "/admin/<submission_id>/tenprint/list" )
@admin_required
def admin_tenprint_list( submission_id = "all" ):
    """
        Get the list of all tenprints.
    """
    current_app.logger.info( "Get all tenprints cards" )
    
    sql = """
        SELECT files.id, files.uuid, files.folder, users.username, submissions.uuid as submission_uuid
        FROM files
        LEFT JOIN submissions ON files.folder = submissions.id
        LEFT JOIN users ON submissions.email_hash = users.email 
        WHERE ( files.type = 1 OR files.type = 2 OR files.type = 5 )
    """
    data = ()
    
    if submission_id != "all":
        sql += " AND submissions.uuid = %s"
        data = ( submission_id, )
    
    sql += """
        ORDER BY users.id ASC, files.type ASC
    """
    
    tenprint_cards = config.db.query_fetchall( sql, data )
    
    if submission_id != "all":
        sql = """
            SELECT users.username, submissions.uuid
            FROM submissions
            LEFT JOIN users ON submissions.donor_id = users.id
            WHERE submissions.uuid = %s
        """
        selector, submission_uuid = config.db.query_fetchone( sql, ( submission_id, ) )
        submission_uuid = None
    current_app.logger.info( "{} tenprints cards found".format( len( tenprint_cards ) ) )
    
    return my_render_template( 
        "admin/tenprint_list.html",
        tenprint_cards = tenprint_cards,
        selector = selector,
        submission_uuid = submission_uuid
    )

@submission_view.route( "/admin/<submission_id>/tenprint/<tenprint_id>" )
@admin_required
def admin_tenprint( submission_id, tenprint_id ):
    """
        Serve the page to see and edit a tenprint file.
    """
    current_app.logger.info( "Serve tenprint edit page for '{}', submission '{}'".format( tenprint_id, submission_id ) )
    sql = """
        SELECT
            files.uuid,
            files.format, files.resolution, files.width, files.height, files.size,
            files.creation_time, files.type,
            files.quality,
            users.username
        FROM files
        LEFT JOIN submissions ON files.folder = submissions.id
        LEFT JOIN users ON submissions.donor_id = users.id
        WHERE
            submissions.uuid = %s AND
            files.uuid = %s
    """
    tenprint_file = config.db.query_fetchone( sql, ( submission_id, tenprint_id, ) )
    
    current_app.logger.debug( "tenprint type: {}".format( tenprint_file[ "type" ] ) )
    
    if tenprint_file[ "type" ] == 5:
        current_app.logger.debug( "Redirect to the segments list page" )
        return redirect( url_for( "submission.tenprint_segments_list", submission_id = submission_id, tenprint_id = tenprint_id ) )
    
    else:
        tenprint_file[ "size" ] = round( 100 * float( tenprint_file[ "size" ] ) / ( 1024 * 1024 ) ) / 100
        
        if tenprint_file[ "type" ] == 1:
            side = "front"
        elif tenprint_file[ "type" ] == 2:
            side = "back"
        
        ############################################################################
        
        sql = "SELECT id, name FROM quality_type"
        quality_type = config.db.query_fetchall( sql )
        
        ############################################################################
        
        sql = "SELECT width, height, resolution FROM files WHERE uuid = %s LIMIT 1"
        img_info = config.db.query_fetchone( sql, ( tenprint_id, ) )
        svg_hw_factor = float( img_info[ "width" ] ) / float( img_info[ "height" ] )
        
        ############################################################################
        
        sql = "SELECT * FROM segments_locations WHERE tenprint_id = %s ORDER BY fpc ASC"
        zones_raw = config.db.query_fetchall( sql, ( tenprint_id, ) )
        zones = []
        
        for z in zones_raw:
            tmp = {}
            for k in [ "fpc", "orientation" ]:
                tmp[ k ] = z[ k ]
            
            for k in [ "x", "width" ]:
                tmp[ k ] = z[ k ] / img_info[ "width" ]
            for k in [ "y", "height" ]:
                tmp[ k ] = z[ k ] / img_info[ "height" ]
            
            zones.append( tmp )
        
        ############################################################################
        
        sql = "SELECT width, height, resolution FROM files WHERE uuid = %s LIMIT 1"
        img_info = config.db.query_fetchone( sql, ( tenprint_id, ) )
        svg_hw_factor = float( img_info[ "width" ] ) / float( img_info[ "height" ] )
        
        ############################################################################
        
        if side == "front":
            to_annotate = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
        else:
            to_annotate = [ 25, 27, 22, 24 ]
        
        ############################################################################
            "shared/tenprint.html",
            admin = True,
            segments_position_code = segments_position_code,
            to_annotate = to_annotate,
            submission_id = submission_id,
            file = tenprint_file,
            img_info = img_info,
            svg_hw_factor = svg_hw_factor,
            zones = zones,
            quality_type = quality_type
        )

@submission_view.route( "/admin/submission/<submission_id>/tenprint/<tenprint_id>/segment/list" )
@admin_required
def admin_submission_tenprint_segments_list( submission_id, tenprint_id ):
    """
        Serve the page with the list of segments for a tenprint image.
    """
    current_app.logger.info( "Get the list of segments for tenprint '{}', submission id '{}'".format( tenprint_id, submission_id ) )
    
    sql = """
        SELECT files_segments.pc, files_segments.data, pc.name
        FROM files_segments
        LEFT JOIN pc ON pc.id = files_segments.pc
        WHERE tenprint = %s
    """
    segments = config.db.query_fetchall( sql, ( tenprint_id, ) )
    nb_segments = len( segments )
    
    current_app.logger.debug( "{} segments stored in database".format( nb_segments ) )
    
    sql = "SELECT username FROM users LEFT JOIN submissions ON submissions.donor_id = users.id WHERE submissions.uuid = %s"
    donor_username = config.db.query_fetchone( sql, ( submission_id, ) )[ "username" ]
    
    ############################################################################
    
    return my_render_template( 
        "admin/segment_list.html",
        submission_id = submission_id,
        tenprint_id = tenprint_id,
        donor_username = donor_username,
        segments = segments,
        nb_segments = nb_segments
    )

@submission_view.route( "/admin/<submission_id>/gp" )
@submission_has_access
def admin_submission_gp( submission_id ):
    """
        Serve the page to upload the general pattern for a donor.
    """
    current_app.logger.info( "Serve the page to set the GP for {}".format( submission_id ) )
    
    finger_names = []
    for laterality in [ "Right", "Left" ]:
        for finger in [ "thumb", "index", "middel", "ring", "little" ]:
            finger_names.append( "{} {}".format( laterality, finger ) )
    
    gp_list = [
        {
            "div_name": "ll",
            "name": "left loop"
        },
        {
            "div_name": "rl",
            "name": "right loop"
        },
        {
            "div_name": "whorl",
            "name": "whorl"
        },
        {
            "div_name": "arch",
            "name": "arch"
        },
        {
            "div_name": "cpl",
            "name": "central pocket loop"
        },
        {
            "div_name": "dl",
            "name": "double loop"
        },
        {
            "div_name": "ma",
            "name": "missing/amputated"
        },
        {
            "div_name": "sm",
            "name": "scarred/mutilated"
        },
        {
            "div_name": "unknown",
            "name": "unknown"
        }
    ]
    
    try:
        sql = """
            SELECT donor_fingers_gp.fpc, gp.div_name, gp.name
            FROM donor_fingers_gp
            LEFT JOIN submissions ON donor_fingers_gp.donor_id = submissions.donor_id
            LEFT JOIN gp ON donor_fingers_gp.gp = gp.id
            WHERE submissions.uuid = %s AND donor_fingers_gp.fpc <= 10
            ORDER BY donor_fingers_gp.fpc ASC
        """
        current_gp = config.db.query_fetchall( sql, ( submission_id, ) )
        
        dek_check( submission_id )
        
        sql = """
            SELECT users.username
            FROM submissions
            LEFT JOIN users ON submissions.donor_id = users.id
            WHERE uuid = %s
        """
        donor = config.db.query_fetchone( sql, ( submission_id, ) )
        
        return my_render_template( 
            "admin/set_gp.html",
            submission_id = submission_id,
            finger_names = finger_names,
            gp_list = gp_list,
            current_gp = current_gp,
            donor = donor
        )
    
    except:
        return jsonify( {
            "error": True,
            "message": "Case not found"
        } )