Newer
Older

Marco De Donno
committed
@app.route( baseurl + "/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.
"""
app.logger.info( "Get the list of segments for tenprint '{}', submission id '{}'".format( tenprint_id, submission_id ) )

Marco De Donno
committed
sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
r = config.db.query( sql, ( submission_id, ) )
submission_folder_id, nickname = r.fetchone()

Marco De Donno
committed
nickname = do_decrypt_user_session( nickname )

Marco De Donno
committed
sql = "SELECT uuid, filename FROM files WHERE folder = %s AND files.uuid = %s"
r = config.db.query( sql, ( submission_folder_id, tenprint_id, ) )
tenprint_file = r.fetchone()

Marco De Donno
committed
filename = do_decrypt_user_session( tenprint_file[ "filename" ] )

Marco De Donno
committed
############################################################################
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( sql, ( tenprint_id, ) ).fetchall()
nb_segments = len( segments )
app.logger.debug( "{} segments stored in database".format( nb_segments ) )

Marco De Donno
committed
############################################################################

Marco De Donno
committed
"submission/segment_list.html",

Marco De Donno
committed
nickname = nickname,
filename = filename,
segments = segments,
nb_segments = nb_segments

Marco De Donno
committed
)
@app.route( baseurl + "/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.
"""
app.logger.info( "Serve the edit page for segment '{}'".format( pc ) )
pc = int( pc )
if not pc in config.all_fpc:
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:
app.logger.debug( "Retrieving data for submission '{}', pc '{}'".format( submission_id, pc ) )
sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
r = config.db.query( sql, ( submission_id, ) )
submission_folder_id, nickname = r.fetchone()

Marco De Donno
committed
nickname = do_decrypt_user_session( nickname )
sql = "SELECT uuid, filename, type FROM files WHERE folder = %s AND files.uuid = %s"
r = config.db.query( sql, ( submission_folder_id, tenprint_id, ) )
tp_file = r.fetchone()

Marco De Donno
committed
tp_filename = do_decrypt_user_session( tp_file[ "filename" ] )
sql = "SELECT name FROM pc WHERE id = %s"
pc_name = config.db.query( sql, ( pc, ) ).fetchone()[ 0 ]
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( sql, ( submission_id, pc, ) ).fetchone()[ 0 ]
except:
current_gp = None
if pc in xrange( 1, 10 ):
next_pc = pc + 1
elif pc == 10:
next_pc = None
tp_type = "finger"
elif pc == 25:
next_pc = 27
tp_type = "palm"
elif pc == 27:
tp_type = "palm"
else:
return abort( 404 )
app.logger.debug( "pc: {}".format( pc ) )
app.logger.debug( "tp_type: {}".format( tp_type ) )
app.logger.debug( "next pc: {}".format( next_pc ) )
"submission/segment.html",
nickname = nickname,
pc_name = pc_name,
tp_filename = tp_filename,
pc = pc,
current_gp = current_gp,
tp_type = tp_type
@app.route( baseurl + "/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).
"""
app.logger.info( "Set general pattern for '{}', pc '{}' to '{}'".format( submission_id, pc, gp ) )
sql = "SELECT id FROM gp WHERE name = %s"
r = config.db.query( sql, ( gp, ) ).fetchone()
if r == None:
app.logger.error( "General pattern not recognized" )
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:
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:
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( {
################################################################################
# User profile
@app.route( baseurl + "/user/myprofile/dek" )
@login_required
def user_myprofile_dek():
"""
Serve the page to manadge the Data Encryption Key of a donor.
"""
app.logger.info( "Serve the donor DEK page" )
SELECT dek, salt
FROM donor_dek
WHERE donor_name = %s
"""
data = config.db.query_fetchone( sql, ( session[ "username" ], ) )
has_dek = data[ "dek" ] != None
has_salt = data[ "salt" ] != None
app.logger.debug( "username: {}".format( session[ "username" ] ) )
app.logger.debug( "has_dek: {}".format( has_dek ) )
app.logger.debug( "has_salt: {}".format( has_salt ) )
return my_render_template(
"users/profile/dek.html",
has_dek = has_dek,
has_salt = has_salt
@app.route( baseurl + "/user/myprofile/tenprint" )
def user_myprofile_tenprint():
"""
Serve the page to see all the information related to the current user.
This page is the summary of all informations related to the current logged user,
i.e. the tenprint cards and mark images. The consent form, beeing mendatory to
upload the tenprint and mark images, and beeing encrypted in the database, is
not accessible by the user via this interface. The consent form has been sent the
the donor by email anyways before uploading any of the images.
"""
app.logger.info( "Serve the page with all tenprint to the donor" )
sql = """
SELECT files.id, files.uuid
FROM users
LEFT JOIN submissions ON users.email = submissions.email_hash
LEFT JOIN files ON files.folder = submissions.id
WHERE users.id = %s AND ( files.type = 1 OR files.type = 2 OR files.type = 5 )
"""
tenprint_cards = config.db.query_fetchall( sql, ( session[ "user_id" ], ) )
app.logger.debug( "{} tenprint(s) stored in database".format( len( tenprint_cards ) ) )
"users/profile/tenprint.html",
tenprint_cards = tenprint_cards
################################################################################
# Tenprint templates
@app.route( baseurl + "/template/tenprint/list" )
@admin_required
def template_tenprint_list():
"""
Serve the page with the list of templates.
"""
app.logger.info( "Serve the list of tenprint templates" )
sql = "SELECT id, country_code, name FROM tenprint_cards ORDER BY name ASC"
tp_templates = config.db.query( sql ).fetchall()
app.logger.debug( "{} tenmplates found".format( len( tp_templates ) ) )
tp_templates = tp_templates
@app.route( baseurl + "/template/tenprint/new" )

Marco De Donno
committed
@admin_required
def template_tenprint_new_meta():
"""
Serve the page to create a new tenprint template.
"""
app.logger.info( "Create a new tenprint template" )
return my_render_template( "tp_template/new_meta.html" )

Marco De Donno
committed
@app.route( baseurl + "/template/tenprint/new/<template_id>/images" )

Marco De Donno
committed
@admin_required
def template_tenprint_new_images( template_id ):
"""
Add new images to a tenprint template.
"""
app.logger.info( "Add a new image to the tenprint template '{}'".format( template_id ) )
sql = "SELECT id, name, country_code FROM tenprint_cards WHERE id = %s"
card = config.db.query( sql, ( template_id, ) ).fetchone()
"tp_template/new_images.html",
card = card
)
@app.route( baseurl + "/template/tenprint/new/insert", methods = [ "POST" ] )

Marco De Donno
committed
@admin_required
def template_tenprint_new_do():
"""
Save the tenprint template to the database.
"""
app.logger.info( "Save the tenprint template to the database" )

Marco De Donno
committed
name = request.form.get( "name" )
country_code = request.form.get( "country_code" )
app.logger.debug( "name: {}".format( name ) )
app.logger.debug( "country code: {}".format( country_code ) )

Marco De Donno
committed
sql = utils.sql.sql_insert_generate( "tenprint_cards", [ "name", "country_code" ], "id" )

Marco De Donno
committed
q = config.db.query( sql, ( name, country_code, ) )

Marco De Donno
committed
template_id = q.fetchone()[ "id" ]

Marco De Donno
committed
app.logger.debug( "Set all zones values to 0 for FPC in {}".format( config.all_fpc ) )
for pc in config.all_fpc:
sql = utils.sql.sql_insert_generate( "tenprint_zones", [ "card", "pc", "angle", "tl_x", "tl_y", "br_x", "br_y" ] )
config.db.query( sql, ( template_id, pc, 0, 0, 0, 0, 0 ) )

Marco De Donno
committed

Marco De Donno
committed
config.db.commit()
return jsonify( {
"id": template_id

Marco De Donno
committed
} )
@app.route( baseurl + "/template/tenprint/new/<template_id>/upload_image", methods = [ "POST" ] )
@admin_required
def template_tenprint_new_uploadimage( template_id ):
Save the front and back images for a tenprint template to the database.
app.logger.info( "Upload new image for the tenprint template '{}'".format( template_id ) )
side = request.form.get( "card_face" )
if side in [ "front", "back" ]:
img = Image.open( data )
image_width, image_height = img.size

Marco De Donno
committed
try:

Marco De Donno
committed
width = round( image_width * 2.54 / float( res ) )
height = round( image_height * 2.54 / float( res ) )
except:
res = 0
width = 0
height = 0
app.logger.debug( "side: {}".format( side ) )
app.logger.debug( "image: {}".format( img ) )
app.logger.debug( "width: {}".format( width ) )
app.logger.debug( "height: {}".format( height ) )
app.logger.debug( "resolution: {}".format( res ) )
fp = StringIO()
img.save( fp, format = "JPEG" )
fp.seek( 0 )
data = fp.getvalue()
data = base64.b64encode( data )
app.logger.debug( "Saving the image to the database" )
sql = """
UPDATE tenprint_cards
SET
image_{0} = %s,
image_{0}_width = %s,
image_{0}_height = %s,
image_resolution = %s,
image_format = %s,
width = %s,
height = %s
WHERE id = %s""".format( side )
config.db.query( sql, ( data, image_width, image_height, res, "JPEG", width, height, template_id, ) )
config.db.commit()
# If the resolution is set to 0 (hence not correclty set in the image),
# the user need to perform an action to set it correctly. The storage
# of the image data has to be done before.

Marco De Donno
committed
if res != 0:
return jsonify( {

Marco De Donno
committed
} )
else:
return jsonify( {
"need_action": True,
"action": "set_resolution"

Marco De Donno
committed
} )
else:
return abort( 403 )
@app.route( baseurl + "/template/tenprint/<template_id>/set/resolution", methods = [ "POST" ] )

Marco De Donno
committed
@admin_required
def template_tenprint_new_setresolution( template_id ):
"""
Set the resolution for a tenprint template image.
"""

Marco De Donno
committed
res = request.form.get( "resolution" )
app.logger.info( "Set the resolution of the tenprint template '{}' to '{}'".format( template_id, res ) )

Marco De Donno
committed
try:
sql = "UPDATE tenprint_cards SET image_resolution = %s WHERE id = %s"
config.db.query( sql, ( res, template_id, ) )

Marco De Donno
committed
config.db.commit()
return jsonify( {
} )

Marco De Donno
committed
except:
return jsonify( {

Marco De Donno
committed
} )
def get_tenprint_template_zones( template_id, t ):
"""
Get all the segments zones for a template passed in parameter.
"""
app.logger.info( "Get all zones for the tenprint template '{}'".format( template_id, t ) )
sql = """
SELECT
tenprint_zones.pc, tl_x, tl_y, br_x, br_y, angle, pc.name
FROM tenprint_zones
JOIN tenprint_zones_location ON tenprint_zones.pc = tenprint_zones_location.pc
JOIN pc ON tenprint_zones.pc = pc.id
WHERE
card = %s AND
tenprint_zones_location.side = %s
ORDER BY pc
"""
r = config.db.query( sql, ( template_id, t, ) ).fetchall()
zones = []
for pc, tl_x, tl_y, br_x, br_y, angle, pc_name in r:
tl_x = utils.misc.float_or_null( tl_x )
tl_y = utils.misc.float_or_null( tl_y )
br_x = utils.misc.float_or_null( br_x )
br_y = utils.misc.float_or_null( br_y )
zones.append( {
"pc": pc,
"tl_x": tl_x,
"tl_y": tl_y,
"br_x": br_x,
"br_y": br_y,
"angle": angle,
"pc_name": pc_name
} )
app.logger.debug( "{} zones for the tenprint template '{}'".format( len( zones ), template_id ) )
return zones
@app.route( baseurl + "/template/tenprint/<template_id>/<side>" )
def template_tenprint( template_id, side ):
"""
Serve the tenprint template page.
"""
app.logger.info( "Serve the tenprint template edit page for '{}', '{}'".format( template_id, side ) )
sql = """
SELECT
tenprint_zones.pc, tl_x, tl_y, br_x, br_y, angle, pc.name
FROM tenprint_zones
JOIN tenprint_zones_location ON tenprint_zones.pc = tenprint_zones_location.pc
JOIN pc ON tenprint_zones.pc = pc.id
WHERE card = %s AND tenprint_zones_location.side = %s ORDER BY pc
"""
r = config.db.query( sql, ( template_id, side, ) ).fetchall()
for pc, tl_x, tl_y, br_x, br_y, angle, pc_name in r:
tl_x = utils.misc.float_or_null( tl_x )
tl_y = utils.misc.float_or_null( tl_y )
br_x = utils.misc.float_or_null( br_x )
br_y = utils.misc.float_or_null( br_y )
zones.append( {
"pc": pc,
"tl_x": tl_x,
"tl_y": tl_y,
"br_x": br_x,
"br_y": br_y,
"angle": angle,
"pc_name": pc_name
app.logger.debug( "{} zones for '{}'".format( len( zones ), template_id ) )
datacolumns = [ "tl_x", "tl_y", "br_x", "br_y", "angle" ]

Marco De Donno
committed
sql = """
SELECT
id,
name, country_code,
width, height, size_display,
image_{0}_width, image_{0}_height,
image_resolution
FROM tenprint_cards
WHERE id = %s LIMIT 1
r = config.db.query( sql, ( template_id, ) )
img_info = r.fetchone()
card_info = {
"width": int( round( float( img_info[ "width" ] ) / 2.54 * img_info[ "image_resolution" ] ) ),
"height": int( round( float( img_info[ "height" ] ) / 2.54 * img_info[ "image_resolution" ] ) ),
app.logger.debug( "card width: {}".format( card_info[ "width" ] ) )
app.logger.debug( "card height: {}".format( card_info[ "height" ] ) )
svg_h = float( img_info[ "image_{}_height".format( side ) ] )
svg_w = float( img_info[ "image_{}_width".format( side ) ] )
svg_hw_factor = svg_w / svg_h
app.logger.debug( "svg width: {}".format( svg_w ) )
app.logger.debug( "svg height: {}".format( svg_h ) )
"tp_template/template.html",
zones = zones,
img_info = img_info,
card_info = card_info,

Marco De Donno
committed
svg_hw_factor = svg_hw_factor,
card_id = template_id,

Marco De Donno
committed
datacolumns = datacolumns,
**config.misc
app.logger.error( "{} not allowed".format( side ) )
@app.route( baseurl + "/template/tenprint/<template_id>/set/zones", methods = [ "POST" ] )
@login_required
def update_zone_coordinates( template_id ):
"""
Update the segments zones coordinates in the database.
"""
app.logger.info( "Set zones for '{}'".format( template_id ) )
template_id = int( template_id )
data = request.form.get( "data" )

Marco De Donno
committed
if data != None:
data = json.loads( data )
for pc, value in data.iteritems():
pc = int( pc )
app.logger.debug( "{}: {}".format( pc, value ) )
for coordinate, v in value.iteritems():
sql = "UPDATE tenprint_zones SET {} = %s WHERE card = %s AND pc = %s".format( coordinate )
data = ( v, template_id, pc, )
config.db.query( sql, data )

Marco De Donno
committed
config.db.commit()
return jsonify( {

Marco De Donno
committed
} )
else:
return abort( 403 )
@app.route( baseurl + "/template/tenprint/<template_id>/delete/zone", methods = [ "POST" ] )
@login_required
def delete_zone_coordinates( template_id ):
"""
Delete a unused segment zone for a template (for example FPC 25 and 27 on the front-page, ...)
"""
pc = request.form.get( "pc" )
app.logger.info( "Delete zone '{}' for template '{}'".format( pc, template_id ) )
try:
sql = "DELETE FROM tenprint_zones WHERE card = %s AND pc = %s"
config.db.query( sql, ( template_id, pc, ) )
config.db.commit()
return jsonify( {
} )
except:
return jsonify( {
} )
@app.route( baseurl + "/template/tenprint/<template_id>/set/<varname>", methods = [ "POST" ] )

Marco De Donno
committed
@login_required
def update_tptemplate_var( template_id, varname ):
"""
Update the name, country_code or displayed size variable for a tenprint template.
"""
app.logger.info( "Setting variable '{}' to template '{}'".format( varname, template_id ) )

Marco De Donno
committed
if not varname in [ "name", "country_code", "size_display" ]:
app.logger.error( "'{}' not allowed".format( varname ) )

Marco De Donno
committed
return jsonify( {
"error": True

Marco De Donno
committed
} )
else:
try:
data = request.form.get( varname )
data = str( data )
sql = "UPDATE tenprint_cards SET {} = %s WHERE id = %s".forat( varname )
config.db.query( sql, ( data, template_id, ) )
config.db.commit()
return jsonify( {
} )
except:
return jsonify( {

Marco De Donno
committed
@app.route( baseurl + "/template/tenprint/<template_id>/set/hw", methods = [ "POST" ] )
@login_required

Marco De Donno
committed
def update_tptemplate_heightwidth( template_id ):
"""
Set the image size of a template.
"""
app.logger.info( "Setting the height and width for tenprint template '{}'".format( template_id ) )
try:

Marco De Donno
committed
height = request.form.get( "height" )
width = request.form.get( "width" )

Marco De Donno
committed
height = float( height )
width = float( width )

Marco De Donno
committed
app.logger.debug( "height: {}".format( height ) )
app.logger.debug( "wigth: {}".format( width ) )
sql = "UPDATE tenprint_cards SET height = %s, width = %s WHERE id = %s"

Marco De Donno
committed
config.db.query( sql, ( height, width, template_id, ) )
config.db.commit()
return jsonify( {
} )
except:
return jsonify( {
} )
@app.route( baseurl + "/template/tenprint/<template_id>/set/resolution" )
@login_required
def update_tptemplate_res( template_id ):
"""
Update the resolution of the image for a template.
"""
app.logger.info( "Setting the resolution for tenprint template '{}'".format( template_id ) )
try:
res = request.form.get( "resolution" )
res = float( res )
app.logger.debug( "resolution: {}".format( res ) )
sql = "UPDATE tenprint_cards SET image_resolution = %s WHERE id = %s"
config.db.query( sql, ( res, template_id, ) )
config.db.commit()
return jsonify( {
} )
except:
return jsonify( {
} )
################################################################################
# PiAnoS API
@admin_required
def pianos_actions():
"""
Serve the page with all actions related to the dedicated PiAnoS server.
"""
app.logger.info( "Serve the PiAnoS actions page" )
return my_render_template( "PiAnoS/actions.html" )
@app.route( baseurl + "/pianos_api/add_user/all" )
@admin_required
def pianos_update_all_accounts():
"""
serve the function to update the users in PiAnoS
"""
app.logger.info( "Copy all accounts to PiAnoS" )
return jsonify( {
"error": not do_pianos_update_all_accounts()
def do_pianos_update_all_accounts():
"""
Copy/update the credentials for all users.
This function keep the credentials in sync between ICNML and PiAnoS.
"""
try:
sql = """
SELECT users.username, users.password, account_type.name as g
FROM users
LEFT JOIN account_type ON users.type = account_type.id
WHERE users.password IS NOT NULL
for user in config.db.query_fetchall( sql ):
app.logger.debug( "Copy the user '{}' to PiAnoS".format( username ) )
groupid = config.pianosdb.create_group( group_name )

Marco De Donno
committed
pianos_user_id = config.pianosdb.create_user( username = username, hash = h, groupid = groupid )
config.pianosdb.reset_user( username, hash = h )

Marco De Donno
committed
config.pianosdb.create_folder( "{}'s folder".format( username ), pianos_user_id, None, pianos_user_id )
app.logger.info( "{} users copied to PiAnoS".format( nb ) )
@app.route( baseurl + "/pianos_api/add_segments/all" )
@admin_required
def pianos_copy_all_segments():
"""
Route to push all segments to PiAnoS.
"""
app.logger.info( "Copy all segments to PiAnoS" )
"error": not do_pianos_copy_all_segments()
} )
def do_pianos_copy_all_segments():
"""
Copy all segments images to PiAnoS. If the case already exists, the image is not pushed to PiAnoS.
"""
try:
folder_id = config.pianosdb.create_folder( "Annotation" )
img = Image.new( "L", ( 200, 200 ), 255 )
empty_img_res = 500
empty_img_id = config.pianosdb.create_image( "PRINT", img, empty_img_res, "empty" )
sql = """
SELECT files_segments.uuid, files_segments.data, files_v.resolution
FROM files_segments
LEFT JOIN files_v ON files_segments.tenprint = files_v.uuid
"""
for segment in config.db.query_fetchall( sql ):
img = str2img( segment[ "data" ] )
app.logger.debug( "{}: {}".format( segment[ "uuid" ], img ) )
try:
config.pianosdb.create_exercise(
folder_id,
segment[ "uuid" ], "",
img, segment[ "resolution" ],
empty_img_id, empty_img_res
)
except caseExistsInDB:
continue
except:
raise
config.pianosdb.commit()
return True
except:
return False
################################################################################
# Home page
@login_required
"""
Serve the homepage to all users.
"""
return my_render_template( "index.html" )
################################################################################
gpg = gnupg.GPG( **config.gpg_options )
for key_file in os.listdir( config.keys_folder ):
with open( config.keys_folder + "/" + key_file, "r" ) as fp:

Marco De Donno
committed
account_type_id_name = {}
sql = "SELECT id, name FROM account_type"
for at in config.db.query_fetchall( sql ):
account_type_id_name[ at[ "id" ] ] = at[ "name" ]