Utilise a new field to send justifications instead of too complex guessing crap

This commit is contained in:
nemunaire 2018-11-28 07:39:50 +01:00
parent 69a866bbbf
commit d40922629b
6 changed files with 69 additions and 24 deletions

View file

@ -19,6 +19,7 @@ import (
type ResponsesUpload struct { type ResponsesUpload struct {
Keys map[int64]string `json:"flags"` Keys map[int64]string `json:"flags"`
MCQs map[int64]bool `json:"mcqs"` MCQs map[int64]bool `json:"mcqs"`
MCQJ map[int64]string `json:"justifications"`
} }
func treatSubmission(pathname string, team fic.Team, exercice_id string) { func treatSubmission(pathname string, team fic.Team, exercice_id string) {
@ -78,6 +79,25 @@ func treatSubmission(pathname string, team fic.Team, exercice_id string) {
return return
} }
// Handle MCQ justifications: convert to expected keyid
for cid, j := range responses.MCQJ {
if mcq, choice, err := fic.GetMCQbyChoice(cid); err != nil {
log.Println(id, "[ERR] Unable to retrieve mcq from justification:", err)
return
} else if mcq.IdExercice != exercice.Id {
log.Println(id, "[ERR] We retrieve an invalid MCQ: from exercice", mcq.IdExercice, "whereas expected from exercice", exercice.Id)
return
} else if key, err := mcq.GetJustifiedFlag(exercice, choice); err != nil {
log.Println(id, "[ERR] Unable to retrieve mcq justification flag:", err)
return
} else {
if responses.Keys == nil {
responses.Keys = map[int64]string{}
}
responses.Keys[key.Id] = j
}
}
// Check given answers // Check given answers
solved, err := exercice.CheckResponse(cksum[:], responses.Keys, responses.MCQs, team) solved, err := exercice.CheckResponse(cksum[:], responses.Keys, responses.MCQs, team)
if err != nil { if err != nil {

View file

@ -268,11 +268,12 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
}); });
$scope.ssubmit = function() { $scope.ssubmit = function() {
var resp = {"flags":{}} var resp = {}
var check = undefined var check = undefined
if ($scope.my.exercices[$rootScope.current_exercice].flags && Object.keys($scope.my.exercices[$rootScope.current_exercice].flags).length) if ($scope.my.exercices[$rootScope.current_exercice].flags && Object.keys($scope.my.exercices[$rootScope.current_exercice].flags).length)
{ {
resp["flags"] = {};
angular.forEach($scope.my.exercices[$rootScope.current_exercice].flags, function(flag,kid) { angular.forEach($scope.my.exercices[$rootScope.current_exercice].flags, function(flag,kid) {
if (flag.found == null) { if (flag.found == null) {
if (flag.soluce !== undefined) { if (flag.soluce !== undefined) {
@ -293,7 +294,6 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
var soluce = ""; var soluce = "";
resp["mcqs"] = {}; resp["mcqs"] = {};
angular.forEach($scope.my.exercices[$rootScope.current_exercice].mcqs, function(mcq) { angular.forEach($scope.my.exercices[$rootScope.current_exercice].mcqs, function(mcq) {
var nid = 0;
if (mcq.solved == null) { if (mcq.solved == null) {
angular.forEach(mcq.choices, function(choice, cid) { angular.forEach(mcq.choices, function(choice, cid) {
if (mcq.soluce !== undefined) { if (mcq.soluce !== undefined) {
@ -304,10 +304,10 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
if (choice.value) { if (choice.value) {
resp["mcqs"][cid] = choice.value; resp["mcqs"][cid] = choice.value;
if (mcq.justify !== undefined) { if (mcq.justify !== undefined) {
if (resp["justifications"] == undefined)
resp["justifications"] = {};
if (choice.justify) if (choice.justify)
resp["flags"][mcq.justify[nid++]] = choice.justify; resp["justifications"][cid] = choice.justify;
else if (!choice.solved)
nid++;
} }
} }
} }

View file

@ -94,7 +94,7 @@
<div class="custom-control custom-checkbox" ng-repeat="(cid,choice) in mcq.choices" ng-if="!mcq.solved"> <div class="custom-control custom-checkbox" ng-repeat="(cid,choice) in mcq.choices" ng-if="!mcq.solved">
<input class="custom-control-input" type="checkbox" id="mcq_{{k}}_{{cid}}" name="mcq_{{k}}_{{cid}}" ng-model="choice.value" ng-disabled="choice.disabled"> <input class="custom-control-input" type="checkbox" id="mcq_{{k}}_{{cid}}" name="mcq_{{k}}_{{cid}}" ng-model="choice.value" ng-disabled="choice.disabled">
<label class="custom-control-label" for="mcq_{{k}}_{{cid}}" ng-bind="choice.label"></label> <label class="custom-control-label" for="mcq_{{k}}_{{cid}}" ng-bind="choice.label"></label>
<input type="text" class="form-control" autocomplete="off" placeholder="Flag correspondant" name="sol_{{ cid }}" ng-model="choice.justify" ng-if="choice.value && mcq.justify.length && !choice.solved"> <input type="text" class="form-control" autocomplete="off" placeholder="Flag correspondant" name="sol_{{ cid }}" ng-model="choice.justify" ng-if="choice.value && mcq.justify && !choice.solved">
<span class="glyphicon glyphicon-ok form-control-feedback text-success" aria-hidden="true" ng-if="choice.solved" title="Flag trouvé !"></span> <span class="glyphicon glyphicon-ok form-control-feedback text-success" aria-hidden="true" ng-if="choice.solved" title="Flag trouvé !"></span>
</div> </div>
<hr> <hr>

View file

@ -52,6 +52,12 @@ func (e Exercice) GetFlags() ([]Flag, error) {
} }
} }
// GetFlagByLabel returns a flag matching the given label.
func (e Exercice) GetFlagByLabel(label string) (k Flag, err error) {
err = DBQueryRow("SELECT id_flag, id_exercice, type, help, ignorecase, validator_regexp, cksum FROM exercice_flags WHERE type = ? AND id_exercice = ?", label, e.Id).Scan(&k.Id, &k.IdExercice, &k.Label, &k.Help, &k.IgnoreCase, &k.ValidatorRegexp, &k.Checksum)
return
}
// getHashedFlag calculates the expected checksum for the given raw_value. // getHashedFlag calculates the expected checksum for the given raw_value.
func getHashedFlag(raw_value []byte) [blake2b.Size]byte { func getHashedFlag(raw_value []byte) [blake2b.Size]byte {
hash := blake2b.Sum512(raw_value) hash := blake2b.Sum512(raw_value)

View file

@ -66,6 +66,35 @@ func (e Exercice) GetMCQ() ([]MCQ, error) {
} }
} }
// GetMCQbyChoice returns the MCQ corresponding to a choice ID.
func GetMCQbyChoice(cid int64) (m MCQ, c MCQ_entry, err error) {
if errr := DBQueryRow("SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_mcq = (SELECT id_mcq FROM mcq_entries WHERE id_mcq_entry = ?)", cid).Scan(&m.Id, &m.IdExercice, &m.Title); err != nil {
return MCQ{}, MCQ_entry{}, errr
}
if entries_rows, errr := DBQuery("SELECT id_mcq_entry, label, response FROM mcq_entries WHERE id_mcq = ?", m.Id); err != nil {
return MCQ{}, MCQ_entry{}, errr
} else {
defer entries_rows.Close()
for entries_rows.Next() {
var e MCQ_entry
if err = entries_rows.Scan(&e.Id, &e.Label, &e.Response); err != nil {
return
}
if e.Id == cid {
c = e
}
m.Entries = append(m.Entries, e)
}
}
return
}
// AddMCQ creates and fills a new struct MCQ and registers it into the database. // AddMCQ creates and fills a new struct MCQ and registers it into the database.
func (e Exercice) AddMCQ(title string) (MCQ, error) { func (e Exercice) AddMCQ(title string) (MCQ, error) {
if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, title) VALUES (?, ?)", e.Id, title); err != nil { if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, title) VALUES (?, ?)", e.Id, title); err != nil {
@ -145,6 +174,11 @@ func (e Exercice) WipeMCQs() (int64, error) {
} }
} }
// GetJustifiedFlag searchs for a flag in the scope of the given exercice.
func (m MCQ) GetJustifiedFlag(e Exercice, c MCQ_entry) (Flag, error) {
return e.GetFlagByLabel("%" + m.Title + "%" + c.Label)
}
// Check if the given vals are the expected ones to validate this flag. // Check if the given vals are the expected ones to validate this flag.
func (m MCQ) Check(vals map[int64]bool) int { func (m MCQ) Check(vals map[int64]bool) int {
diff := 0 diff := 0

View file

@ -23,7 +23,7 @@ type myTeamHint struct {
} }
type myTeamMCQ struct { type myTeamMCQ struct {
Title string `json:"title"` Title string `json:"title"`
Justify []int64 `json:"justify,omitempty"` Justify bool `json:"justify,omitempty"`
Choices map[int64]string `json:"choices,omitempty"` Choices map[int64]string `json:"choices,omitempty"`
Solved *time.Time `json:"solved,omitempty"` Solved *time.Time `json:"solved,omitempty"`
PSolved map[int64]int `json:"checks_solved,omitempty"` PSolved map[int64]int `json:"checks_solved,omitempty"`
@ -211,8 +211,6 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
soluce := "" soluce := ""
solved_justify := true solved_justify := true
var nb_gen_justify_id int64
var max_justify_id int64
for _, e := range mcq.Entries { for _, e := range mcq.Entries {
m.Choices[e.Id] = e.Label m.Choices[e.Id] = e.Label
@ -222,29 +220,16 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
soluce += "f" soluce += "f"
} }
if v, ok := justifiedMCQ[m.Title + "%" + e.Label]; ok { if v, ok := justifiedMCQ[m.Title + "%" + e.Label]; ok {
if m.Justify == nil { m.Justify = true
m.Justify = []int64{}
}
if t == nil { if t == nil {
soluce += hex.EncodeToString(v) soluce += hex.EncodeToString(v)
} }
if v, ok := justifiedMCQ_ids[m.Title + "%" + e.Label]; ok { if _, ok := justifiedMCQ_ids[m.Title + "%" + e.Label]; ok {
solved_justify = false solved_justify = false
m.Justify = append(m.Justify, v)
if v > max_justify_id {
max_justify_id = v
} }
} }
} else {
nb_gen_justify_id += 1
}
}
// Fill the rest of the array with factice values in order to hide number of valid choices
for i := int64(0); i < nb_gen_justify_id; i++ {
m.Justify = append(m.Justify, max_justify_id + 1 + i)
} }
if t != nil { if t != nil {