Rename Exercice's Keys as Flags
This commit is contained in:
parent
f36e1c4e4d
commit
d21f3b0b83
18 changed files with 252 additions and 252 deletions
|
|
@ -30,11 +30,11 @@ func init() {
|
|||
router.PUT("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(updateExerciceHint)))
|
||||
router.DELETE("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(deleteExerciceHint)))
|
||||
|
||||
router.GET("/api/exercices/:eid/keys", apiHandler(exerciceHandler(listExerciceKeys)))
|
||||
router.POST("/api/exercices/:eid/keys", apiHandler(exerciceHandler(createExerciceKey)))
|
||||
router.GET("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(showExerciceKey)))
|
||||
router.PUT("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(updateExerciceKey)))
|
||||
router.DELETE("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(deleteExerciceKey)))
|
||||
router.GET("/api/exercices/:eid/flags", apiHandler(exerciceHandler(listExerciceFlags)))
|
||||
router.POST("/api/exercices/:eid/flags", apiHandler(exerciceHandler(createExerciceFlag)))
|
||||
router.GET("/api/exercices/:eid/flags/:kid", apiHandler(flagHandler(showExerciceFlag)))
|
||||
router.PUT("/api/exercices/:eid/flags/:kid", apiHandler(flagHandler(updateExerciceFlag)))
|
||||
router.DELETE("/api/exercices/:eid/flags/:kid", apiHandler(flagHandler(deleteExerciceFlag)))
|
||||
|
||||
router.GET("/api/exercices/:eid/quiz", apiHandler(exerciceHandler(listExerciceQuiz)))
|
||||
router.GET("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(showExerciceQuiz)))
|
||||
|
|
@ -50,9 +50,9 @@ func init() {
|
|||
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
|
||||
return sync.SyncExerciceHints(sync.GlobalImporter, exercice), nil
|
||||
})))
|
||||
router.POST("/api/sync/exercices/:eid/keys", apiHandler(exerciceHandler(
|
||||
router.POST("/api/sync/exercices/:eid/flags", apiHandler(exerciceHandler(
|
||||
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
|
||||
return sync.SyncExerciceKeys(sync.GlobalImporter, exercice), nil
|
||||
return sync.SyncExerciceFlags(sync.GlobalImporter, exercice), nil
|
||||
})))
|
||||
|
||||
router.POST("/api/sync/exercices/:eid/fixurlid", apiHandler(exerciceHandler(
|
||||
|
|
@ -77,8 +77,8 @@ func listExerciceHints(exercice fic.Exercice, body []byte) (interface{}, error)
|
|||
return exercice.GetHints()
|
||||
}
|
||||
|
||||
func listExerciceKeys(exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||
return exercice.GetKeys()
|
||||
func listExerciceFlags(exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||
return exercice.GetFlags()
|
||||
}
|
||||
|
||||
func listExerciceQuiz(exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||
|
|
@ -188,56 +188,56 @@ func deleteExerciceHint(hint fic.EHint, _ []byte) (interface{}, error) {
|
|||
return hint.Delete()
|
||||
}
|
||||
|
||||
type uploadedKey struct {
|
||||
type uploadedFlag struct {
|
||||
Label string
|
||||
Help string
|
||||
ICase bool
|
||||
Key string
|
||||
Flag string
|
||||
Hash []byte
|
||||
}
|
||||
|
||||
func createExerciceKey(exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||
var uk uploadedKey
|
||||
func createExerciceFlag(exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||
var uk uploadedFlag
|
||||
if err := json.Unmarshal(body, &uk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(uk.Key) == 0 {
|
||||
return nil, errors.New("Key not filled")
|
||||
if len(uk.Flag) == 0 {
|
||||
return nil, errors.New("Flag not filled")
|
||||
}
|
||||
|
||||
return exercice.AddRawKey(uk.Label, uk.Help, uk.ICase, uk.Key)
|
||||
return exercice.AddRawFlag(uk.Label, uk.Help, uk.ICase, uk.Flag)
|
||||
}
|
||||
|
||||
func showExerciceKey(key fic.Key, _ fic.Exercice, body []byte) (interface{}, error) {
|
||||
return key, nil
|
||||
func showExerciceFlag(flag fic.Flag, _ fic.Exercice, body []byte) (interface{}, error) {
|
||||
return flag, nil
|
||||
}
|
||||
|
||||
func updateExerciceKey(key fic.Key, exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||
var uk uploadedKey
|
||||
func updateExerciceFlag(flag fic.Flag, exercice fic.Exercice, body []byte) (interface{}, error) {
|
||||
var uk uploadedFlag
|
||||
if err := json.Unmarshal(body, &uk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(uk.Label) == 0 {
|
||||
key.Label = "Flag"
|
||||
flag.Label = "Flag"
|
||||
} else {
|
||||
key.Label = uk.Label
|
||||
flag.Label = uk.Label
|
||||
}
|
||||
|
||||
key.Help = uk.Help
|
||||
key.IgnoreCase = uk.ICase
|
||||
key.Checksum = uk.Hash
|
||||
flag.Help = uk.Help
|
||||
flag.IgnoreCase = uk.ICase
|
||||
flag.Checksum = uk.Hash
|
||||
|
||||
if _, err := key.Update(); err != nil {
|
||||
if _, err := flag.Update(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return key, nil
|
||||
return flag, nil
|
||||
}
|
||||
|
||||
func deleteExerciceKey(key fic.Key, _ fic.Exercice, _ []byte) (interface{}, error) {
|
||||
return key.Delete()
|
||||
func deleteExerciceFlag(flag fic.Flag, _ fic.Exercice, _ []byte) (interface{}, error) {
|
||||
return flag.Delete()
|
||||
}
|
||||
|
||||
func showExerciceQuiz(quiz fic.MCQ, _ fic.Exercice, body []byte) (interface{}, error) {
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ func hintHandler(f func(fic.EHint, []byte) (interface{}, error)) func(httprouter
|
|||
}
|
||||
}
|
||||
|
||||
func keyHandler(f func(fic.Key, fic.Exercice, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
|
||||
func flagHandler(f func(fic.Flag, fic.Exercice, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
|
||||
return func(ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
var exercice fic.Exercice
|
||||
exerciceHandler(func(ex fic.Exercice, _ []byte) (interface{}, error) {
|
||||
|
|
@ -175,12 +175,12 @@ func keyHandler(f func(fic.Key, fic.Exercice, []byte) (interface{}, error)) func
|
|||
|
||||
if kid, err := strconv.Atoi(string(ps.ByName("kid"))); err != nil {
|
||||
return nil, err
|
||||
} else if keys, err := exercice.GetKeys(); err != nil {
|
||||
} else if flags, err := exercice.GetFlags(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
for _, key := range keys {
|
||||
if key.Id == int64(kid) {
|
||||
return f(key, exercice, body)
|
||||
for _, flag := range flags {
|
||||
if flag.Id == int64(kid) {
|
||||
return f(flag, exercice, body)
|
||||
}
|
||||
}
|
||||
return nil, errors.New("Unable to find the requested key")
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ func init() {
|
|||
router.GET("/api/themes/:thid/exercices/:eid/hints", apiHandler(exerciceHandler(listExerciceHints)))
|
||||
router.POST("/api/themes/:thid/exercices/:eid/hints", apiHandler(exerciceHandler(createExerciceHint)))
|
||||
|
||||
router.GET("/api/themes/:thid/exercices/:eid/keys", apiHandler(exerciceHandler(listExerciceKeys)))
|
||||
router.POST("/api/themes/:thid/exercices/:eid/keys", apiHandler(exerciceHandler(createExerciceKey)))
|
||||
router.GET("/api/themes/:thid/exercices/:eid/keys", apiHandler(exerciceHandler(listExerciceFlags)))
|
||||
router.POST("/api/themes/:thid/exercices/:eid/keys", apiHandler(exerciceHandler(createExerciceFlag)))
|
||||
|
||||
// Remote
|
||||
router.GET("/api/remote/themes", apiHandler(sync.ApiListRemoteThemes))
|
||||
|
|
@ -66,7 +66,7 @@ func init() {
|
|||
})))
|
||||
router.POST("/api/sync/themes/:thid/exercices/:eid/keys", apiHandler(exerciceHandler(
|
||||
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
|
||||
return sync.SyncExerciceKeys(sync.GlobalImporter, exercice), nil
|
||||
return sync.SyncExerciceFlags(sync.GlobalImporter, exercice), nil
|
||||
})))
|
||||
|
||||
router.POST("/api/sync/themes/:thid/fixurlid", apiHandler(themeHandler(
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ func init() {
|
|||
}
|
||||
|
||||
func showVersion(_ httprouter.Params, body []byte) (interface{}, error) {
|
||||
return map[string]interface{}{"version": 0.5}, nil
|
||||
return map[string]interface{}{"version": 0.6}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,12 +218,12 @@ angular.module("FICApp")
|
|||
update: {method: 'PUT'}
|
||||
})
|
||||
})
|
||||
.factory("ExerciceKey", function($resource) {
|
||||
return $resource("/api/exercices/:exerciceId/keys/:keyId", { exerciceId: '@idExercice', keyId: '@id' }, {
|
||||
.factory("ExerciceFlag", function($resource) {
|
||||
return $resource("/api/exercices/:exerciceId/flags/:flagId", { exerciceId: '@idExercice', flagId: '@id' }, {
|
||||
update: {method: 'PUT'}
|
||||
})
|
||||
})
|
||||
.factory("ExerciceMCQKey", function($resource) {
|
||||
.factory("ExerciceMCQFlag", function($resource) {
|
||||
return $resource("/api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, {
|
||||
update: {method: 'PUT'}
|
||||
})
|
||||
|
|
@ -995,8 +995,8 @@ angular.module("FICApp")
|
|||
work.push("/api/sync/exercices/" + ex.id + "/files");
|
||||
if ($scope.syncHints)
|
||||
work.push("/api/sync/exercices/" + ex.id + "/hints");
|
||||
if ($scope.syncKeys)
|
||||
work.push("/api/sync/exercices/" + ex.id + "/keys");
|
||||
if ($scope.syncFlags)
|
||||
work.push("/api/sync/exercices/" + ex.id + "/flags");
|
||||
});
|
||||
$scope.total = work.length;
|
||||
go();
|
||||
|
|
@ -1004,7 +1004,7 @@ angular.module("FICApp")
|
|||
};
|
||||
$scope.syncFiles = true;
|
||||
$scope.syncHints = true;
|
||||
$scope.syncKeys = true;
|
||||
$scope.syncFlags = true;
|
||||
})
|
||||
.controller("ExercicesListController", function($scope, ThemedExercice, $routeParams, $location) {
|
||||
$scope.exercices = ThemedExercice.query({ themeId: $routeParams.themeId });
|
||||
|
|
@ -1106,35 +1106,35 @@ angular.module("FICApp")
|
|||
};
|
||||
})
|
||||
|
||||
.controller("ExerciceKeysController", function($scope, ExerciceKey, $routeParams, $rootScope, $http) {
|
||||
$scope.keys = ExerciceKey.query({ exerciceId: $routeParams.exerciceId });
|
||||
.controller("ExerciceFlagsController", function($scope, ExerciceFlag, $routeParams, $rootScope, $http) {
|
||||
$scope.flags = ExerciceFlag.query({ exerciceId: $routeParams.exerciceId });
|
||||
|
||||
$scope.addKey = function() {
|
||||
$scope.keys.push(new ExerciceKey());
|
||||
$scope.addFlag = function() {
|
||||
$scope.flags.push(new ExerciceFlag());
|
||||
}
|
||||
$scope.deleteKey = function() {
|
||||
this.key.$delete(function() {
|
||||
$scope.keys.splice($scope.keys.indexOf(this.key), 1);
|
||||
$scope.deleteFlag = function() {
|
||||
this.flag.$delete(function() {
|
||||
$scope.flags.splice($scope.flags.indexOf(this.flag), 1);
|
||||
}, function(response) {
|
||||
$rootScope.newBox('danger', 'An error occurs when trying to delete flag:', response.data);
|
||||
});
|
||||
}
|
||||
$scope.saveKey = function() {
|
||||
if (this.key.id) {
|
||||
this.key.$update();
|
||||
$scope.saveFlag = function() {
|
||||
if (this.flag.id) {
|
||||
this.flag.$update();
|
||||
} else {
|
||||
this.key.$save({ exerciceId: $routeParams.exerciceId });
|
||||
this.flag.$save({ exerciceId: $routeParams.exerciceId });
|
||||
}
|
||||
}
|
||||
$scope.inSync = false;
|
||||
$scope.syncKeys = function() {
|
||||
$scope.syncFlags = function() {
|
||||
$scope.inSync = true;
|
||||
$http({
|
||||
url: "/api/sync/exercices/" + $routeParams.exerciceId + "/keys",
|
||||
url: "/api/sync/exercices/" + $routeParams.exerciceId + "/flags",
|
||||
method: "POST"
|
||||
}).then(function(response) {
|
||||
$scope.inSync = false;
|
||||
$scope.keys = ExerciceKey.query({ exerciceId: $routeParams.exerciceId });
|
||||
$scope.flags = ExerciceFlag.query({ exerciceId: $routeParams.exerciceId });
|
||||
if (response.data)
|
||||
$rootScope.newBox('danger', response.data);
|
||||
else
|
||||
|
|
@ -1146,11 +1146,11 @@ angular.module("FICApp")
|
|||
};
|
||||
})
|
||||
|
||||
.controller("ExerciceMCQKeysController", function($scope, ExerciceMCQKey, $routeParams, $rootScope, $http) {
|
||||
$scope.quiz = ExerciceMCQKey.query({ exerciceId: $routeParams.exerciceId });
|
||||
.controller("ExerciceMCQFlagsController", function($scope, ExerciceMCQFlag, $routeParams, $rootScope, $http) {
|
||||
$scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId });
|
||||
|
||||
$scope.addQuiz = function() {
|
||||
$scope.quiz.push(new ExerciceMCQKey());
|
||||
$scope.quiz.push(new ExerciceMCQFlag());
|
||||
}
|
||||
$scope.deleteQuiz = function() {
|
||||
this.q.$delete(function() {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
<label class="btn btn-sm btn-secondary" ng-class="{active: syncHints, 'btn-warning': syncHints}" ng-show="whoami">
|
||||
<input type="checkbox" ng-model="syncHints"> Indices
|
||||
</label>
|
||||
<label class="btn btn-sm btn-secondary" ng-class="{active: syncKeys, 'btn-warning': syncKeys}">
|
||||
<input type="checkbox" ng-model="syncKeys"> Flags
|
||||
<label class="btn btn-sm btn-secondary" ng-class="{active: syncFlags, 'btn-warning': syncFlags}">
|
||||
<input type="checkbox" ng-model="syncFlags"> Flags
|
||||
</label>
|
||||
</div>
|
||||
</small>
|
||||
|
|
|
|||
|
|
@ -80,38 +80,38 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4" ng-controller="ExerciceKeysController">
|
||||
<div class="col-md-4" ng-controller="ExerciceFlagsController">
|
||||
<div class="card border-success">
|
||||
<div class="card-header bg-success text-light">
|
||||
<button ng-click="addKey()" class="float-right btn btn-sm btn-primary ml-2"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
|
||||
<button ng-click="syncKeys()" class="float-right btn btn-sm btn-light ml-2"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
|
||||
<button ng-click="addFlag()" class="float-right btn btn-sm btn-primary ml-2"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
|
||||
<button ng-click="syncFlags()" class="float-right btn btn-sm btn-light ml-2"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
|
||||
<h4>Drapeaux</h4>
|
||||
</div>
|
||||
<div class="list-group">
|
||||
<form ng-submit="saveKey()" class="list-group-item form-horizontal bg-light text-dark" ng-repeat="key in keys">
|
||||
<div class="form-group row" id="key-{{key.id}}">
|
||||
<input type="text" id="klabel{{key.id}}" ng-model="key.label" class="col form-control" placeholder="Intitulé">
|
||||
<div class="col-auto" ng-show="key.id">
|
||||
<button ng-click="deleteKey()" class="btn btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
|
||||
<form ng-submit="saveFlag()" class="list-group-item form-horizontal bg-light text-dark" ng-repeat="flag in flags">
|
||||
<div class="form-group row" id="flag-{{flag.id}}">
|
||||
<input type="text" id="klabel{{flag.id}}" ng-model="flag.label" class="col form-control" placeholder="Intitulé">
|
||||
<div class="col-auto" ng-show="flag.id">
|
||||
<button ng-click="deleteFlag()" class="btn btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<input type="text" id="khelp{{key.id}}" ng-model="key.help" class="col form-control" placeholder="Indication de formatage">
|
||||
<input type="text" id="khelp{{flag.id}}" ng-model="flag.help" class="col form-control" placeholder="Indication de formatage">
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row" ng-show="key.id">
|
||||
<input type="text" id="kvalue{{key.id}}" ng-model="key.value" class="col form-control" placeholder="Condensat">
|
||||
<div class="form-group row" ng-show="flag.id">
|
||||
<input type="text" id="kvalue{{flag.id}}" ng-model="flag.value" class="col form-control" placeholder="Condensat">
|
||||
</div>
|
||||
<div class="form-group row" ng-show="!key.id">
|
||||
<input type="text" id="kvalue{{key.id}}" ng-model="key.key" class="col form-control" placeholder="Chaîne à valider">
|
||||
<div class="form-group row" ng-show="!flag.id">
|
||||
<input type="text" id="kvalue{{flag.id}}" ng-model="flag.flag" class="col form-control" placeholder="Chaîne à valider">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-success mt-2" ng-controller="ExerciceMCQKeysController">
|
||||
<div class="card border-success mt-2" ng-controller="ExerciceMCQFlagsController">
|
||||
<div class="card-header bg-success text-light">
|
||||
<button ng-click="addQuiz()" class="float-right btn btn-sm btn-primary ml-2"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
|
||||
<h4>Quizz</h4>
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ func isFullGraphic(s string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// SyncExerciceKeys reads the content of challenge.txt and import "classic" flags as Key for the given challenge.
|
||||
func SyncExerciceKeys(i Importer, exercice fic.Exercice) (errs []string) {
|
||||
if _, err := exercice.WipeKeys(); err != nil {
|
||||
// SyncExerciceFlags reads the content of challenge.txt and import "classic" flags as Key for the given challenge.
|
||||
func SyncExerciceFlags(i Importer, exercice fic.Exercice) (errs []string) {
|
||||
if _, err := exercice.WipeFlags(); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
} else if _, err := exercice.WipeMCQs(); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
|
|
@ -40,7 +40,7 @@ func SyncExerciceKeys(i Importer, exercice fic.Exercice) (errs []string) {
|
|||
errs = append(errs, fmt.Sprintf("%q: WARNING flag #%d: non-printable characters in flag, is this really expected?", path.Base(exercice.Path), nline + 1))
|
||||
}
|
||||
|
||||
if k, err := exercice.AddRawKey(flag.Label, flag.Help, flag.IgnoreCase, flag.Raw); err != nil {
|
||||
if k, err := exercice.AddRawFlag(flag.Label, flag.Help, flag.IgnoreCase, flag.Raw); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: error flag #%d: %s", path.Base(exercice.Path), nline + 1, err))
|
||||
continue
|
||||
} else {
|
||||
|
|
@ -67,7 +67,7 @@ func SyncExerciceKeys(i Importer, exercice fic.Exercice) (errs []string) {
|
|||
errs = append(errs, fmt.Sprintf("%q: WARNING flag UCQ #%d: non-printable characters in flag, is this really expected?", path.Base(exercice.Path), nline + 1))
|
||||
}
|
||||
|
||||
if k, err := exercice.AddRawKey(flag.Label, flag.Help, flag.IgnoreCase, flag.Raw); err != nil {
|
||||
if k, err := exercice.AddRawFlag(flag.Label, flag.Help, flag.IgnoreCase, flag.Raw); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: error flag UCQ #%d: %s", path.Base(exercice.Path), nline + 1, err))
|
||||
continue
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func SyncDeep(i Importer) (errs map[string][]string) {
|
|||
|
||||
if exercices, err := theme.GetExercices(); err == nil {
|
||||
for _, exercice := range exercices {
|
||||
errs[theme.Name] = append(errs[theme.Name], SyncExerciceKeys(i, exercice)...)
|
||||
errs[theme.Name] = append(errs[theme.Name], SyncExerciceFlags(i, exercice)...)
|
||||
errs[theme.Name] = append(errs[theme.Name], SyncExerciceFiles(i, exercice)...)
|
||||
errs[theme.Name] = append(errs[theme.Name], SyncExerciceHints(i, exercice)...)
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue