diff --git a/sql/install/30-cnm_annotation.sql b/sql/install/30-cnm_annotation.sql
deleted file mode 100644
index b69a0abf40d8326676a5746204b5bd83050a32db..0000000000000000000000000000000000000000
--- a/sql/install/30-cnm_annotation.sql
+++ /dev/null
@@ -1,65 +0,0 @@
---
--- PostgreSQL database dump
---
-
-
-SET statement_timeout = 0;
-SET lock_timeout = 0;
-SET idle_in_transaction_session_timeout = 0;
-SET client_encoding = 'UTF8';
-SET standard_conforming_strings = on;
-SELECT pg_catalog.set_config('search_path', '', false);
-SET check_function_bodies = false;
-SET xmloption = content;
-SET client_min_messages = warning;
-SET row_security = off;
-
-SET default_tablespace = '';
-
-SET default_with_oids = false;
-
---
--- Name: cnm_annotation; Type: TABLE; Schema: public; Owner: icnml
---
-
-CREATE TABLE public.cnm_annotation (
- id integer NOT NULL,
- uuid uuid NOT NULL,
- folder uuid NOT NULL,
- annotation_data character varying NOT NULL,
- fpc integer NOT NULL
-);
-
-
-ALTER TABLE public.cnm_annotation OWNER TO icnml;
-
---
--- Name: cnm_annotation_id_seq; Type: SEQUENCE; Schema: public; Owner: icnml
---
-
-CREATE SEQUENCE public.cnm_annotation_id_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
-ALTER TABLE public.cnm_annotation_id_seq OWNER TO icnml;
-
---
--- Name: cnm_annotation_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: icnml
---
-
-ALTER SEQUENCE public.cnm_annotation_id_seq OWNED BY public.cnm_annotation.id;
-
-
---
--- Name: cnm_annotation id; Type: DEFAULT; Schema: public; Owner: icnml
---
-
-ALTER TABLE ONLY public.cnm_annotation ALTER COLUMN id SET DEFAULT nextval('public.cnm_annotation_id_seq'::regclass);
-
-
-
diff --git a/sql/install/31-cnm_data.sql b/sql/install/31-cnm_data.sql
deleted file mode 100644
index 6734fb9b977572e615c3d6b04c172f6012928909..0000000000000000000000000000000000000000
--- a/sql/install/31-cnm_data.sql
+++ /dev/null
@@ -1,67 +0,0 @@
---
--- PostgreSQL database dump
---
-
-
-SET statement_timeout = 0;
-SET lock_timeout = 0;
-SET idle_in_transaction_session_timeout = 0;
-SET client_encoding = 'UTF8';
-SET standard_conforming_strings = on;
-SELECT pg_catalog.set_config('search_path', '', false);
-SET check_function_bodies = false;
-SET xmloption = content;
-SET client_min_messages = warning;
-SET row_security = off;
-
-SET default_tablespace = '';
-
-SET default_with_oids = false;
-
---
--- Name: cnm_data; Type: TABLE; Schema: public; Owner: icnml
---
-
-CREATE TABLE public.cnm_data (
- id integer NOT NULL,
- uuid uuid NOT NULL,
- folder uuid NOT NULL,
- user_id integer NOT NULL,
- fpc integer NOT NULL,
- cnm_type integer,
- db_size integer,
- cnm_data character varying
-);
-
-
-ALTER TABLE public.cnm_data OWNER TO icnml;
-
---
--- Name: cnm_data_id_seq; Type: SEQUENCE; Schema: public; Owner: icnml
---
-
-CREATE SEQUENCE public.cnm_data_id_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
-ALTER TABLE public.cnm_data_id_seq OWNER TO icnml;
-
---
--- Name: cnm_data_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: icnml
---
-
-ALTER SEQUENCE public.cnm_data_id_seq OWNED BY public.cnm_data.id;
-
-
---
--- Name: cnm_data id; Type: DEFAULT; Schema: public; Owner: icnml
---
-
-ALTER TABLE ONLY public.cnm_data ALTER COLUMN id SET DEFAULT nextval('public.cnm_data_id_seq'::regclass);
-
-
diff --git a/sql/install/32-cnm_folder.sql b/sql/install/32-cnm_folder.sql
deleted file mode 100644
index cfe68c12487fdc879c5bc7d93e571cd83292b5c3..0000000000000000000000000000000000000000
--- a/sql/install/32-cnm_folder.sql
+++ /dev/null
@@ -1,62 +0,0 @@
---
--- PostgreSQL database dump
---
-
-
-SET statement_timeout = 0;
-SET lock_timeout = 0;
-SET idle_in_transaction_session_timeout = 0;
-SET client_encoding = 'UTF8';
-SET standard_conforming_strings = on;
-SELECT pg_catalog.set_config('search_path', '', false);
-SET check_function_bodies = false;
-SET xmloption = content;
-SET client_min_messages = warning;
-SET row_security = off;
-
-SET default_tablespace = '';
-
-SET default_with_oids = false;
-
---
--- Name: cnm_folder; Type: TABLE; Schema: public; Owner: icnml
---
-
-CREATE TABLE public.cnm_folder (
- id integer NOT NULL,
- donor uuid NOT NULL,
- uuid uuid NOT NULL
-);
-
-
-ALTER TABLE public.cnm_folder OWNER TO icnml;
-
---
--- Name: cnm_folder_id_seq; Type: SEQUENCE; Schema: public; Owner: icnml
---
-
-CREATE SEQUENCE public.cnm_folder_id_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
-ALTER TABLE public.cnm_folder_id_seq OWNER TO icnml;
-
---
--- Name: cnm_folder_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: icnml
---
-
-ALTER SEQUENCE public.cnm_folder_id_seq OWNED BY public.cnm_folder.id;
-
-
---
--- Name: cnm_folder id; Type: DEFAULT; Schema: public; Owner: icnml
---
-
-ALTER TABLE ONLY public.cnm_folder ALTER COLUMN id SET DEFAULT nextval('public.cnm_folder_id_seq'::regclass);
-
-
diff --git a/sql/install/33-cnm_segments.sql b/sql/install/33-cnm_segments.sql
deleted file mode 100644
index e33e6bcdedbf01a4672bba0cd578e5c6a9867390..0000000000000000000000000000000000000000
--- a/sql/install/33-cnm_segments.sql
+++ /dev/null
@@ -1,64 +0,0 @@
---
--- PostgreSQL database dump
---
-
-
-SET statement_timeout = 0;
-SET lock_timeout = 0;
-SET idle_in_transaction_session_timeout = 0;
-SET client_encoding = 'UTF8';
-SET standard_conforming_strings = on;
-SELECT pg_catalog.set_config('search_path', '', false);
-SET check_function_bodies = false;
-SET xmloption = content;
-SET client_min_messages = warning;
-SET row_security = off;
-
-SET default_tablespace = '';
-
-SET default_with_oids = false;
-
---
--- Name: cnm_segments; Type: TABLE; Schema: public; Owner: icnml
---
-
-CREATE TABLE public.cnm_segments (
- id integer NOT NULL,
- uuid uuid NOT NULL,
- fpc integer NOT NULL,
- folder_uuid uuid NOT NULL
-);
-
-
-ALTER TABLE public.cnm_segments OWNER TO icnml;
-
---
--- Name: cnm_segments_id_seq; Type: SEQUENCE; Schema: public; Owner: icnml
---
-
-CREATE SEQUENCE public.cnm_segments_id_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
-ALTER TABLE public.cnm_segments_id_seq OWNER TO icnml;
-
---
--- Name: cnm_segments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: icnml
---
-
-ALTER SEQUENCE public.cnm_segments_id_seq OWNED BY public.cnm_segments.id;
-
-
---
--- Name: cnm_segments id; Type: DEFAULT; Schema: public; Owner: icnml
---
-
-ALTER TABLE ONLY public.cnm_segments ALTER COLUMN id SET DEFAULT nextval('public.cnm_segments_id_seq'::regclass);
-
-
-
diff --git a/templates/navigations/administrator.html b/templates/navigations/administrator.html
index 64150c99ec2141a1324ad3c4257700699c978b72..f4e3a9fd92f8c192090df74cf01292efb86f6bfe 100644
--- a/templates/navigations/administrator.html
+++ b/templates/navigations/administrator.html
@@ -11,9 +11,6 @@
-
diff --git a/utils/__init__.py b/utils/__init__.py
index 5098b20324e4edd84044c98fe59ae6f27dcdeaec..1e1b9232de225f1028eca0c722675c07a5374dd6 100644
--- a/utils/__init__.py
+++ b/utils/__init__.py
@@ -4,6 +4,7 @@
from . import aes
from . import decorator
from . import encryption
+from . import fingers
from . import hash
from . import images
from . import mail
diff --git a/utils/fingers.py b/utils/fingers.py
new file mode 100644
index 0000000000000000000000000000000000000000..3bc8c4b99df3eb9f4f844ba27226d9a07a63bedd
--- /dev/null
+++ b/utils/fingers.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+def get_multi_img_fpc( fpc ):
+ multi_img_fpc = {
+ 1: [ 1, 11 ],
+ 2: [ 2, 13 ],
+ 3: [ 3, 13 ],
+ 4: [ 4, 13 ],
+ 5: [ 5, 13 ],
+ 6: [ 6, 12 ],
+ 7: [ 7, 14 ],
+ 8: [ 8, 14 ],
+ 9: [ 9, 14 ],
+ 10: [ 10, 14 ]
+ }
+ fpc = int( fpc )
+ fpcs = multi_img_fpc.get( fpc, [ fpc ] )
+
+ return fpcs
+
diff --git a/views/afis/__init__.py b/views/afis/__init__.py
index 88a44bd3e62f03c5dbbc6c99f2b24cffb919fb04..987a47cba940589bc95a7ab9eef12839724ae2f8 100644
--- a/views/afis/__init__.py
+++ b/views/afis/__init__.py
@@ -1,9 +1,11 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
+from cStringIO import StringIO
+from flask import Blueprint, session, current_app, request, jsonify, send_file, url_for, abort, redirect
+from uuid import uuid4
import base64
import json
-import os
import zipfile
from cStringIO import StringIO
from uuid import uuid4
@@ -23,578 +25,439 @@ segments_position_code = dict( FINGER_POSITION_CODE, **PALM_POSITION_CODE )
afis_view = Blueprint( "afis", __name__, template_folder = "templates" )
-@afis_view.route( "/admin/afis/list" )
-@utils.decorator.admin_required
-def admin_list_folders():
- return list_folders_inner( True )
-
@afis_view.route( "/afis/list" )
@utils.decorator.login_required
def list_folders():
- return list_folders_inner( False )
-
-def list_folders_inner( isadmin ):
- if isadmin:
- sql = """
- SELECT
- cnm_folder.uuid,
- users.username
- FROM cnm_folder
- INNER JOIN submissions ON submissions.uuid = cnm_folder.donor
- INNER JOIN users ON submissions.donor_id = users.id
- ORDER BY users.id DESC
- """
- else:
- sql = """
- SELECT DISTINCT ON ( users.id )
- cnm_folder.uuid,
- users.username
- FROM cnm_folder
- INNER JOIN cnm_folder_users ON cnm_folder.uuid = cnm_folder_users.folder_id
- INNER JOIN submissions ON submissions.uuid = cnm_folder.donor
- INNER JOIN users ON submissions.donor_id = users.id
- WHERE cnm_folder_users.user_id = %s
- ORDER BY users.id DESC
- """
- folders = config.db.query_fetchall( sql, ( session.get( "user_id" ), ) )
+ user_id = session.get( "user_id", None )
sql = """
SELECT
- submissions.uuid,
- users.username
- FROM submissions
- LEFT JOIN users ON submissions.donor_id = users.id
- LEFT JOIN cnm_folder ON submissions.uuid = cnm_folder.donor
- WHERE cnm_folder.uuid IS NULL
- ORDER BY users.id ASC
+ cnm_assignment.folder_uuid,
+ tmp.*
+ FROM cnm_assignment
+ LEFT JOIN cnm_folder ON cnm_assignment.folder_uuid = cnm_folder.uuid
+ LEFT JOIN (
+ SELECT DISTINCT ON ( donor_id, pc ) *
+ FROM donor_segments_v
+ ) AS tmp ON cnm_folder.donor_id = tmp.donor_id AND cnm_folder.pc = tmp.pc
+
+ WHERE cnm_assignment.user_id = %s
+
+ ORDER BY
+ tmp.donor_id ASC,
+ tmp.pc ASC
"""
- donors = config.db.query_fetchall( sql )
+ folder_list = config.db.query_fetchall( sql, ( user_id, ) )
return utils.template.my_render_template(
- "afis/shared/list.html",
- folders = folders,
- donors = donors
+ "afis/user/folder_list.html",
+ folder_list = folder_list
)
-@afis_view.route( "/admin/afis/new_folder", methods = [ "POST" ] )
+@afis_view.route( "/admin/target///new" )
@utils.decorator.admin_required
-def admin_add_new_folder():
- try:
- donor_uuid = request.form.get( "donor_uuid", False )
-
- sql = "SELECT count( * ) AS nb FROM cnm_folder WHERE donor = %s"
- nb = config.db.query_fetchone( sql, ( donor_uuid, ) )[ "nb" ]
-
- if nb == 0:
- sql = utils.sql.sql_insert_generate( "cnm_folder", [ "donor", "uuid" ], "id" )
- config.db.query_fetchone( sql, ( donor_uuid, str( uuid4() ) ) )
- config.db.commit()
-
- return jsonify( {
- "error": False
- } )
+def admin_create_new_target_and_redirect( submission_id, pc ):
+ sql = "SELECT donor_id FROM submissions WHERE uuid = %s"
+ donor_id = config.db.query_fetchone( sql, ( submission_id, ) )[ "donor_id" ]
+ pc = int( pc )
- except:
- return jsonify( {
- "error": True
- } )
-
-@afis_view.route( "/admin/afis//delete" )
-@utils.decorator.admin_required
-def admin_delete_folder( folder_id ):
- try:
- sql = "DELETE FROM cnm_annotation WHERE folder = %s"
- config.db.query( sql, ( folder_id, ) )
-
- sql = "DELETE FROM cnm_segments WHERE folder_uuid = %s"
- config.db.query( sql, ( folder_id, ) )
-
- sql = "DELETE FROM cnm_folder WHERE uuid = %s"
- config.db.query( sql, ( folder_id, ) )
-
- config.db.commit()
-
- return jsonify( {
- "error": False
- } )
- except:
- return jsonify( {
- "error": True
- } )
-
+ target_uuid = str( uuid4() )
+
+ sql = utils.sql.sql_insert_generate( "cnm_folder", [ "uuid", "pc", "donor_id" ], "id" )
+ config.db.query_fetchone( sql, ( target_uuid, pc, donor_id, ) )
+ config.db.commit()
+
+ return redirect( url_for( "afis.admin_show_target", uuid = target_uuid ) )
-@afis_view.route( "/admin/afis/" )
+@afis_view.route( "/admin/target/" )
@utils.decorator.admin_required
-def admin_folder_show( folder_id ):
- return folder_show_inner( folder_id )
+def admin_show_target( uuid ):
+ return show_folder_inner( uuid, True )
-@afis_view.route( "/afis/" )
+@afis_view.route( "/afis/" )
@utils.decorator.login_required
-def folder_show( folder_id ):
- return folder_show_inner( folder_id )
-
-def folder_show_inner( folder_id ):
- admin = session.get( "account_type_name", None ) == "Administrator"
+def show_folder( uuid ):
+ return show_folder_inner( uuid, False )
+def get_segment_list_for_target_folder( uuid, admin = True ):
+ if not admin:
+ sql = """
+ SELECT count(*) AS count
+ FROM cnm_assignment
+ LEFT JOIN cnm_assignment_type ON cnm_assignment.assignment_type = cnm_assignment_type.id
+ WHERE
+ folder_uuid = %s AND
+ user_id = %s AND
+ cnm_assignment_type.name = 'reference'
+ """
+ if config.db.query_fetchone( sql, ( uuid, session.get( "user_id", False ), ) )[ "count" ] == 0:
+ return None
+
sql = """
SELECT
- segments_locations.fpc
- FROM segments_locations
- INNER JOIN files ON segments_locations.tenprint_id = files.uuid
- INNER JOIN submissions ON files.folder = submissions.id
- INNER JOIN cnm_folder ON submissions.uuid = cnm_folder.donor
- WHERE
- cnm_folder.uuid = %s AND
- (
- fpc <= 10 OR
- fpc = 22 OR
- fpc = 24 OR
- fpc = 25 OR
- fpc = 27
- )
- GROUP BY fpc
- ORDER BY fpc ASC
- """
- segment_list = config.db.query_fetchall( sql, ( folder_id, ) )
-
- sql = """
- SELECT *
- FROM cnm_segments
- WHERE folder_uuid = %s
- ORDER BY fpc ASC
- """
- segment_list_in_folder = config.db.query_fetchall( sql, ( folder_id, ) )
-
- sql = """
- SELECT
- files_segments.tenprint,
- files_segments.pc
+ cnm_folder.uuid AS folder_uuid,
+ donor_segments_v.*
FROM cnm_folder
- INNER JOIN submissions ON cnm_folder.donor = submissions.uuid
- INNER JOIN files ON submissions.id = files.folder
- INNER JOIN files_segments ON files.uuid = files_segments.tenprint
- WHERE cnm_folder.uuid = %s
- """
- tpid = config.db.query_fetchall( sql, ( folder_id, ) )
- sql = """
- SELECT username
- FROM users
- INNER JOIN submissions ON users.id = submissions.donor_id
- INNER JOIN cnm_folder ON submissions.uuid = cnm_folder.donor
- WHERE cnm_folder.uuid = %s
- """
- username = config.db.query_fetchone( sql, ( folder_id, ) )[ "username" ]
+ LEFT JOIN fingers_same ON cnm_folder.pc = fingers_same.base_finger
+ RIGHT JOIN donor_segments_v ON
+ cnm_folder.donor_id = donor_segments_v.donor_id AND
+ fingers_same.target = donor_segments_v.pc
- # Users assigned to this folder
- sql = "SELECT id, username FROM users WHERE type = 5"
- users = config.db.query_fetchall( sql )
+ WHERE cnm_folder.uuid = %s
- sql = """
- SELECT
- users.id,
- users.username
- FROM cnm_folder_users
- INNER JOIN users ON cnm_folder_users.user_id = users.id
- WHERE
- folder_id = %s AND
- img_type = 1
+ ORDER BY
+ donor_segments_v.donor_id ASC,
+ donor_segments_v.pc ASC
"""
- users_assigned_refs = config.db.query_fetchall( sql, ( folder_id, ) )
-
- sql = """
- SELECT
- users.id,
- users.username
- FROM cnm_folder_users
- INNER JOIN users ON cnm_folder_users.user_id = users.id
- WHERE
- folder_id = %s AND
- img_type = 2
- """
- users_assigned_marks = config.db.query_fetchall( sql, ( folder_id, ) )
-
- return utils.template.my_render_template(
- "afis/shared/folder.html",
- segment_list = segment_list,
- segment_list_in_folder = segment_list_in_folder,
- tpid = tpid,
- username = username,
- users = users,
- users_assigned_refs = users_assigned_refs,
- users_assigned_marks = users_assigned_marks,
- folder_id = folder_id,
- segments_position_code = segments_position_code
- )
+ return config.db.query_fetchall( sql, ( uuid, ) )
-@afis_view.route( "/admin/afis//add/segment", methods = [ "POST" ] )
-@utils.decorator.admin_required
-def admin_add_segment_to_cnmfolder( folder_id ):
- try:
- fpc = request.form.get( "fpc" )
-
- sql = "SELECT count( * ) AS nb FROM cnm_segments WHERE folder_uuid = %s AND fpc = %s"
- nb = config.db.query_fetchone( sql, ( folder_id, fpc, ) )[ "nb" ]
-
- if nb == 0:
- sql = utils.sql.sql_insert_generate( "cnm_segments", [ "uuid", "folder_uuid", "fpc" ], "uuid" )
- config.db.query_fetchone( sql, ( str( uuid4() ), folder_id, fpc, ) )
- config.db.commit()
+def get_marks_list_for_target_folder( uuid, admin = True ):
+ if not admin:
+ sql = """
+ SELECT count(*) AS count
+ FROM cnm_assignment
+ LEFT JOIN cnm_assignment_type ON cnm_assignment.assignment_type = cnm_assignment_type.id
+ WHERE
+ folder_uuid = %s AND
+ user_id = %s AND
+ cnm_assignment_type.name = 'mark'
+ """
+ if config.db.query_fetchone( sql, ( uuid, session.get( "user_id", False ), ) )[ "count" ] == 0:
+ return None
- return jsonify( {
- "error": False
- } )
-
- except:
- return jsonify( {
- "error": True
- } )
-
-@afis_view.route( "/admin/afis//segment/" )
-@utils.decorator.admin_required
-def admin_view_segment( folder_id, fpc ):
- return view_segment_inner( folder_id, fpc, True )
-
-@afis_view.route( "/afis//segment/" )
-@utils.decorator.login_required
-def view_segment( folder_id, fpc ):
- return view_segment_inner( folder_id, fpc, False )
-
-def view_segment_mark_ref_anno_lists( folder_id, fpc, isadmin ):
- mark_list = view_segment_mark_ref_anno_lists_marks( folder_id, fpc, isadmin )
- tenprints_list = view_segment_mark_ref_anno_lists_ref( folder_id, fpc, isadmin )
- annotations = view_segment_mark_ref_anno_lists_annotations( folder_id, fpc, isadmin )
-
- return {
- "mark_list": mark_list,
- "tenprints_list": tenprints_list,
- "annotations": annotations
- }
-
-def view_segment_anno_list( folder_id, isadmin ):
- annotations = view_segment_mark_ref_anno_lists_annotations( folder_id, "all", isadmin )
-
- return {
- "mark_list": [],
- "tenprints_list": [],
- "annotations": annotations
- }
-
-def get_multi_img_fpc( fpc ):
- multi_img_fpc = {
- 1: [ 1, 11 ],
- 2: [ 2, 13 ],
- 3: [ 3, 13 ],
- 4: [ 4, 13 ],
- 5: [ 5, 13 ],
- 6: [ 6, 12 ],
- 7: [ 7, 14 ],
- 8: [ 8, 14 ],
- 9: [ 9, 14 ],
- 10: [ 10, 14 ]
- }
- fpc = int( fpc )
- fpcs = multi_img_fpc.get( fpc, [ fpc ] )
-
- return fpcs
-
-def view_segment_mark_ref_anno_lists_ref( folder_id, fpc, isadmin ):
- fpcs = get_multi_img_fpc( fpc )
-
- tmp_sql = [ "files_segments.pc = %s" ] * len( fpcs )
- tmp_sql = " OR ".join( tmp_sql )
-
sql = """
SELECT
- files_segments.tenprint,
- files_segments.pc,
- files_segments.uuid
+ files_v.uuid,
+ mark_info.pfsp
FROM cnm_folder
- INNER JOIN submissions ON cnm_folder.donor = submissions.uuid
- INNER JOIN files ON submissions.id = files.folder
- INNER JOIN files_segments ON files.uuid = files_segments.tenprint
+ LEFT JOIN submissions ON cnm_folder.donor_id = submissions.donor_id
+ LEFT JOIN files_v ON submissions.id = files_v.folder
+ LEFT JOIN files_type ON files_v.type = files_type.id
+ LEFT JOIN mark_info ON files_v.uuid = mark_info.uuid
WHERE
cnm_folder.uuid = %s AND
- ( {} )
- ORDER BY pc ASC
- """.format( tmp_sql )
-
- data = [ folder_id, ]
- data.extend( fpcs )
- tenprints_list = config.db.query_fetchall( sql, data )
-
- if not isadmin:
- sql = "SELECT count( * ) FROM cnm_folder_users WHERE user_id = %s AND folder_id = %s AND img_type = 1"
- r = config.db.query_fetchone( sql, ( session.get( "user_id" ), folder_id, ) )[ "count" ]
- if r == 0:
- tenprints_list = []
+ files_type.name = 'mark_target'
+ """
+ return config.db.query_fetchall( sql, ( uuid, ) )
- return tenprints_list
-
-def view_segment_mark_ref_anno_lists_marks( folder_id, fpc, isadmin ):
- fpcs = get_multi_img_fpc( fpc )
-
+def get_annotation_list_for_target_folder( uuid, admin = True ):
sql = """
- SELECT
- files.id,
- files.uuid
- FROM files
- INNER JOIN mark_info ON files.uuid = mark_info.uuid
- INNER JOIN submissions ON files.folder = submissions.id
- INNER JOIN cnm_folder ON submissions.uuid = cnm_folder.donor
+ SELECT uuid
+ FROM cnm_data
+ LEFT JOIN cnm_data_type ON cnm_data.type_id = cnm_data_type.id
WHERE
- cnm_folder.uuid = %s AND
- ( files.type = 3 OR files.type = 4 )
+ folder_uuid = %s AND
+ cnm_data_type.name = 'annotation'
"""
+ return config.db.query_fetchall( sql, ( uuid, ) )
+
+def show_folder_inner( uuid, admin ):
+ if not admin:
+ sql = "SELECT count(*) FROM cnm_assignment WHERE folder_uuid = %s AND user_id = %s"
+ if config.db.query_fetchone( sql, ( uuid, session.get( "user_id" ), ) )[ "count" ] == 0:
+ return redirect( url_for( "base.home" ) )
- sql_where = []
- for f in fpcs:
- for q in fpc2pfsp[ f ]:
- sql_where.append( "mark_info.pfsp LIKE '%%{}%%'".format( q ) )
-
- if len( sql_where ) > 0:
- sql += " AND ( {} )".format( " OR ".join( sql_where ) )
-
- sql += " ORDER BY files.id ASC"
+ segments_list = get_segment_list_for_target_folder( uuid, admin )
+ annotation_list = get_annotation_list_for_target_folder( uuid, admin )
+ marks_list_tmp = get_marks_list_for_target_folder( uuid, admin )
- mark_list = config.db.query_fetchall( sql, ( folder_id, ) )
-
- if not isadmin:
- sql = "SELECT count( * ) FROM cnm_folder_users WHERE user_id = %s AND folder_id = %s AND img_type = 2"
- r = config.db.query_fetchone( sql, ( session.get( "user_id" ), folder_id, ) )[ "count" ]
- if r == 0:
- mark_list = []
-
- return mark_list
-
-def view_segment_mark_ref_anno_lists_annotations( folder_id, fpc, isadmin ):
- sql = """
- SELECT
- id,
- uuid,
- fpc
- FROM cnm_annotation
- WHERE folder = %s
- """
- data = ( folder_id, )
+ if admin:
+ sql = """
+ SELECT
+ submissions.uuid,
+ cnm_folder.pc,
+ users.username
+ FROM cnm_folder
+ INNER JOIN submissions ON cnm_folder.donor_id = submissions.donor_id
+ INNER JOIN users ON cnm_folder.donor_id = users.id
+ WHERE cnm_folder.uuid = %s
+ """
+ submission_id, pc, username = config.db.query_fetchone( sql, ( uuid, ) )
+ finger_name = "{} (F{})".format( segments_position_code[ pc ], pc )
- if fpc != "all":
- sql += " AND fpc = %s"
- data = ( folder_id, fpc, )
+ marks_list = []
+ for m in marks_list_tmp:
+ for z in m[ "pfsp" ].split( "," ):
+ if pc in pfsp2fpc[ z ]:
+ marks_list.append( m )
- annotations = config.db.query_fetchall( sql, data )
+ sql = """
+ SELECT
+ users.id,
+ users.username
+ FROM users
+ LEFT JOIN account_type ON users.type = account_type.id
+ WHERE account_type.name = 'AFIS'
+ """
+ all_afis_users = config.db.query_fetchall( sql )
+
+ def get_user_assined( assignment_type ):
+ sql = """
+ SELECT
+ cnm_assignment.user_id AS id
+ FROM cnm_assignment
+ LEFT JOIN cnm_assignment_type ON cnm_assignment.assignment_type = cnm_assignment_type.id
+ WHERE
+ cnm_assignment.folder_uuid = %s AND
+ cnm_assignment_type.name = '{}'
+ """.format( assignment_type )
+ return config.db.query_fetchall( sql, ( uuid, ) )
+
+ users_assigned_refs = get_user_assined( "reference" )
+ users_assigned_marks = get_user_assined( "mark" )
- return annotations
-
-def view_segment_inner( folder_id, fpc, isadmin ):
- d = view_segment_mark_ref_anno_lists( folder_id, fpc, isadmin )
- mark_list = d[ "mark_list" ]
- tenprints_list = d[ "tenprints_list" ]
- annotations = d[ "annotations" ]
-
- # Get the username of the donor
- sql = """
- SELECT username
- FROM users
- INNER JOIN submissions ON users.id = submissions.donor_id
- INNER JOIN cnm_folder ON submissions.uuid = cnm_folder.donor
- WHERE cnm_folder.uuid = %s
- """
- username = config.db.query_fetchone( sql, ( folder_id, ) )[ "username" ]
+ else:
+ submission_id = None
+ finger_name = None
+ username = None
+ all_afis_users = None
+ users_assigned_refs = []
+ users_assigned_marks = []
- #
return utils.template.my_render_template(
"afis/shared/segment.html",
- folder_id = folder_id,
- fpc = fpc,
- tenprints_list = tenprints_list,
- len_tenprints_list = len( tenprints_list ),
- mark_list = mark_list,
- len_mark_list = len( mark_list ),
+ target_uuid = uuid,
+ segments_list = segments_list,
+ annotation_list = annotation_list,
+ marks_list = marks_list,
+ submission_id = submission_id,
username = username,
- annotations = annotations,
- segments_position_code = segments_position_code
+ finger_name = finger_name,
+ all_afis_users = all_afis_users,
+ users_assigned_refs = users_assigned_refs,
+ users_assigned_marks = users_assigned_marks
)
-@afis_view.route( "/admin/afis//segment//add/illustration", methods = [ "POST" ] )
+@afis_view.route( "/admin/target//new_illustration", methods = [ "POST" ] )
@utils.decorator.admin_required
-def admin_add_illustration( folder_id, fpc ):
+def admin_add_illustration( uuid ):
try:
sql = """
- SELECT donor
+ SELECT submissions.uuid
FROM cnm_folder
- WHERE uuid = %s
+ LEFT JOIN submissions ON cnm_folder.donor_id = submissions.donor_id
+ WHERE cnm_folder.uuid = %s
"""
- donor_uuid = config.db.query_fetchone( sql, ( folder_id, ) )[ "donor" ]
-
+ donor_id = config.db.query_fetchone( sql, ( uuid, ) )[ "uuid" ]
+
+ sql = "SELECT id FROM cnm_data_type WHERE name = 'annotation'"
+ annotation_type_id = config.db.query_fetchone( sql )[ "id" ]
+
uploaded_file = request.files[ "file" ]
-
+
fp = StringIO()
uploaded_file.save( fp )
fp.seek( 0 )
-
+
file_data = fp.getvalue()
file_data = base64.b64encode( file_data )
- file_data = utils.encryption.do_encrypt_dek( file_data, donor_uuid )
+ file_data = utils.encryption.do_encrypt_dek( file_data, donor_id )
- sql = utils.sql.sql_insert_generate( "cnm_annotation", [ "uuid", "folder", "fpc", "annotation_data" ], "id" )
- config.db.query_fetchone( sql, ( str( uuid4() ), folder_id, fpc, file_data, ) )
+ sql = utils.sql.sql_insert_generate(
+ "cnm_data",
+ [ "uuid", "folder_uuid", "data", "type_id" ],
+ "id"
+ )
+ data = ( str( uuid4() ), uuid, file_data, annotation_type_id, )
+ config.db.query_fetchone( sql, data )
config.db.commit()
-
+
return jsonify( {
"error": False
} )
except:
return jsonify( {
- "error": True
+ "error": False
} )
-@afis_view.route( "/admin/afis//segment//remove/illustration", methods = [ "POST" ] )
+@afis_view.route( "/admin/target//target/annotation/delete", methods = [ "POST" ] )
@utils.decorator.admin_required
-def admin_remove_illustration( folder_id, fpc ):
+def admin_delete_annotation( folder_uuid ):
try:
illustration_uuid = request.form.get( "uuid" )
- sql = "DELETE FROM cnm_annotation WHERE folder = %s AND fpc = %s AND uuid = %s"
- config.db.query( sql, ( folder_id, fpc, illustration_uuid, ) )
+ sql = "DELETE FROM cnm_data WHERE folder_uuid = %s AND uuid = %s"
+ config.db.query( sql, ( folder_uuid, illustration_uuid, ) )
config.db.commit()
-
- return jsonify( {
- "error": False
- } )
-
- except:
- return jsonify( {
- "error": True
- } )
-
-@afis_view.route( "/admin/afis//remove/segment", methods = [ "POST" ] )
-@utils.decorator.admin_required
-def admin_remove_segment( folder_id ):
- try:
- fpc = request.form.get( "fpc" )
- sql = "DELETE FROM cnm_segments WHERE folder_uuid = %s AND fpc = %s"
- config.db.query( sql, ( folder_id, fpc, ) )
-
- sql = "DELETE FROM cnm_annotation WHERE folder = %s AND fpc = %s"
- config.db.query( sql, ( folder_id, fpc, ) )
- config.db.commit()
-
return jsonify( {
"error": False
} )
-
+
except:
return jsonify( {
"error": True
} )
-@afis_view.route( "//afis//annotation/" )
+@afis_view.route( "/afis//download" )
@utils.decorator.login_required
-def get_annotation_image( folder_id, a_uuid, u_type = "afis" ):
- img = get_annotation_image_inner( folder_id, a_uuid )
- buff = utils.images.pil2buffer( img, "PNG" )
- return send_file( buff, mimetype = "image/png" )
+def download_target_folder( uuid ):
+ short_uuid = uuid[ 0:18 ]
+
+ annotation_list = get_annotation_list_for_target_folder( uuid, False )
+ segments_list = get_segment_list_for_target_folder( uuid, False )
+ marks_list = get_marks_list_for_target_folder( uuid, False )
+
+ zipbuffer = StringIO()
+
+ with zipfile.ZipFile( zipbuffer, "w", zipfile.ZIP_DEFLATED ) as fp:
+ if isinstance( annotation_list, list ):
+ for fid in annotation_list:
+ file_id = fid[ "uuid" ]
+ short_file_id = file_id[ 0:18 ]
+
+ submission_id = views.images.get_submission_uuid_for_annotation( file_id )
+
+ img, _ = views.images.image_serve( "cnm_data", file_id, submission_id )
+ img = views.images.image_tatoo( img, file_id )
+
+ buff = utils.images.pil2buffer( img, "TIFF" )
+ fp.writestr(
+ "{}_annotation_{}.tiff".format( short_uuid, short_file_id ),
+ buff.getvalue()
+ )
+
+ if isinstance( segments_list, list ):
+ for sid in segments_list:
+ file_id = sid[ "uuid" ]
+ short_file_id = file_id[ 0:18 ]
+ tenprint_id = sid[ "tenprint" ]
+ pc = sid[ "pc" ]
+
+ submission_id = views.images.get_submission_uuid_for_file( tenprint_id )
+
+ img, _ = views.images.image_serve( "files_segments", ( tenprint_id, pc ), submission_id )
+ img = views.images.image_tatoo( img, file_id )
+
+ buff = utils.images.pil2buffer( img, "TIFF" )
+ fp.writestr(
+ "{}_reference_{}.tiff".format( short_uuid, short_file_id ),
+ buff.getvalue()
+ )
+
+ if isinstance( marks_list, list ):
+ for mid in marks_list:
+ file_id = mid[ "uuid" ]
+ short_file_id = file_id[ 0:18 ]
+
+ submission_id = views.images.get_submission_uuid_for_file( file_id )
+ img, _ = views.images.image_serve( "files", file_id, submission_id )
+ img = views.images.image_tatoo( img, file_id )
+
+ buff = utils.images.pil2buffer( img, "TIFF" )
+ fp.writestr(
+ "{}_mark_{}.tiff".format( short_uuid, short_file_id ),
+ buff.getvalue()
+ )
+
+ zipbuffer.seek( 0 )
+
+ return send_file(
+ zipbuffer,
+ attachment_filename = "{}.zip".format( short_uuid ),
+ as_attachment = True
+ )
-def get_annotation_image_inner( folder_id, a_uuid ):
- sql = "SELECT donor FROM cnm_folder WHERE uuid = %s"
- donor_uuid = config.db.query_fetchone( sql, ( folder_id, ) )[ "donor" ]
+@afis_view.route( "/afis//upload/list" )
+def upload_cnm_list_page( uuid ):
+ sql = """
+ SELECT uuid
+ FROM cnm_result
+ WHERE
+ cnm_folder = %s AND
+ uploader = %s
+ """
+ cnm_result_list = config.db.query_fetchall( sql, ( uuid, session.get( "user_id" ), ) )
+ return utils.template.my_render_template(
+ "afis/user/upload_cnm_list.html",
+ cnm_result_list = cnm_result_list,
+ )
+
+@afis_view.route( "/admin//target/list" )
+@utils.decorator.admin_required
+def admin_show_target_list( uuid ):
sql = """
- SELECT annotation_data
- FROM cnm_annotation
- WHERE uuid = %s
+ SELECT DISTINCT ON ( donor_segments_v.pc )
+ donor_segments_v.*,
+ cnm_folder.uuid AS folder_uuid
+ FROM donor_segments_v
+ LEFT JOIN submissions ON submissions.donor_id = donor_segments_v.donor_id
+ LEFT JOIN cnm_folder ON
+ donor_segments_v.donor_id = cnm_folder.donor_id AND
+ donor_segments_v.pc = cnm_folder.pc
+ WHERE submissions.uuid = %s
"""
- data = config.db.query_fetchone( sql, ( a_uuid, ) )[ "annotation_data" ]
+ segments_list = config.db.query_fetchall( sql, ( uuid, ) )
- data = utils.encryption.do_decrypt_dek( data, donor_uuid )
- img = base64.b64decode( data )
+ sql = """
+ SELECT
+ cnm_folder.pc
+ FROM submissions
+ LEFT JOIN cnm_folder ON submissions.donor_id = cnm_folder.donor_id
+ LEFT JOIN cnm_data ON cnm_folder.uuid = cnm_data.folder_uuid
+ LEFT JOIN cnm_data_type ON cnm_data.type_id = cnm_data_type.id
+ WHERE
+ submissions.uuid = %s AND
+ cnm_data_type.name = 'annotation'
+ GROUP BY pc
+ """
+ annotations = config.db.query_fetchall( sql, ( uuid, ) )
+ annotations = [ a[ 'pc' ] for a in annotations ]
- buff = StringIO()
- buff.write( img )
- buff.seek( 0 )
+ sql = """
+ SELECT username
+ FROM users
+ LEFT JOIN submissions ON users.id = submissions.donor_id
+ WHERE submissions.uuid = %s
+ """
+ username = config.db.query_fetchone( sql, ( uuid, ) )[ "username" ]
- return Image.open( buff )
-
-@afis_view.route( "/admin/afis//user/update", methods = [ "POST" ] )
+ return utils.template.my_render_template(
+ "afis/admin/folder_list.html",
+ segments_list = segments_list,
+ annotations = annotations,
+ segments_position_code = segments_position_code,
+ username = username,
+ submission_uuid = uuid
+ )
+
+@afis_view.route( "/admin/afis//user/update", methods = [ "POST" ] )
@utils.decorator.admin_required
-def admin_update_users_in_afis_folder( folder_id ):
+def admin_update_users_in_afis_folder( target_uuid ):
try:
users = request.form.get( "users" )
users = json.loads( users )
- if request.form.get( "type" ) == "ref":
- img_type = 1
- else:
- img_type = 2
- sql = "DELETE FROM cnm_folder_users WHERE folder_id = %s AND img_type = %s"
- config.db.query( sql, ( folder_id, img_type, ) )
+ assignment_type = request.form.get( "type" )
+ sql = "SELECT id FROM cnm_assignment_type WHERE name = %s"
+ assignment_type_id = config.db.query_fetchone( sql, ( assignment_type, ) )[ "id" ]
- sql = utils.sql.sql_insert_generate( "cnm_folder_users", [ "user_id", "folder_id", "img_type" ], "id" )
+ sql = """
+ DELETE FROM cnm_assignment
+ WHERE
+ folder_uuid = %s AND
+ assignment_type = %s
+ """
+ config.db.query( sql, ( target_uuid, assignment_type_id, ) )
+
+ sql = utils.sql.sql_insert_generate(
+ "cnm_assignment",
+ [ "folder_uuid", "user_id", "assignment_type" ],
+ "id"
+ )
for user in users:
- config.db.query_fetchone( sql, ( user, folder_id, img_type, ) )
-
+ config.db.query_fetchone( sql, ( target_uuid, user, assignment_type_id, ) )
+
config.db.commit()
-
+
return jsonify( {
"error": False
} )
+
except:
return jsonify( {
"error": True
} )
-
- return jsonify( view_segment_mark_ref_anno_lists( folder_id, fpc, False ) )
-
-@afis_view.route( "/afis//download/" )
-@utils.decorator.login_required
-def download_folder_afis( folder_id, fpc ):
- return download_folder_inner( folder_id, fpc, False )
-
-@afis_view.route( "/admin/afis//download/" )
-@utils.decorator.login_required
-def download_folder_admin( folder_id, fpc ):
- return download_folder_inner( folder_id, fpc, True )
-
-def download_folder_inner( folder_id, fpc, isadmin ):
- if fpc == "all":
- lst = view_segment_anno_list( folder_id, isadmin )
- else:
- lst = view_segment_mark_ref_anno_lists( folder_id, fpc, isadmin )
-
- zipbuffer = StringIO()
-
- with zipfile.ZipFile( zipbuffer, "w", zipfile.ZIP_DEFLATED ) as fp:
- for fid in lst[ "mark_list" ]:
- file_id = fid[ "uuid" ]
- submission_id = views.images.get_submission_uuid_for_file( file_id )
- img, _ = views.images.image_serve( "files", file_id, submission_id )
- img = views.images.image_tatoo( img, file_id )
- buff = utils.images.pil2buffer( img, "TIFF" )
-
- fp.writestr( "mark_{}.tiff".format( file_id ), buff.getvalue() )
-
- for fid in lst[ "tenprints_list" ]:
- file_id = fid[ "tenprint" ]
- pc = fid[ "pc" ]
- submission_id = views.images.get_submission_uuid_for_file( file_id )
- img, _ = views.images.image_serve( "files_segments", ( file_id, pc ), submission_id )
- img = views.images.image_tatoo( img, file_id )
- buff = utils.images.pil2buffer( img, "TIFF" )
-
- fp.writestr( "reference_{}.tiff".format( file_id ), buff.getvalue() )
-
- for fid in lst[ "annotations" ]:
- file_id = fid[ "uuid" ]
- fpc = fid[ "fpc" ]
- img = get_annotation_image_inner( folder_id, file_id )
- img = views.images.image_tatoo( img, file_id )
- buff = utils.images.pil2buffer( img, "PNG" )
-
- fp.writestr( "annotation_finger{}_{}.png".format( fpc, file_id ), buff.getvalue() )
- zipbuffer.seek( 0 )
-
- return send_file( zipbuffer, attachment_filename = "{}.zip".format( folder_id ), as_attachment = True )
-
diff --git a/views/afis/templates/afis/admin/folder_list.html b/views/afis/templates/afis/admin/folder_list.html
new file mode 100644
index 0000000000000000000000000000000000000000..ae32e30752bffcfbef6c1913133e4002a356c7ee
--- /dev/null
+++ b/views/afis/templates/afis/admin/folder_list.html
@@ -0,0 +1,179 @@
+{% import "jinja_functions.html" as common %}
+
+
+
+
+ {% for src in js %}
+
+ {% endfor %}
+ {% for src in css %}
+
+ {% endfor %}
+
+ {% autoescape false %}
+ {{ app_files }}
+ {% endautoescape %}
+
+
+
+
+
+
+ {% include "header.html" %}
+ {% include navigation %}
+
+
+
+
+
+ {% for n in [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] %}
+
+
+
+
+ segment not available
+ {{ common.checked_question( "segment_" + n|e + "_checked_error" ) }}
+
+
+
+ {% endfor %}
+
+
+
+
+
+ {% for n in [ 24, 27, 25, 22 ] %}
+
+
+
+
+ segment not available
+ {{ common.checked_question( "segment_" + n|e + "_checked_error" ) }}
+
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/views/afis/templates/afis/shared/segment.html b/views/afis/templates/afis/shared/segment.html
index 17323d07a6571e30c831cce6c25141f814f04e26..4f45c984bc263878288098180fd7799222784970 100644
--- a/views/afis/templates/afis/shared/segment.html
+++ b/views/afis/templates/afis/shared/segment.html
@@ -5,6 +5,95 @@
{{ app_files }}
{% endautoescape %}
+
+
-
-
+ .list_of_assignee {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ grid-gap: 3px 20px;
+ margin-bottom: 30px;
+ }
+ .icnml_download_target_buttons {
+ width: fit-content;
+ width: -moz-fit-content;
+ margin-top: 30px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+ .icnml_buttons_list {
+ display: grid;
+ grid-template-columns: repeat( 2, 1fr );
+ grid-gap: 10px;
+ margin: 20px;
+ }
+ .icnml_button {
+ height: 120px;
+ width: 120px;
+ padding: 0px;
+ }
+ .icnml_button > span {
+ height: 120px;
+ width: 120px;
+ line-height: 120px;
+ vertical-align: center;
+ text-align: center;
+ }
+
{% include "header.html" %}
{% include navigation %}
-
-
-
Annotation illustration PiAnoS ({{ annotations|length }})
-
- {% for a in annotations %}
-
-
-
- {% if admin %}
-
-
- {% else %}
+ {% if not admin %}
+
+ {% endif %}
+
+ {% if admin %}
+
+
Marks
+
+
+
+
References
+
+
+
+
+ {% endif %}
+
+ {% if annotation_list != None %}
+
+
Target annotations ({{ annotation_list|length }})
+
+ {% for s in annotation_list %}
+
+
+
+ style="background-image: url( {{ url_for( 'image.image_annotation_serve', uuid = s[ 'uuid' ] ) }} )">
- {% endif %}
+
-
- {% endfor %}
- {% if admin %}
-
-
-
-
-
+ {% endfor %}
+
+ {% if admin %}
+
-
- {% endif %}
+ {% endif %}
+
-
- {% if tenprints_list|length > 0 %}
+ {% else %}
+
No annotations for this finger at the moment
+ {% endif %}
+
+ {% if segments_list != None %}
-
Tenprint ({{ tenprints_list|length }})
+
Non annotated images ({{ segments_list|length }})
- {% for tenprint in tenprints_list %}
-
-
+ {% for s in segments_list %}
+
+
+ style="background-image: url( {{ url_for( 'image.image_segment_serve', tenprint_id = s[ 'tenprint' ], pc = s[ 'pc' ] ) }} )">
{% endfor %}
+ {% elif admin %}
+
No segment images in this folder at the moment
{% endif %}
- {% if mark_list|length > 0 %}
+
+ {% if marks_list != None %}
-
Marks ({{ mark_list|length }})
+
Marks ({{ marks_list|length }})
- {% for mark in mark_list %}
-
-
+ {% for mark in marks_list %}
+
+
@@ -149,20 +266,64 @@
{% endfor %}
+ {% elif admin %}
+
No mark images in this folder at the moment
{% endif %}
+
-