Newer
Older
@app.route( baseurl + "/image/file/<image_id>/info" )
def img_info( image_id ):
"""
Get and return the metadata for a particular image.
See do_img_info() for more informations.
"""
app.logger.info( "Serve image informations for image '{}'".format( image_id ) )
d = do_img_info( image_id )
if d != None:
return jsonify( d )
else:
return abort( 404 )
def do_img_info( image_id ):
"""
Retrieve the metadata for a particular image from the database.
"""
app.logger.debug( "Get image information from database for '{}'".format( image_id ) )
sql = "SELECT size, width, height, resolution, format FROM files WHERE uuid = %s"
d = config.db.query_fetchone( sql, ( image_id, ) )
for key, value in d.iteritems():
app.logger.debug( "{}: {}".format( key, value ) )
if d != None:
return dict( d )
else:
return None
def create_thumbnail( file_uuid, img, submission_id ):
"""
Generate a thumbnail image for a PIL image passed in argument.
"""
app.logger.info( "Creating a thumbnail for the file '{}', submission '{}'".format( file_uuid, submission_id ) )
app.logger.debug( "Input image: {}".format( img ) )
img.thumbnail( ( 1000, 1000 ) )
width, height = img.size
app.logger.debug( "Thumbnail: {}".format( img ) )
img_format = img.format
if img_format.upper() in [ "TIFF", "TIF" ]:
img.save( buff, format = img_format, compression = "raw" )
else:
img.save( buff, format = img_format )
img_size = buff.tell()
buff.seek( 0 )
app.logger.debug( "Encrypt the thumnbnail with DEK" )
img_data = buff.getvalue()
img_data = base64.b64encode( img_data )
img_data = do_encrypt_dek( img_data, submission_id )
app.logger.debug( "Saving thumnbail to database" )
sql = utils.sql.sql_insert_generate( "thumbnails", [ "uuid", "width", "height", "size", "format", "data" ] )
data = ( file_uuid, width, height, img_size, img.format, img_data, )
config.db.query( sql, data )
config.db.commit()
@app.route( baseurl + "/image/segment/<tenprint_id>/start" )

Marco De Donno
committed
@login_required
def image_tenprint_segmentation( tenprint_id ):
"""
Route to start the segmentation of a tenprint image into segments (fingers or palm images).
"""
app.logger.info( "Start segmentations for '{}'".format( tenprint_id ) )
ret = do_image_tenprint_segmentation( tenprint_id )

Marco De Donno
committed
return jsonify( {

Marco De Donno
committed
} )
def do_image_tenprint_segmentation( tenprint_id ):
"""
Backend function to create all the segments images for a tenprint souce image.
"""

Marco De Donno
committed
sql = "SELECT size, resolution, type, format, data FROM files WHERE uuid = %s"
img = config.db.query_fetchone( sql, ( tenprint_id, ) )

Marco De Donno
committed
for key, value in img.iteritems():
if isinstance( value, str ) and len( value ) > 20:
value = "{}...".format( value[ 0:20 ] )
app.logger.debug( "{}: {}".format( key, value ) )
res = img[ "resolution" ]
img_format = img[ "format" ]

Marco De Donno
committed
side = {
1: "front",
2: "back"
}[ img[ "type" ] ]

Marco De Donno
committed
app.logger.debug( "side: {}".format( side ) )
submission_id = get_submission_uuid_for_file( tenprint_id )
app.logger.debug( "Decrypt data with DEK" )
img = do_decrypt_dek( img[ "data" ], submission_id )
img = base64.b64decode( img )

Marco De Donno
committed
buff = StringIO()
buff.write( img )
buff.seek( 0 )
img = Image.open( buff )
app.logger.debug( "image: {}".format( img ) )

Marco De Donno
committed
sql = "SELECT template FROM file_template WHERE file = %s"
template_id = config.db.query_fetchone( sql, ( tenprint_id, ) )[ "template" ]

Marco De Donno
committed

Marco De Donno
committed
zones = get_tenprint_template_zones( template_id, side )

Marco De Donno
committed
app.logger.debug( "Use '{}' as tenprint template".format( template_id ) )

Marco De Donno
committed
for z in zones:
app.logger.debug( "Segmenting fpc '{}' ({})".format( z[ "pc" ], z[ "pc_name" ] ) )

