server/frontend/static/js/challenge.js

488 lines
15 KiB
JavaScript
Raw Normal View History

2016-01-23 11:29:19 +00:00
angular.module("FICApp", ["ngRoute", "ngSanitize"])
2016-01-16 21:40:59 +00:00
.config(function($routeProvider, $locationProvider) {
$routeProvider
2016-12-04 18:07:52 +00:00
.when("/rules", {
controller: "HomeController",
templateUrl: "views/rules.html"
})
2016-01-16 21:40:59 +00:00
.when("/edit", {
controller: "MyTeamController",
templateUrl: "views/team-edit.html"
})
.when("/rank", {
2016-01-21 04:00:15 +00:00
controller: "RankController",
templateUrl: "views/rank.html"
2016-01-16 21:40:59 +00:00
})
2017-12-21 21:18:18 +00:00
.when("/register", {
controller: "RegisterController",
templateUrl: "views/register.html"
})
2017-04-02 18:29:15 +00:00
.when("/videos", {
controller: "VideosController",
templateUrl: "views/videos.html"
})
2016-01-16 21:40:59 +00:00
.when("/:theme", {
2016-01-21 00:38:43 +00:00
controller: "ExerciceController",
2016-01-16 21:40:59 +00:00
templateUrl: "views/theme.html"
})
.when("/:theme/:exercice", {
controller: "ExerciceController",
templateUrl: "views/theme.html"
})
2016-01-21 00:38:43 +00:00
.when("/", {
2016-01-16 21:40:59 +00:00
controller: "HomeController",
templateUrl: "views/home.html"
2016-01-21 00:38:43 +00:00
})
.otherwise({
redirectTo: "/"
2016-01-16 21:40:59 +00:00
});
$locationProvider.html5Mode(true);
})
2017-01-15 22:56:28 +00:00
.run(function($rootScope, $interval) {
2016-01-21 00:38:43 +00:00
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice_my = 0;
2016-01-23 11:29:19 +00:00
$rootScope.time = {};
2017-12-14 02:20:38 +00:00
$('[data-toggle="popover"]').popover();
2016-01-23 11:29:19 +00:00
function updTime() {
if (sessionStorage.userService) {
var time = angular.fromJson(sessionStorage.userService);
var srv_cur = (Date.now() + (time.cu * 1000 - time.he)) / 1000;
var remain = time.du;
if (time.st == Math.floor(srv_cur)) {
$rootScope.refresh(true);
}
if (time.st > 0 && time.st <= srv_cur) {
remain = time.st + time.du - srv_cur;
}
if (remain < 0) {
remain = 0;
$rootScope.time.end = true;
$rootScope.time.expired = true;
} else if (remain < 60) {
$rootScope.time.end = false;
$rootScope.time.expired = true;
} else {
$rootScope.time.end = false;
$rootScope.time.expired = false;
}
$rootScope.time.start = time.st * 1000;
2016-01-24 14:22:53 +00:00
$rootScope.time.duration = time.du;
2016-01-23 11:29:19 +00:00
$rootScope.time.remaining = remain;
$rootScope.time.hours = Math.floor(remain / 3600);
$rootScope.time.minutes = Math.floor((remain % 3600) / 60);
$rootScope.time.seconds = Math.floor(remain % 60);
}
}
updTime();
2017-01-15 22:56:28 +00:00
$interval(updTime, 1000);
2016-12-04 18:13:44 +00:00
})
2017-12-21 21:18:18 +00:00
.controller("DataController", function($sce, $scope, $http, $rootScope, $timeout, $location) {
2016-01-21 00:38:43 +00:00
var actMenu = function() {
if ($scope.my && $scope.themes) {
angular.forEach($scope.themes, function(theme, key) {
$scope.themes[key].exercice_solved = 0;
angular.forEach(theme.exercices, function(exercice, k) {
2017-12-14 02:20:38 +00:00
if ($scope.my.exercices && $scope.my.exercices[k] && $scope.my.exercices[k].solved) {
2016-01-21 00:38:43 +00:00
$scope.themes[key].exercice_solved++;
}
});
});
}
}
2016-01-23 11:29:19 +00:00
$rootScope.refresh = function(justMy) {
if (!justMy) {
2016-01-25 02:09:22 +00:00
$timeout.cancel($scope.cbr);
$scope.cbr = $timeout($rootScope.refresh, 42000);
2017-12-14 02:20:38 +00:00
$http.get("/time.json").then(function(response) {
var time = response.data;
2016-01-23 11:29:19 +00:00
time.he = (new Date()).getTime();
sessionStorage.userService = angular.toJson(time);
});
2017-12-14 02:20:38 +00:00
$http.get("/settings.json").then(function(response) {
$scope.settings = response.data;
2017-01-16 12:09:31 +00:00
});
2017-12-14 02:20:38 +00:00
$http.get("/themes.json").then(function(response) {
$scope.themes = response.data;
2016-01-24 14:22:53 +00:00
$scope.max_gain = 0;
2017-01-16 12:09:31 +00:00
$scope.max_solved = 0;
2018-01-18 10:07:50 +00:00
$scope.themesUrl = {};
$scope.exercicesUrl = {};
2017-12-14 02:20:38 +00:00
angular.forEach(response.data, function(theme, key) {
2018-01-18 10:07:50 +00:00
$scope.themesUrl[theme.urlid] = key;
2016-01-23 11:29:19 +00:00
this[key].exercice_count = Object.keys(theme.exercices).length;
2017-01-16 12:09:31 +00:00
this[key].exercice_coeff_max = 0;
2016-01-24 14:22:53 +00:00
this[key].gain = 0;
2017-01-16 12:09:31 +00:00
this[key].solved = 0;
2016-01-24 14:22:53 +00:00
angular.forEach(theme.exercices, function(ex, k) {
2018-01-18 10:07:50 +00:00
$scope.exercicesUrl[ex.urlid] = k;
2016-01-24 14:22:53 +00:00
this.gain += ex.gain;
2017-01-16 12:09:31 +00:00
this.solved += ex.solved;
this.exercice_coeff_max = Math.max(this.exercice_coeff_max, ex.curcoeff);
2016-01-24 14:22:53 +00:00
}, theme);
$scope.max_gain += theme.gain;
2017-01-16 12:09:31 +00:00
$scope.max_solved = Math.max($scope.max_solved, theme.solved);
2017-12-14 02:20:38 +00:00
}, response.data);
2016-01-23 11:29:19 +00:00
actMenu();
});
2017-12-14 02:20:38 +00:00
$http.get("/teams.json").then(function(response) {
var teams = response.data;
2016-01-23 11:29:19 +00:00
$scope.teams_count = Object.keys(teams).length
$scope.teams = teams;
2016-01-21 00:38:43 +00:00
2016-01-23 11:29:19 +00:00
$scope.rank = [];
angular.forEach($scope.teams, function(team, tid) {
team.id = tid;
this.push(team);
}, $scope.rank);
});
}
2017-12-14 02:20:38 +00:00
$http.get("/my.json").then(function(response) {
$scope.my = response.data;
2016-10-13 18:16:42 +00:00
angular.forEach($scope.my.exercices, function(exercice, eid) {
2017-01-16 12:09:31 +00:00
exercice.solved = exercice.solved_rank > 0;
2016-10-13 18:16:42 +00:00
if (exercice.video_uri) {
exercice.video_uri = $sce.trustAsResourceUrl(exercice.video_uri);
}
});
2016-01-21 00:38:43 +00:00
actMenu();
2017-12-14 02:20:38 +00:00
if ($scope.my.team_id == 0) {
angular.forEach($scope.my.exercices, function(exercice, eid) {
angular.forEach(exercice.hints, function(hint, hid) {
$scope.my.exercices[eid].hints[hid].hidden = true;
});
});
}
2017-12-21 21:18:18 +00:00
}, function(response) {
if (!$scope.my && response.status == 404) {
$location.url("/register");
}
2016-01-21 00:38:43 +00:00
});
console.log("refresh!");
}
2016-01-23 11:29:19 +00:00
$rootScope.refresh();
2016-01-21 00:38:43 +00:00
})
2016-12-09 10:55:58 +00:00
.controller("ExerciceController", function($scope, $routeParams, $http, $rootScope, $timeout) {
2018-01-18 10:07:50 +00:00
$rootScope.current_theme = $scope.themesUrl[$routeParams.theme];
2016-01-21 00:38:43 +00:00
if ($routeParams.exercice) {
2018-01-18 10:07:50 +00:00
$rootScope.current_exercice = $scope.exercicesUrl[$routeParams.exercice];
2016-01-21 00:38:43 +00:00
} else {
if ($scope.themes && $scope.my && $scope.themes[$scope.current_theme]) {
2018-05-13 12:15:53 +00:00
var exos = $scope.themes[$scope.current_theme].exercices;
2016-01-21 00:38:43 +00:00
var i = 0;
2016-01-24 13:32:46 +00:00
for (; i < exos.length; i++) {
2018-05-13 12:15:53 +00:00
if (!$scope.my.exercices || !$scope.my.exercices[exos[i].id] || !$scope.my.exercices[exos[i].id].solved)
2016-01-21 00:38:43 +00:00
break;
}
2016-01-24 13:32:46 +00:00
if (i < exos.length) {
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice = i;
2016-01-24 13:32:46 +00:00
} else {
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice = 0;
2016-01-24 13:32:46 +00:00
}
2016-01-21 00:38:43 +00:00
} else {
$rootScope.current_exercice = 0;
}
}
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice_my = $scope.themes[$scope.current_theme].exercices[$rootScope.current_exercice].id;
2016-01-21 00:38:43 +00:00
2016-12-09 10:55:58 +00:00
$scope.hsubmit = function(hint) {
hint.submitted = true;
2018-05-13 12:15:53 +00:00
$http({ url: "/openhint/" + $rootScope.current_exercice_my, method: "POST", data: { id: hint.id } }).then(function(response, status, header, config) {
2016-12-09 10:55:58 +00:00
var checkDiffHint = function() {
2017-12-14 02:20:38 +00:00
$http.get("/my.json").then(function(response) {
var my = response.data;
2018-05-13 12:15:53 +00:00
angular.forEach(my.exercices[$rootScope.current_exercice_my].hints, function(h,hid){
2016-12-09 10:55:58 +00:00
if (hint.id == h.id) {
if (hint.content != h.content) {
$rootScope.refresh();
} else {
$timeout.cancel($scope.cbh);
$scope.cbh = $timeout(checkDiffHint, 750);
}
}
});
});
};
checkDiffHint();
2017-12-14 02:20:38 +00:00
}, function(response, status, header, config) {
2016-12-09 10:55:58 +00:00
hint.submitted = false;
2017-12-14 02:20:38 +00:00
console.error(response.data.errmsg);
2016-12-09 10:55:58 +00:00
});
};
2016-01-23 11:29:19 +00:00
})
.controller("SubmissionController", function($scope, $http, $rootScope, $timeout) {
2016-12-04 18:08:46 +00:00
$scope.flags = [];
2016-01-24 13:32:46 +00:00
$rootScope.sberr = "";
2016-01-23 11:29:19 +00:00
var waitMy = function() {
2018-05-13 12:15:53 +00:00
if (!$scope.my || !$scope.my.exercices || !$scope.my.exercices[$rootScope.current_exercice_my]) {
2016-01-25 02:09:22 +00:00
$timeout.cancel($scope.cbs);
$scope.cbs = $timeout(waitMy, 420);
2016-01-23 11:29:19 +00:00
} else {
2016-12-04 18:08:46 +00:00
$scope.flags = [];
2018-05-13 12:15:53 +00:00
angular.forEach($scope.my.exercices[$rootScope.current_exercice_my].keys, function(key,kid) {
2016-12-04 18:08:46 +00:00
var o = {
2016-01-23 11:29:19 +00:00
id: kid,
name: key,
value: ""
2016-12-04 18:08:46 +00:00
};
2018-05-13 12:15:53 +00:00
if ($scope.my.exercices[$rootScope.current_exercice_my].solved_matrix != null)
o.found = $scope.my.exercices[$rootScope.current_exercice_my].solved_matrix[kid];
2016-12-04 18:08:46 +00:00
this.push(o);
2016-01-23 11:29:19 +00:00
}, $scope.flags);
2017-12-16 01:12:44 +00:00
$scope.mcqs = [];
2018-05-13 12:15:53 +00:00
angular.forEach($scope.my.exercices[$rootScope.current_exercice_my].mcqs, function(mcq,qid) {
2017-12-16 01:12:44 +00:00
var o = {
title: mcq.title,
kind: mcq.kind,
solved: mcq.solved,
choices: {}
};
angular.forEach(mcq["choices"], function(choice,cid) {
this[cid] = {
label: choice,
value: false
};
}, o["choices"]);
this.push(o);
}, $scope.mcqs);
2016-01-21 00:38:43 +00:00
}
2016-01-23 11:29:19 +00:00
}
waitMy();
$scope.ssubmit = function() {
2017-12-16 01:12:44 +00:00
var resp = {}
2016-01-23 11:29:19 +00:00
2017-12-16 01:12:44 +00:00
if ($scope.flags && $scope.flags.length)
{
resp["flags"] = {};
angular.forEach($scope.flags, function(flag,kid) {
resp["flags"][flag.name] = flag.value;
});
}
if ($scope.mcqs && $scope.mcqs.length)
{
resp["mcqs"] = {};
angular.forEach($scope.mcqs, function(mcq) {
angular.forEach(mcq.choices, function(choice, cid) {
if (choice.value) resp["mcqs"][cid] = choice.value;
})
});
}
2016-01-23 11:29:19 +00:00
2018-05-13 12:15:53 +00:00
$http({ url: "/submit/" + $rootScope.current_exercice_my, method: "POST", data: resp }).then(function(response, status, header, config) {
2016-01-24 13:32:46 +00:00
$rootScope.messageClass = {"text-success": true};
2017-12-14 02:20:38 +00:00
$rootScope.message = response.data.errmsg;
2016-01-24 13:32:46 +00:00
$rootScope.sberr = "";
angular.forEach($scope.flags, function(flag,kid) {
flag.value = "";
});
2016-01-21 00:38:43 +00:00
2016-01-23 11:29:19 +00:00
var checkDiff = function() {
2017-12-14 02:20:38 +00:00
$http.get("/my.json").then(function(response) {
var my = response.data;
2018-05-13 12:15:53 +00:00
if ($scope.my.exercices[$rootScope.current_exercice_my].tries != my.exercices[$rootScope.current_exercice_my].tries || $scope.my.exercices[$rootScope.current_exercice_my].solved_time != my.exercices[$rootScope.current_exercice_my].solved_time) {
$rootScope.refresh();
$scope.my = my;
2016-12-08 11:02:06 +00:00
waitMy();
2016-01-21 00:38:43 +00:00
} else {
2016-01-25 02:09:22 +00:00
$timeout.cancel($scope.cbd);
$scope.cbd = $timeout(checkDiff, 750);
2016-01-21 00:38:43 +00:00
}
});
};
checkDiff();
2017-12-14 02:20:38 +00:00
}, function(response, status, header, config) {
2016-01-21 00:38:43 +00:00
if (status >= 500) {
2018-05-13 12:15:53 +00:00
$scope.my.exercices[$rootScope.current_exercice_my].submitted = false;
2016-01-21 00:38:43 +00:00
}
2016-01-24 13:32:46 +00:00
$rootScope.messageClass = {"text-danger": true};
2017-12-14 02:20:38 +00:00
$rootScope.message = response.data.errmsg;
2016-01-24 13:32:46 +00:00
if (status != 402) {
$rootScope.sberr = "Une erreur est survenue lors de l'envoi. Veuillez réessayer dans quelques instants.";
}
2016-01-21 00:38:43 +00:00
});
2018-05-13 12:15:53 +00:00
$scope.my.exercices[$rootScope.current_exercice_my].submitted = true;
2016-01-21 00:38:43 +00:00
};
2016-01-16 21:40:59 +00:00
})
2016-01-24 13:23:04 +00:00
.controller("MyTeamController", function($scope, $http, $rootScope, $timeout) {
2016-01-16 21:40:59 +00:00
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice_my = 0;
2016-01-24 13:23:04 +00:00
if ($scope.my) {
$rootScope.title = $scope.my.name;
$rootScope.authors = $scope.my.members.map(function (cur) {
return cur.firstname.capitalize() + " " + cur.lastname.capitalize();
}).join(", ");
}
$scope.newName = "";
$rootScope.message = "";
$rootScope.sberr = "";
$scope.tsubmit = function() {
$rootScope.sberr = "";
if ($scope.newName.length < 1) {
$rootScope.messageClass = {"text-danger": true};
$rootScope.sberr = "Nom d'équipe invalide: pas d'entrée.";
return false;
}
else if ($scope.newName.length > 32) {
$rootScope.messageClass = {"text-danger": true};
$rootScope.sberr = "Nom d'équipe invalide: pas plus de 32 caractères.";
return false;
}
else if (!$scope.newName.match(/^[A-Za-z0-9 àéèêëîïôùûü_-]+$/)) {
$rootScope.messageClass = {"text-danger": true};
$rootScope.sberr = "Nom d'équipe invalide: seuls les caractères alpha-numériques sont autorisés.";
return false;
}
$http({
url: "/submit/name",
method: "POST",
data: {newName: $scope.newName}
2017-12-14 02:20:38 +00:00
}).then(function(response, status, header, config) {
2016-01-24 13:23:04 +00:00
$rootScope.messageClass = {"text-success": true};
2017-12-14 02:20:38 +00:00
$rootScope.message = response.data.errmsg;
2016-01-24 13:23:04 +00:00
var checkDiff = function() {
2017-12-14 02:20:38 +00:00
$http.get("/my.json").then(function(response) {
if ($scope.my.name != response.data.name) {
2016-01-24 13:23:04 +00:00
$scope.newName = "";
$rootScope.message = "";
$rootScope.refresh();
} else {
2016-01-25 02:09:22 +00:00
$timeout.cancel($scope.cbt);
$scope.cbt = $timeout(checkDiff, 750);
2016-01-24 13:23:04 +00:00
}
});
};
checkDiff();
2017-12-14 02:20:38 +00:00
}, function(response, status, header, config) {
2016-01-24 13:23:04 +00:00
$rootScope.messageClass = {"text-danger": true};
2017-12-14 02:20:38 +00:00
$rootScope.message = response.data.errmsg;
2016-01-24 13:23:04 +00:00
if (status != 402) {
$rootScope.sberr = "Une erreur est survenue lors de l'envoi. Veuillez réessayer dans quelques instants.";
}
});
};
2016-01-16 21:40:59 +00:00
})
2017-12-21 21:18:18 +00:00
.controller("RegisterController", function($scope, $rootScope, $location, $http) {
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice_my = 0;
2017-12-21 21:18:18 +00:00
$rootScope.title = "Bienvenue au challenge forensic !";
$rootScope.authors = null;
$scope.members = [{}];
$scope.AddMember = function() {
$scope.members.push({});
}
$scope.RemoveMember = function(k) {
$scope.members.splice(k, 1);
}
$scope.Validate = function() {
if ($scope.teamName.length <= 3) {
$('#teamName').addClass("is-invalid")
return;
} else {
$('#vldBtn').removeClass("input-group-btn");
$('#vldBtn').css("display", "none");
$scope.part2 = true;
}
}
$scope.rsubmit = function() {
if (!$scope.part2)
return $scope.Validate();
// Remove empty members
$scope.members = $scope.members.filter(function(m) {
return ((m.lastname != undefined && m.lastname != "") || (m.firstname != undefined && m.firstname != "") || (m.nickname != undefined && m.nickname != ""));
});
if ($scope.members.length == 0) {
$scope.messageClass = {"text-danger": true};
$scope.message = "Veuillez ajouter au moins un membre dans votre équipe !";
$scope.members.push({});
return;
}
$http({
url: "/registration",
method: "POST",
data: {
teamName: $scope.teamName,
members: $scope.members,
}
}).then(function(response, status, header, config) {
$scope.messageClass = {"text-success": true};
$scope.message = response.data.errmsg;
$rootScope.refresh();
if ($scope.my)
$location.url("/");
}, function(response) {
$scope.messageClass = {"text-danger": true};
console.log(response);
if (response.data && response.data.errmsg)
$scope.message = response.data.errmsg;
else
$scope.message = "Une erreur est survenue lors de l'inscription de l'équipe. Veuillez réessayer dans quelques instants.";
});
}
if ($scope.my) {
$location.url("/");
}
})
2016-01-21 00:38:43 +00:00
.controller("RankController", function($scope, $rootScope) {
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice_my = 0;
2016-01-21 00:38:43 +00:00
$rootScope.title = "Classement général";
2016-01-24 13:32:46 +00:00
$rootScope.authors = "";
2016-01-21 00:38:43 +00:00
$scope.fields = ["rank", "name", "score"];
$scope.rankOrder = "rank";
$scope.reverse = false;
$scope.order = function(fld) {
if ($scope.rankOrder == fld) {
$scope.reverse = !$scope.reverse;
} else {
$scope.rankOrder = fld;
2017-01-14 14:01:18 +00:00
$scope.reverse = (fld == "score");
2016-01-21 00:38:43 +00:00
}
};
})
2017-04-02 18:29:15 +00:00
.controller("VideosController", function($scope, $rootScope) {
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice_my = 0;
2017-04-02 18:29:15 +00:00
$rootScope.title = "Vidéos de résolution";
$rootScope.authors = "";
})
2016-01-16 21:40:59 +00:00
.controller("HomeController", function($scope, $rootScope) {
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;
2018-05-13 12:15:53 +00:00
$rootScope.current_exercice_my = 0;
2016-01-16 21:40:59 +00:00
$rootScope.title = "";
2016-01-24 13:32:46 +00:00
$rootScope.authors = "";
2016-01-16 21:40:59 +00:00
});
2016-01-21 00:38:43 +00:00
function sready() {
if ($("#solution").val().length) {
$("#sbmt").removeClass("disabled");
} else {
$("#sbmt").addClass("disabled");
}
};