2020-03-04 11:07:12 +00:00
package main
import (
"encoding/json"
"errors"
"net/http"
"time"
"strconv"
"github.com/julienschmidt/httprouter"
)
func init ( ) {
router . GET ( "/api/surveys" , apiAuthHandler (
func ( u * User , _ httprouter . Params , _ [ ] byte ) HTTPResponse {
2020-03-08 01:18:32 +00:00
if u == nil {
return formatApiResponse ( getSurveys ( "WHERE shown = TRUE AND NOW() > start_availability" ) )
} else if u . IsAdmin {
2020-03-04 11:07:12 +00:00
return formatApiResponse ( getSurveys ( "" ) )
} else {
return formatApiResponse ( getSurveys ( "WHERE shown = TRUE" ) )
}
} ) )
router . POST ( "/api/surveys" , apiHandler ( func ( _ httprouter . Params , body [ ] byte ) HTTPResponse {
var new Survey
if err := json . Unmarshal ( body , & new ) ; err != nil {
return APIErrorResponse { err : err }
}
return formatApiResponse ( NewSurvey ( new . Title , new . Shown , new . StartAvailability , new . EndAvailability ) )
} , adminRestricted ) )
router . GET ( "/api/surveys/:sid" , apiAuthHandler ( surveyAuthHandler (
func ( s Survey , u * User , _ [ ] byte ) HTTPResponse {
2020-03-08 00:06:44 +00:00
if s . Shown || ( u != nil && u . IsAdmin ) {
2020-03-04 11:07:12 +00:00
return APIResponse { s }
} else {
return APIErrorResponse {
status : http . StatusForbidden ,
err : errors . New ( "Not accessible" ) ,
}
}
} ) ) )
router . PUT ( "/api/surveys/:sid" , apiHandler ( surveyHandler ( func ( current Survey , body [ ] byte ) HTTPResponse {
var new Survey
if err := json . Unmarshal ( body , & new ) ; err != nil {
return APIErrorResponse { err : err }
}
new . Id = current . Id
return formatApiResponse ( new . Update ( ) )
} ) , adminRestricted ) )
router . DELETE ( "/api/surveys/:sid" , apiHandler ( surveyHandler (
func ( s Survey , _ [ ] byte ) HTTPResponse {
return formatApiResponse ( s . Delete ( ) )
} ) , adminRestricted ) )
2020-03-08 00:06:44 +00:00
router . GET ( "/api/surveys/:sid/score" , apiAuthHandler ( surveyAuthHandler (
func ( s Survey , u * User , _ [ ] byte ) HTTPResponse {
if s . Shown || ( u != nil && u . IsAdmin ) {
return formatApiResponse ( s . GetScore ( u ) )
} else {
return APIErrorResponse {
status : http . StatusForbidden ,
err : errors . New ( "Not accessible" ) ,
}
}
} ) , loggedUser ) )
2020-03-04 11:07:12 +00:00
}
func surveyHandler ( f func ( Survey , [ ] byte ) HTTPResponse ) func ( httprouter . Params , [ ] byte ) HTTPResponse {
return func ( ps httprouter . Params , body [ ] byte ) HTTPResponse {
if sid , err := strconv . Atoi ( string ( ps . ByName ( "sid" ) ) ) ; err != nil {
return APIErrorResponse { err : err }
} else if survey , err := getSurvey ( sid ) ; err != nil {
return APIErrorResponse { err : err }
} else {
return f ( survey , body )
}
}
}
func surveyAuthHandler ( f func ( Survey , * User , [ ] byte ) HTTPResponse ) func ( * User , httprouter . Params , [ ] byte ) HTTPResponse {
return func ( u * User , ps httprouter . Params , body [ ] byte ) HTTPResponse {
if sid , err := strconv . Atoi ( string ( ps . ByName ( "sid" ) ) ) ; err != nil {
return APIErrorResponse { err : err }
} else if survey , err := getSurvey ( sid ) ; err != nil {
return APIErrorResponse { err : err }
} else {
return f ( survey , u , body )
}
}
}
type Survey struct {
Id int64 ` json:"id" `
Title string ` json:"title" `
Shown bool ` json:"shown" `
2020-03-08 00:06:44 +00:00
Corrected bool ` json:"corrected" `
2020-03-04 11:07:12 +00:00
StartAvailability time . Time ` json:"start_availability" `
EndAvailability time . Time ` json:"end_availability" `
}
func getSurveys ( cnd string , param ... interface { } ) ( surveys [ ] Survey , err error ) {
2020-03-08 00:06:44 +00:00
if rows , errr := DBQuery ( "SELECT id_survey, title, shown, corrected, start_availability, end_availability FROM surveys " + cnd , param ... ) ; errr != nil {
2020-03-04 11:07:12 +00:00
return nil , errr
} else {
defer rows . Close ( )
for rows . Next ( ) {
var s Survey
2020-03-08 00:06:44 +00:00
if err = rows . Scan ( & s . Id , & s . Title , & s . Shown , & s . Corrected , & s . StartAvailability , & s . EndAvailability ) ; err != nil {
2020-03-04 11:07:12 +00:00
return
}
surveys = append ( surveys , s )
}
if err = rows . Err ( ) ; err != nil {
return
}
return
}
}
func getSurvey ( id int ) ( s Survey , err error ) {
2020-03-08 00:06:44 +00:00
err = DBQueryRow ( "SELECT id_survey, title, shown, corrected, start_availability, end_availability FROM surveys WHERE id_survey=?" , id ) . Scan ( & s . Id , & s . Title , & s . Shown , & s . Corrected , & s . StartAvailability , & s . EndAvailability )
2020-03-04 11:07:12 +00:00
return
}
func NewSurvey ( title string , shown bool , startAvailability time . Time , endAvailability time . Time ) ( Survey , error ) {
if res , err := DBExec ( "INSERT INTO surveys (title, shown, start_availability, end_availability) VALUES (?, ?, ?, ?)" , title , shown , startAvailability , endAvailability ) ; err != nil {
return Survey { } , err
} else if sid , err := res . LastInsertId ( ) ; err != nil {
return Survey { } , err
} else {
2020-03-08 00:06:44 +00:00
return Survey { sid , title , shown , false , startAvailability , endAvailability } , nil
2020-03-04 11:07:12 +00:00
}
}
2020-03-08 00:06:44 +00:00
func ( s Survey ) GetScore ( u * User ) ( score int64 , err error ) {
err = DBQueryRow ( "SELECT SUM(M.score) FROM (SELECT MAX(score) FROM survey_responses R INNER JOIN survey_quests Q ON Q.id_question = R.id_question WHERE Q.id_survey=? AND R.id_user=? GROUP BY id_question) M" , s . Id , u . Id ) . Scan ( & score )
return
}
2020-03-04 11:07:12 +00:00
func ( s Survey ) Update ( ) ( int64 , error ) {
2020-03-08 00:06:44 +00:00
if res , err := DBExec ( "UPDATE surveys SET title = ?, shown = ?, corrected = ?, start_availability = ?, end_availability = ? WHERE id_survey = ?" , s . Title , s . Shown , s . Corrected , s . StartAvailability , s . EndAvailability , s . Id ) ; err != nil {
2020-03-04 11:07:12 +00:00
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
func ( s Survey ) Delete ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM surveys WHERE id_survey = ?" , s . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
func ClearSurveys ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM surveys" ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}