Newer
Older
} )
elif not password.startswith( "pbkdf2" ):
return jsonify( {
'error': True,
'message': "password not in the correct format"
} )
elif not pbkdf2( email, user[ 'email' ] ).verify():
return jsonify( {
'error': True,
'message': "email not corresponding to the request form"
} )
elif user.get( 'password', None ) != None:
return jsonify( {
'error': True,
'message': "password already set"
} )
############################################################################
password = pbkdf2( password, random_data( 65 ), 50000 ).hash()
q = config.db.query( "UPDATE users SET password = %s WHERE username = %s", ( password, username, ) )
config.db.commit()
session[ 'username' ] = username
############################################################################
return jsonify( {
'error': False
} )
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
@app.route( baseurl + '/config/donor/<h>' )
def config_new_user_donor( h ):
session.clear()
sql = "SELECT id, username, email FROM users WHERE type = 2 AND password IS NULL"
for r in config.db.query_fetchall( sql ):
if h == hashlib.sha512( r[ 'email' ] ).hexdigest():
user = r
break
else:
return redirect( url_for( "home" ) )
session[ 'email_hash' ] = h
session[ 'user_id' ] = user[ 'id' ]
return render_template(
"users/config.html",
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
envtype = envtype,
next_step = "do_config_new_donor",
hash = h
)
@app.route( baseurl + '/do_config/donor', methods = [ 'POST' ] )
def do_config_new_donor():
username = request.form.get( "username" )
password = request.form.get( "password" )
password = pbkdf2( password, random_data( 100 ), 50000 ).hash()
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
h = request.form.get( "hash" )
sql = "SELECT id FROM users WHERE username = %s"
user_id = config.db.query_fetchone( sql, ( username, ) )[ 'id' ]
session[ 'username' ] = username
if session[ "email_hash" ] == h and session[ "user_id" ] == user_id:
q = config.db.query( "UPDATE users SET password = %s WHERE username = %s", ( password, username, ) )
config.db.commit()
return jsonify( {
"error": False
} )
else:
return jsonify( {
"error": True,
"message": "Invalid parameters"
} )
@app.route( baseurl + '/totp_help' )
def totp_help():
return render_template(
"totp_help.html",
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
################################################################################
# QR Code generation
def renew_secret():
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
session[ 'secret' ] = secret
return secret
def get_secret():
secret = session.get( "secret", None )
if secret == None:
secret = renew_secret()
return secret
@app.route( baseurl + '/set_secret' )
def set_secret():
config.db.query( "UPDATE users SET totp = %s WHERE username = %s", ( session[ 'secret' ], session[ 'username' ], ) )
config.db.commit()
return jsonify( {
'error': False
} )
@app.route( baseurl + '/secret' )
def request_secret():
get_secret()
return jsonify( {
'error': False,
'secret': session[ 'secret' ]
} )
@app.route( baseurl + '/new_secret' )
@login_required
def request_renew_secret():
renew_secret()
return jsonify( {
'error': False,
'secret': session[ 'secret' ]
} )
@app.route( baseurl + '/qrcode' )
def send_qrcode():
if 'username' in session:
qrcode_value = 'otpauth://totp/ICNML%20' + session[ 'username' ] + '?secret=' + get_secret()
else:
qrcode_value = 'otpauth://totp/ICNML?secret=' + get_secret()
img = qrcode.make( qrcode_value )
temp = StringIO()
img.save( temp, format = "png" )
temp.seek( 0 )
return send_file( temp, mimetype = 'image/png' )
@app.route( baseurl + '/user_qrcode' )
@login_required
return render_template(
"qrcode.html",
baseurl = baseurl,
secret = get_secret(),
js = config.cdnjs,
session_timeout = config.session_timeout,

Marco De Donno
committed
envtype = envtype,

Marco De Donno
committed
account_type = session.get( "account_type", None )
################################################################################
# Data decryption

Marco De Donno
committed
encryption_prefix = "icnml$"

Marco De Donno
committed
data = AESCipher( session[ 'password' ] ).decrypt( data )
if data.startswith( encryption_prefix ):
return data[ len( encryption_prefix ): ]
else:
return "-"

Marco De Donno
committed
return "-"

Marco De Donno
committed
return AESCipher( session[ 'password' ] ).encrypt( encryption_prefix + data )
################################################################################
# File upload
@app.route( baseurl + '/upload', methods = [ 'GET', 'POST' ] )
@login_required
def upload_file():
upload_type = request.form.get( "upload_type", None )
file_extension = request.form.get( "extension", None )
if isinstance( file_extension, str ):
file_extension = file_extension.lower()
if upload_type == None:
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"
} )

