server/admin/api/exercice.go

278 lines
7.8 KiB
Go

package api
import (
"encoding/hex"
"encoding/json"
"errors"
"strings"
"srs.epita.fr/fic-server/admin/sync"
"srs.epita.fr/fic-server/libfic"
"github.com/julienschmidt/httprouter"
)
func init() {
router.GET("/api/exercices/", apiHandler(listExercices))
router.GET("/api/exercices/:eid", apiHandler(exerciceHandler(showExercice)))
router.PUT("/api/exercices/:eid", apiHandler(exerciceHandler(updateExercice)))
router.DELETE("/api/exercices/:eid", apiHandler(exerciceHandler(deleteExercice)))
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(showExerciceFile)))
router.DELETE("/api/exercices/:eid/files/:fid", apiHandler(exerciceFileHandler(deleteExerciceFile)))
router.GET("/api/exercices/:eid/hints", apiHandler(exerciceHandler(listExerciceHints)))
router.POST("/api/exercices/:eid/hints", apiHandler(exerciceHandler(createExerciceHint)))
router.GET("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(showExerciceHint)))
router.PUT("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(updateExerciceHint)))
router.DELETE("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(deleteExerciceHint)))
router.GET("/api/exercices/:eid/keys", apiHandler(exerciceHandler(listExerciceKeys)))
router.POST("/api/exercices/:eid/keys", apiHandler(exerciceHandler(createExerciceKey)))
router.GET("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(showExerciceKey)))
router.PUT("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(updateExerciceKey)))
router.DELETE("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(deleteExerciceKey)))
router.GET("/api/exercices/:eid/quiz", apiHandler(exerciceHandler(listExerciceQuiz)))
router.GET("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(showExerciceQuiz)))
router.DELETE("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(deleteExerciceQuiz)))
// Synchronize
router.POST("/api/sync/exercices/:eid/files", apiHandler(exerciceHandler(
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
return sync.SyncExerciceFiles(sync.GlobalImporter, exercice), nil
})))
router.POST("/api/sync/exercices/:eid/hints", apiHandler(exerciceHandler(
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
return sync.SyncExerciceHints(sync.GlobalImporter, exercice), nil
})))
router.POST("/api/sync/exercices/:eid/keys", apiHandler(exerciceHandler(
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
return sync.SyncExerciceKeys(sync.GlobalImporter, exercice), nil
})))
router.POST("/api/sync/exercices/:eid/quiz", apiHandler(exerciceHandler(
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
return sync.SyncExerciceMCQ(sync.GlobalImporter, exercice), nil
})))
router.POST("/api/sync/exercices/:eid/fixurlid", apiHandler(exerciceHandler(
func(exercice fic.Exercice, _ []byte) (interface{}, error) {
if exercice.FixURLId() {
return exercice.Update()
}
return 0, nil
})))
}
func listExercices(_ httprouter.Params, body []byte) (interface{}, error) {
// List all exercices
return fic.GetExercices()
}
func listExerciceFiles(exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetFiles()
}
func listExerciceHints(exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetHints()
}
func listExerciceKeys(exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetKeys()
}
func listExerciceQuiz(exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice.GetMCQ()
}
func showExercice(exercice fic.Exercice, body []byte) (interface{}, error) {
return exercice, nil
}
func deleteExercice(exercice fic.Exercice, _ []byte) (interface{}, error) {
return exercice.Delete()
}
func updateExercice(exercice fic.Exercice, body []byte) (interface{}, error) {
var ue fic.Exercice
if err := json.Unmarshal(body, &ue); err != nil {
return nil, err
}
ue.Id = exercice.Id
if len(ue.Title) == 0 {
return nil, errors.New("Exercice's title not filled")
}
if _, err := ue.Update(); err != nil {
return nil, err
}
return ue, nil
}
func createExercice(theme fic.Theme, body []byte) (interface{}, error) {
// Create a new exercice
var ue fic.Exercice
if err := json.Unmarshal(body, &ue); err != nil {
return nil, err
}
if len(ue.Title) == 0 {
return nil, errors.New("Title not filled")
}
var depend *fic.Exercice = nil
if ue.Depend != nil {
if d, err := fic.GetExercice(*ue.Depend); err != nil {
return nil, err
} else {
depend = &d
}
}
return theme.AddExercice(ue.Title, ue.URLId, ue.Path, ue.Statement, ue.Overview, depend, ue.Gain, ue.VideoURI)
}
type uploadedHint struct {
Title string
Path string
Content string
Cost int64
URI string
}
func createExerciceHint(exercice fic.Exercice, body []byte) (interface{}, error) {
var uh uploadedHint
if err := json.Unmarshal(body, &uh); err != nil {
return nil, err
}
if len(uh.Content) != 0 {
return exercice.AddHint(uh.Title, uh.Content, uh.Cost)
} else if len(uh.URI) != 0 {
return sync.ImportFile(sync.GlobalImporter, uh.URI,
func(filePath string, origin string) (interface{}, error) {
return exercice.AddHint(uh.Title, "$FILES"+strings.TrimPrefix(filePath, fic.FilesDir), uh.Cost)
})
} else {
return nil, errors.New("Hint's content not filled")
}
}
func showExerciceHint(hint fic.EHint, body []byte) (interface{}, error) {
return hint, nil
}
func updateExerciceHint(hint fic.EHint, body []byte) (interface{}, error) {
var uh fic.EHint
if err := json.Unmarshal(body, &uh); err != nil {
return nil, err
}
uh.Id = hint.Id
if len(uh.Title) == 0 {
return nil, errors.New("Hint's title not filled")
}
if _, err := uh.Update(); err != nil {
return nil, err
}
return uh, nil
}
func deleteExerciceHint(hint fic.EHint, _ []byte) (interface{}, error) {
return hint.Delete()
}
type uploadedKey struct {
Label string
Key string
Hash []byte
}
func createExerciceKey(exercice fic.Exercice, body []byte) (interface{}, error) {
var uk uploadedKey
if err := json.Unmarshal(body, &uk); err != nil {
return nil, err
}
if len(uk.Key) == 0 {
return nil, errors.New("Key not filled")
}
return exercice.AddRawKey(uk.Label, uk.Key)
}
func showExerciceKey(key fic.Key, _ fic.Exercice, body []byte) (interface{}, error) {
return key, nil
}
func updateExerciceKey(key fic.Key, exercice fic.Exercice, body []byte) (interface{}, error) {
var uk uploadedKey
if err := json.Unmarshal(body, &uk); err != nil {
return nil, err
}
if len(uk.Label) == 0 {
key.Label = "Flag"
} else {
key.Label = uk.Label
}
key.Checksum = uk.Hash
if _, err := key.Update(); err != nil {
return nil, err
}
return key, nil
}
func deleteExerciceKey(key fic.Key, _ fic.Exercice, _ []byte) (interface{}, error) {
return key.Delete()
}
func showExerciceQuiz(quiz fic.MCQ, _ fic.Exercice, body []byte) (interface{}, error) {
return quiz, nil
}
func deleteExerciceQuiz(quiz fic.MCQ, _ fic.Exercice, _ []byte) (interface{}, error) {
return quiz.Delete()
}
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 showExerciceFile(file fic.EFile, body []byte) (interface{}, error) {
return file, nil
}
func deleteExerciceFile(file fic.EFile, _ []byte) (interface{}, error) {
return file.Delete()
}