190 lines
3.9 KiB
Go
190 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"git.andreafazzi.eu/andrea/oef/client"
|
|
"git.andreafazzi.eu/andrea/oef/config"
|
|
"git.andreafazzi.eu/andrea/oef/orm"
|
|
"github.com/BurntSushi/toml"
|
|
"github.com/gocarina/gocsv"
|
|
)
|
|
|
|
type importer struct {
|
|
client *client.Client
|
|
importFuncs map[string]func(*client.Client, string) error
|
|
}
|
|
|
|
func newImporter(c *client.Client) *importer {
|
|
return &importer{
|
|
c,
|
|
map[string]func(*client.Client, string) error{
|
|
"contests": importContest,
|
|
"schools": importSchools,
|
|
"participants": importParticipants,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (i *importer) runImport(importer, filename string) error {
|
|
f, ok := i.importFuncs[importer]
|
|
if !ok {
|
|
return fmt.Errorf("Importer %s not defined!", importer)
|
|
}
|
|
return f(i.client, filename)
|
|
}
|
|
|
|
func importSchools(client *client.Client, filename string) error {
|
|
var schools []*orm.School
|
|
data, err := ioutil.ReadFile(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := gocsv.Unmarshal(strings.NewReader(string(data)), &schools); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
for _, s := range schools {
|
|
id, err := client.Create(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
log.Println("Create school with ID", id)
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func importParticipants(client *client.Client, filename string) error {
|
|
var participants []*orm.Participant
|
|
data, err := ioutil.ReadFile(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := gocsv.Unmarshal(strings.NewReader(string(data)), &participants); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
for _, p := range participants {
|
|
id, err := client.Create(p)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
log.Println("Create participant with ID", id)
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func importContest(client *client.Client, filename string) error {
|
|
log.Println("Reading contest data from toml file...")
|
|
var contest *orm.Contest
|
|
if _, err := toml.DecodeFile(filename, &contest); err != nil {
|
|
return err
|
|
}
|
|
|
|
var contests []*orm.Contest
|
|
err := client.ReadAll(&contests)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 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 {
|
|
return err
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
contestID, err := client.Create(contest)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Println("Create contest with ID", contestID)
|
|
|
|
log.Println("Creating questions...")
|
|
|
|
for _, question := range contest.Questions {
|
|
|
|
err := client.DeleteAllFunc(&[]*orm.Question{}, func(model interface{}) bool {
|
|
return model.(*orm.Question).Text == question.Text
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
question.ContestID = contestID
|
|
questionID, err := client.Create(question)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Println("Create question with ID", questionID)
|
|
|
|
for pos, answer := range question.Answers {
|
|
|
|
err := client.DeleteAllFunc(&[]*orm.Answer{}, func(model interface{}) bool {
|
|
return model.(*orm.Answer).Text == answer.Text && model.(*orm.Answer).Question != nil && model.(*orm.Answer).Question.Text == question.Text
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
answer.QuestionID = questionID
|
|
if pos == 0 {
|
|
answer.Correct = true
|
|
}
|
|
id, err := client.Create(answer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Println("Create answer with ID", id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
var importer string
|
|
|
|
flag.StringVar(&importer, "importer", "contest", "Name of importer to use")
|
|
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)
|
|
}
|
|
|
|
i := newImporter(client)
|
|
err = i.runImport(importer, flag.Arg(0))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|