Marco De Donno
committed
tl_x, tl_y, br_x, br_y = map( lambda v: v * res / 2.54 , [ z[ "tl_x" ], z[ "tl_y" ], z[ "br_x" ], z[ "br_y" ] ] )
tmp = img.crop( ( tl_x, tl_y, br_x, br_y ) )
buff = StringIO()
tmp.save( buff, format = img_format )
buff.seek( 0 )
app.logger.debug( "Encrypting segment image with DEK" )

Marco De Donno
committed
file_data = buff.getvalue()
file_data = base64.b64encode( file_data )
file_data = do_encrypt_dek( file_data, submission_id )

Marco De Donno
committed
sql = "SELECT id FROM files_segments WHERE tenprint = %s AND pc = %s"
q = config.db.query_fetchone( sql, ( tenprint_id, z[ "pc" ], ) )

Marco De Donno
committed
if q == None:
app.logger.debug( "Inserting to the database" )
sql = utils.sql.sql_insert_generate( "files_segments", [ "tenprint", "uuid", "pc", "data" ] )
data = ( tenprint_id, str( uuid4() ), z[ "pc" ], file_data )

Marco De Donno
committed
config.db.query( sql, data )
else:
app.logger.debug( "Updating the database" )
sql = "UPDATE files_segments SET data = %s WHERE tenprint = %s AND pc = %s"
data = ( file_data, tenprint_id, z[ "pc" ] )

Marco De Donno
committed
config.db.query( sql, data )
config.db.commit()
return True

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

Marco De Donno
committed
@app.route( baseurl + "/submission/<submission_id>/tenprint/list" )
@submission_has_access
def submission_tenprint_list( submission_id ):
"""
Serve the page with the list of tenprint images, splitted by front, back and NIST format.
"""
app.logger.info( "Get the list of tenprint for the submission '{}'".format( submission_id ) )
sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
submission_folder_id, nickname = config.db.query_fetchone( sql, ( submission_id, ) )

Marco De Donno
committed
nickname = do_decrypt_user_session( nickname )

Marco De Donno
committed
SELECT id, filename, uuid, type, creation_time
WHERE folder = %s AND ( type = 1 OR type = 2 OR type = 5 )
ORDER BY creation_time DESC
"""
q = config.db.query_fetchall( sql, ( submission_folder_id, ) )

Marco De Donno
committed

Marco De Donno
committed
for tenprint in q:
app.logger.debug( "tenprint: '{}'".format( tenprint[ "id" ] ) )
nb += 1
tenprint_cards[ str( tenprint[ "type" ] ) ].append( {
"id": tenprint.get( "id", None ),

Marco De Donno
committed
"filename": do_decrypt_user_session( tenprint.get( "filename", None ) ),
"uuid": tenprint.get( "uuid", None ),
"type": tenprint.get( "type", None )

Marco De Donno
committed
} )
app.logger.info( "{} tenprint(s) for the submission '{}'".format( nb, submission_id ) )
tenprint_cards_front = tenprint_cards[ "1" ],
tenprint_cards_back = tenprint_cards[ "2" ],
tenprint_cards_nist = tenprint_cards[ "5" ],
nickname = nickname

Marco De Donno
committed
)
@app.route( baseurl + "/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.
"""
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, ) )

Marco De Donno
committed
nickname = do_decrypt_user_session( nickname )

Marco De Donno
committed
sql = """
SELECT
files.uuid, files.filename, files.note,
files.format, files.resolution, files.width, files.height, files.size,
files.creation_time, files.type,
file_template.template, files.quality

Marco De Donno
committed
FROM files

Marco De Donno
committed
LEFT JOIN file_template ON files.uuid = file_template.file

Marco De Donno
committed
WHERE
folder = %s AND
files.uuid = %s
"""
tenprint_file = config.db.query_fetchone( sql, ( submission_folder_id, tenprint_id, ) )

Marco De Donno
committed
app.logger.debug( "tenprint type: {}".format( tenprint_file[ "type" ] ) )
if tenprint_file[ "type" ] == 5:
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 ) )

