package scoreboard import ( "bytes" "encoding/json" "fmt" "log/slog" "os" "os/exec" "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" ) type StageRecord struct { StageName string `json:"stagename"` StageResults []stage.StageResult `json:"stageresults"` } type ScoreboardData struct { StageRecords []StageRecord `json:"stagerecords"` } type Scoreboard struct { studentName string studentId string scoreboard ScoreboardData } func (b *Scoreboard) Init(studentName string, studentId string) { b.studentName = studentName b.studentId = studentId b.scoreboard.StageRecords = make([]StageRecord, 0) } func (b *Scoreboard) AddScore(stagename string, results []stage.StageResult) { b.scoreboard.StageRecords = append(b.scoreboard.StageRecords, StageRecord{StageName: stagename, StageResults: results}) } func (b *Scoreboard) SaveFile(filePath string) { json_file, _ := os.Create(filePath) defer json_file.Close() encoder := json.NewEncoder(json_file) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") _ = encoder.Encode(b.scoreboard) } func (b *Scoreboard) Submit() { e := os.Mkdir("repos", 0o777) if e != nil { slog.Error("Encountered problems createing folder: ", "err", e) return } var teapotCommand string origHome := os.Getenv("ORIG_HOME") if origHome != "" { // For drone server teapotCommand = fmt.Sprintf("cp %s/.config/ci/teapot.env .env && joint-teapot JOJ3-scoreboard \"../../scoreboard.json\" %s %s \"JOJ3-examples\" \"JOJ3_dev.csv\"", origHome, b.studentName, b.studentId) } else { // For local developers jointTeapotRoot := os.Getenv("TEAPOT_ROOT") if jointTeapotRoot == "" { slog.Error("Unable to find joint-teapot. Have you configured environment variable TEAPOT_ROOT?") return } teapotCommand = fmt.Sprintf("cp %s/.env .env && source %s/env/bin/activate && python3 -m joint_teapot JOJ3-scoreboard \"../../scoreboard.json\" %s %s \"JOJ3-examples\" \"JOJ3_dev.csv\" && deactivate", jointTeapotRoot, jointTeapotRoot, b.studentName, b.studentId) } defer os.Remove(".env") teapotCmd := exec.Command("/bin/bash", "-c", teapotCommand) defer os.Remove("joint-teapot.log") stderrPipe, err := teapotCmd.StderrPipe() if err != nil { slog.Error("Error creating stderr pipe when submitting scoreboard: ", "err", err) return } err = teapotCmd.Start() if err != nil { slog.Error("Error starting command when submitting scoreboard: ", "err", err) return } var stderr bytes.Buffer _, err = stderr.ReadFrom(stderrPipe) if err != nil { slog.Error("Error reading stderr when submitting scoreboard: ", "err", err) return } err = teapotCmd.Wait() if err != nil { slog.Error("Tried to submit scoreboard, but it finished with error: ", "err", err) slog.Error("Stderr output:", "stderr", stderr.String()) return } slog.Info("Scoreboard was submitted with following outputs: ", "stderr", stderr.String()) }