import_contest prototype script

This commit is contained in:
Andrea Fazzi 2020-01-08 15:41:04 +01:00
parent 02795fd740
commit 766ba387a6
6 changed files with 217 additions and 13 deletions

View file

@ -8,8 +8,11 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"reflect"
"strconv"
"strings" "strings"
"git.andreafazzi.eu/andrea/oef/i18n"
"git.andreafazzi.eu/andrea/oef/orm" "git.andreafazzi.eu/andrea/oef/orm"
"git.andreafazzi.eu/andrea/oef/renderer" "git.andreafazzi.eu/andrea/oef/renderer"
"github.com/jinzhu/inflection" "github.com/jinzhu/inflection"
@ -114,6 +117,106 @@ func (c *Client) ReadAll(model interface{}) error {
return nil return nil
} }
func (c *Client) Create(model interface{}) (uint, error) {
var response renderer.JsonResponse
data, err := json.Marshal(model)
if err != nil {
return 0, err
}
resp, err := c.SendRequest("POST", fmt.Sprintf("/api/%s/create/?format=json", pluralizedModelName(model)), data)
if err != nil {
return 0, err
}
if err := json.Unmarshal(resp, &response); err != nil {
return 0, err
}
if string(response.Error) != "" {
return 0, errors.New(string(response.Error))
}
id, err := strconv.Atoi(string(response.Result))
if err != nil {
return 0, err
}
return uint(id), nil
}
func (c *Client) Delete(model orm.IDer) (uint, error) {
var response renderer.JsonResponse
data, err := json.Marshal(model)
if err != nil {
return 0, err
}
resp, err := c.SendRequest("DELETE", fmt.Sprintf("/api/%s/%d/delete?format=json", pluralizedModelName(model), model.GetID()), data)
if err != nil {
return 0, err
}
if err := json.Unmarshal(resp, &response); err != nil {
return 0, err
}
if string(response.Error) != "" {
return 0, errors.New(string(response.Error))
}
id, err := strconv.Atoi(string(response.Result))
if err != nil {
return 0, err
}
return uint(id), nil
}
func (c *Client) DeleteAllByName(model interface{}, name string) error {
err := c.ReadAll(model)
if err != nil {
return err
}
switch reflect.TypeOf(model).Kind() {
case reflect.Ptr:
s := reflect.ValueOf(model).Elem()
// FIXME: Check whatever s is a slice before cycling through it!
for i := 0; i < s.Len(); i++ {
if callString(s.Index(i).Interface()) == name {
_, err := c.Delete(s.Index(i).Interface().(orm.IDer))
if err != nil {
return err
}
}
}
}
return nil
}
// FIXME: refactor this (it's duplicated across the code)
func pluralizedModelName(value interface{}) string { func pluralizedModelName(value interface{}) string {
return inflection.Plural(strings.ToLower(orm.ModelName(value))) return inflection.Plural(strings.ToLower(orm.ModelName(value)))
} }
// FIXME: refactor this (it's duplicated across the code)
func callString(value interface{}) string {
if value != nil {
switch reflect.ValueOf(value).Kind() {
case reflect.String:
return value.(string)
case reflect.Bool:
if value.(bool) {
return i18n.Text["answerCorrect"]["it"]
}
return "false"
default:
return reflect.ValueOf(value).MethodByName("String").Interface().(func() string)()
}
} else {
return ""
}
}

View file

