server/admin/api/file.go

153 lines
3.7 KiB
Go

package api
import (
"encoding/hex"
"encoding/json"
"fmt"
"srs.epita.fr/fic-server/admin/sync"
"srs.epita.fr/fic-server/libfic"
"github.com/julienschmidt/httprouter"
)
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)))
// Remote
router.GET("/api/remote/themes/:thid/exercices/:exid/files", apiHandler(sync.ApiGetRemoteExerciceFiles))
// Check
router.POST("/api/files/:fileid/check", apiHandler(fileHandler(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
})))
}
type APIFile struct {
fic.EFile
Depends []fic.Flag `json:"depends,omitempty"`
}
func genFileList(in []fic.EFile, e error) (out []APIFile, err error) {
if e != nil {
return nil, e
}
for _, f := range in {
g := APIFile{EFile: f}
var deps []fic.Flag
deps, err = f.GetDepends()
if err != nil {
return
}
for _, d := range deps {
if k, ok := d.(fic.FlagKey); ok {
k, err = fic.GetFlagKey(k.Id)
if err != nil {
return
}
g.Depends = append(g.Depends, k)
} else if m, ok := d.(fic.MCQ); ok {
m, err = fic.GetMCQ(m.Id)
if err != nil {
return
}
g.Depends = append(g.Depends, m)
} else {
err = fmt.Errorf("Unknown type %T to handle file dependancy", k)
return
}
}
out = append(out, g)
}
return
}
func listFiles(_ httprouter.Params, body []byte) (interface{}, error) {
return genFileList(fic.GetFiles())
}
func listExerciceFiles(exercice fic.Exercice, body []byte) (interface{}, error) {
return genFileList(exercice.GetFiles())
}
func clearFiles(_ httprouter.Params, _ []byte) (interface{}, error) {
return fic.ClearFiles()
}
func showFile(file fic.EFile, _ []byte) (interface{}, error) {
return file, nil
}
type uploadedFile struct {
URI string
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
}
return 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)
}
})
}
func updateFile(file fic.EFile, body []byte) (interface{}, error) {
var uf fic.EFile
if err := json.Unmarshal(body, &uf); err != nil {
return nil, err
}
uf.Id = file.Id
if _, err := uf.Update(); err != nil {
return nil, err
} else {
return uf, nil
}
}
func deleteFile(file fic.EFile, _ []byte) (interface{}, error) {
return file.Delete()
}
func deleteFileDep(file fic.EFile, depid int, _ []byte) (interface{}, error) {
return true, file.DeleteDepend(fic.FlagKey{Id: depid})
}
func checkFile(file fic.EFile, _ []byte) (interface{}, error) {
return true, file.CheckFileOnDisk()
}