admin: complet API and interface with files checking page

This commit is contained in:
nemunaire 2017-12-27 01:53:01 +01:00
parent 184714aeeb
commit 9a1a64c41c
9 changed files with 166 additions and 19 deletions

View file

@ -21,8 +21,8 @@ func init() {
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(fileHandler(showExerciceFile)))
router.DELETE("/api/exercices/:eid/files/:fid", apiHandler(fileHandler(deleteExerciceFile)))
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)))
@ -233,6 +233,11 @@ func deleteExerciceQuiz(quiz fic.MCQ, _ fic.Exercice, _ []byte) (interface{}, er
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 {

View file

@ -1,8 +1,50 @@
package api
import ()
import (
"encoding/json"
type uploadedFile struct {
URI string
Digest string
"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)))
}
func listFiles(_ httprouter.Params, body []byte) (interface{}, error) {
// List all files
return fic.GetFiles()
}
func clearFiles(_ httprouter.Params, _ []byte) (interface{}, error) {
return fic.ClearFiles()
}
func showFile(file fic.EFile, _ []byte) (interface{}, error) {
return file, nil
}
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()
}

View file

@ -213,7 +213,7 @@ func quizHandler(f func(fic.MCQ,fic.Exercice,[]byte) (interface{}, error)) func
}
}
func fileHandler(f func(fic.EFile,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
func exerciceFileHandler(f func(fic.EFile,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
return func (ps httprouter.Params, body []byte) (interface{}, error) {
var exercice fic.Exercice
exerciceHandler(func (ex fic.Exercice, _[]byte) (interface{}, error) {
@ -248,6 +248,18 @@ func eventHandler(f func(fic.Event,[]byte) (interface{}, error)) func (httproute
}
}
func fileHandler(f func(fic.EFile,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
return func (ps httprouter.Params, body []byte) (interface{}, error) {
if fileid, err := strconv.Atoi(string(ps.ByName("fileid"))); err != nil {
return nil, err
} else if file, err := fic.GetFile(fileid); err != nil {
return nil, err
} else {
return f(file, body)
}
}
}
func notFound(ps httprouter.Params, _ []byte) (interface{}, error) {
return nil, nil
}

View file

@ -33,6 +33,7 @@ const indextpl = `<!DOCTYPE html>
<li class="nav-item"><a class="nav-link" href="{{.urlbase}}teams">&Eacute;quipes</a></li>
<li class="nav-item"><a class="nav-link" href="{{.urlbase}}themes">Thèmes</a></li>
<li class="nav-item"><a class="nav-link" href="{{.urlbase}}exercices">Exercices</a></li>
<li class="nav-item"><a class="nav-link" href="{{.urlbase}}files">Fichiers</a></li>
<li class="nav-item"><a class="nav-link" href="{{.urlbase}}public/0">Public</a></li>
<li class="nav-item"><a class="nav-link" href="{{.urlbase}}events">&Eacute;vénements</a></li>
<li class="nav-item"><a class="nav-link" href="{{.urlbase}}settings">Paramètres</a></li>

View file

@ -19,6 +19,9 @@ func init() {
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("/files/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
api.Router().GET("/public/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})

View file

@ -31,6 +31,7 @@
<li class="nav-item"><a class="nav-link" href="/teams">&Eacute;quipes</a></li>
<li class="nav-item"><a class="nav-link" href="/themes">Thèmes</a></li>
<li class="nav-item"><a class="nav-link" href="/exercices">Exercices</a></li>
<li class="nav-item"><a class="nav-link" href="/files">Fichiers</a></li>
<li class="nav-item"><a class="nav-link" href="/public/0">Public</a></li>
<li class="nav-item"><a class="nav-link" href="/events">&Eacute;vénements</a></li>
<li class="nav-item"><a class="nav-link" href="/settings">Paramètres</a></li>

View file

@ -49,6 +49,10 @@ angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"])
controller: "PublicController",
templateUrl: "views/public.html"
})
.when("/files", {
controller: "FilesListController",
templateUrl: "views/file-list.html"
})
.when("/events", {
controller: "EventsListController",
templateUrl: "views/event-list.html"
@ -72,6 +76,9 @@ angular.module("FICApp")
'update': {method: 'PUT'},
})
})
.factory("File", function($resource) {
return $resource("/api/files/:fileId", { fileId: '@id' })
})
.factory("ROSettings", function($resource) {
return $resource("/api/settings-ro.json")
})
@ -525,6 +532,37 @@ angular.module("FICApp")
};
})
.controller("FilesListController", function($scope, File, $location, $http, $rootScope) {
$scope.files = File.query();
$scope.fields = ["id", "path", "name", "checksum", "size"];
$scope.clearFiles = function(id) {
File.delete(function() {
$scope.files = [];
});
};
$scope.checksum = function(f) {
$http({
url: "/api/files/" + f.id + "/checksum",
method: "GET"
}).then(function(response) {
if (response.data)
$rootScope.newBox('danger', response.data);
}, function(response) {
$scope.inSync = false;
$rootScope.newBox('danger', 'An error occurs when checking files:', response.data);
})
};
$scope.checksumAll = function() {
angular.forEach($scope.files, function(file) {
$scope.checksum(file);
});
};
$scope.show = function(f) {
$location.url("/exercices/" + f.idExercice);
};
})
.controller("EventsListController", function($scope, Event, $location) {
$scope.events = Event.query();
$scope.fields = ["id", "kind", "txt", "time"];

View file

@ -0,0 +1,22 @@
<h2>
Fichiers
<button ng-click="checksumAll()" class="float-right btn btn-sm btn-secondary mr-sm-2"><span class="glyphicon glyphicon-flash" aria-hidden="true"></span> Vérifier les fichiers</button>
</h2>
<p><input type="search" class="form-control" placeholder="Search" ng-model="query"></p>
<table class="table table-hover table-bordered table-striped table-sm">
<thead class="thead-dark">
<tr>
<th ng-repeat="field in fields">
{{ field }}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="file in files | filter: query" ng-click="show(file)">
<td ng-repeat="field in fields">
{{ file[field] }}
</td>
</tr>
</tbody>
</table>