@ -6,7 +6,6 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"path"
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime/debug" "runtime/debug"
@ -79,7 +78,7 @@ func generateHandler(r *mux.Router, model interface{}) {
// Generate API patterns prefixing "api" path // Generate API patterns prefixing "api" path
for _, p := range patterns { for _, p := range patterns {
apiPatterns = append(apiPatterns, PathPattern{path.Join("/", "api", p.PathPattern), "", p.Methods, p.Permission}) apiPatterns = append(apiPatterns, PathPattern{"/api" + p.PathPattern, "", p.Methods, p.Permission})
} }
// Install standard paths // Install standard paths
@ -246,7 +245,6 @@ func get(w http.ResponseWriter, r *http.Request, model string, pattern PathPatte
respondWithError(w, r, err) respondWithError(w, r, err)
} else { } else {
claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims) claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
log.Println(claims)
role := claims["role"].(string) role := claims["role"].(string)
if !hasPermission(role, pattern.Path(model)) { if !hasPermission(role, pattern.Path(model)) {
setFlashMessage(w, r, "notAuthorized") setFlashMessage(w, r, "notAuthorized")

View file

@ -55,9 +55,9 @@ func (c *Contest) Create(args map[string]string, w http.ResponseWriter, r *http.
endTime := r.FormValue("EndTime") endTime := r.FormValue("EndTime")
log.Println("Zero time", date) log.Println("Zero time", date)
if date == "" { if date == "" {
r.PostForm.Set("Date", time.Time{}.String()) r.PostForm.Set("Date", time.Time{}.Format(time.RFC3339))
r.PostForm.Set("StartTime", time.Time{}.String()) r.PostForm.Set("StartTime", time.Time{}.Format(time.RFC3339))
r.PostForm.Set("EndTime", time.Time{}.String()) r.PostForm.Set("EndTime", time.Time{}.Format(time.RFC3339))
} else { } else {
r.PostForm.Set("Date", fmt.Sprintf("%sT%s:00+01:00", date, startTime)) r.PostForm.Set("Date", fmt.Sprintf("%sT%s:00+01:00", date, startTime))
r.PostForm.Set("StartTime", fmt.Sprintf("%sT%s:00+01:00", date, startTime)) r.PostForm.Set("StartTime", fmt.Sprintf("%sT%s:00+01:00", date, startTime))
@ -160,8 +160,15 @@ func (c *Contest) Update(args map[string]string, w http.ResponseWriter, r *http.
} }
} }
func (c *Contest) Delete(args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) { func (model *Contest) Delete(args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) {
return nil, nil contest, err := model.Read(args, w, r)
if err != nil {
return nil, err
}
if err := DB().Unscoped().Delete(contest.(*Contest)).Error; err != nil {
return nil, err
}
return contest.(*Contest), nil
} }
func CreateContest(contest *Contest) (*Contest, error) { func CreateContest(contest *Contest) (*Contest, error) {

View file

@ -1,2 +1,4 @@
import_contest import_contest
contests config.yaml

View file

@ -0,0 +1,26 @@
name = "Test Diagnostico"
[[questions]]
text = "Quanto fa 1+1?"
[[questions.answers]]
text = "2"
[[questions.answers]]
text = "3"
[[questions.answers]]
text = "4"
[[questions.answers]]
text = "5"
[[questions]]
text = "Il sole è"
[[questions.answers]]
text = "una stella"
[[questions.answers]]
text = "un pianeta"
[[questions.answers]]
text = "una galassia"
[[questions.answers]]
text = "una nebulosa"

View file

@ -1,31 +1,99 @@
package main package main
import ( import (
"flag"
"log" "log"
"os"
"git.andreafazzi.eu/andrea/oef/client" "git.andreafazzi.eu/andrea/oef/client"
"git.andreafazzi.eu/andrea/oef/config"
"git.andreafazzi.eu/andrea/oef/orm" "git.andreafazzi.eu/andrea/oef/orm"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
) )
func main() { func main() {
url := "http://localhost:3000" flag.Parse()
if flag.NArg() == 0 {
panic("A toml filename is needed as first argument of this script.")
}
conf := new(config.ConfigT)
if _, err := os.Stat("./config.yaml"); err != nil {
panic(err)
}
err := config.ReadFile("./config.yaml", conf)
if err != nil {
panic(err)
}
client, err := client.Dial(conf.Url, conf.Admin.Username, conf.Admin.Password)
if err != nil {
panic(err)
}
log.Println("Reading toml file...") log.Println("Reading toml file...")
var contest *orm.Contest var contest *orm.Contest
if _, err := toml.DecodeFile("contests/test_diagnostico.toml", &contest); err != nil { if _, err := toml.DecodeFile(flag.Arg(0), &contest); err != nil {
panic(err) panic(err)
} }
var contests []*orm.Contest var contests []*orm.Contest
err := client.ReadAll(&contests) err = client.ReadAll(&contests)
if err != nil { if err != nil {
panic(err) panic(err)
} }
id, err := client.Create(contest) // Remove all contest with the same name
for _, c := range contests {
if c.Name == contest.Name {
log.Println("Remove contest with ID", c.ID)
_, err := client.Delete(c)
if err != nil {
panic(err)
}
}
}
contestID, err := client.Create(contest)
if err != nil { if err != nil {
panic(err) panic(err)
} }
log.Println("Create contest with ID", contestID)
log.Println("Creating questions...")
for _, question := range contest.Questions {
err := client.DeleteAllByName(&[]*orm.Question{}, question.Text)
if err != nil {
panic(err)
}
question.ContestID = contestID
questionID, err := client.Create(question)
if err != nil {
panic(err)
}
log.Println("Create question with ID", questionID)
for pos, answer := range question.Answers {
err := client.DeleteAllByName(&[]*orm.Answer{}, answer.Text)
if err != nil {
panic(err)
}
answer.QuestionID = questionID
if pos == 0 {
answer.Correct = true
}
id, err := client.Create(answer)
if err != nil {
panic(err)
}
log.Println("Create answer with ID", id)
}
}
} }