server/admin/api/handlers.go

132 lines
3.7 KiB
Go
Raw Normal View History

package api
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strconv"
"srs.epita.fr/fic-server/libfic"
"github.com/gorilla/mux"
)
type DispatchFunction func([]string, []byte) (interface{}, error)
func apiHandler(f func (map[string]string,[]byte) (interface{}, error)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent())
w.Header().Set("Content-Type", "application/json")
var ret interface{}
var err error = nil
// Read the body
if r.ContentLength < 0 || r.ContentLength > 6553600 {
http.Error(w, fmt.Sprintf("{errmsg:\"Request too large or request size unknown\"}", err), http.StatusRequestEntityTooLarge)
return
}
var body []byte
if r.ContentLength > 0 {
tmp := make([]byte, 1024)
for {
n, err := r.Body.Read(tmp)
for j := 0; j < n; j++ {
body = append(body, tmp[j])
}
if err != nil || n <= 0 {
break
}
}
}
ret, err = f(mux.Vars(r), body)
// Format response
resStatus := http.StatusOK
if err != nil {
ret = map[string]string{"errmsg": err.Error()}
resStatus = http.StatusBadRequest
log.Println(r.RemoteAddr, resStatus, err.Error())
}
if ret == nil {
ret = map[string]string{"errmsg": "Page not found"}
resStatus = http.StatusNotFound
}
if str, found := ret.(string); found {
w.WriteHeader(resStatus)
io.WriteString(w, str)
} else if bts, found := ret.([]byte); found {
w.WriteHeader(resStatus)
w.Write(bts)
} else if j, err := json.Marshal(ret); err != nil {
http.Error(w, fmt.Sprintf("{\"errmsg\":\"%q\"}", err), http.StatusInternalServerError)
} else {
w.WriteHeader(resStatus)
w.Write(j)
}
}
}
func teamHandler(f func(fic.Team,map[string]string,[]byte) (interface{}, error)) func (map[string]string,[]byte) (interface{}, error) {
return func (args map[string]string, body []byte) (interface{}, error) {
if tid, err := strconv.Atoi(string(args["tid"])); err != nil {
if team, err := fic.GetTeamByInitialName(args["tid"]); err != nil {
return nil, err
} else {
return f(team, args, body)
}
} else if team, err := fic.GetTeam(tid); err != nil {
return nil, err
} else {
return f(team, args, body)
}
}
}
func themeHandler(f func(fic.Theme,map[string]string,[]byte) (interface{}, error)) func (map[string]string,[]byte) (interface{}, error) {
return func (args map[string]string, body []byte) (interface{}, error) {
if tid, err := strconv.Atoi(string(args["tid"])); err != nil {
return nil, err
} else if theme, err := fic.GetTheme(tid); err != nil {
return nil, err
} else {
return f(theme, args, body)
}
}
}
func exerciceHandler(f func(fic.Exercice,map[string]string,[]byte) (interface{}, error)) func (map[string]string,[]byte) (interface{}, error) {
return func (args map[string]string, body []byte) (interface{}, error) {
if eid, err := strconv.Atoi(string(args["eid"])); err != nil {
return nil, err
} else if exercice, err := fic.GetExercice(int64(eid)); err != nil {
return nil, err
} else {
return f(exercice, args, body)
}
}
}
func themedExerciceHandler(f func(fic.Theme,fic.Exercice,map[string]string,[]byte) (interface{}, error)) func (fic.Theme,map[string]string,[]byte) (interface{}, error) {
return func (theme fic.Theme, args map[string]string, body []byte) (interface{}, error) {
if eid, err := strconv.Atoi(string(args["eid"])); err != nil {
return nil, err
} else if exercice, err := fic.GetExercice(int64(eid)); err != nil {
return nil, err
} else {
return f(theme, exercice, args, body)
}
}
}
func notFound(args map[string]string, body []byte) (interface{}, error) {
return nil, nil
}