2020-11-20 14:46:52 +00:00
package main
import (
2023-03-08 03:40:03 +00:00
"fmt"
2022-07-09 17:42:00 +00:00
"log"
2020-11-20 14:46:52 +00:00
"net/http"
2023-03-05 12:17:25 +00:00
"strconv"
2020-11-20 14:46:52 +00:00
2022-07-09 17:42:00 +00:00
"github.com/gin-gonic/gin"
2020-11-20 14:46:52 +00:00
)
2022-07-09 17:42:00 +00:00
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" )
2020-11-20 14:46:52 +00:00
} else {
2022-07-09 17:42:00 +00:00
c . JSON ( http . StatusOK , score )
2020-11-20 14:46:52 +00:00
}
2022-07-09 17:42:00 +00:00
} 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 )
2020-11-20 14:46:52 +00:00
} else {
2022-07-09 17:42:00 +00:00
c . AbortWithStatusJSON ( http . StatusForbidden , gin . H { "errmsg" : "Not authorized" } )
return
2020-11-20 14:46:52 +00:00
}
}
2022-07-09 17:42:00 +00:00
} )
2020-11-20 14:46:52 +00:00
}
2023-03-05 12:17:25 +00:00
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 ( )
}
}
2023-03-08 03:40:03 +00:00
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 {
2020-11-20 14:46:52 +00:00
return nil , errr
} else {
defer rows . Close ( )
2023-03-08 03:40:03 +00:00
scores = map [ int64 ] map [ string ] * float64 { }
2020-11-20 14:46:52 +00:00
for rows . Next ( ) {
var id_user int64
2023-03-08 03:40:03 +00:00
var kind string
var id int64
2020-11-20 14:46:52 +00:00
var score * float64
2023-03-08 03:40:03 +00:00
if err = rows . Scan ( & id_user , & kind , & id , & score ) ; err != nil {
2020-11-20 14:46:52 +00:00
return
}
if scores [ id_user ] == nil {
2023-03-08 03:40:03 +00:00
scores [ id_user ] = map [ string ] * float64 { }
2020-11-20 14:46:52 +00:00
}
2023-03-08 03:40:03 +00:00
scores [ id_user ] [ fmt . Sprintf ( "%c.%d" , kind [ 0 ] , id ) ] = score
2020-11-20 14:46:52 +00:00
}
if err = rows . Err ( ) ; err != nil {
return
}
}
return
}
func ( s Survey ) GetGrades ( ) ( scores map [ int64 ] * float64 , err error ) {
2023-03-08 03:40:03 +00:00
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 {
2020-11-20 14:46:52 +00:00
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 ) {
2023-03-08 03:40:03 +00:00
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 {
2020-11-20 14:46:52 +00:00
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
}