package main import ( "fmt" "log" "net/http" "strconv" "github.com/gin-gonic/gin" ) func declareAPIAuthGradesRoutes(router *gin.RouterGroup) { router.GET("/grades", func(c *gin.Context) { uauth := c.MustGet("LoggedUser").(*User) if survey, ok := c.Get("survey"); !ok { if uauth == nil || !uauth.IsAdmin { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not authorized"}) return } grades, err := GetAllGrades() if err != nil { log.Println("Unable to GetAllGrades:", err) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to retrieve grades."}) return } c.JSON(http.StatusOK, grades) } else { s := survey.(*Survey) if user, ok := c.Get("user"); ok { u := user.(*User) if uauth == nil || !((s.Shown && u.Id == uauth.Id) || uauth.IsAdmin) { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not accessible"}) return } score, err := s.GetUserGrades(u) if err != nil { log.Printf("Unable to GetUserGrades(sid=%d; uid=%d): %s", s.Id, u.Id, err.Error()) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrive user grade. Please try again later."}) return } if score == nil { c.JSON(http.StatusOK, "N/A") } else { c.JSON(http.StatusOK, score) } } else if uauth.IsAdmin { scores, err := s.GetGrades() if err != nil { log.Printf("Unable to GetGrades(sid=%d): %s", s.Id, err.Error()) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrive grades."}) return } c.JSON(http.StatusOK, scores) } else { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not authorized"}) return } } }) } func gradeHandler(c *gin.Context) { work := c.MustGet("work").(*Work) if gid, err := strconv.Atoi(string(c.Param("gid"))); err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Bad grade identifier."}) return } else if grade, err := work.GetGrade(int64(gid)); err != nil { c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Grade not found."}) return } else { c.Set("grade", grade) c.Next() } } func GetAllGrades() (scores map[int64]map[string]*float64, err error) { if rows, errr := DBQuery("SELECT id_user, kind, id, SUM(score)/COUNT(*) FROM student_scores GROUP BY id_user, kind, id"); errr != nil { return nil, errr } else { defer rows.Close() scores = map[int64]map[string]*float64{} for rows.Next() { var id_user int64 var kind string var id int64 var score *float64 if err = rows.Scan(&id_user, &kind, &id, &score); err != nil { return } if scores[id_user] == nil { scores[id_user] = map[string]*float64{} } scores[id_user][fmt.Sprintf("%c.%d", kind[0], id)] = score } if err = rows.Err(); err != nil { return } } return } func (s Survey) GetGrades() (scores map[int64]*float64, err error) { if rows, errr := DBQuery("SELECT id_question, SUM(score)/COUNT(*) FROM student_scores WHERE kind = 'survey' AND id=? GROUP BY id_question", s.Id); errr != nil { return nil, errr } else { defer rows.Close() scores = map[int64]*float64{} for rows.Next() { var id_question int64 var score *float64 if err = rows.Scan(&id_question, &score); err != nil { return } scores[id_question] = score } if err = rows.Err(); err != nil { return } } return } func (s Survey) GetUserGrades(u *User) (scores map[int64]*float64, err error) { if rows, errr := DBQuery("SELECT id_question, MAX(score) FROM student_scores WHERE kind = 'survey' AND id=? AND id_user = ? GROUP BY id_question", s.Id, u.Id); errr != nil { return nil, errr } else { defer rows.Close() scores = map[int64]*float64{} for rows.Next() { var id_question int64 var score *float64 if err = rows.Scan(&id_question, &score); err != nil { return } scores[id_question] = score } if err = rows.Err(); err != nil { return } } return }