func ApplyExecution(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || (me.Level != data.Judge && me.Level != data.Administrator) { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) exec, err := data.GetExecution(id) catch(err) if exec.Status != 7 { http.Error(w, "", http.StatusBadRequest) return } subm, err := exec.Submission() catch(err) subm.Apply(exec) err = subm.Put() catch(err) hub.Send([]interface{}{"SYNC", "submissions", subm.Id}) err = data.NewActivity(me, fmt.Sprintf("applied execution %d to submission %d", exec.Id, subm.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func JudgeSubmission(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || (me.Level != data.Judge && me.Level != data.Administrator) { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) subm, err := data.GetSubmission(id) catch(err) subm.Reset() err = subm.Put() catch(err) hub.Send([]interface{}{"SYNC", "submissions", subm.Id}) exec := &data.Execution{ SubmissionId: subm.Id, Apply: true, } err = exec.Put() catch(err) belt.Push(exec) err = data.NewActivity(me, fmt.Sprintf("judged submission %d", subm.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func DeleteProblem(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Level != data.Administrator { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) prob, err := data.GetProblem(id) catch(err) err = prob.Del() catch(err) err = json.NewEncoder(w).Encode(&struct { Id int64 `json:"id"` }{ Id: prob.Id, }) catch(err) hub.Send([]interface{}{"SYNC", "problems"}) err = data.NewActivity(me, fmt.Sprintf("deleted problem %d", prob.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func UpdateSubmission(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || (me.Level != data.Judge && me.Level != data.Administrator) { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) subm, err := data.GetSubmission(id) catch(err) body := struct { Verdict data.Verdict `json:"verdict"` }{} err = json.NewDecoder(r.Body).Decode(&body) catch(err) subm.Tamper(body.Verdict) err = subm.Put() catch(err) err = json.NewEncoder(w).Encode(subm) catch(err) hub.Send([]interface{}{"SYNC", "submissions", subm.Id}) err = data.NewActivity(me, fmt.Sprintf("updated submission %d", subm.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func DeleteClarification(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || (me.Level != data.Judge && me.Level != data.Administrator) { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) clar, err := data.GetClarification(id) catch(err) err = clar.Del() catch(err) json.NewEncoder(w).Encode(&struct { Id int64 `json:"id"` }{ Id: clar.Id, }) hub.Send([]interface{}{"SYNC", "clarifications"}) err = data.NewActivity(me, fmt.Sprintf("deleted clarification %d", clar.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func UpdateClarification(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || (me.Level != data.Judge && me.Level != data.Administrator) { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) clar, err := data.GetClarification(id) catch(err) body := struct { ProblemId int64 `json:"problemId"` Question string `json:"question"` Response data.Response `json:"response"` Message string `json:"message"` }{} err = json.NewDecoder(r.Body).Decode(&body) catch(err) prob, err := data.GetProblem(body.ProblemId) catch(err) if prob != nil { clar.ProblemId = prob.Id } else { clar.ProblemId = 0 } clar.Question = body.Question clar.Response = body.Response clar.Message = body.Message err = clar.Put() catch(err) err = json.NewEncoder(w).Encode(clar) catch(err) hub.Send([]interface{}{"SYNC", "clarifications", clar.Id}) err = data.NewActivity(me, fmt.Sprintf("updated clarification %d", clar.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) if clar.Response != data.Unresponded { if clar.Response == data.Broadcasted { err = data.NewNotification(0, data.Participant, fmt.Sprintf("Clarification %d updated", clar.Id)).Put() catch(err) } else { err = data.NewNotification(clar.AskerId, 0, fmt.Sprintf("Clarification %d updated", clar.Id)).Put() catch(err) } hub.Send([]interface{}{"SYNC", "notifications"}) } }
func CreateAccount(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Level != data.Administrator { http.Error(w, "", http.StatusForbidden) return } body := struct { Handle string `json:"handle"` Password string `json:"password"` Level data.Level `json:"level"` Name string `json:"name"` }{} err := json.NewDecoder(r.Body).Decode(&body) catch(err) switch { case len(body.Handle) < 4: http.Error(w, "", http.StatusBadRequest) return case len(body.Password) < 4: http.Error(w, "", http.StatusBadRequest) return case body.Level != data.Participant && body.Level != data.Judge && body.Level != data.Administrator: http.Error(w, "", http.StatusBadRequest) return case body.Name == "": body.Name = body.Handle } acc := &data.Account{} acc.Handle = body.Handle err = acc.SetPassword(body.Password) catch(err) acc.Level = body.Level acc.Name = body.Name err = acc.Put() if err, ok := err.(*sqlite3.Error); ok && err.Code() == sqlite3.CONSTRAINT_UNIQUE { http.Error(w, "", http.StatusConflict) return } catch(err) err = json.NewEncoder(w).Encode(acc) catch(err) hub.Send([]interface{}{"SYNC", "accounts"}) err = data.NewActivity(me, fmt.Sprintf("created account %d", acc.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func ImportAccounts(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Level != data.Administrator { http.Error(w, "", http.StatusForbidden) return } body := csv.NewReader(r.Body) for { cols, err := body.Read() if err == io.EOF { break } catch(err) acc := &data.Account{} acc.Handle = cols[0] err = acc.SetPassword(cols[1]) catch(err) col2, err := strconv.ParseInt(cols[2], 10, 32) catch(err) acc.Level = data.Level(col2) acc.Name = cols[3] switch { case len(acc.Handle) < 4: continue case len(acc.Password) < 4: continue case acc.Level != data.Participant && acc.Level != data.Judge && acc.Level != data.Administrator: continue case acc.Name == "": acc.Name = acc.Handle } err = acc.Put() if err, ok := err.(*sqlite3.Error); ok && err.Code() == sqlite3.CONSTRAINT_UNIQUE { continue } catch(err) err = data.NewActivity(me, fmt.Sprintf("created account %d", acc.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) } hub.Send([]interface{}{"SYNC", "accounts"}) }
func CreateSubmission(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil { http.Error(w, "", http.StatusForbidden) return } body := struct { ProblemId int64 `json:"problemId"` Language string `json:"language"` Source string `json:"source"` }{} err := json.NewDecoder(r.Body).Decode(&body) catch(err) prob, err := data.GetProblem(body.ProblemId) catch(err) key, err := data.Blobs.Put("", strings.NewReader(body.Source)) catch(err) subm := &data.Submission{ AuthorId: me.Id, ProblemId: prob.Id, Language: body.Language, SourceKey: string(key), } err = subm.Put() catch(err) err = json.NewEncoder(w).Encode(subm) catch(err) hub.Send([]interface{}{"SYNC", "submissions"}) err = data.NewActivity(me, fmt.Sprintf("created submission %d", subm.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) if prob.Judge == "automatic" { exec := &data.Execution{ SubmissionId: subm.Id, Apply: true, } err = exec.Put() catch(err) belt.Push(exec) } }
func HandleLogin(w http.ResponseWriter, r *http.Request) { acc, err := data.GetAccountByHandle(r.FormValue("handle")) catch(err) if acc == nil { http.Error(w, "", http.StatusUnauthorized) return } ok, err := acc.CmpPassword(r.FormValue("password")) catch(err) if !ok { http.Error(w, "", http.StatusUnauthorized) return } sess, err := Store.Get(r, "s") catch(err) sess.Values["me.id"] = acc.Id err = sess.Save(r, w) catch(err) host, _, err := net.SplitHostPort(r.RemoteAddr) catch(err) err = data.NewActivity(acc, fmt.Sprintf("logged in from %s", host)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func UpdateAccountPart(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) acc, err := data.GetAccount(id) catch(err) me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Id != acc.Id { http.Error(w, "", http.StatusForbidden) return } body := struct { Notified time.Time `json:"notified"` }{} err = json.NewDecoder(r.Body).Decode(&body) catch(err) acc.Notified = body.Notified err = acc.Put() catch(err) json.NewEncoder(w).Encode(acc) hub.Send([]interface{}{"SYNC", "accounts", acc.Id}) }
func CreateExecution(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || (me.Level != data.Judge && me.Level != data.Administrator) { http.Error(w, "", http.StatusForbidden) return } body := struct { SubmissionId int64 `json:"submissionId"` }{} err := json.NewDecoder(r.Body).Decode(&body) catch(err) subm, err := data.GetSubmission(body.SubmissionId) catch(err) exec := &data.Execution{ SubmissionId: subm.Id, } err = exec.Put() catch(err) belt.Push(exec) err = json.NewEncoder(w).Encode(exec) catch(err) err = data.NewActivity(me, fmt.Sprintf("created execution %d for submission %d", exec.Id, subm.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func CreateProblem(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Level != data.Administrator { http.Error(w, "", http.StatusForbidden) return } body := struct { Char string `json:"char"` Title string `json:"title"` }{} err := json.NewDecoder(r.Body).Decode(&body) catch(err) switch { case len(body.Char) != 1 || !strings.Contains("abcdefghijklmnopqrstuvwxyz", body.Char): http.Error(w, "", http.StatusBadRequest) return case body.Title == "": http.Error(w, "", http.StatusBadRequest) return } prob := &data.Problem{ Slug: strings.Trim(regexp.MustCompile("[^a-z0-9]+").ReplaceAllString(strings.ToLower(body.Char+" "+body.Title), "-"), " -"), Char: body.Char, Title: body.Title, Judge: "automatic", Scoring: "strict", } err = prob.Put() catch(err) json.NewEncoder(w).Encode(prob) hub.Send([]interface{}{"SYNC", "problems"}) err = data.NewActivity(me, fmt.Sprintf("created problem %d", prob.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func UpdateAccount(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Level != data.Administrator { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) acc, err := data.GetAccount(id) catch(err) body := struct { Handle string `json:"handle"` Password string `json:"password"` Level data.Level `json:"level"` Name string `json:"name"` }{} err = json.NewDecoder(r.Body).Decode(&body) catch(err) acc.Handle = body.Handle if body.Password != "" { err = acc.SetPassword(body.Password) catch(err) } acc.Level = body.Level acc.Name = body.Name err = acc.Put() catch(err) json.NewEncoder(w).Encode(acc) hub.Send([]interface{}{"SYNC", "accounts", acc.Id}) err = data.NewActivity(me, fmt.Sprintf("updated account %d", acc.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func CreateClarification(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) body := struct { ProblemId int64 `json:"problemId"` Question string `json:"question"` }{} err := json.NewDecoder(r.Body).Decode(&body) catch(err) clar := &data.Clarification{ AskerId: me.Id, Question: body.Question, } prob, err := data.GetProblem(body.ProblemId) catch(err) if prob != nil { clar.ProblemId = prob.Id } err = clar.Put() catch(err) err = json.NewEncoder(w).Encode(clar) catch(err) hub.Send([]interface{}{"SYNC", "clarifications"}) err = data.NewActivity(me, fmt.Sprintf("created clarification %d", clar.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) err = data.NewNotification(0, data.Judge, fmt.Sprintf("Clarification %d requested", clar.Id)).Put() catch(err) err = data.NewNotification(0, data.Administrator, fmt.Sprintf("Clarification %d requested", clar.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "notifications"}) }
func UpdateContest(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Level != data.Administrator { http.Error(w, "", http.StatusForbidden) return } cnt, err := data.GetContest() catch(err) err = json.NewDecoder(r.Body).Decode(cnt) catch(err) err = cnt.Put() catch(err) err = json.NewEncoder(w).Encode(cnt) catch(err) hub.Send([]interface{}{"SYNC", "contest"}) err = data.NewActivity(me, fmt.Sprintf("updated contest %d", cnt.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func UpdateProblem(w http.ResponseWriter, r *http.Request) { me, _ := context.Get(r, "me").(*data.Account) if me == nil || me.Level != data.Administrator { http.Error(w, "", http.StatusForbidden) return } vars := mux.Vars(r) id, err := strconv.ParseInt(vars["id"], 10, 64) catch(err) prob, err := data.GetProblem(id) catch(err) if prob == nil { http.Error(w, "", http.StatusNotFound) } body := struct { Char string `json:"char"` Title string `json:"title"` Statement struct { Body string `json:"body"` Input string `json:"input"` Output string `json:"output"` } `json:"statement"` Samples []struct { Input string `json:"input"` Answer string `json:"answer"` } `json:"samples"` Notes string `json:"notes"` Judge string `json:"judge"` Checker struct { Language string `json:"language"` Source string `json:"source"` SourceKey string `json:"sourceKey"` } `json:"checker"` Limits struct { Cpu float64 `json:"cpu"` Memory int `json:"memory"` } `json:"limits"` Languages []string `json:"languages"` Tests []struct { Input string `json:"input"` InputKey string `json:"inputKey"` Answer string `json:"answer"` AnswerKey string `json:"answerKey"` Points int `json:"points"` } `json:"tests"` Scoring string `json:"scoring"` }{} err = json.NewDecoder(r.Body).Decode(&body) catch(err) switch { case len(body.Char) != 1 || !strings.Contains("abcdefghijklmnopqrstuvwxyz", body.Char): http.Error(w, "", http.StatusBadRequest) return case body.Title == "": http.Error(w, "", http.StatusBadRequest) return } prob.Slug = strings.Trim(regexp.MustCompile("[^a-z0-9]+").ReplaceAllString(strings.ToLower(body.Char+" "+body.Title), "-"), " -") prob.Char = body.Char prob.Title = body.Title prob.Statement = body.Statement prob.Samples = body.Samples prob.Notes = body.Notes prob.Judge = body.Judge if body.Checker.Language != "" { if body.Checker.SourceKey == "" { body.Checker.SourceKey = fmt.Sprintf("problems:%d:checker:source", prob.Id) _, err := data.Blobs.Put(body.Checker.SourceKey, strings.NewReader(body.Checker.Source)) catch(err) } prob.Checker = struct { Language string `json:"language"` SourceKey string `json:"sourceKey"` }{ Language: body.Checker.Language, SourceKey: body.Checker.SourceKey, } } else { prob.Checker = struct { Language string `json:"language"` SourceKey string `json:"sourceKey"` }{ Language: "", SourceKey: "", } } prob.Limits = body.Limits prob.Languages = body.Languages prob.Tests = nil for i, test := range body.Tests { if test.InputKey == "" { test.InputKey = fmt.Sprintf("problems:%d:tests:%d:in", prob.Id, i) _, err := data.Blobs.Put(test.InputKey, strings.NewReader(test.Input)) catch(err) } if test.AnswerKey == "" { test.AnswerKey = fmt.Sprintf("problems:%d:tests:%d:ans", prob.Id, i) _, err := data.Blobs.Put(test.AnswerKey, strings.NewReader(test.Answer)) catch(err) } prob.Tests = append(prob.Tests, struct { InputKey string `json:"inputKey"` AnswerKey string `json:"answerKey"` Points int `json:"points"` }{ InputKey: test.InputKey, AnswerKey: test.AnswerKey, Points: test.Points, }) } prob.Scoring = body.Scoring err = prob.Put() catch(err) err = json.NewEncoder(w).Encode(prob) catch(err) hub.Send([]interface{}{"SYNC", "problems", prob.Id}) err = data.NewActivity(me, fmt.Sprintf("updated problem %d", prob.Id)).Put() catch(err) hub.Send([]interface{}{"SYNC", "activities"}) }
func init() { go func() { for id := range chZerk { cnt, err := GetContest() catch(err) acc, err := GetAccount(id) catch(err) s, err := GetStandingByAuthor(acc) catch(err) if s == nil { continue } if acc.Level != Participant { err = s.Del() catch(err) continue } s.Author.Handle = acc.Handle s.Author.Name = acc.Name s.Attempts = map[string]*Attempt{} probs := map[int64]*Problem{} subms, err := ListSubmissionsByAuthor(acc) catch(err) for i := len(subms) - 1; i >= 0; i-- { subm := subms[i] prob, _ := probs[subm.ProblemId] if prob == nil { prob, err = GetProblem(subm.ProblemId) catch(err) probs[subm.ProblemId] = prob delete(s.Attempts, strconv.FormatInt(prob.Id, 10)) } att := s.Attempts[strconv.FormatInt(prob.Id, 10)] if att == nil { att = &Attempt{ ProblemId: prob.Id, } s.Attempts[strconv.FormatInt(prob.Id, 10)] = att } if subm.Verdict == Accepted { score := 0 perfect := true if subm.Manual { for _, test := range prob.Tests { score += test.Points } } else { for _, test := range subm.Tests { if test.Verdict == Accepted { score += test.Points } else { perfect = false } } } if score > att.Score { att.Score = score att.Tries += att.Extras + 1 att.Extras = 0 att.Penalty = (att.Tries-1)*20 + int(subm.Created.Sub(cnt.Starts)/time.Minute) att.Perfect = perfect } } else if subm.Verdict != CompilationError { att.Extras += 1 } } s.Score = 0 s.Penalty = 0 for _, att := range s.Attempts { s.Score += att.Score s.Penalty += att.Penalty } err = s.Put() catch(err) hub.Send([]interface{}{"SYNC", "standings"}) } }() }