Skip to content
Commits on Source (16)
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
<div id="icnml_navigation_exercises"> <div id="icnml_navigation_exercises">
<a href="{{ url_for( 'trainer.exercises_list' ) }}">Trainer folders</a> <a href="{{ url_for( 'trainer.exercises_list' ) }}">Trainer folders</a>
</div> </div>
<div id="icnml_navigation_afis_batch_assign">
<a href="{{ url_for( 'afis.batch_assign' ) }}">AFIS assign</a>
</div>
<div id="icnml_navigation_pianos"> <div id="icnml_navigation_pianos">
<a href="{{ url_for( 'pianos.pianos_actions' ) }}">PiAnoS</a> <a href="{{ url_for( 'pianos.pianos_actions' ) }}">PiAnoS</a>
</div> </div>
......
...@@ -14,6 +14,8 @@ from flask import Blueprint ...@@ -14,6 +14,8 @@ from flask import Blueprint
from flask import jsonify, request, send_file, current_app, session from flask import jsonify, request, send_file, current_app, session
from PIL import Image from PIL import Image
import psycopg2
import utils import utils
import config import config
...@@ -478,4 +480,164 @@ def admin_update_users_in_afis_folder( target_uuid ): ...@@ -478,4 +480,164 @@ def admin_update_users_in_afis_folder( target_uuid ):
return jsonify( { return jsonify( {
"error": True "error": True
} ) } )
@afis_view.route( "/admin/afis/get_target_list" )
@utils.decorator.admin_required
def get_target_list():
try:
sql = """
SELECT
tmp.uuid,
tmp.donor_username,
tmp.pc,
tmp.nb,
users.username AS submitter_username
FROM (
SELECT
cnm_folder.uuid,
users.username as donor_username,
users.id as donor_id,
cnm_folder.pc,
count( cnm_folder.uuid ) AS nb,
submissions.submitter_id
FROM cnm_data
LEFT JOIN cnm_folder ON cnm_data.folder_uuid = cnm_folder.uuid
LEFT JOIN cnm_data_type ON cnm_data.type_id = cnm_data_type.id
LEFT JOIN submissions ON cnm_folder.donor_id = submissions.donor_id
LEFT JOIN users ON users.id = submissions.donor_id
WHERE
cnm_data_type.name = 'annotation'
GROUP BY
cnm_folder.uuid,
cnm_folder.pc,
users.username,
users.id,
submissions.submitter_id
) AS tmp
LEFT JOIN users ON tmp.submitter_id = users.id
ORDER BY
tmp.donor_id,
tmp.pc
"""
targets = config.db.query_fetchall( sql )
return jsonify( {
"error": False,
"data": targets,
"headers": [ "uuid", "donor_username", "fpc", "count", "submitter_username" ]
} )
except:
return jsonify( {
"error": True
} )
@afis_view.route( "/admin/afis/get_assignments" )
@utils.decorator.admin_required
def get_target_assignements():
try:
sql = """
SELECT
cnm_assignment.folder_uuid,
cnm_assignment_type.name,
users.username
FROM cnm_assignment
LEFT JOIN users ON cnm_assignment.user_id = users.id
LEFT JOIN cnm_assignment_type ON cnm_assignment.assignment_type = cnm_assignment_type.id
"""
assignments = config.db.query_fetchall( sql )
return jsonify( {
"error": False,
"data": assignments,
"headers": [ "folder_uuid", "type", "username" ]
} )
except:
return jsonify( {
"error": True
} )
@afis_view.route( "/admin/afis/get_afis_users" )
@utils.decorator.admin_required
def get_afis_users_list():
try:
sql = """
SELECT
users.id,
users.username
FROM users
LEFT JOIN account_type ON users.type = account_type.id
WHERE account_type.name = 'AFIS'
ORDER BY users.id ASC
"""
users_list = config.db.query_fetchall( sql )
return jsonify( {
"error": False,
"data": users_list,
"headers": [ "id", "username" ]
} )
except:
return jsonify( {
"error": True
} )
@afis_view.route( "/admin/afis/batch_assign/do", methods = [ "POST" ] )
def batch_assign_do():
try:
data = request.form.get( "data" )
data = data.split( "\n" )
assignments_type_dict = {}
for a in config.db.query_fetchall( "select * from cnm_assignment_type" ):
assignments_type_dict[ a[ "name" ] ] = a[ "id" ]
sql_insert = utils.sql.sql_insert_generate(
"cnm_assignment",
[ "folder_uuid", "user_id", "assignment_type" ],
"id"
)
for d in data:
if d == "":
continue
uuid, assignment_type, username = d.split( ";" )
if uuid == "folder_uuid":
continue
user_id = config.db.query_fetchone(
"SELECT id FROM users WHERE username = %s",
( username, )
)[ "id" ]
try:
config.db.query_fetchone(
sql_insert,
( uuid, user_id, assignments_type_dict[ assignment_type ], )
)
# Check for UniqueViolation; This is done with the lookup() function to avoid the linter error
except psycopg2.errors.lookup( "23505" ):
continue
config.db.commit()
return jsonify( {
"error": False
} )
except:
return jsonify( {
"error": True
} )
@afis_view.route( "/admin/afis/batch_assign" )
@utils.decorator.admin_required
def batch_assign():
return utils.template.my_render_template(
"afis/admin/batch_assign.html"
)
{% import "jinja_functions.html" as common %}
<!DOCTYPE html>
<html>
<head>
{% autoescape false %}
{{ app_files }}
{% endautoescape %}
<style type="text/css">
.icnml_afis_assignments_actions {
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( 4, 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;
}
</style>
<script type="text/javascript">
baseurl = "{{ baseurl }}";
var data_to_csv = function( data )
{
var ret = data.headers.join( ";" );
ret += "\n";
_.forEach( data.data, function( d ){
ret += d.join( ";" );
ret += "\n";
} );
return ret;
}
var build_dialog = function( data, title )
{
return $( "<div />" )
.attr( "id", "afis_dialog" )
.append(
$( "<textarea />" )
.css( "margin-top", "10px" )
.css( "margin-bottom", "10px" )
.css( "font-family", "monospace" )
.attr( "rows", "15" )
.text( data_to_csv( data ) )
)
.dialog( {
title: title,
modal: true,
width: "550px",
buttons: {
"Close": function()
{
$( this ).dialog( "close" );
},
},
close: function()
{
$( this ).remove();
},
open: function()
{
$( ".ui-widget-overlay" ).bind( "click", function()
{
$( "#afis_dialog" ).dialog( "close" );
} );
}
} );
}
var get_data_and_build_dialog = function( target, title )
{
$.ajax( {
url: target,
dataType: "json",
method: "GET",
success: function( data ){
if( ! data.error )
{
build_dialog( data, title );
} else {
toastr.error( "Server error" );
}
},
error: function( data ){
toastr.error( "Network error" );
}
} );
}
var afis_users_function = function()
{
get_data_and_build_dialog(
"{{ url_for( 'afis.get_afis_users_list' ) }}",
"List of AFIS users"
)
}
var target_list_function = function()
{
get_data_and_build_dialog(
"{{ url_for( 'afis.get_target_list' ) }}",
"List of AFIS targets"
)
}
var current_assignments_list_function = function()
{
get_data_and_build_dialog(
"{{ url_for( 'afis.get_target_assignements' ) }}",
"Current assignements"
);
}
var update_assignements_function_db = function()
{
var data = $( "#assignements_list" ).val();
$.ajax( {
url: "{{ url_for( 'afis.batch_assign_do' ) }}",
dataType: "json",
method: "POST",
data: {
data: data
},
success: function( data )
{
if( ! data.error )
{
toastr.success( "Update OK" );
$( "#afis_dialog" ).dialog( "close" );
} else {
toastr.error( "Error while updating the assignments" );
}
},
error: function()
{
toastr.error( "Network error" );
}
} );
}
var update_assignements_function = function()
{
$( "<div />" )
.attr( "id", "afis_dialog" )
.append(
$( "<textarea />" )
.attr( "id", "assignements_list" )
.css( "margin-top", "10px" )
.css( "margin-bottom", "10px" )
.css( "font-family", "monospace" )
.attr( "rows", "15" )
)
.dialog( {
title: "Update the user assignement for AFIS targets",
modal: true,
width: "550px",
buttons: {
"Save": update_assignements_function_db,
"Close": function()
{
$( this ).dialog( "close" );
},
},
close: function()
{
$( this ).remove();
},
open: function()
{
$( ".ui-widget-overlay" ).bind( "click", function()
{
$( "#afis_dialog" ).dialog( "close" );
} );
}
} );
}
</script>
</head>
<body class="icnml_main_layout">
{% include "header.html" %}
{% include navigation %}
<div class="icnml_content">
<div class="icnml_afis_assignments_actions">
<div class="ui-widget-header ui-corner-top icnml_box_top">Targets assignements to AFIS users</div>
<div class="ui-widget-content ui-corner-bottom">
<div class="icnml_buttons_list">
<div class="icnml_button">
<a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only icnml_button" id="afis_users_button" role="button" aria-disabled="false">
<span>AFIS users</span>
</a>
</div>
<div class="icnml_button">
<a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only icnml_button" id="target_list_button" role="button" aria-disabled="false">
<span>Targets</span>
</a>
</div>
<div class="icnml_button">
<a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only icnml_button" id="current_assignments_list_button" role="button" aria-disabled="false">
<span>Current</span>
</a>
</div>
<div class="icnml_button">
<a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only icnml_button" id="update_assignements_button" role="button" aria-disabled="false">
<span>Update</span>
</a>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$( "#afis_users_button" ).on( "click", afis_users_function );
$( "#target_list_button" ).on( "click", target_list_function );
$( "#current_assignments_list_button" ).on( "click", current_assignments_list_function );
$( "#update_assignements_button" ).on( "click", update_assignements_function );
$( "#icnml_navigation_afis_batch_assign" )
.addClass( "activated" );
$( "#navloc" ).append(
$( "<span />" )
.text( "AFIS batch assignment" )
);
</script>
</body>
</html>