fic: Add Order, Help and Type values in struct

This commit is contained in:
nemunaire 2021-08-30 18:33:14 +02:00
parent 867e9bb345
commit 74e8c3801a
16 changed files with 134 additions and 110 deletions

View File

@ -143,7 +143,7 @@ func deleteFile(file fic.EFile, _ []byte) (interface{}, error) {
return file.Delete()
}
func deleteFileDep(file fic.EFile, depid int64, _ []byte) (interface{}, error) {
func deleteFileDep(file fic.EFile, depid int, _ []byte) (interface{}, error) {
return true, file.DeleteDepend(fic.FlagKey{Id: depid})
}

View File

@ -115,7 +115,7 @@ func teamAssocHandler(f func(fic.Team, string, []byte) (interface{}, error)) fun
return func(ps httprouter.Params, body []byte) (interface{}, error) {
var team fic.Team
teamHandler(func (tm fic.Team, _ []byte) (interface{}, error) {
teamHandler(func(tm fic.Team, _ []byte) (interface{}, error) {
team = tm
return nil, nil
})(ps, body)
@ -193,7 +193,7 @@ func flagKeyHandler(f func(fic.FlagKey, fic.Exercice, []byte) (interface{}, erro
return nil, err
} else {
for _, flag := range flags {
if flag.Id == kid {
if flag.Id == int(kid) {
return f(flag, exercice, body)
}
}
@ -212,9 +212,9 @@ func choiceHandler(f func(fic.FlagChoice, fic.Exercice, []byte) (interface{}, er
return nil, nil
})(ps, body)
if cid, err := strconv.ParseInt(string(ps.ByName("cid")), 10, 64); err != nil {
if cid, err := strconv.ParseInt(string(ps.ByName("cid")), 10, 32); err != nil {
return nil, err
} else if choice, err := flag.GetChoice(cid); err != nil {
} else if choice, err := flag.GetChoice(int(cid)); err != nil {
return nil, err
} else {
return f(choice, exercice, body)
@ -236,7 +236,7 @@ func quizHandler(f func(fic.MCQ, fic.Exercice, []byte) (interface{}, error)) fun
return nil, err
} else {
for _, mcq := range mcqs {
if mcq.Id == int64(qid) {
if mcq.Id == int(qid) {
return f(mcq, exercice, body)
}
}
@ -316,13 +316,13 @@ func fileHandler(f func(fic.EFile, []byte) (interface{}, error)) func(httprouter
}
}
func fileDependancyHandler(f func(fic.EFile, int64, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
func fileDependancyHandler(f func(fic.EFile, int, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
return func(ps httprouter.Params, body []byte) (interface{}, error) {
if depid, err := strconv.ParseInt(string(ps.ByName("depid")), 10, 64); err != nil {
return nil, err
} else {
return fileHandler(func(file fic.EFile, b []byte) (interface{}, error) {
return f(file, depid, b)
return f(file, int(depid), b)
})(ps, body)
}
}

View File

@ -40,6 +40,7 @@ type ExerciceFlag struct {
CaseSensitive bool `toml:",omitempty"`
ValidatorRe string `toml:"validator_regexp,omitempty"`
Placeholder string `toml:",omitempty"`
Help string `toml:",omitempty"`
ChoicesCost int64 `toml:"choices_cost,omitempty"`
Choice []ExerciceFlagChoice
LockedFile []ExerciceUnlockFile `toml:"unlock_file,omitempty"`

View File

@ -128,8 +128,10 @@ func buildKeyFlag(exercice fic.Exercice, flag ExerciceFlag, flagline int, defaul
}
fl := fic.Flag(fic.FlagKey{
IdExercice: exercice.Id,
Order: int8(flagline),
Label: flag.Label,
Placeholder: flag.Placeholder,
Help: flag.Help,
IgnoreCase: !flag.CaseSensitive,
Multiline: flag.Type == "text",
ValidatorRegexp: validatorRegexp(flag.ValidatorRe),
@ -221,6 +223,7 @@ func buildExerciceFlag(i Importer, exercice fic.Exercice, flag ExerciceFlag, nli
} else if flag.Type == "mcq" {
addedFlag := fic.MCQ{
IdExercice: exercice.Id,
Order: int8(nline + 1),
Title: flag.Label,
Entries: []fic.MCQ_entry{},
}

View File

@ -13,7 +13,7 @@ import (
)
type wantChoices struct {
FlagId int64 `json:"id"`
FlagId int `json:"id"`
}
func treatWantChoices(pathname string, team fic.Team) {

View File

@ -18,9 +18,9 @@ import (
)
type ResponsesUpload struct {
Keys map[int64]string `json:"flags"`
MCQs map[int64]bool `json:"mcqs"`
MCQJ map[int64]string `json:"justifications"`
Keys map[int]string `json:"flags"`
MCQs map[int]bool `json:"mcqs"`
MCQJ map[int]string `json:"justifications"`
}
func treatSubmission(pathname string, team fic.Team, exercice_id string) {
@ -100,7 +100,7 @@ func treatSubmission(pathname string, team fic.Team, exercice_id string) {
continue
} else {
if responses.Keys == nil {
responses.Keys = map[int64]string{}
responses.Keys = map[int]string{}
}
responses.Keys[key.Id] = j
}

View File

@ -176,7 +176,10 @@ CREATE TABLE IF NOT EXISTS exercice_hints(
CREATE TABLE IF NOT EXISTS exercice_flags(
id_flag INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
id_exercice INTEGER NOT NULL,
ordre TINYINT NOT NULL,
label VARCHAR(255) NOT NULL,
type VARCHAR(255) NOT NULL,
placeholder VARCHAR(255) NOT NULL,
help VARCHAR(255) NOT NULL,
ignorecase BOOLEAN NOT NULL DEFAULT 0,
multiline BOOLEAN NOT NULL DEFAULT 0,
@ -233,6 +236,7 @@ CREATE TABLE IF NOT EXISTS exercice_files_okey_deps(
CREATE TABLE IF NOT EXISTS exercice_mcq(
id_mcq INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
id_exercice INTEGER NOT NULL,
ordre TINYINT NOT NULL,
title VARCHAR(255) NOT NULL,
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

View File

@ -408,7 +408,7 @@ func (e Exercice) MCQSolved() (res []int64) {
// CheckResponse, given both flags and MCQ responses, figures out if thoses are correct (or if they are previously solved).
// In the meanwhile, CheckResponse registers good answers given (but it does not mark the challenge as solved at the end).
func (e Exercice) CheckResponse(cksum []byte, respflags map[int64]string, respmcq map[int64]bool, t Team) (bool, error) {
func (e Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq map[int]bool, t Team) (bool, error) {
if err := e.NewTry(t, cksum); err != nil {
return false, err
} else if flags, err := e.GetFlagKeys(); err != nil {

View File

@ -326,11 +326,11 @@ func (f EFile) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}
deps = append(deps, FlagKey{d, f.IdExercice, "", "", false, false, nil, []byte{}, 0})
deps = append(deps, FlagKey{d, f.IdExercice, 0, "", "", "", "", false, false, nil, []byte{}, 0})
}
if err := rows.Err(); err != nil {
return nil, err
@ -343,11 +343,11 @@ func (f EFile) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}
deps = append(deps, MCQ{d, f.IdExercice, "", []MCQ_entry{}})
deps = append(deps, MCQ{d, f.IdExercice, 0, "", []MCQ_entry{}})
}
if err := rows.Err(); err != nil {
return nil, err

View File

@ -3,13 +3,14 @@ package fic
import ()
type Flag interface {
GetId() int64
GetId() int
RecoverId() (Flag, error)
Create(e Exercice) (Flag, error)
Update() (int64, error)
Delete() (int64, error)
AddDepend(d Flag) error
GetDepends() ([]Flag, error)
GetOrder() int8
Check(val interface{}) int
FoundBy(t Team)
}

View File

@ -4,9 +4,9 @@ import ()
// FlagChoice represents a choice a respond to a classic flag
type FlagChoice struct {
Id int64 `json:"id"`
Id int `json:"id"`
// IdFlag is the identifier of the underlying flag
IdFlag int64 `json:"idFlag"`
IdFlag int `json:"idFlag"`
// Label is the title of the choice as displayed to players
Label string `json:"label"`
// Value is the raw content that'll be written as response if this choice is selected
@ -40,7 +40,7 @@ func (f FlagKey) GetChoices() ([]FlagChoice, error) {
}
// GetChoice returns a choice for the given Flag.
func (f FlagKey) GetChoice(id int64) (c FlagChoice, err error) {
func (f FlagKey) GetChoice(id int) (c FlagChoice, err error) {
if errr := DBQueryRow("SELECT id_choice, id_flag, label, response FROM flag_choices WHERE id_choice = ?", id).Scan(&c.Id, &c.IdFlag, &c.Label, &c.Value); errr != nil {
return c, errr
}
@ -52,7 +52,8 @@ func (f FlagKey) AddChoice(c FlagChoice) (FlagChoice, error) {
if res, err := DBExec("INSERT INTO flag_choices (id_flag, label, response) VALUES (?, ?, ?)", f.Id, c.Label, c.Value); err != nil {
return c, err
} else {
c.Id, err = res.LastInsertId()
cid, err := res.LastInsertId()
c.Id = int(cid)
return c, err
}
}

View File

@ -12,13 +12,19 @@ import (
// FlagKey represents a flag's challenge, stored as hash.
type FlagKey struct {
Id int64 `json:"id"`
Id int `json:"id"`
// IdExercice is the identifier of the underlying challenge
IdExercice int64 `json:"idExercice"`
// Order is used to sort the flag between them
Order int8 `json:"order"`
// Label is the title of the flag as displayed to players
Label string `json:"label"`
// Type is the kind of flag
Type string `json:"type,omitempty"`
// Placeholder is a small piece of text that aims to add useful information like flag format, ...
Placeholder string `json:"placeholder"`
// Help is a description of the flag
Help string `json:"help"`
// IgnoreCase indicates if the case is sensitive to case or not
IgnoreCase bool `json:"ignorecase"`
// Multiline indicates if the flag is stored on multiple lines
@ -33,7 +39,7 @@ type FlagKey struct {
// GetFlagKeys returns a list of key's flags comming with the challenge.
func (e Exercice) GetFlagKeys() ([]FlagKey, error) {
if rows, err := DBQuery("SELECT id_flag, id_exercice, type, help, ignorecase, multiline, validator_regexp, cksum, choices_cost FROM exercice_flags WHERE id_exercice = ?", e.Id); err != nil {
if rows, err := DBQuery("SELECT id_flag, id_exercice, ordre, label, type, placeholder, help, ignorecase, multiline, validator_regexp, cksum, choices_cost FROM exercice_flags WHERE id_exercice = ?", e.Id); err != nil {
return nil, err
} else {
defer rows.Close()
@ -43,7 +49,7 @@ func (e Exercice) GetFlagKeys() ([]FlagKey, error) {
var k FlagKey
k.IdExercice = e.Id
if err := rows.Scan(&k.Id, &k.IdExercice, &k.Label, &k.Placeholder, &k.IgnoreCase, &k.Multiline, &k.ValidatorRegexp, &k.Checksum, &k.ChoicesCost); err != nil {
if err := rows.Scan(&k.Id, &k.IdExercice, &k.Order, &k.Label, &k.Type, &k.Placeholder, &k.Help, &k.IgnoreCase, &k.Multiline, &k.ValidatorRegexp, &k.Checksum, &k.ChoicesCost); err != nil {
return nil, err
}
@ -58,14 +64,14 @@ func (e Exercice) GetFlagKeys() ([]FlagKey, error) {
}
// GetFlagKey returns a list of flags comming with the challenge.
func GetFlagKey(id int64) (k FlagKey, err error) {
err = DBQueryRow("SELECT id_flag, id_exercice, type, help, ignorecase, multiline, validator_regexp, cksum, choices_cost FROM exercice_flags WHERE id_flag = ?", id).Scan(&k.Id, &k.IdExercice, &k.Label, &k.Placeholder, &k.IgnoreCase, &k.Multiline, &k.ValidatorRegexp, &k.Checksum, &k.ChoicesCost)
func GetFlagKey(id int) (k FlagKey, err error) {
err = DBQueryRow("SELECT id_flag, id_exercice, ordre, label, type, placeholder, help, ignorecase, multiline, validator_regexp, cksum, choices_cost FROM exercice_flags WHERE id_flag = ?", id).Scan(&k.Id, &k.IdExercice, &k.Order, &k.Label, &k.Type, &k.Placeholder, &k.Help, &k.IgnoreCase, &k.Multiline, &k.ValidatorRegexp, &k.Checksum, &k.ChoicesCost)
return
}
// GetFlagKeyByLabel returns a flag matching the given label.
func (e Exercice) GetFlagKeyByLabel(label string) (k FlagKey, err error) {
err = DBQueryRow("SELECT id_flag, id_exercice, type, help, ignorecase, multiline, validator_regexp, cksum, choices_cost FROM exercice_flags WHERE type LIKE ? AND id_exercice = ?", label, e.Id).Scan(&k.Id, &k.IdExercice, &k.Label, &k.Placeholder, &k.IgnoreCase, &k.Multiline, &k.ValidatorRegexp, &k.Checksum, &k.ChoicesCost)
err = DBQueryRow("SELECT id_flag, id_exercice, ordre, label, type, placeholder, help, ignorecase, multiline, validator_regexp, cksum, choices_cost FROM exercice_flags WHERE type LIKE ? AND id_exercice = ?", label, e.Id).Scan(&k.Id, &k.IdExercice, &k.Order, &k.Label, &k.Type, &k.Placeholder, &k.Help, &k.IgnoreCase, &k.Multiline, &k.ValidatorRegexp, &k.Checksum, &k.ChoicesCost)
return
}
@ -126,13 +132,13 @@ func (e Exercice) AddRawFlagKey(name string, placeholder string, ignorecase bool
}
// GetId returns the Flag identifier.
func (k FlagKey) GetId() int64 {
func (k FlagKey) GetId() int {
return k.Id
}
// RecoverId returns the Flag identifier as register in DB.
func (k FlagKey) RecoverId() (Flag, error) {
if err := DBQueryRow("SELECT id_flag FROM exercice_flags WHERE type LIKE ? AND id_exercice = ?", k.Label, k.IdExercice).Scan(&k.Id); err != nil {
if err := DBQueryRow("SELECT id_flag FROM exercice_flags WHERE label LIKE ? AND id_exercice = ?", k.Label, k.IdExercice).Scan(&k.Id); err != nil {
return FlagKey{}, err
} else {
return k, err
@ -148,12 +154,12 @@ func (k FlagKey) Create(e Exercice) (Flag, error) {
}
}
if res, err := DBExec("INSERT INTO exercice_flags (id_exercice, type, help, ignorecase, multiline, validator_regexp, cksum, choices_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", e.Id, k.Label, k.Placeholder, k.IgnoreCase, k.Multiline, k.ValidatorRegexp, k.Checksum, k.ChoicesCost); err != nil {
if res, err := DBExec("INSERT INTO exercice_flags (id_exercice, ordre, label, type, placeholder, help, ignorecase, multiline, validator_regexp, cksum, choices_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", e.Id, k.Order, k.Label, k.Type, k.Placeholder, k.Help, k.IgnoreCase, k.Multiline, k.ValidatorRegexp, k.Checksum, k.ChoicesCost); err != nil {
return k, err
} else if kid, err := res.LastInsertId(); err != nil {
return k, err
} else {
k.Id = kid
k.Id = int(kid)
k.IdExercice = e.Id
return k, nil
}
@ -173,7 +179,7 @@ func (k FlagKey) Update() (int64, error) {
}
}
if res, err := DBExec("UPDATE exercice_flags SET id_exercice = ?, type = ?, help = ?, ignorecase = ?, multiline = ?, validator_regexp = ?, cksum = ?, choices_cost = ? WHERE id_flag = ?", k.IdExercice, k.Label, k.Placeholder, k.IgnoreCase, k.Multiline, k.ValidatorRegexp, k.Checksum, k.ChoicesCost, k.Id); err != nil {
if res, err := DBExec("UPDATE exercice_flags SET id_exercice = ?, ordre = ?, label = ?, type = ?, placeholder = ?, help = ?, ignorecase = ?, multiline = ?, validator_regexp = ?, cksum = ?, choices_cost = ? WHERE id_flag = ?", k.IdExercice, k.Order, k.Label, k.Type, k.Placeholder, k.Help, k.IgnoreCase, k.Multiline, k.ValidatorRegexp, k.Checksum, k.ChoicesCost, k.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
@ -203,6 +209,10 @@ func (k FlagKey) Delete() (int64, error) {
}
}
func (k FlagKey) GetOrder() int8 {
return k.Order
}
// AddDepend insert a new dependency to a given flag.
func (k FlagKey) AddDepend(j Flag) (err error) {
if d, ok := j.(FlagKey); ok {
@ -225,7 +235,7 @@ func (k FlagKey) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}
@ -242,7 +252,7 @@ func (k FlagKey) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}

View File

@ -152,7 +152,7 @@ func (h EHint) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}
@ -169,7 +169,7 @@ func (h EHint) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}

View File

@ -8,9 +8,11 @@ import (
// MCQ represents a flag's challenge, in the form of checkbox.
type MCQ struct {
Id int64 `json:"id"`
Id int `json:"id"`
// IdExercice is the identifier of the underlying challenge
IdExercice int64 `json:"idExercice"`
// Order is used to sort the flag between them
Order int8 `json:"order"`
// Title is the label of the question
Title string `json:"title"`
// Entries stores the set of proposed answers
@ -19,7 +21,7 @@ type MCQ struct {
// MCQ_entry represents a proposed response for a given MCQ.
type MCQ_entry struct {
Id int64 `json:"id"`
Id int `json:"id"`
// Label is the text displayed to players as proposed answer
Label string `json:"label"`
// Response stores if expected checked state.
@ -27,8 +29,8 @@ type MCQ_entry struct {
}
// GetMCQ returns a list of flags comming with the challenge.
func GetMCQ(id int64) (m MCQ, err error) {
err = DBQueryRow("SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_mcq = ?", id).Scan(&m.Id, &m.IdExercice, &m.Title)
func GetMCQ(id int) (m MCQ, err error) {
err = DBQueryRow("SELECT id_mcq, id_exercice, order, title FROM exercice_mcq WHERE id_mcq = ?", id).Scan(&m.Id, &m.IdExercice, &m.Order, &m.Title)
m.fillEntries()
return
}
@ -55,7 +57,7 @@ func (m *MCQ) fillEntries() ([]MCQ_entry, error) {
// GetMCQ returns the MCQs coming with the challenge.
func (e Exercice) GetMCQ() ([]MCQ, error) {
if rows, err := DBQuery("SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_exercice = ?", e.Id); err != nil {
if rows, err := DBQuery("SELECT id_mcq, id_exercice, ordre, title FROM exercice_mcq WHERE id_exercice = ?", e.Id); err != nil {
return nil, err
} else {
defer rows.Close()
@ -65,7 +67,7 @@ func (e Exercice) GetMCQ() ([]MCQ, error) {
var m MCQ
m.IdExercice = e.Id
if err := rows.Scan(&m.Id, &m.IdExercice, &m.Title); err != nil {
if err := rows.Scan(&m.Id, &m.IdExercice, &m.Order, &m.Title); err != nil {
return nil, err
}
@ -82,8 +84,8 @@ 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); errr != nil {
func GetMCQbyChoice(cid int) (m MCQ, c MCQ_entry, err error) {
if errr := DBQueryRow("SELECT id_mcq, id_exercice, ordre, title FROM exercice_mcq WHERE id_mcq = (SELECT id_mcq FROM mcq_entries WHERE id_mcq_entry = ?)", cid).Scan(&m.Id, &m.IdExercice, &m.Order, &m.Title); errr != nil {
return MCQ{}, MCQ_entry{}, errr
}
@ -111,7 +113,7 @@ func GetMCQbyChoice(cid int64) (m MCQ, c MCQ_entry, err error) {
}
// GetId returns the MCQ identifier.
func (m MCQ) GetId() int64 {
func (m MCQ) GetId() int {
return m.Id
}
@ -126,12 +128,12 @@ func (m MCQ) RecoverId() (Flag, error) {
// Create registers a MCQ into the database and recursively add its entries.
func (m MCQ) Create(e Exercice) (Flag, error) {
if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, title) VALUES (?, ?)", e.Id, m.Title); err != nil {
if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, ordre, title) VALUES (?, ?, ?)", e.Id, m.Order, m.Title); err != nil {
return m, err
} else if qid, err := res.LastInsertId(); err != nil {
return m, err
} else {
m.Id = qid
m.Id = int(qid)
m.IdExercice = e.Id
// Add entries
@ -149,7 +151,7 @@ func (m MCQ) Create(e Exercice) (Flag, error) {
// Update applies modifications back to the database.
func (m MCQ) Update() (int64, error) {
if res, err := DBExec("UPDATE exercice_mcq SET id_exercice = ?, title = ? WHERE id_mcq = ?", m.IdExercice, m.Title, m.Id); err != nil {
if res, err := DBExec("UPDATE exercice_mcq SET id_exercice = ?, ordre = ?, title = ? WHERE id_mcq = ?", m.IdExercice, m.Order, m.Title, m.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
@ -186,7 +188,7 @@ func (m MCQ) AddEntry(e MCQ_entry) (MCQ_entry, error) {
} else if nid, err := res.LastInsertId(); err != nil {
return e, err
} else {
e.Id = nid
e.Id = int(nid)
return e, nil
}
}
@ -236,6 +238,10 @@ func (e Exercice) WipeMCQs() (int64, error) {
}
}
func (m MCQ) GetOrder() int8 {
return m.Order
}
// AddDepend insert a new dependency to a given flag.
func (m MCQ) AddDepend(j Flag) (err error) {
if d, ok := j.(FlagKey); ok {
@ -258,7 +264,7 @@ func (m MCQ) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}
@ -276,7 +282,7 @@ func (m MCQ) GetDepends() ([]Flag, error) {
defer rows.Close()
for rows.Next() {
var d int64
var d int
if err := rows.Scan(&d); err != nil {
return nil, err
}
@ -298,8 +304,8 @@ func (c MCQ_entry) GetJustifiedFlag(e Exercice) (FlagKey, error) {
// Check if the given vals are the expected ones to validate this flag.
func (m MCQ) Check(v interface{}) int {
var vals map[int64]bool
if va, ok := v.(map[int64]bool); !ok {
var vals map[int]bool
if va, ok := v.(map[int]bool); !ok {
return -1
} else {
vals = va

View File

@ -2,17 +2,17 @@ package fic
import (
"errors"
"strings"
"strconv"
"strings"
)
type FlagLabel struct {
Label string
IdChoice int64
IdChoice int
}
// IsMCQJustification tells you if this key represent a justification from a MCQ.
func (k FlagKey) IsMCQJustification() (bool) {
func (k FlagKey) IsMCQJustification() bool {
return len(k.Label) > 0 && k.Label[0] == '%'
}
@ -20,7 +20,9 @@ func (k FlagKey) IsMCQJustification() (bool) {
func (k FlagKey) GetMCQJustification() (fl FlagLabel, err error) {
spl := strings.Split(k.Label, "%")
if len(spl) >= 3 && len(spl[0]) == 0 {
fl.IdChoice, err = strconv.ParseInt(spl[1], 10, 64)
var idChoice int64
idChoice, err = strconv.ParseInt(spl[1], 10, 32)
fl.IdChoice = int(idChoice)
fl.Label = strings.Join(spl[2:], "%")
} else {
err = errors.New("This is not a MCQ justification")

View File

@ -27,50 +27,46 @@ type myTeamHint struct {
Cost int64 `json:"cost"`
}
type myTeamFlag struct {
Label string `json:"label"`
Placeholder string `json:"placeholder,omitempty"`
Separator string `json:"separator,omitempty"`
NbLines uint64 `json:"nb_lines,omitempty"`
IgnoreOrder bool `json:"ignore_order,omitempty"`
IgnoreCase bool `json:"ignore_case,omitempty"`
Multiline bool `json:"multiline,omitempty"`
ValidatorRe *string `json:"validator_regexp,omitempty"`
Solved *time.Time `json:"found,omitempty"`
Soluce string `json:"soluce,omitempty"`
Choices map[string]string `json:"choices,omitempty"`
ChoicesCost int64 `json:"choices_cost,omitempty"`
Order int8 `json:"order"`
Label string `json:"label"`
Type string `json:"type,omitempty"`
Placeholder string `json:"placeholder,omitempty"`
Help string `json:"help,omitempty"`
Separator string `json:"separator,omitempty"`
NbLines uint64 `json:"nb_lines,omitempty"`
IgnoreOrder bool `json:"ignore_order,omitempty"`
IgnoreCase bool `json:"ignore_case,omitempty"`
Multiline bool `json:"multiline,omitempty"`
ValidatorRe *string `json:"validator_regexp,omitempty"`
Solved *time.Time `json:"found,omitempty"`
PSolved *time.Time `json:"part_solved,omitempty"`
Soluce string `json:"soluce,omitempty"`
Justify bool `json:"justify,omitempty"`
Choices map[string]interface{} `json:"choices,omitempty"`
ChoicesCost int64 `json:"choices_cost,omitempty"`
}
type myTeamMCQJustifiedChoice struct {
Label string `json:"label"`
Value bool `json:"value,omitempty"`
Justification myTeamFlag `json:"justification,omitempty"`
}
type myTeamMCQ struct {
Title string `json:"title"`
Justify bool `json:"justify,omitempty"`
Choices map[int64]interface{} `json:"choices,omitempty"`
Solved *time.Time `json:"solved,omitempty"`
PSolved *time.Time `json:"part_solved,omitempty"`
Soluce string `json:"soluce,omitempty"`
}
type myTeamExercice struct {
ThemeId int64 `json:"theme_id"`
Statement string `json:"statement"`
Overview string `json:"overview,omitempty"`
Finished string `json:"finished,omitempty"`
Hints []myTeamHint `json:"hints,omitempty"`
Gain int `json:"gain"`
Files []myTeamFile `json:"files,omitempty"`
Flags map[int64]myTeamFlag `json:"flags,omitempty"`
MCQs map[int64]myTeamMCQ `json:"mcqs,omitempty"`
SolveDist int64 `json:"solve_dist,omitempty"`
SolvedTime *time.Time `json:"solved_time,omitempty"`
SolvedRank int64 `json:"solved_rank,omitempty"`
Tries int64 `json:"tries,omitempty"`
TotalTries int64 `json:"total_tries,omitempty"`
VideoURI string `json:"video_uri,omitempty"`
Issue string `json:"issue,omitempty"`
IssueKind string `json:"issuekind,omitempty"`
ThemeId int64 `json:"theme_id"`
Statement string `json:"statement"`
Overview string `json:"overview,omitempty"`
Finished string `json:"finished,omitempty"`
Hints []myTeamHint `json:"hints,omitempty"`
Gain int `json:"gain"`
Files []myTeamFile `json:"files,omitempty"`
Flags map[int]myTeamFlag `json:"flags,omitempty"`
SolveDist int64 `json:"solve_dist,omitempty"`
SolvedTime *time.Time `json:"solved_time,omitempty"`
SolvedRank int64 `json:"solved_rank,omitempty"`
Tries int64 `json:"tries,omitempty"`
TotalTries int64 `json:"total_tries,omitempty"`
VideoURI string `json:"video_uri,omitempty"`
Issue string `json:"issue,omitempty"`
IssueKind string `json:"issuekind,omitempty"`
}
type myTeam struct {
Id int64 `json:"team_id"`
@ -179,8 +175,8 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
// Expose exercice flags
justifiedMCQ := map[int64]myTeamFlag{}
exercice.Flags = map[int64]myTeamFlag{}
justifiedMCQ := map[int]myTeamFlag{}
exercice.Flags = map[int]myTeamFlag{}
if flags, err := e.GetFlagKeys(); err != nil {
return nil, err
@ -188,6 +184,8 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
for _, k := range flags {
var flag myTeamFlag
flag.Order = k.Order
if !DisplayAllFlags && t != nil && !t.CanSeeFlag(k) {
// Dependancy missing, skip the flag for now
continue
@ -225,7 +223,7 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
if choices, err := k.GetChoices(); err != nil {
return nil, err
} else if t == nil || WChoiceCoefficient < 0 || k.ChoicesCost == 0 || t.SeeChoices(k) {
flag.Choices = map[string]string{}
flag.Choices = map[string]interface{}{}
for _, c := range choices {
flag.Choices[c.Value] = c.Label
}
@ -243,10 +241,6 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
}
}
// Expose exercice MCQs
exercice.MCQs = map[int64]myTeamMCQ{}
if mcqs, err := e.GetMCQ(); err != nil {
return nil, err
} else {
@ -256,9 +250,11 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
continue
}
m := myTeamMCQ{
Title: mcq.Title,
Choices: map[int64]interface{}{},
m := myTeamFlag{
Type: "mcq",
Label: mcq.Title,
Order: mcq.Order,
Choices: map[string]interface{}{},
}
soluce := ""
@ -292,12 +288,12 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
jc.Value = e.Response
}
m.Choices[e.Id] = jc
m.Choices[strconv.Itoa(e.Id)] = jc
} else {
m.Choices[e.Id] = e.Label
m.Choices[strconv.Itoa(e.Id)] = e.Label
}
} else {
m.Choices[e.Id] = e.Label
m.Choices[strconv.Itoa(e.Id)] = e.Label
}
}
@ -311,7 +307,7 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
m.PSolved = nil
}
exercice.MCQs[mcq.Id] = m
exercice.Flags[mcq.Id] = m
}
}