Partial resolution of exercices

This commit is contained in:
nemunaire 2016-12-04 19:08:46 +01:00
parent 25bf34e82c
commit e76d055bdb
8 changed files with 46 additions and 24 deletions

View File

@ -47,6 +47,7 @@ func main() {
flag.StringVar(&TeamsDir, "teams", "../TEAMS", "Base directory where save teams JSON files") flag.StringVar(&TeamsDir, "teams", "../TEAMS", "Base directory where save teams JSON files")
flag.StringVar(&fic.FilesDir, "files", "/files", "Request path prefix to reach files") flag.StringVar(&fic.FilesDir, "files", "/files", "Request path prefix to reach files")
var skipFullGeneration = flag.Bool("skipFullGeneration", false, "Skip initial full generation (safe to skip after start)") var skipFullGeneration = flag.Bool("skipFullGeneration", false, "Skip initial full generation (safe to skip after start)")
flag.BoolVar(&fic.PartialValidation, "partialValidation", false, "Validates flags which are corrects, don't be binary")
flag.BoolVar(&fic.UnlockedChallenges, "unlockedChallenges", false, "Make all challenges accessible without having to validate previous level") flag.BoolVar(&fic.UnlockedChallenges, "unlockedChallenges", false, "Make all challenges accessible without having to validate previous level")
flag.Parse() flag.Parse()

View File

@ -197,7 +197,7 @@ angular.module("FICApp")
}) })
.controller("SubmissionController", function($scope, $http, $rootScope, $timeout) { .controller("SubmissionController", function($scope, $http, $rootScope, $timeout) {
$scope.flags = [] $scope.flags = [];
$rootScope.sberr = ""; $rootScope.sberr = "";
var waitMy = function() { var waitMy = function() {
@ -205,12 +205,16 @@ angular.module("FICApp")
$timeout.cancel($scope.cbs); $timeout.cancel($scope.cbs);
$scope.cbs = $timeout(waitMy, 420); $scope.cbs = $timeout(waitMy, 420);
} else { } else {
$scope.flags = [];
angular.forEach($scope.my.exercices[$rootScope.current_exercice].keys, function(key,kid) { angular.forEach($scope.my.exercices[$rootScope.current_exercice].keys, function(key,kid) {
this.push({ var o = {
id: kid, id: kid,
name: key, name: key,
value: "" value: ""
}); };
if ($scope.my.exercices[$rootScope.current_exercice].solved_matrix != null)
o.found = $scope.my.exercices[$rootScope.current_exercice].solved_matrix[kid];
this.push(o);
}, $scope.flags); }, $scope.flags);
} }
} }
@ -219,23 +223,10 @@ angular.module("FICApp")
$scope.ssubmit = function() { $scope.ssubmit = function() {
var flgs = {} var flgs = {}
var filled = true;
angular.forEach($scope.flags, function(flag,kid) { angular.forEach($scope.flags, function(flag,kid) {
flgs[flag.name] = flag.value; flgs[flag.name] = flag.value;
filled = filled && flag.value.length > 0;
}); });
if (!filled) {
$rootScope.messageClass = {"text-danger": true};
$rootScope.sberr = "Tous les champs sont obligatoires.";
$timeout(function() {
if ($rootScope.sberr == "Tous les champs sont obligatoires.") {
$rootScope.sberr = "";
}
}, 2345);
return;
}
$http({ $http({
url: "/submit/" + $rootScope.current_exercice, url: "/submit/" + $rootScope.current_exercice,
method: "POST", method: "POST",

View File

@ -52,9 +52,10 @@
</ul> </ul>
<div class="panel-body" ng-show="!my.exercices[current_exercice].submitted || sberr"> <div class="panel-body" ng-show="!my.exercices[current_exercice].submitted || sberr">
<form ng-controller="SubmissionController" ng-submit="ssubmit()"> <form ng-controller="SubmissionController" ng-submit="ssubmit()">
<div class="form-group" ng-repeat="key in flags"> <div class="form-group" ng-repeat="key in flags" ng-class="{'has-success': key.found, 'has-feedback': key.found}">
<label for="sol_{{ key.id }}">{{ key.name }} :</label> <label for="sol_{{ key.id }}">{{ key.name }} :</label>
<input type="text" class="form-control" id="sol_{{ key.id }}" name="sol_{{ index }}" ng-model="key.value"> <input type="text" class="form-control" id="sol_{{ key.id }}" name="sol_{{ index }}" ng-model="key.value" ng-disabled="key.found">
<span class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true" ng-show="key.found"></span>
</div> </div>
<div class="form-group text-right"> <div class="form-group text-right">
<button type="submit" class="btn btn-danger" id="sbmt">Soumettre</button> <button type="submit" class="btn btn-danger" id="sbmt">Soumettre</button>

View File

@ -107,6 +107,17 @@ CREATE TABLE IF NOT EXISTS exercice_keys(
value BINARY(64) NOT NULL, value BINARY(64) NOT NULL,
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice) FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
); );
`); err != nil {
return err
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS key_found(
id_key INTEGER NOT NULL,
id_team INTEGER NOT NULL,
time TIMESTAMP NOT NULL,
FOREIGN KEY(id_key) REFERENCES exercice_keys(id_key),
FOREIGN KEY(id_team) REFERENCES teams(id_team)
);
`); err != nil { `); err != nil {
return err return err
} }

View File

@ -5,6 +5,8 @@ import (
"time" "time"
) )
var PartialValidation bool
type Exercice struct { type Exercice struct {
Id int64 `json:"id"` Id int64 `json:"id"`
Title string `json:"title"` Title string `json:"title"`
@ -201,13 +203,14 @@ func (e Exercice) CheckResponse(resps map[string]string, t Team) (bool, error) {
valid := true valid := true
for _, key := range keys { for _, key := range keys {
if _, ok := resps[key.Type]; !ok { if res, ok := resps[key.Type]; !ok {
valid = false valid = false
break } else if !key.Check(res) {
} if !PartialValidation || t.HasPartiallySolved(key) == nil {
if !key.Check(resps[key.Type]) { valid = false
valid = false }
break } else {
key.FoundBy(t)
} }
} }

View File

@ -2,6 +2,7 @@ package fic
import ( import (
"crypto/sha512" "crypto/sha512"
"time"
) )
type Key struct { type Key struct {
@ -88,3 +89,7 @@ func (k Key) Check(val string) bool {
return true return true
} }
func (k Key) FoundBy(t Team) {
DBExec("INSERT INTO key_found (id_key, id_team, time) VALUES (?, ?, ?)", k.Id, t.Id, time.Now())
}

View File

@ -244,6 +244,12 @@ func IsSolved(e Exercice) (int, time.Time) {
} }
} }
func (t Team) HasPartiallySolved(k Key) (*time.Time) {
var tm *time.Time
DBQueryRow("SELECT MIN(time) FROM key_found WHERE id_team = ? AND id_key = ?", t.Id, k.Id).Scan(&tm)
return tm
}
type statLine struct { type statLine struct {
Tip string `json:"tip"` Tip string `json:"tip"`
Total int `json:"total"` Total int `json:"total"`

View File

@ -28,6 +28,7 @@ type myTeamExercice struct {
Files []myTeamFile `json:"files"` Files []myTeamFile `json:"files"`
Keys []string `json:"keys"` Keys []string `json:"keys"`
Solved bool `json:"solved"` Solved bool `json:"solved"`
SolvedMat []bool `json:"solved_matrix"`
SolvedTime time.Time `json:"solved_time"` SolvedTime time.Time `json:"solved_time"`
SolvedNumber int64 `json:"solved_number"` SolvedNumber int64 `json:"solved_number"`
VideoURI string `json:"video_uri"` VideoURI string `json:"video_uri"`
@ -116,6 +117,9 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
exercice.Keys = append(exercice.Keys, fmt.Sprintf("%x", k.Value)+k.Type) exercice.Keys = append(exercice.Keys, fmt.Sprintf("%x", k.Value)+k.Type)
} else { } else {
exercice.Keys = append(exercice.Keys, k.Type) exercice.Keys = append(exercice.Keys, k.Type)
if PartialValidation {
exercice.SolvedMat = append(exercice.SolvedMat, t.HasPartiallySolved(k) != nil)
}
} }
} }
} }