Marco De Donno
committed
tenprint_file[ "size" ] = round( 100 * float( tenprint_file[ "size" ] ) / ( 1024 * 1024 ) ) / 100

Marco De Donno
committed
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:
elif tenprint_file[ "type" ] == 2:
############################################################################
try:
sql = "SELECT width, height, image_resolution FROM tenprint_cards WHERE id = %s LIMIT 1"
tmp = config.db.query_fetchone( sql, ( tenprint_file[ "template" ], ) )
card_info = {
"width": int( round( float( tmp[ "width" ] ) / 2.54 * tmp[ "image_resolution" ] ) ),
"height": int( round( float( tmp[ "height" ] ) / 2.54 * tmp[ "image_resolution" ] ) ),
"width_cm": tmp[ "width" ],
"height_cm": tmp[ "height" ]
}
except:
card_info = {
"width": 0,
"height": 0,
"width_cm": 0,
"height_cm": 0
}
############################################################################
sql = "SELECT id, country_code, name, width, height, size_display FROM tenprint_cards ORDER BY name"
tenprint_templates = config.db.query_fetchall( sql )
############################################################################
sql = "SELECT id, name FROM quality_type"
quality_type = config.db.query_fetchall( sql )
############################################################################
zones = get_tenprint_template_zones( tenprint_file[ "template" ], side )
datacolumns = [ "tl_x", "tl_y", "br_x", "br_y", "angle" ]
############################################################################
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" ] )
"submission/tenprint.html",
file = tenprint_file,
nickname = nickname,
card_info = card_info,
img_info = img_info,
svg_hw_factor = svg_hw_factor,
zones = zones,
datacolumns = datacolumns,
tenprint_templates = tenprint_templates,
quality_type = quality_type

Marco De Donno
committed
@app.route( baseurl + "/submission/<submission_id>/tenprint/<tenprint_id>/delete" )
@submission_has_access
def submission_tenprint_delete( submission_id, tenprint_id ):
"""
Endpoint to delete a tenprint image.
"""
app.logger.info( "Delete tenprint '{}' from submission '{}'".format( tenprint_id, submission_id ) )
try:
sql = "DELETE FROM files WHERE creator = %s AND uuid = %s"
config.db.query( sql, ( session[ "user_id" ], 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
} )
@app.route( baseurl + "/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" )
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
} )

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

Marco De Donno
committed
@app.route( baseurl + "/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:
app.logger.info( "Add note for tenprint '{}', '{}', submission id '{}'".format( tenprint_id, file_type, submission_id ) )
note = request.form.get( "note" )
note = do_encrypt_user_session( 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
} )
@app.route( baseurl + "/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" )
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
} )

Marco De Donno
committed
################################################################################
# Tenprint segments
@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"
submission_folder_id, nickname = config.db.query_fetchone( sql, ( submission_id, ) )

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"
tenprint_file = config.db.query_fetchone( sql, ( submission_folder_id, tenprint_id, ) )

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_fetchall( sql, ( tenprint_id, ) )
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"
submission_folder_id, nickname = config.db.query_fetchone( sql, ( submission_id, ) )

Marco De Donno
committed
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, ) )

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_fetchone( sql, ( pc, ) )[ "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
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
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).
"""
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
try:
pc = int( pc )
gp = request.form.get( "gp" )
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_fetchone( sql, ( gp, ) )
if r == None:
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:
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()
except:
return jsonify( {
"error": True
} )
################################################################################
# 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_fetchall( sql )
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_fetchone( sql, ( template_id, ) )
"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.
"""
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
try:
app.logger.info( "Save the tenprint template to the database" )
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 ) )
sql = utils.sql.sql_insert_generate( "tenprint_cards", [ "name", "country_code" ], "id" )
template_id = config.db.query_fetchone( sql, ( name, country_code, ) )[ "id" ]
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 ) )
config.db.commit()
return jsonify( {
"error": False,
"id": template_id
} )

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

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, side ):
"""
Get all the segments zones for a template passed in parameter.
"""
app.logger.info( "Get all zones for the tenprint template '{}'".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_fetchall( sql, ( template_id, side, ) )
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 ) )
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_fetchall( sql, ( template_id, side, ) )
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
img_info = config.db.query_fetchone( sql, ( template_id, ) )
"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( {