admin: Can gunzip files
This commit is contained in:
parent
c082ee43d0
commit
a0cd651dae
@ -37,6 +37,7 @@ func declareFilesRoutes(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
// Check
|
// Check
|
||||||
apiFilesRoutes.POST("/check", checkFile)
|
apiFilesRoutes.POST("/check", checkFile)
|
||||||
|
apiFilesRoutes.POST("/gunzip", gunzipFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FileHandler(c *gin.Context) {
|
func FileHandler(c *gin.Context) {
|
||||||
@ -266,3 +267,15 @@ func checkFile(c *gin.Context) {
|
|||||||
|
|
||||||
c.JSON(http.StatusOK, true)
|
c.JSON(http.StatusOK, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gunzipFile(c *gin.Context) {
|
||||||
|
file := c.MustGet("file").(*fic.EFile)
|
||||||
|
|
||||||
|
err := file.GunzipFileOnDisk()
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, true)
|
||||||
|
}
|
||||||
|
@ -1350,7 +1350,8 @@ angular.module("FICApp")
|
|||||||
|
|
||||||
.controller("FilesListController", function($scope, File, $location, $http, $rootScope) {
|
.controller("FilesListController", function($scope, File, $location, $http, $rootScope) {
|
||||||
$scope.files = File.query();
|
$scope.files = File.query();
|
||||||
$scope.errfnd = 0;
|
$scope.errfnd = null;
|
||||||
|
$scope.errzip = null;
|
||||||
$scope.fields = ["id", "path", "name", "checksum", "size"];
|
$scope.fields = ["id", "path", "name", "checksum", "size"];
|
||||||
|
|
||||||
$scope.clearFiles = function(id) {
|
$scope.clearFiles = function(id) {
|
||||||
@ -1359,6 +1360,21 @@ angular.module("FICApp")
|
|||||||
$scope.files = [];
|
$scope.files = [];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
$scope.gunzipFile = function(f) {
|
||||||
|
f.gunzipWIP = true;
|
||||||
|
$http({
|
||||||
|
url: "api/files/" + f.id + "/gunzip",
|
||||||
|
method: "POST"
|
||||||
|
}).then(function(response) {
|
||||||
|
f.gunzipWIP = false;
|
||||||
|
f.err = true;
|
||||||
|
}, function(response) {
|
||||||
|
f.gunzipWIP = false;
|
||||||
|
$scope.inSync = false;
|
||||||
|
$scope.errzip += 1;
|
||||||
|
f.err = response.data.errmsg;
|
||||||
|
})
|
||||||
|
};
|
||||||
$scope.checksum = function(f) {
|
$scope.checksum = function(f) {
|
||||||
$http({
|
$http({
|
||||||
url: "api/files/" + f.id + "/check",
|
url: "api/files/" + f.id + "/check",
|
||||||
@ -1372,10 +1388,18 @@ angular.module("FICApp")
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
$scope.checksumAll = function() {
|
$scope.checksumAll = function() {
|
||||||
$scope.errfnd = 0;
|
$scope.errfnd = null;
|
||||||
angular.forEach($scope.files, function(file) {
|
angular.forEach($scope.files, function(file) {
|
||||||
$scope.checksum(file);
|
$scope.checksum(file);
|
||||||
});
|
});
|
||||||
|
if ($scope.errfnd === null) $scope.errfnd = 0;
|
||||||
|
};
|
||||||
|
$scope.gunzipFiles = function() {
|
||||||
|
$scope.errzip = null;
|
||||||
|
angular.forEach($scope.files, function(file) {
|
||||||
|
$scope.gunzipFile(file);
|
||||||
|
});
|
||||||
|
if ($scope.errzip === null) $scope.errzip = 0;
|
||||||
};
|
};
|
||||||
$scope.show = function(f) {
|
$scope.show = function(f) {
|
||||||
$location.url("/exercices/" + f.idExercice);
|
$location.url("/exercices/" + f.idExercice);
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
<h2>
|
<h2>
|
||||||
Fichiers
|
Fichiers
|
||||||
<small class="text-muted" ng-if="errfnd > 0"><span class="glyphicon glyphicon-exclamation-sign"></span> <ng-pluralize count="errfnd" when="{'one': '{} erreur trouvée', 'other': '{} erreurs trouvées'}"></ng-pluralize></small>
|
<small class="text-muted" ng-if="errfnd > 0"><span class="glyphicon glyphicon-exclamation-sign"></span> <ng-pluralize count="errfnd" when="{'one': '{} erreur trouvée', 'other': '{} erreurs trouvées'}"></ng-pluralize></small>
|
||||||
<button type="button" ng-click="checksumAll()" class="float-right btn btn-sm btn-secondary"><span class="glyphicon glyphicon-flash" aria-hidden="true"></span> Vérifier les fichiers</button>
|
<small class="text-muted" ng-if="errzip > 0"><span class="glyphicon glyphicon-exclamation-sign"></span> <ng-pluralize count="errzip" when="{'one': '{} décompression problématique', 'other': '{} décompressions problématiques'}"></ng-pluralize></small>
|
||||||
|
<button type="button" ng-click="checksumAll()" class="float-right btn btn-sm" ng-class="{'btn-secondary': errfnd === null, 'btn-success': errfnd === 0, 'btn-danger': errfnd > 0}"><span class="glyphicon glyphicon-flash" aria-hidden="true"></span> Vérifier les fichiers</button>
|
||||||
|
<button type="button" ng-click="gunzipFiles()" class="float-right btn btn-sm mx-1" ng-class="{'btn-secondary': errzip === null, 'btn-success': errzip === 0, 'btn-danger': errzip > 0}" title="Décompresse tous les fichiers compressés afin d'afficher la bonne taille au moment du téléchargement"><span class="glyphicon glyphicon-compressed" aria-hidden="true"></span> Gunzip</button>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p><input type="search" class="form-control" placeholder="Search" ng-model="query" autofocus></p>
|
<p><input type="search" class="form-control" placeholder="Search" ng-model="query" autofocus></p>
|
||||||
<table class="table table-hover table-bordered table-striped table-sm">
|
<table class="table table-hover table-bordered table-striped table-sm">
|
||||||
<thead class="thead-dark">
|
<thead class="thead-dark">
|
||||||
<tr>
|
<tr>
|
||||||
|
<th></th>
|
||||||
<th ng-repeat="field in fields">
|
<th ng-repeat="field in fields">
|
||||||
{{ field }}
|
{{ field }}
|
||||||
</th>
|
</th>
|
||||||
@ -15,6 +18,13 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="file in files | filter: query" ng-class="{'bg-danger': file.err !== undefined && file.err !== true}" ng-click="show(file)">
|
<tr ng-repeat="file in files | filter: query" ng-class="{'bg-danger': file.err !== undefined && file.err !== true}" ng-click="show(file)">
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-light" ng-click="$event.stopPropagation();checksum(file)"><span class="glyphicon glyphicon-flash" aria-hidden="true"></span></button>
|
||||||
|
<button type="button" class="btn btn-sm btn-light" ng-click="$event.stopPropagation();gunzipFile(file)" ng-disabled="file.gunzipWIP">
|
||||||
|
<span class="glyphicon glyphicon-compressed" aria-hidden="true" ng-if="!file.gunzipWIP"></span>
|
||||||
|
<div class="spinner-border spinner-border-sm" role="status" ng-if="file.gunzipWIP"></div>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
<td ng-repeat="field in fields">
|
<td ng-repeat="field in fields">
|
||||||
{{ file[field] }}
|
{{ file[field] }}
|
||||||
<span ng-if="field == 'id' && file.err !== undefined && file.err !== true" title="{{ file.err }}" class="glyphicon glyphicon-exclamation-sign"></span>
|
<span ng-if="field == 'id' && file.err !== undefined && file.err !== true" title="{{ file.err }}" class="glyphicon glyphicon-exclamation-sign"></span>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package fic
|
package fic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"compress/gzip"
|
||||||
"crypto"
|
"crypto"
|
||||||
_ "crypto/sha1"
|
_ "crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@ -403,3 +404,35 @@ func (f *EFile) CheckFileOnDisk() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GunzipFileOnDisk gunzip a compressed file.
|
||||||
|
func (f *EFile) GunzipFileOnDisk() error {
|
||||||
|
if !strings.HasSuffix(f.origin, ".gz") || strings.HasSuffix(f.origin, ".tar.gz") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fdIn, err := os.Open(path.Join(FilesDir, f.Path+".gz"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fdIn.Close()
|
||||||
|
|
||||||
|
fdOut, err := os.Create(path.Join(FilesDir, strings.TrimSuffix(f.Path, ".gz")))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fdOut.Close()
|
||||||
|
|
||||||
|
gunzipfd, err := gzip.NewReader(fdIn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer gunzipfd.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(fdOut, gunzipfd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user