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() }