Use github.com/julienschmidt/httprouter instead of gorilla

This commit is contained in:
nemunaire 2016-12-16 00:51:56 +01:00
parent 5a0b81ba32
commit 3b320469b5
13 changed files with 226 additions and 172 deletions

View File

@ -5,25 +5,26 @@ import (
"os"
"srs.epita.fr/fic-server/libfic"
"github.com/julienschmidt/httprouter"
)
func init() {
router.Path("/ca").Methods("GET").HandlerFunc(apiHandler(genCA))
router.GET("/api/ca", apiHandler(genCA))
rt := router.PathPrefix("/teams/{tid}/certificate").Subrouter()
rt.Path("/").Methods("GET").HandlerFunc(apiHandler(teamHandler(GetTeamCertificate)))
rt.Path("/generate").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) { return team.GenerateCert(), nil })))
rt.Path("/revoke").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) { return team.RevokeCert(), nil })))
router.GET("/api/teams/:tid/certificate/", apiHandler(teamHandler(GetTeamCertificate)))
router.GET("/api/teams/:tid/certificate/generate", apiHandler(teamHandler(
func(team fic.Team, _ []byte) (interface{}, error) { return team.GenerateCert(), nil })))
router.GET("/api/teams/:tid/certificate/revoke", apiHandler(teamHandler(
func(team fic.Team, _ []byte) (interface{}, error) { return team.RevokeCert(), nil })))
}
func genCA(args map[string]string, body []byte) (interface{}, error) {
func genCA(_ httprouter.Params, body []byte) (interface{}, error) {
return fic.GenerateCA(), nil
}
func GetTeamCertificate(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
if fd, err := os.Open("../PKI/pkcs/" + team.Name + ".p12"); err == nil {
func GetTeamCertificate(team fic.Team, body []byte) (interface{}, error) {
if fd, err := os.Open("../PKI/pkcs/" + team.Name + ".p12"); err == nil {
return ioutil.ReadAll(fd)
} else {
return nil, err

View File

@ -2,13 +2,15 @@ package api
import (
"srs.epita.fr/fic-server/libfic"
"github.com/julienschmidt/httprouter"
)
func init() {
router.Path("/events/").Methods("GET").HandlerFunc(apiHandler(getEvents))
router.GET("/api/events/", apiHandler(getEvents))
}
func getEvents(args map[string]string, body []byte) (interface{}, error) {
func getEvents(_ httprouter.Params, _ []byte) (interface{}, error) {
if evts, err := fic.GetEvents(); err != nil {
return nil, err
} else {

View File

@ -6,27 +6,29 @@ import (
"strconv"
"srs.epita.fr/fic-server/libfic"
"github.com/julienschmidt/httprouter"
)
func init() {
router.Path("/exercices/").Methods("GET").HandlerFunc(apiHandler(listExercices))
re := router.Path("/exercices/{eid:[0-9]+}").Subrouter()
re.Methods("GET").HandlerFunc(apiHandler(exerciceHandler(showExercice)))
re.Methods("PUT").HandlerFunc(apiHandler(updateExercice))
re.Methods("DELETE").HandlerFunc(apiHandler(deleteExercice))
router.GET("/api/exercices/", apiHandler(listExercices))
router.GET("/api/exercices/:eid", apiHandler(exerciceHandler(showExercice)))
router.PUT("/api/exercices/:eid", apiHandler(updateExercice))
router.DELETE("/api/exercices/:eid", apiHandler(deleteExercice))
}
func listExercices(args map[string]string, body []byte) (interface{}, error) {
func listExercices(_ httprouter.Params, body []byte) (interface{}, error) {
// List all exercices
return fic.GetExercices()
}
func showExercice(exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func showExercice(exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice, nil
}
func deleteExercice(args map[string]string, body []byte) (interface{}, error) {
if eid, err := strconv.Atoi(args["eid"]); err != nil {
func deleteExercice(ps httprouter.Params, body []byte) (interface{}, error) {
if eid, err := strconv.Atoi(ps.ByName("eid")); err != nil {
return nil, err
} else if exercice, err := fic.GetExercice(int64(eid)); err != nil {
return nil, err
@ -43,8 +45,8 @@ type uploadedExercice struct {
VideoURI string
}
func updateExercice(args map[string]string, body []byte) (interface{}, error) {
if eid, err := strconv.Atoi(args["eid"]); err != nil {
func updateExercice(ps httprouter.Params, body []byte) (interface{}, error) {
if eid, err := strconv.Atoi(ps.ByName("eid")); err != nil {
return nil, err
} else if exercice, err := fic.GetExercice(int64(eid)); err != nil {
return nil, err
@ -75,7 +77,7 @@ func updateExercice(args map[string]string, body []byte) (interface{}, error) {
}
}
func createExercice(theme fic.Theme, args map[string]string, body []byte) (interface{}, error) {
func createExercice(theme fic.Theme, body []byte) (interface{}, error) {
// Create a new exercice
var ue uploadedExercice
if err := json.Unmarshal(body, &ue); err != nil {
@ -103,7 +105,7 @@ type uploadedKey struct {
Key string
}
func createExerciceKey(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func createExerciceKey(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
var uk uploadedKey
if err := json.Unmarshal(body, &uk); err != nil {
return nil, err
@ -122,7 +124,7 @@ type uploadedHint struct {
Cost int64
}
func createExerciceHint(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func createExerciceHint(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
var uh uploadedHint
if err := json.Unmarshal(body, &uh); err != nil {
return nil, err

View File

@ -27,7 +27,7 @@ type uploadedFile struct {
Parts []string
}
func createExerciceFile(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func createExerciceFile(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
var uf uploadedFile
if err := json.Unmarshal(body, &uf); err != nil {
return nil, err

View File

@ -10,14 +10,14 @@ import (
"srs.epita.fr/fic-server/libfic"
"github.com/gorilla/mux"
"github.com/julienschmidt/httprouter"
)
type DispatchFunction func([]string, []byte) (interface{}, error)
type DispatchFunction func(httprouter.Params, []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) {
func apiHandler(f DispatchFunction) func(http.ResponseWriter, *http.Request, httprouter.Params) {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
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")
@ -44,7 +44,7 @@ func apiHandler(f func (map[string]string,[]byte) (interface{}, error)) func(htt
}
}
ret, err = f(mux.Vars(r), body)
ret, err = f(ps, body)
// Format response
resStatus := http.StatusOK
@ -74,58 +74,83 @@ func apiHandler(f func (map[string]string,[]byte) (interface{}, error)) func(htt
}
}
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 {
func teamPublicHandler(f func(*fic.Team,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
return func (ps httprouter.Params, body []byte) (interface{}, error) {
if tid, err := strconv.Atoi(string(ps.ByName("tid"))); err != nil {
if team, err := fic.GetTeamByInitialName(ps.ByName("tid")); err != nil {
return nil, err
} else {
return f(team, args, body)
return f(&team, body)
}
} else if tid == 0 {
return f(nil, body)
} else if team, err := fic.GetTeam(tid); err != nil {
return nil, err
} else {
return f(&team, body)
}
}
}
func teamHandler(f func(fic.Team,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
return func (ps httprouter.Params, body []byte) (interface{}, error) {
if tid, err := strconv.Atoi(string(ps.ByName("tid"))); err != nil {
if team, err := fic.GetTeamByInitialName(ps.ByName("tid")); err != nil {
return nil, err
} else {
return f(team, body)
}
} else if team, err := fic.GetTeam(tid); err != nil {
return nil, err
} else {
return f(team, args, body)
return f(team, 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 {
func themeHandler(f func(fic.Theme,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
return func (ps httprouter.Params, body []byte) (interface{}, error) {
if thid, err := strconv.Atoi(string(ps.ByName("thid"))); err != nil {
return nil, err
} else if theme, err := fic.GetTheme(tid); err != nil {
} else if theme, err := fic.GetTheme(thid); err != nil {
return nil, err
} else {
return f(theme, args, body)
return f(theme, 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 {
func exerciceHandler(f func(fic.Exercice,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
return func (ps httprouter.Params, body []byte) (interface{}, error) {
if eid, err := strconv.Atoi(string(ps.ByName("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)
return f(exercice, 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 themedExerciceHandler(f func(fic.Theme,fic.Exercice,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
return func (ps httprouter.Params, body []byte) (interface{}, error) {
var theme fic.Theme
var exercice fic.Exercice
themeHandler(func (th fic.Theme, _[]byte) (interface{}, error) {
theme = th
return nil,nil
})(ps, body)
exerciceHandler(func (ex fic.Exercice, _[]byte) (interface{}, error) {
exercice = ex
return nil,nil
})(ps, body)
return f(theme, exercice, body)
}
}
func notFound(args map[string]string, body []byte) (interface{}, error) {
func notFound(ps httprouter.Params, _ []byte) (interface{}, error) {
return nil, nil
}

View File

@ -1,14 +1,11 @@
package api
import (
"github.com/gorilla/mux"
"github.com/julienschmidt/httprouter"
)
var api_router = mux.NewRouter().StrictSlash(true)
var router = httprouter.New()
var router = api_router.PathPrefix("/api/").Subrouter()
func Router() *mux.Router {
return api_router
func Router() *httprouter.Router {
return router
}

View File

@ -6,66 +6,59 @@ import (
"strings"
"srs.epita.fr/fic-server/libfic"
"github.com/julienschmidt/httprouter"
)
func init() {
rts := router.PathPrefix("/teams").Subrouter()
router.Path("/teams.json").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
router.GET("/api/teams.json", apiHandler(
func(httprouter.Params,[]byte) (interface{}, error) {
return fic.ExportTeams() }))
rts.Path("/").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
return fic.GetTeams() }))
rts.Path("/binding").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
router.GET("/api/teams-binding", apiHandler(
func(httprouter.Params,[]byte) (interface{}, error) {
return bindingTeams() }))
rts.Path("/nginx").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
router.GET("/api/teams-nginx", apiHandler(
func(httprouter.Params,[]byte) (interface{}, error) {
return nginxGenTeam() }))
rts.Path("/nginx-members").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
router.GET("/api/teams-nginx-members", apiHandler(
func(httprouter.Params,[]byte) (interface{}, error) {
return nginxGenMember() }))
rts.Path("/binding").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
router.GET("/api/teams-tries.json", apiHandler(
func(httprouter.Params,[]byte) (interface{}, error) {
return fic.GetTries(nil, nil) }))
rts.Path("/0/my.json").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
return fic.MyJSONTeam(nil, true) }))
rts.Path("/0/wait.json").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
return fic.MyJSONTeam(nil, false) }))
rts.Path("/0/stats.json").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
return fic.GetTeamsStats(nil) }))
rts.Path("/0/tries").Methods("GET").HandlerFunc(apiHandler(
func(map[string]string,[]byte) (interface{}, error) {
return fic.GetTries(nil, nil) }))
router.GET("/api/teams/", apiHandler(
func(httprouter.Params,[]byte) (interface{}, error) {
return fic.GetTeams() }))
rt := rts.PathPrefix("/{tid}").Subrouter()
rt.Path("/").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
router.GET("/api/teams/:tid/", apiHandler(teamHandler(
func(team fic.Team, _ []byte) (interface{}, error) {
return team, nil })))
rt.Path("/").Methods("DELETE").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
router.DELETE("/api/teams/:tid/", apiHandler(teamHandler(
func(team fic.Team, _ []byte) (interface{}, error) {
return team.Delete() })))
rt.Path("/my.json").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
return fic.MyJSONTeam(&team, true) })))
rt.Path("/wait.json").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
return fic.MyJSONTeam(&team, false) })))
rt.Path("/stats.json").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
return team.GetStats() })))
rt.Path("/tries").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
return fic.GetTries(&team, nil) })))
rt.Path("/members").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
router.GET("/api/teams/:tid/my.json", apiHandler(teamPublicHandler(
func(team *fic.Team, _ []byte) (interface{}, error) {
return fic.MyJSONTeam(team, true) })))
router.GET("/api/teams/:tid/wait.json", apiHandler(teamPublicHandler(
func(team *fic.Team, _ []byte) (interface{}, error) {
return fic.MyJSONTeam(team, false) })))
router.GET("/api/teams/:tid/stats.json", apiHandler(teamPublicHandler(
func(team *fic.Team, _ []byte) (interface{}, error) {
if team != nil {
return team.GetStats()
} else {
return fic.GetTeamsStats(nil)
}
})))
router.GET("/api/teams/:tid/tries", apiHandler(teamPublicHandler(
func(team *fic.Team, _ []byte) (interface{}, error) {
return fic.GetTries(team, nil) })))
router.GET("/api/teams/:tid/members", apiHandler(teamHandler(
func(team fic.Team, _ []byte) (interface{}, error) {
return team.GetMembers() })))
rt.Path("/name").Methods("GET").HandlerFunc(apiHandler(teamHandler(
func(team fic.Team, args map[string]string, body []byte) (interface{}, error) {
router.GET("/api/teams/:tid/name", apiHandler(teamHandler(
func(team fic.Team, _ []byte) (interface{}, error) {
return team.Name, nil })))
}

View File

@ -7,42 +7,39 @@ import (
"strconv"
"srs.epita.fr/fic-server/libfic"
"github.com/julienschmidt/httprouter"
)
func init() {
router.Path("/themes/").Methods("GET").HandlerFunc(apiHandler(listThemes))
router.Path("/themes/").Methods("POST").HandlerFunc(apiHandler(createTheme))
router.Path("/themes.json").Methods("GET").HandlerFunc(apiHandler(exportThemes))
router.Path("/themes/files-bindings").Methods("GET").HandlerFunc(apiHandler(bindingFiles))
router.GET("/api/themes", apiHandler(listThemes))
router.POST("/api/themes", apiHandler(createTheme))
router.GET("/api/themes.json", apiHandler(exportThemes))
router.GET("/api/files-bindings", apiHandler(bindingFiles))
rt := router.PathPrefix("/themes/{tid:[0-9]+}").Subrouter()
rt.Path("/").Methods("GET").HandlerFunc(apiHandler(themeHandler(showTheme)))
rt.Path("/").Methods("PUT").HandlerFunc(apiHandler(themeHandler(updateTheme)))
rt.Path("/").Methods("DELETE").HandlerFunc(apiHandler(themeHandler(deleteTheme)))
router.GET("/api/themes/:thid", apiHandler(themeHandler(showTheme)))
router.PUT("/api/themes/:thid", apiHandler(themeHandler(updateTheme)))
router.DELETE("/api/themes/:thid", apiHandler(themeHandler(deleteTheme)))
rtes := rt.PathPrefix("/exercices").Subrouter()
rtes.Path("/").Methods("GET").HandlerFunc(apiHandler(themeHandler(listThemedExercices)))
rtes.Path("/").Methods("POST").HandlerFunc(apiHandler(themeHandler(createExercice)))
router.GET("/api/themes/:thid/exercices", apiHandler(themeHandler(listThemedExercices)))
router.POST("/api/themes/:thid/exercices", apiHandler(themeHandler(createExercice)))
rte := rtes.PathPrefix("/{eid:[0-9]+}").Subrouter()
rte.Path("/").Methods("GET").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(showThemedExercice))))
rte.Path("/").Methods("PUT").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(updateThemedExercice))))
rte.Path("/").Methods("DELETE").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(deleteThemedExercice))))
router.GET("/api/themes/:thid/exercices/:eid", apiHandler(themedExerciceHandler(showThemedExercice)))
router.PUT("/api/themes/:thid/exercices/:eid", apiHandler(themedExerciceHandler(updateThemedExercice)))
router.DELETE("/api/themes/:thid/exercices/:eid", apiHandler(themedExerciceHandler(deleteThemedExercice)))
rtef := rte.Path("/files").Subrouter()
rtef.Methods("GET").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(listThemedExerciceFiles))))
rtef.Methods("POST").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(createExerciceFile))))
rteh := rte.Path("/hints").Subrouter()
rteh.Methods("GET").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(listThemedExerciceHints))))
rteh.Methods("POST").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(createExerciceHint))))
router.GET("/api/themes/:thid/exercices/:eid/files", apiHandler(themedExerciceHandler(listThemedExerciceFiles)))
router.POST("/api/themes/:thid/exercices/:eid/files", apiHandler(themedExerciceHandler(createExerciceFile)))
rtek := rte.Path("/keys").Subrouter()
rtek.Methods("GET").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(listThemedExerciceKeys))))
rtek.Methods("POST").HandlerFunc(apiHandler(themeHandler(themedExerciceHandler(createExerciceKey))))
router.GET("/api/themes/:thid/exercices/:eid/hints", apiHandler(themedExerciceHandler(listThemedExerciceHints)))
router.POST("/api/themes/:thid/exercices/:eid/hints", apiHandler(themedExerciceHandler(createExerciceHint)))
router.GET("/api/themes/:thid/exercices/:eid/keys", apiHandler(themedExerciceHandler(listThemedExerciceKeys)))
router.POST("/api/themes/:thid/exercices/:eid/keys", apiHandler(themedExerciceHandler(createExerciceKey)))
}
func bindingFiles(args map[string]string, body []byte) (interface{}, error) {
func bindingFiles(_ httprouter.Params, body []byte) (interface{}, error) {
if files, err := fic.GetFiles(); err != nil {
return "", err
} else {
@ -66,35 +63,35 @@ func getExercice(args []string) (fic.Exercice, error) {
}
}
func listThemes(args map[string]string, body []byte) (interface{}, error) {
func listThemes(_ httprouter.Params, _ []byte) (interface{}, error) {
return fic.GetThemes()
}
func exportThemes(args map[string]string, body []byte) (interface{}, error) {
func exportThemes(_ httprouter.Params, _ []byte) (interface{}, error) {
return fic.ExportThemes()
}
func showTheme(theme fic.Theme, args map[string]string, body []byte) (interface{}, error) {
func showTheme(theme fic.Theme, _ []byte) (interface{}, error) {
return theme, nil
}
func listThemedExercices(theme fic.Theme, args map[string]string, body []byte) (interface{}, error) {
func listThemedExercices(theme fic.Theme, _ []byte) (interface{}, error) {
return theme.GetExercices()
}
func showThemedExercice(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func showThemedExercice(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice, nil
}
func listThemedExerciceFiles(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func listThemedExerciceFiles(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetFiles()
}
func listThemedExerciceHints(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func listThemedExerciceHints(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetHints()
}
func listThemedExerciceKeys(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func listThemedExerciceKeys(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetKeys()
}
@ -104,7 +101,7 @@ type uploadedTheme struct {
Authors string
}
func createTheme(args map[string]string, body []byte) (interface{}, error) {
func createTheme(_ httprouter.Params, body []byte) (interface{}, error) {
var ut uploadedTheme
if err := json.Unmarshal(body, &ut); err != nil {
return nil, err
@ -117,7 +114,7 @@ func createTheme(args map[string]string, body []byte) (interface{}, error) {
return fic.CreateTheme(ut.Name, ut.Authors)
}
func updateTheme(theme fic.Theme, args map[string]string, body []byte) (interface{}, error) {
func updateTheme(theme fic.Theme, body []byte) (interface{}, error) {
var ut fic.Theme
if err := json.Unmarshal(body, &ut); err != nil {
return nil, err
@ -132,7 +129,7 @@ func updateTheme(theme fic.Theme, args map[string]string, body []byte) (interfac
return ut.Update()
}
func updateThemedExercice(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func updateThemedExercice(theme fic.Theme, exercice fic.Exercice, body []byte) (interface{}, error) {
// Update an exercice
var ue fic.Exercice
if err := json.Unmarshal(body, &ue); err != nil {
@ -152,10 +149,10 @@ func updateThemedExercice(theme fic.Theme, exercice fic.Exercice, args map[strin
return ue, nil
}
func deleteTheme(theme fic.Theme, args map[string]string, body []byte) (interface{}, error) {
func deleteTheme(theme fic.Theme, _ []byte) (interface{}, error) {
return theme.Delete()
}
func deleteThemedExercice(theme fic.Theme, exercice fic.Exercice, args map[string]string, body []byte) (interface{}, error) {
func deleteThemedExercice(_ fic.Theme, exercice fic.Exercice, _ []byte) (interface{}, error) {
return exercice.Delete()
}

View File

@ -1,11 +1,13 @@
package api
import ()
import (
"github.com/julienschmidt/httprouter"
)
func init() {
router.Path("/version").Methods("GET").HandlerFunc(apiHandler(showVersion))
router.GET("/api/version", apiHandler(showVersion))
}
func showVersion(args map[string]string, body []byte) (interface{}, error) {
func showVersion(_ httprouter.Params, body []byte) (interface{}, error) {
return map[string]interface{}{"version": 0.1}, nil
}

View File

@ -8,7 +8,7 @@ CLOUDPASS=fic:'f>t\nV33R|(+?$i*'
new_theme() {
NAME=`echo $1 | sed 's/"/\\\\"/g'`
AUTHORS=`echo $2 | sed 's/"/\\\\"/g'`
curl -f -s -d "{\"name\": \"$NAME\", \"authors\": \"$AUTHORS\"}" "${BASEURL}/api/themes/" |
curl -f -s -d "{\"name\": \"$NAME\", \"authors\": \"$AUTHORS\"}" "${BASEURL}/api/themes" |
grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+"
}
@ -20,7 +20,7 @@ new_exercice() {
GAIN="$5"
VIDEO="$6"
curl -f -s -d "{\"title\": \"$TITLE\", \"statement\": \"$STATEMENT\", \"depend\": $DEPEND, \"gain\": $GAIN, \"videoURI\": \"$VIDEO\"}" "${BASEURL}/api/themes/$THEME/exercices/" |
curl -f -s -d "{\"title\": \"$TITLE\", \"statement\": \"$STATEMENT\", \"depend\": $DEPEND, \"gain\": $GAIN, \"videoURI\": \"$VIDEO\"}" "${BASEURL}/api/themes/$THEME/exercices" |
grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+"
}

View File

@ -51,6 +51,13 @@ func main() {
if fic.FilesDir, err = filepath.Abs(fic.FilesDir); err != nil {
log.Fatal(err)
}
if *baseURL != "/" {
tmp := path.Clean(*baseURL)
baseURL = &tmp
} else {
tmp := ""
baseURL = &tmp
}
log.Println("Opening database...")
if err := fic.DBInit(fmt.Sprintf("%s?parseTime=true", *dsn)); err != nil {
@ -63,12 +70,12 @@ func main() {
log.Fatal("Cannot create database: ", err)
}
log.Println("Changing base url...")
log.Println("Changing base URL to", *baseURL,"...")
if file, err := os.OpenFile(path.Join(StaticDir, "index.html"), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0644)); err != nil {
log.Println("Unable to open index.html: ", err)
} else if indexTmpl, err := template.New("index").Parse(indextpl); err != nil {
log.Println("Cannot create template: ", err)
} else if err := indexTmpl.Execute(file, map[string]string{"urlbase": path.Clean(path.Join(baseURL + "/", "nuke"))[:len(path.Clean(path.Join(baseURL + "/", "nuke"))) - 4]}); err != nil {
} else if err := indexTmpl.Execute(file, map[string]string{"urlbase": path.Clean(path.Join(*baseURL + "/", "nuke"))[:len(path.Clean(path.Join(*baseURL + "/", "nuke"))) - 4]}); err != nil {
log.Println("An error occurs during template execution: ", err)
}

View File

@ -3,16 +3,42 @@ package main
import (
"net/http"
"path"
"srs.epita.fr/fic-server/admin/api"
"github.com/julienschmidt/httprouter"
)
type staticRouting struct {
StaticDir string
}
func init() {
api.Router().GET("/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
api.Router().GET("/exercices/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
api.Router().GET("/events/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
api.Router().GET("/teams/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
api.Router().GET("/themes/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
func StaticHandler(staticDir string) http.Handler {
return staticRouting{staticDir}
}
func (a staticRouting) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, path.Join(a.StaticDir, "index.html"))
api.Router().GET("/css/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, r.URL.Path))
})
api.Router().GET("/fonts/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, r.URL.Path))
})
api.Router().GET("/img/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, r.URL.Path))
})
api.Router().GET("/js/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, r.URL.Path))
})
api.Router().GET("/views/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, r.URL.Path))
})
}

View File

@ -37,7 +37,7 @@ angular.module("FICApp")
})
.factory("Team", function($resource) {
return $resource("/api/teams/:teamId", { teamId: '@id' }, {
'save': {method: 'PATCH'},
'update': {method: 'PUT'},
})
})
.factory("TeamMember", function($resource) {
@ -47,7 +47,7 @@ angular.module("FICApp")
return $resource("/api/teams/:teamId/my.json", { teamId: '@id' })
})
.factory("Teams", function($resource) {
return $resource("/api/teams/teams.json")
return $resource("/api/teams.json")
})
.factory("TeamStats", function($resource) {
return $resource("/api/teams/:teamId/stats.json", { teamId: '@id' })
@ -56,17 +56,19 @@ angular.module("FICApp")
return $resource("/api/teams/:teamId/tries", { teamId: '@id' })
})
.factory("Theme", function($resource) {
return $resource("/api/themes/:themeId", null, {
'save': {method: 'PATCH'},
})
return $resource("/api/themes/:themeId", { themeId: '@id' }, {
update: {method: 'PUT'}
});
})
.factory("Themes", function($resource) {
return $resource("/api/themes/themes.json", null, {
return $resource("/api/themes.json", null, {
'get': {method: 'GET'},
})
})
.factory("Exercice", function($resource) {
return $resource("/api/exercices/:exerciceId")
return $resource("/api/exercices/:exerciceId", { exerciceId: '@id' }, {
update: {method: 'PUT'}
})
});
String.prototype.capitalize = function() {