admin: Use gin-gonic as router
This commit is contained in:
parent
83468ad723
commit
8b3fbdb64a
32 changed files with 2785 additions and 1635 deletions
|
@ -2,43 +2,79 @@ package api
|
|||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
"srs.epita.fr/fic-server/libfic"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
router.GET("/api/files/", apiHandler(listFiles))
|
||||
router.DELETE("/api/files/", apiHandler(clearFiles))
|
||||
|
||||
router.GET("/api/files/:fileid", apiHandler(fileHandler(showFile)))
|
||||
router.PUT("/api/files/:fileid", apiHandler(fileHandler(updateFile)))
|
||||
router.DELETE("/api/files/:fileid", apiHandler(fileHandler(deleteFile)))
|
||||
|
||||
router.DELETE("/api/files/:fileid/dependancies/:depid", apiHandler(fileDependancyHandler(deleteFileDep)))
|
||||
|
||||
router.GET("/api/exercices/:eid/files", apiHandler(exerciceHandler(listExerciceFiles)))
|
||||
router.POST("/api/exercices/:eid/files", apiHandler(exerciceHandler(createExerciceFile)))
|
||||
|
||||
router.GET("/api/exercices/:eid/files/:fid", apiHandler(exerciceFileHandler(showFile)))
|
||||
router.PUT("/api/exercices/:eid/files/:fid", apiHandler(exerciceFileHandler(updateFile)))
|
||||
router.DELETE("/api/exercices/:eid/files/:fid", apiHandler(exerciceFileHandler(deleteFile)))
|
||||
func declareFilesGlobalRoutes(router *gin.RouterGroup) {
|
||||
router.DELETE("/files/", clearFiles)
|
||||
|
||||
// Remote
|
||||
router.GET("/api/remote/themes/:thid/exercices/:exid/files", apiHandler(sync.ApiGetRemoteExerciceFiles))
|
||||
router.GET("/remote/themes/:thid/exercices/:exid/files", sync.ApiGetRemoteExerciceFiles)
|
||||
}
|
||||
|
||||
func declareFilesRoutes(router *gin.RouterGroup) {
|
||||
router.GET("/files", listFiles)
|
||||
router.POST("/files", createExerciceFile)
|
||||
|
||||
apiFilesRoutes := router.Group("/files/:fileid")
|
||||
apiFilesRoutes.Use(FileHandler)
|
||||
apiFilesRoutes.GET("", showFile)
|
||||
apiFilesRoutes.PUT("", updateFile)
|
||||
apiFilesRoutes.DELETE("", deleteFile)
|
||||
|
||||
apiFileDepsRoutes := apiFilesRoutes.Group("/dependancies/:depid")
|
||||
apiFileDepsRoutes.Use(FileDepHandler)
|
||||
apiFileDepsRoutes.DELETE("", deleteFileDep)
|
||||
|
||||
// Check
|
||||
router.POST("/api/files/:fileid/check", apiHandler(fileHandler(checkFile)))
|
||||
apiFilesRoutes.POST("/check", checkFile)
|
||||
}
|
||||
|
||||
// Synchronize
|
||||
router.POST("/api/sync/exercices/:eid/files", apiHandler(exerciceHandler(
|
||||
func(exercice *fic.Exercice, _ []byte) (interface{}, error) {
|
||||
return sync.SyncExerciceFiles(sync.GlobalImporter, exercice), nil
|
||||
})))
|
||||
func FileHandler(c *gin.Context) {
|
||||
fileid, err := strconv.ParseInt(string(c.Params.ByName("fileid")), 10, 64)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Invalid file identifier"})
|
||||
return
|
||||
}
|
||||
|
||||
var file *fic.EFile
|
||||
if exercice, exists := c.Get("exercice"); exists {
|
||||
file, err = exercice.(*fic.Exercice).GetFile(fileid)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "File not found"})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
file, err = fic.GetFile(fileid)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "File not found"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.Set("file", file)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func FileDepHandler(c *gin.Context) {
|
||||
depid, err := strconv.ParseInt(string(c.Params.ByName("depid")), 10, 64)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Invalid dependency identifier"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("file-depid", depid)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
type APIFile struct {
|
||||
|
@ -87,20 +123,35 @@ func genFileList(in []*fic.EFile, e error) (out []APIFile, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func listFiles(_ httprouter.Params, body []byte) (interface{}, error) {
|
||||
return genFileList(fic.GetFiles())
|
||||
func listFiles(c *gin.Context) {
|
||||
var files []APIFile
|
||||
var err error
|
||||
|
||||
if exercice, exists := c.Get("exercice"); exists {
|
||||
files, err = genFileList(exercice.(*fic.Exercice).GetFiles())
|
||||
} else {
|
||||
files, err = genFileList(fic.GetFiles())
|
||||
}
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, files)
|
||||
}
|
||||
|
||||
func listExerciceFiles(exercice *fic.Exercice, body []byte) (interface{}, error) {
|
||||
return genFileList(exercice.GetFiles())
|
||||
func clearFiles(c *gin.Context) {
|
||||
_, err := fic.ClearFiles()
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, true)
|
||||
}
|
||||
|
||||
func clearFiles(_ httprouter.Params, _ []byte) (interface{}, error) {
|
||||
return fic.ClearFiles()
|
||||
}
|
||||
|
||||
func showFile(file *fic.EFile, _ []byte) (interface{}, error) {
|
||||
return file, nil
|
||||
func showFile(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, c.MustGet("file").(*fic.EFile))
|
||||
}
|
||||
|
||||
type uploadedFile struct {
|
||||
|
@ -108,45 +159,92 @@ type uploadedFile struct {
|
|||
Digest string
|
||||
}
|
||||
|
||||
func createExerciceFile(exercice *fic.Exercice, body []byte) (interface{}, error) {
|
||||
var uf uploadedFile
|
||||
if err := json.Unmarshal(body, &uf); err != nil {
|
||||
return nil, err
|
||||
func createExerciceFile(c *gin.Context) {
|
||||
exercice, exists := c.Get("exercice")
|
||||
if !exists {
|
||||
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "File can only be added inside an exercice."})
|
||||
return
|
||||
}
|
||||
|
||||
return sync.ImportFile(sync.GlobalImporter, uf.URI,
|
||||
var uf uploadedFile
|
||||
err := c.ShouldBindJSON(&uf)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
ret, err := sync.ImportFile(sync.GlobalImporter, uf.URI,
|
||||
func(filePath string, origin string) (interface{}, error) {
|
||||
if digest, err := hex.DecodeString(uf.Digest); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return exercice.ImportFile(filePath, origin, digest)
|
||||
return exercice.(*fic.Exercice).ImportFile(filePath, origin, digest)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, ret)
|
||||
}
|
||||
|
||||
func updateFile(file *fic.EFile, body []byte) (interface{}, error) {
|
||||
func updateFile(c *gin.Context) {
|
||||
file := c.MustGet("file").(*fic.EFile)
|
||||
|
||||
var uf fic.EFile
|
||||
if err := json.Unmarshal(body, &uf); err != nil {
|
||||
return nil, err
|
||||
err := c.ShouldBindJSON(&uf)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
uf.Id = file.Id
|
||||
|
||||
if _, err := uf.Update(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return uf, nil
|
||||
log.Println("Unable to updateFile:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to update file."})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, uf)
|
||||
}
|
||||
|
||||
func deleteFile(file *fic.EFile, _ []byte) (interface{}, error) {
|
||||
return file.Delete()
|
||||
func deleteFile(c *gin.Context) {
|
||||
file := c.MustGet("file").(*fic.EFile)
|
||||
|
||||
_, err := file.Delete()
|
||||
if err != nil {
|
||||
log.Println("Unable to updateFile:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to update file."})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, true)
|
||||
}
|
||||
|
||||
func deleteFileDep(file *fic.EFile, depid int, _ []byte) (interface{}, error) {
|
||||
return true, file.DeleteDepend(&fic.FlagKey{Id: depid})
|
||||
func deleteFileDep(c *gin.Context) {
|
||||
file := c.MustGet("file").(*fic.EFile)
|
||||
depid := c.MustGet("file-depid").(int64)
|
||||
|
||||
err := file.DeleteDepend(&fic.FlagKey{Id: int(depid)})
|
||||
if err != nil {
|
||||
log.Println("Unable to deleteFileDep:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to delete file dependency."})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, true)
|
||||
}
|
||||
|
||||
func checkFile(file *fic.EFile, _ []byte) (interface{}, error) {
|
||||
return true, file.CheckFileOnDisk()
|
||||
func checkFile(c *gin.Context) {
|
||||
file := c.MustGet("file").(*fic.EFile)
|
||||
|
||||
err := file.CheckFileOnDisk()
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, true)
|
||||
}
|
||||
|
|
Reference in a new issue