From 74e8c3801a0f0aeccbe67f851691bc282e95a5dc Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 30 Aug 2021 18:33:14 +0200 Subject: [PATCH] fic: Add Order, Help and Type values in struct --- admin/api/file.go | 2 +- admin/api/handlers.go | 14 ++--- admin/sync/exercice_defines.go | 1 + admin/sync/exercice_keys.go | 3 ++ backend/choices.go | 2 +- backend/submission.go | 8 +-- libfic/db.go | 4 ++ libfic/exercice.go | 2 +- libfic/file.go | 8 +-- libfic/flag.go | 3 +- libfic/flag_choice.go | 9 ++-- libfic/flag_key.go | 36 ++++++++----- libfic/hint.go | 4 +- libfic/mcq.go | 40 ++++++++------ libfic/mcq_justification.go | 10 ++-- libfic/team_my.go | 98 ++++++++++++++++------------------ 16 files changed, 134 insertions(+), 110 deletions(-) diff --git a/admin/api/file.go b/admin/api/file.go index b35e2c74..08822a95 100644 --- a/admin/api/file.go +++ b/admin/api/file.go @@ -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}) } diff --git a/admin/api/handlers.go b/admin/api/handlers.go index fcd37344..4473750b 100644 --- a/admin/api/handlers.go +++ b/admin/api/handlers.go @@ -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) } } diff --git a/admin/sync/exercice_defines.go b/admin/sync/exercice_defines.go index f1336f16..814fe134 100644 --- a/admin/sync/exercice_defines.go +++ b/admin/sync/exercice_defines.go @@ -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"` diff --git a/admin/sync/exercice_keys.go b/admin/sync/exercice_keys.go index 10e8f366..77812442 100644 --- a/admin/sync/exercice_keys.go +++ b/admin/sync/exercice_keys.go @@ -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{}, } diff --git a/backend/choices.go b/backend/choices.go index c2dc52aa..8c09af7d 100644 --- a/backend/choices.go +++ b/backend/choices.go @@ -13,7 +13,7 @@ import ( ) type wantChoices struct { - FlagId int64 `json:"id"` + FlagId int `json:"id"` } func treatWantChoices(pathname string, team fic.Team) { diff --git a/backend/submission.go b/backend/submission.go index b3e24fcf..1bd052df 100644 --- a/backend/submission.go +++ b/backend/submission.go @@ -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 } diff --git a/libfic/db.go b/libfic/db.go index eb049ff6..e63336f4 100644 --- a/libfic/db.go +++ b/libfic/db.go @@ -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; diff --git a/libfic/exercice.go b/libfic/exercice.go index 72adb784..ce44e1c7 100644 --- a/libfic/exercice.go +++ b/libfic/exercice.go @@ -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 { diff --git a/libfic/file.go b/libfic/file.go index 9de693a3..750ee52b 100644 --- a/libfic/file.go +++ b/libfic/file.go @@ -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 diff --git a/libfic/flag.go b/libfic/flag.go index f4f97a61..c0065de7 100644 --- a/libfic/flag.go +++ b/libfic/flag.go @@ -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) } diff --git a/libfic/flag_choice.go b/libfic/flag_choice.go index 1c5b9e59..2aee3f07 100644 --- a/libfic/flag_choice.go +++ b/libfic/flag_choice.go @@ -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 } } diff --git a/libfic/flag_key.go b/libfic/flag_key.go index be27441b..d52ec382 100644 --- a/libfic/flag_key.go +++ b/libfic/flag_key.go @@ -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 } diff --git a/libfic/hint.go b/libfic/hint.go index 42b53954..ad942cb6 100644 --- a/libfic/hint.go +++ b/libfic/hint.go @@ -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 } diff --git a/libfic/mcq.go b/libfic/mcq.go index 70fc4532..c47ab504 100644 --- a/libfic/mcq.go +++ b/libfic/mcq.go @@ -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 diff --git a/libfic/mcq_justification.go b/libfic/mcq_justification.go index 837929db..41e3c499 100644 --- a/libfic/mcq_justification.go +++ b/libfic/mcq_justification.go @@ -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") diff --git a/libfic/team_my.go b/libfic/team_my.go index e6582b50..ab2f5bf9 100644 --- a/libfic/team_my.go +++ b/libfic/team_my.go @@ -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 } }