From a5fd04672b5296e48f54cc3e22af699279c279d3 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 23:49:00 +0100 Subject: [PATCH 1/2] admin: Start compute flag stats --- admin/api/exercice.go | 33 ++++++++++++++++++++++++++ admin/static/js/app.js | 9 +++++++ admin/static/views/exercice-flags.html | 11 ++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/admin/api/exercice.go b/admin/api/exercice.go index cfdb450d..13df73e7 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -62,6 +62,7 @@ func declareExercicesRoutes(router *gin.RouterGroup) { apiFlagsRoutes.POST("/try", tryExerciceFlag) apiFlagsRoutes.DELETE("/", deleteExerciceFlag) apiFlagsRoutes.GET("/dependancies", showExerciceFlagDeps) + apiFlagsRoutes.GET("/statistics", showExerciceFlagStats) apiFlagsRoutes.GET("/choices/", listFlagChoices) apiFlagsChoicesRoutes := apiExercicesRoutes.Group("/choices/:cid") apiFlagsChoicesRoutes.Use(FlagChoiceHandler) @@ -852,6 +853,34 @@ func showExerciceFlagDeps(c *gin.Context) { c.JSON(http.StatusOK, deps) } +func showExerciceFlagStats(c *gin.Context) { + exercice := c.MustGet("exercice").(*fic.Exercice) + flag := c.MustGet("flag-key").(*fic.FlagKey) + + history, err := exercice.GetHistory() + if err != nil { + log.Println("Unable to getExerciceHistory:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving exercice history"}) + return + } + + var completed, tries, nteams int64 + + for _, hline := range history { + if hline["kind"].(string) == "flag_found" { + if *hline["secondary"].(*int) == flag.Id { + completed += 1 + } + } + } + + c.JSON(http.StatusOK, gin.H{ + "completed": completed, + "tries": tries, + "nteams": nteams, + }) +} + func tryExerciceFlag(c *gin.Context) { flag := c.MustGet("flag-key").(*fic.FlagKey) @@ -1048,7 +1077,11 @@ func updateExerciceQuiz(c *gin.Context) { if cur.Id == next.Id { seen = true + log.Println("ici", cur.Label, cur.Response, next.Response) + if cur.Label != next.Label || cur.Response != next.Response { + log.Println("1", cur.Label, cur.Response, next.Response) + cur.Label = next.Label cur.Response = next.Response if _, err := cur.Update(); err != nil { diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 0753bbb0..2fa150f4 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -348,6 +348,9 @@ angular.module("FICApp") .factory("ExerciceFlagDeps", function ($resource) { return $resource("api/exercices/:exerciceId/flags/:flagId/dependancies", { exerciceId: '@idExercice', flagId: '@id' }) }) + .factory("ExerciceFlagStats", function ($resource) { + return $resource("api/exercices/:exerciceId/flags/:flagId/statistics", { exerciceId: '@idExercice', flagId: '@id' }) + }) .factory("ExerciceMCQFlag", function ($resource) { return $resource("api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, { update: { method: 'PUT' } @@ -2345,6 +2348,12 @@ angular.module("FICApp") } }) + .controller("ExerciceFlagStatsController", function ($scope, $routeParams, ExerciceFlagStats) { + $scope.init = function (flag) { + $scope.stats = ExerciceFlagStats.get({ exerciceId: $routeParams.exerciceId, flagId: flag.id }); + } + }) + .controller("ExerciceMCQFlagsController", function ($scope, ExerciceMCQFlag, $routeParams, $rootScope) { $scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId }); diff --git a/admin/static/views/exercice-flags.html b/admin/static/views/exercice-flags.html index 3caf3add..b23556ca 100644 --- a/admin/static/views/exercice-flags.html +++ b/admin/static/views/exercice-flags.html @@ -73,12 +73,21 @@
- Dépendances : + Dépendances :
sans
+
+
+ Statistiques +
    +
  • Validés : {{ stats["completed"] }}
  • +
  • Tentés : {{ stats["tries"] }}
  • +
  • Équipes : {{ stats["nteams"] }}
  • +
+