#41: Batch to rebuild quota storage + UI: show and edit quota

This commit is contained in:
jendib 2015-11-29 23:14:33 +01:00
parent 0fab0e4fc0
commit aa97253ec7
6 changed files with 86 additions and 3 deletions

View File

@ -22,8 +22,10 @@ import org.apache.log4j.Appender;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.sismics.docs.core.dao.jpa.FileDao; 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.context.AppContext;
import com.sismics.docs.core.model.jpa.File; 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.ConfigUtil;
import com.sismics.docs.core.util.DirectoryUtil; import com.sismics.docs.core.util.DirectoryUtil;
import com.sismics.docs.core.util.jpa.PaginatedList; import com.sismics.docs.core.util.jpa.PaginatedList;
@ -185,4 +187,53 @@ public class AppResource extends BaseResource {
.add("status", "ok"); .add("status", "ok");
return Response.ok().entity(response.build()).build(); 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<File> fileList = fileDao.findAll();
// Count each file for the corresponding user quota
UserDao userDao = new UserDao();
Map<String, User> 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();
}
} }

View File

@ -16,6 +16,7 @@ angular.module('docs').controller('SettingsUserEdit', function($scope, $dialog,
*/ */
if ($scope.isEdit()) { if ($scope.isEdit()) {
Restangular.one('user', $stateParams.username).get().then(function(data) { Restangular.one('user', $stateParams.username).get().then(function(data) {
data.storage_quota /= 1000000;
$scope.user = data; $scope.user = data;
}); });
} }
@ -25,15 +26,17 @@ angular.module('docs').controller('SettingsUserEdit', function($scope, $dialog,
*/ */
$scope.edit = function() { $scope.edit = function() {
var promise = null; var promise = null;
var user = angular.copy($scope.user);
user.storage_quota *= 1000000;
if ($scope.isEdit()) { if ($scope.isEdit()) {
promise = Restangular promise = Restangular
.one('user', $stateParams.username) .one('user', $stateParams.username)
.post('', $scope.user); .post('', user);
} else { } else {
promise = Restangular promise = Restangular
.one('user') .one('user')
.put($scope.user); .put(user);
} }
promise.then(function() { promise.then(function() {

View File

@ -110,7 +110,10 @@
</a> </a>
</li> </li>
<li> <li>
<a href="#/settings/account" title="Logged in as {{ userInfo.username }}">{{ userInfo.username }}</a> <a href="#/settings/account" title="Logged in as {{ userInfo.username }}">
<span class="glyphicon glyphicon-user"></span>
{{ userInfo.username }}
</a>
</li> </li>
<li ng-class="{active: $uiRoute}" ui-route="/settings.*"> <li ng-class="{active: $uiRoute}" ui-route="/settings.*">
<a href="#/settings/account"> <a href="#/settings/account">

View File

@ -73,6 +73,11 @@
</select> </select>
</div> </div>
<div class="pull-left" title="To upgrade your quota, ask your administrator">
{{ 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
</div>
<div class="text-right"> <div class="text-right">
{{ totalDocuments }} document{{ totalDocuments > 1 ? 's' : '' }} found {{ totalDocuments }} document{{ totalDocuments > 1 ? 's' : '' }} found
</div> </div>

View File

@ -37,6 +37,21 @@
<span class="help-block" ng-show="editUserForm.email.$error.maxlength">Too long</span> <span class="help-block" ng-show="editUserForm.email.$error.maxlength">Too long</span>
</div> </div>
</div> </div>
<div class="form-group" ng-class="{ 'has-error': !editUserForm.storage_quota.$valid, success: editUserForm.storage_quota.$valid }">
<label class="col-sm-2 control-label" for="inputQuota">Storage quota</label>
<div class="col-sm-7">
<div class="input-group">
<input name="storage_quota" type="number" id="inputQuota" required class="form-control"
ng-pattern="/[0-9]*/" placeholder="Storage quota (in MB)" ng-model="user.storage_quota"/>
<div class="input-group-addon">MB</div>
</div>
</div>
<div class="col-sm-3">
<span class="help-block" ng-show="editUserForm.storage_quota.$error.pattern">Number required</span>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error': !editUserForm.password.$valid, success: editUserForm.password.$valid }"> <div class="form-group" ng-class="{ 'has-error': !editUserForm.password.$valid, success: editUserForm.password.$valid }">
<label class="col-sm-2 control-label" for="inputPassword">Password</label> <label class="col-sm-2 control-label" for="inputPassword">Password</label>

View File

@ -53,6 +53,12 @@ public class TestAppResource extends BaseJerseyTest {
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminAuthenticationToken)
.post(Entity.form(new Form())); .post(Entity.form(new Form()));
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); 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()));
} }
/** /**