diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java index d433dfd4..eb03376d 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java @@ -22,8 +22,10 @@ import org.apache.log4j.Appender; import org.apache.log4j.Logger; import com.sismics.docs.core.dao.jpa.FileDao; +import com.sismics.docs.core.dao.jpa.UserDao; import com.sismics.docs.core.model.context.AppContext; import com.sismics.docs.core.model.jpa.File; +import com.sismics.docs.core.model.jpa.User; import com.sismics.docs.core.util.ConfigUtil; import com.sismics.docs.core.util.DirectoryUtil; import com.sismics.docs.core.util.jpa.PaginatedList; @@ -185,4 +187,53 @@ public class AppResource extends BaseResource { .add("status", "ok"); return Response.ok().entity(response.build()).build(); } + + /** + * Recompute the quota for each user. + * + * @return Response + */ + @POST + @Path("batch/recompute_quota") + public Response batchRecomputeQuota() { + if (!authenticate()) { + throw new ForbiddenClientException(); + } + checkBaseFunction(BaseFunction.ADMIN); + + // Get all files + FileDao fileDao = new FileDao(); + List fileList = fileDao.findAll(); + + // Count each file for the corresponding user quota + UserDao userDao = new UserDao(); + Map userMap = new HashMap<>(); + for (File file : fileList) { + java.nio.file.Path storedFile = DirectoryUtil.getStorageDirectory().resolve(file.getId()); + User user = null; + if (userMap.containsKey(file.getUserId())) { + user = userMap.get(file.getUserId()); + } else { + user = userDao.getById(file.getUserId()); + user.setStorageCurrent(0l); + userMap.put(user.getId(), user); + } + + try { + user.setStorageCurrent(user.getStorageCurrent() + Files.size(storedFile)); + } catch (IOException e) { + throw new ServerException("MissingFile", "File does not exist", e); + } + } + + // Save all users + for (User user : userMap.values()) { + userDao.update(user); + } + + // Always return OK + JsonObjectBuilder response = Json.createObjectBuilder() + .add("status", "ok"); + return Response.ok().entity(response.build()).build(); + } } diff --git a/docs-web/src/main/webapp/src/app/docs/controller/SettingsUserEdit.js b/docs-web/src/main/webapp/src/app/docs/controller/SettingsUserEdit.js index 91537989..792990c2 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/SettingsUserEdit.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/SettingsUserEdit.js @@ -16,6 +16,7 @@ angular.module('docs').controller('SettingsUserEdit', function($scope, $dialog, */ if ($scope.isEdit()) { Restangular.one('user', $stateParams.username).get().then(function(data) { + data.storage_quota /= 1000000; $scope.user = data; }); } @@ -25,15 +26,17 @@ angular.module('docs').controller('SettingsUserEdit', function($scope, $dialog, */ $scope.edit = function() { var promise = null; + var user = angular.copy($scope.user); + user.storage_quota *= 1000000; if ($scope.isEdit()) { promise = Restangular .one('user', $stateParams.username) - .post('', $scope.user); + .post('', user); } else { promise = Restangular .one('user') - .put($scope.user); + .put(user); } promise.then(function() { diff --git a/docs-web/src/main/webapp/src/index.html b/docs-web/src/main/webapp/src/index.html index dc74d15c..c71cf81d 100644 --- a/docs-web/src/main/webapp/src/index.html +++ b/docs-web/src/main/webapp/src/index.html @@ -110,7 +110,10 @@
  • - {{ userInfo.username }} + + + {{ userInfo.username }} +
  • diff --git a/docs-web/src/main/webapp/src/partial/docs/document.html b/docs-web/src/main/webapp/src/partial/docs/document.html index 207e4374..768f8b40 100644 --- a/docs-web/src/main/webapp/src/partial/docs/document.html +++ b/docs-web/src/main/webapp/src/partial/docs/document.html @@ -73,6 +73,11 @@ +
    + {{ userInfo.storage_current / 1000000 | number: 0 }}MB ({{ userInfo.storage_current / userInfo.storage_quota * 100 | number: 1 }}%) + used on {{ userInfo.storage_quota / 1000000 | number: 0 }}MB +
    +
    {{ totalDocuments }} document{{ totalDocuments > 1 ? 's' : '' }} found
    diff --git a/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html b/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html index fa86c1eb..d0208b85 100644 --- a/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html +++ b/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html @@ -37,6 +37,21 @@ Too long +
    + + +
    +
    + +
    MB
    +
    +
    + +
    + Number required +
    +
    diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java index bda989e9..9c1b426f 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestAppResource.java @@ -53,6 +53,12 @@ public class TestAppResource extends BaseJerseyTest { .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken) .post(Entity.form(new Form())); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); + + // Recompute quota + response = target().path("/app/batch/recompute_quota").request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken) + .post(Entity.form(new Form())); + Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); } /**