server/admin/sync/exercice_defines.go

129 lines
4.0 KiB
Go

package sync
import (
"fmt"
"path"
"github.com/BurntSushi/toml"
"srs.epita.fr/fic-server/libfic"
)
// ExerciceHintParams holds EHint definition infomation.
type ExerciceHintParams struct {
Filename string
Content string
Cost *int64
Title string
NeedFlag []ExerciceDependency `toml:"need_flag,omitempty"`
}
// ExerciceDependency holds dependency definitions information.
type ExerciceDependency struct {
Id int64
Theme string `toml:",omitempty"`
}
// ExerciceUnlockFile holds parameters related to a locked file.
type ExerciceUnlockFile struct {
Filename string `toml:",omitempty"`
}
// ExerciceFlag holds informations about one flag.
type ExerciceFlag struct {
Id int64
Label string `toml:",omitempty"`
Type string `toml:",omitempty"`
Raw interface{}
Separator string `toml:",omitempty"`
ShowLines bool `toml:",omitempty"`
Ordered bool `toml:",omitempty"`
CaseSensitive bool `toml:",omitempty"`
NoTrim bool `toml:",omitempty"`
ValidatorRe string `toml:"validator_regexp,omitempty"`
SortReGroups bool `toml:"sort_validator_regexp_groups,omitempty"`
Placeholder string `toml:",omitempty"`
Help string `toml:",omitempty"`
ChoicesCost int64 `toml:"choices_cost,omitempty"`
Choice []ExerciceFlagChoice
LockedFile []ExerciceUnlockFile `toml:"unlock_file,omitempty"`
NeedFlag []ExerciceDependency `toml:"need_flag,omitempty"`
NoShuffle bool
Unit string `toml:"unit,omitempty"`
Variant string `toml:"variant,omitempty"`
NumberMin interface{} `toml:"min,omitempty"`
NumberMax interface{} `toml:"max,omitempty"`
NumberStep interface{} `toml:"step,omitempty"`
}
// ExerciceFlagChoice holds informations about a choice (for MCQ and UCQ).
type ExerciceFlagChoice struct {
ExerciceFlag
Value interface{} `toml:",omitempty"`
}
// ExerciceParams contains values parsed from defines.txt.
type ExerciceParams struct {
Gain int64
Tags []string
Hints []ExerciceHintParams `toml:"hint"`
Dependencies []ExerciceDependency `toml:"depend"`
Flags []ExerciceFlag `toml:"flag"`
FlagsMCQ []ExerciceFlag `toml:"flag_mcq"`
FlagsUCQ []ExerciceFlag `toml:"flag_ucq"`
}
// parseExerciceParams reads challenge definitions from defines.txt and extract usefull data to set up the challenge.
func parseExerciceParams(i Importer, exPath string) (p ExerciceParams, md toml.MetaData, err error) {
var defs string
defs, err = getFileContent(i, path.Join(exPath, "challenge.txt"))
if err != nil {
return
}
md, err = toml.Decode(defs, &p)
return
}
// getExerciceParams returns normalized
func getExerciceParams(i Importer, exercice *fic.Exercice) (params ExerciceParams, errs []string) {
var err error
if params, _, err = parseExerciceParams(i, exercice.Path); err != nil {
errs = append(errs, fmt.Sprintf("%q: challenge.txt: %s", path.Base(exercice.Path), err))
} else if len(params.Flags) == 0 && len(params.FlagsUCQ) == 0 && len(params.FlagsMCQ) == 0 {
errs = append(errs, fmt.Sprintf("%q: has no flag", path.Base(exercice.Path)))
} else {
// Treat legacy UCQ flags as ExerciceFlag
for _, flag := range params.FlagsUCQ {
params.Flags = append(params.Flags, ExerciceFlag{
Id: flag.Id,
Label: flag.Label,
Type: "ucq",
Raw: flag.Raw,
ValidatorRe: flag.ValidatorRe,
Placeholder: flag.Placeholder,
ChoicesCost: flag.ChoicesCost,
Choice: flag.Choice,
LockedFile: flag.LockedFile,
NeedFlag: flag.NeedFlag,
})
}
params.FlagsUCQ = []ExerciceFlag{}
// Treat legacy MCQ flags as ExerciceFlag
for _, flag := range params.FlagsMCQ {
params.Flags = append(params.Flags, ExerciceFlag{
Id: flag.Id,
Label: flag.Label,
Type: "mcq",
ChoicesCost: flag.ChoicesCost,
Choice: flag.Choice,
LockedFile: flag.LockedFile,
NeedFlag: flag.NeedFlag,
})
}
params.FlagsMCQ = []ExerciceFlag{}
}
return
}