Marco De Donno
committed
upload_uuid = request.form.get( "upload_id" )
sql = "SELECT id FROM submissions WHERE uuid = %s"

Marco De Donno
committed
r = config.db.query( sql, ( upload_uuid, ) )
upload_id = r.fetchone()[ 'id' ]
except:
return jsonify( {
"error": True,
"msg": "upload not related to a submission form"
} )
file = request.files[ 'file' ]
file_name = do_encrypt( file.filename )
_, file_ext = os.path.splitext( file.filename )
file_uuid = str( uuid4() )
fp = StringIO()
file.save( fp )
file_size = fp.tell()
fp.seek( 0 )
if file_extension in config.NIST_file_extensions:
file_data = fp.getvalue()
file_data = base64.b64encode( file_data )
return jsonify( {
"error": True,
"msg": "Error while loading the NIST file"
} )

Marco De Donno
committed
# Save the NIST file in the DB
sql = "INSERT INTO files ( folder, creator, filename, type, format, size, width, height, resolution, uuid, data ) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )"
data = ( upload_id, session[ 'user_id' ], file_name, 5, "NIST", file_size, None, None, None, file_uuid, file_data )
config.db.query( sql, data )
# Segmentation of the NIST file
fpc_in_file = []
for fpc in config.all_fpc:
try:
img = n.get_print( fpc = fpc )
buff = StringIO()
img.save( buff, format = "TIFF" )
buff.seek( 0 )
img_data = buff.getvalue()
img_data = base64.b64encode( img_data )
sql = "INSERT INTO files_segments ( tenprint, uuid, pc, data ) values ( %s, %s, %s, %s )"
data = ( file_uuid, str( uuid4() ), fpc, img_data, )
config.db.query( sql, data )
fpc_in_file.append( fpc )
except:
pass
return jsonify( {
"error": False,
"fpc": fpc_in_file
} )
else:
if upload_type in [ 'latent_target', 'latent_incidental', 'tenprint_card_front', 'tenprint_card_back' ]:
img = Image.open( fp )
img_format = img.format
width, height = img.size
try:
res = int( img.info[ 'dpi' ][ 0 ] )
except:
return jsonify( {
"error": True,
"msg": "No resolution found in the image. Upload not possible at the moment."
} )
try:
img = rotate_image_upon_exif( img )
except:
pass
buff = StringIO()
img.save( buff, format = img_format )
buff.seek( 0 )
file_data = buff.getvalue()
if upload_type in [ 'tenprint_card_front', 'tenprint_card_back' ]:
create_thumbnail( file_uuid, img )
file_data_r = file_data
file_data = base64.b64encode( file_data )
sql = "SELECT id FROM files_type WHERE name = %s"
upload_type_id = config.db.query( sql, ( upload_type, ) ).fetchone()[ 0 ]
####################################################################
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
if upload_type == "consent_form":
sql = "SELECT email_aes FROM submissions WHERE uuid = %s"
email = config.db.query_fetchone( sql, ( upload_uuid, ) )[ 'email_aes' ]
email = do_decrypt( email )
sql = "SELECT username, email FROM users WHERE type = 2 ORDER BY id DESC"
for username_db, email_db in config.db.query_fetchall( sql ):
if pbkdf2( email, email_db ).verify():
username = username_db
url_hash = hashlib.sha512( email_db ).hexdigest()
break
else:
return jsonify( {
"error": True,
"message": "user not found"
} )
# Email for the donor
email_content = render_jinja_html(
"templates/email", "donor.html",
username = username,
url = "https://icnml.unil.ch" + url_for( 'config_new_user_donor', h = url_hash )
)
msg = MIMEMultipart()
msg[ "Subject" ] = "ICNML - You have been added as donor"
msg[ "From" ] = config.sender
msg[ "To" ] = email
msg.attach( MIMEText( email_content, "html" ) )
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
part = MIMEApplication( file_data_r, Name = "consent_form.pdf" )
part[ "Content-Disposition" ] = "attachment; filename=consent_form.pdf"
msg.attach( part )
try:
s = smtplib.SMTP( config.smtpserver )
s.sendmail( config.sender, [ email ], msg.as_string() )
s.quit()
except:
return jsonify( {
"error": True,
"message": "Can not send the email to the user"
} )
else:
# Consent form save
file_data = base64.b64encode( file_data )
file_data = gpg.encrypt( file_data, *config.gpg_key )
file_data = str( file_data )
file_data = base64.b64encode( file_data )
sql = "INSERT INTO cf ( uuid, data, email ) VALUES ( %s, %s, %s )"
config.db.query( sql , ( file_uuid, file_data, pbkdf2( email, iterations = 100000 ).hash(), ) )
sql = "UPDATE submissions SET consent_form = true WHERE uuid = %s"
config.db.query( sql, ( upload_uuid, ) )
config.db.commit()
else:
sql = "INSERT INTO files ( folder, creator, filename, type, format, size, width, height, resolution, uuid, data ) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )"
data = ( upload_id, session[ 'user_id' ], file_name, upload_type_id, img_format, file_size, width, height, res, file_uuid, file_data )
config.db.query( sql, data )
config.db.commit()
return jsonify( {
'error': False,
'filesize': file_size,
'uuid': file_uuid
} )
else:
return abort( 403 )
################################################################################
return render_template(
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
session_security_key = session.get( "session_security_key" ),
envtype = envtype
@app.route( baseurl + '/submission/do_new', methods = [ "GET", "POST" ] )
email = request.form.get( "email", False )
# 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' ] ).verify():
return jsonify( {
'error': True,
'msg': "Email already used"
} )
break
email_hash = pbkdf2( email, iterations = 50000 ).hash()
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()
userid = config.db.query_fetchone( "SELECT nextval( 'username_donor_seq' ) as id" )[ 'id' ]
username = "donor_%d" % userid
sql = "INSERT INTO users ( username, email, type ) VALUES ( %s, %s, %s )"
data = ( username, email_hash, 2 )
config.db.commit()
return jsonify( {
'error': False,
'id': id
} )
else:
return jsonify( {
'error': True,
'msg': "Email not provided"
} )
@app.route( baseurl + '/submission/<id>/add_files' )
@login_required
def submission_upload_tplp( id ):
sql = """
SELECT email_aes as email, nickname, created_time, consent_form
FROM submissions
WHERE submitter_id = %s AND uuid = %s
"""
r = config.db.query( sql, ( session[ 'user_id' ], id ) )
user = r.fetchone()
if user[ 'consent_form' ]:
for key in [ 'email', 'nickname' ]:
user[ key ] = do_decrypt( user[ key ] )
return render_template(
"submission/add_files.html",
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
upload_id = id,
session_security_key = session.get( "session_security_key" ),
nist_file_extensions = json.dumps( config.NIST_file_extensions ),
**user
)
else:
return redirect( url_for( 'submission_consent_form', id = id ) )
except:
return jsonify( {
'error': True,
'msg': "Case not found"
} )
@app.route( baseurl + '/submission/<id>/consent_form' )
@login_required
def submission_consent_form( id ):

Marco De Donno
committed
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()
if user != None:
for key in [ 'email', 'nickname' ]:
user[ key ] = do_decrypt( user[ key ] )
return render_template(
"submission/consent_form.html",
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
upload_id = id,
session_security_key = session.get( "session_security_key" ),

Marco De Donno
committed
else:
return abort( 404 )
@app.route( baseurl + '/submission/<id>/set/nickname', methods = [ 'POST' ] )

Marco De Donno
committed
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
@login_required
def submission_update_nickname( id ):
nickname = request.form.get( "nickname", None )
if nickname != None and len( nickname ) != 0:
try:
nickname = do_encrypt( nickname )
sql = "UPDATE submissions SET nickname = %s WHERE uuid = %s"
config.db.query( sql, ( nickname, id, ) )
config.db.commit()
return jsonify( {
'error': False
} )
except:
return jsonify( {
'error': True,
'message': "DB error"
} )
else:
return jsonify( {
'error': True,
'message': "No new nickname in the POST request"
} )
sql = "SELECT * FROM submissions WHERE submitter_id = %s ORDER BY created_time DESC"
r = config.db.query( sql, ( session[ 'user_id' ], ) )
q = r.fetchall()
donors = []
for donor in q:
donors.append( {
'id': donor.get( "id", None ),
'email': do_decrypt( donor.get( "email_aes", None ) ),
'nickname': do_decrypt( donor.get( "nickname", None ) ),
'uuid': donor.get( "uuid", None )
} )
return render_template(
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
session_security_key = session.get( "session_security_key" ),
envtype = envtype
@app.route( baseurl + '/submission/<id>/latent/list' )
@app.route( baseurl + '/submission/<id>/latent/list/<ltype>' )
@login_required
def submission_latent_list( id, ltype = 'all' ):
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
if ltype in [ 'target', 'incidental', 'all' ]:
sql = "SELECT id, nickname FROM submissions WHERE uuid = %s AND submitter_id = %s"
r = config.db.query( sql, ( id, session[ 'user_id' ], ) )
case_id, nickname = r.fetchone()
nickname = do_decrypt( nickname )
sql = """
SELECT files.uuid, files.filename, files.size, files.creation_time
FROM files
LEFT JOIN files_type ON files.type = files_type.id
WHERE folder = %s AND
"""
if ltype == "target":
sql += " files_type.name = 'latent_target'"
elif ltype == "incidental":
sql += " files_type.name = 'latent_incidental'"
elif ltype == "all":
sql += " ( files_type.name = 'latent_target' OR files_type.name = 'latent_incidental' )"
sql += " ORDER BY files.id DESC"
r = config.db.query( sql, ( case_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(
"submission/latent_list.html",
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
submission_id = id,
latent_type = ltype,
files = files,
nickname = nickname,
session_security_key = session.get( "session_security_key" ),
envtype = envtype
else:
return abort( 403 )
@app.route( baseurl + '/submission/<id>/latent/<lid>' )
@login_required
def submission_latent( id, lid ):
sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
r = config.db.query( sql, ( id, ) )
submission_id, nickname = r.fetchone()
nickname = do_decrypt( nickname )
sql = """
SELECT
files.uuid, files.filename, files.note,
files.format, files.resolution, files.width, files.height, files.size,
files.creation_time, files.type,
files_type.name as file_type
FROM files
LEFT JOIN files_type ON files.type = files_type.id
WHERE
folder = %s AND
files.uuid = %s
"""
r = config.db.query( sql, ( submission_id, lid, ) )

Marco De Donno
committed
file = r.fetchone()
file[ 'size' ] = round( 100 * float( file[ 'size' ] ) / ( 1024 * 1024 ) ) / 100
file[ 'filename' ] = do_decrypt( file[ 'filename' ] )
file[ 'note' ] = do_decrypt( file[ 'note' ] )
file[ 'file_type' ] = file[ 'file_type' ].replace( "latent_", "" )
return render_template(
"submission/latent.html",
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
submission_id = id,

Marco De Donno
committed
file = file,
session_security_key = session.get( "session_security_key" ),
envtype = envtype
)
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
@app.route( baseurl + '/submission/<id>/latent/<lid>/pfsp' )
@login_required
def submission_latent_pfsp( id, lid ):
sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"
r = config.db.query( sql, ( id, ) )
submission_id, nickname = r.fetchone()
nickname = do_decrypt( nickname )
sql = """
SELECT
files.uuid, files.filename, files.note,
files.format, files.resolution, files.width, files.height, files.size,
files.creation_time, files.type,
files_type.name as file_type
FROM files
LEFT JOIN files_type ON files.type = files_type.id
WHERE
folder = %s AND
files.uuid = %s
"""
r = config.db.query( sql, ( submission_id, lid, ) )
file = r.fetchone()
file[ 'size' ] = round( 100 * float( file[ 'size' ] ) / ( 1024 * 1024 ) ) / 100
file[ 'filename' ] = do_decrypt( file[ 'filename' ] )
file[ 'note' ] = do_decrypt( file[ 'note' ] )
file[ 'file_type' ] = file[ 'file_type' ].replace( "latent_", "" )
sql = "SELECT pfsp FROM latent_info WHERE uuid = %s"
try:
current_pfsp = config.db.query( sql, ( lid, ) ).fetchone()[ 0 ]
except:
current_pfsp = None
for z in pfsp.zones:
if z[ 'desc' ] == current_pfsp:
current_pfsp = ",".join( z[ 'sel' ] )
return render_template(
"submission/latent_pfsp.html",
baseurl = baseurl,
js = config.cdnjs,
css = config.cdncss,
session_timeout = config.session_timeout,
submission_id = id,
nickname = nickname,
file = file,
pfsp_zones = pfsp.zones,
current_pfsp = current_pfsp,
session_security_key = session.get( "session_security_key" ),
envtype = envtype
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
@app.route( baseurl + '/submission/<id>/latent/<lid>/set/pfsp', methods = [ 'POST' ] )
@login_required
def submission_latent_pfsp_set( id, lid ):
pfsp = request.form.get( "pfsp" )
sql = "SELECT id FROM latent_info WHERE uuid = %s"
q = config.db.query( sql, ( lid, ) ).fetchone()
if q == None:
sql = "INSERT INTO latent_info ( uuid, pfsp ) values ( %s, %s )"
config.db.query( sql, ( lid, pfsp, ) )
else:
sql = "UPDATE latent_info SET pfsp = %s WHERE uuid = %s"
config.db.query( sql, ( pfsp, lid, ) )
config.db.commit()
return jsonify( {
'error': False
} )
@app.route( baseurl + '/submission/<id>/latent/<lid>/delete' )
@login_required
def submission_latent_delete( id, lid ):
sql = "SELECT id FROM submissions WHERE submitter_id = %s AND uuid = %s"
q = config.db.query( sql, ( session[ 'user_id' ], id, ) )
if q != None:
sql = "DELETE FROM files WHERE creator = %s AND uuid = %s"
config.db.query( sql, ( session[ 'user_id' ], lid, ) )
config.db.commit()
return jsonify( {
'error': False
} )
else:
return jsonify( {
'error': True
} )
################################################################################
# Image processing
@app.route( baseurl + '/image/file/<id>/preview' )
@login_required
def image_file_serve( id ):
try:
img, _ = image_serve( "thumbnails", id )
img, _ = image_serve( "files", id )
if img == None:
return abort( 404 )
img = create_thumbnail( id, img )
buff = pil2buffer( img, "PNG" )
return send_file( buff, mimetype = "image/png" )
except:
img = Image.new( "L", ( 210, 297 ), 255 )
draw = ImageDraw.Draw( img )
font = ImageFont.truetype( "arial.ttf", 18 )
draw.text( ( 0, 0 ), "No preview", 0, font = font )
buff = pil2buffer( img, "PNG" )
return send_file( buff, mimetype = "image/png" )
@app.route( baseurl + '/image/segment/<tid>/<pc>' )
@login_required
def image_segment_serve( tid, pc ):
img, id = image_serve( "files_segments", ( tid, pc ) )
img = create_thumbnail( id, img )
buff = pil2buffer( img, "PNG" )
return send_file( buff, mimetype = "image/png" )
@app.route( baseurl + '/image/template/<tid>/<t>' )
@app.route( baseurl + '/image/template/<tid>/<t>/<action>' )
def image_tp_template( tid, t, action = "full" ):
if t in [ 'front', 'back' ]:
img, _ = image_serve( "tenprint_cards", ( tid, t ) )
if action == "preview":
img.thumbnail( ( 500, 500 ) )
buff = pil2buffer( img, "PNG" )
return send_file( buff, mimetype = "image/png" )
else:
return abort( 403 )
def image_serve( db, id ):
if db == "files_segments":
if isinstance( id, tuple ):
tp, pc = id
sql = "SELECT data, uuid FROM " + db + " WHERE tenprint = %s AND pc = %s"
p = ( tp, pc, )
else:
sql = "SELECT data, uuid FROM " + db + " WHERE uuid = %s"
p = ( id, )
elif db in [ "files", "thumbnails" ]:
sql = "SELECT data, uuid FROM " + db + " WHERE uuid = %s"
p = ( id, )
elif db == "tenprint_cards":
id, t = id
sql = "SELECT image_" + t + ", id FROM " + db + " WHERE id = %s"
p = ( id, )
else:
raise Exception( "table not authorized" )
data = config.db.query( sql, p ).fetchone()
if data == None:
return None, None
img, rid = data
img = str2img( img )
def str2img( data ):
if data == None:
return None
else:
img = base64.b64decode( data )
buff = StringIO()
buff.write( img )
buff.seek( 0 )
img = Image.open( buff )
return img
@login_required
def img_info( id ):
d = do_img_info( id )
if d != None:
return jsonify( d )
else:
return abort( 404 )
def do_img_info( id ):
sql = "SELECT size, width, height, resolution, format FROM files WHERE uuid = %s"
r = config.db.query( sql, ( id, ) )
d = r.fetchone()
if d != None:
return dict( d )
else:
return None
def create_thumbnail( file_uuid, img ):
img.thumbnail( ( 1000, 1000 ) )
width, height = img.size
file_format = img.format
buff = StringIO()
img.save( buff, format = img.format )
img_size = buff.tell()
buff.seek( 0 )
img_data = buff.getvalue()
img_data = base64.b64encode( img_data )
sql = "INSERT INTO thumbnails ( uuid, width, height, size, format, data ) VALUES ( %s, %s, %s, %s, %s, %s )"
data = ( file_uuid, width, height, img_size, img.format, img_data, )
config.db.query( sql, data )
config.db.commit()
@app.route( baseurl + '/image/segment/<id>/start' )

Marco De Donno
committed
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
@login_required
def image_tenprint_segmentation( id ):
ret = do_image_tenprint_segmentation( id )
return jsonify( {
'error': False,
'data': ret
} )
def do_image_tenprint_segmentation( id ):
sql = "SELECT size, resolution, type, format, data FROM files WHERE uuid = %s"
r = config.db.query( sql, ( id, ) )
img = r.fetchone()
res = img[ 'resolution' ]
img_format = img[ 'format' ]
t = {
1: 'front',
2: 'back'
}[ img[ 'type' ] ]
img = base64.b64decode( img[ 'data' ] )
buff = StringIO()
buff.write( img )
buff.seek( 0 )
img = Image.open( buff )
sql = "SELECT template FROM file_template WHERE file = %s"
r = config.db.query( sql, ( id, ) )
template_id = r.fetchone()[ 'template' ]
zones = get_tenprint_template_zones( template_id, t )
for z in zones:
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 )
file_data = buff.getvalue()
file_data = base64.b64encode( file_data )
sql = "SELECT id FROM files_segments WHERE tenprint = %s AND pc = %s"

Marco De Donno
committed
q = config.db.query( sql, ( id, z[ 'pc' ], ) ).fetchone()
if q == None:
sql = "INSERT INTO files_segments ( tenprint, uuid, pc, data ) VALUES ( %s, %s, %s, %s )"
data = ( id, str( uuid4() ), z[ 'pc' ], file_data )
config.db.query( sql, data )
else:
sql = "UPDATE files_segments SET data = %s WHERE tenprint = %s AND pc = %s"

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/<id>/tenprint/list' )

Marco De Donno
committed
@login_required
sql = "SELECT id, nickname FROM submissions WHERE uuid = %s"

Marco De Donno
committed
r = config.db.query( sql, ( id, ) )
submission_id, nickname = r.fetchone()
nickname = do_decrypt( nickname )

Marco De Donno
committed
sql = """
SELECT
id, filename, uuid, type, creation_time
FROM files
WHERE folder = %s AND ( type = 1 OR type = 2 OR type = 5 )
ORDER BY creation_time DESC
"""