mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
#41: Batch to rebuild quota storage + UI: show and edit quota
This commit is contained in:
parent
0fab0e4fc0
commit
aa97253ec7
@ -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<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();
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -110,7 +110,10 @@
|
||||
</a>
|
||||
</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 ng-class="{active: $uiRoute}" ui-route="/settings.*">
|
||||
<a href="#/settings/account">
|
||||
|
@ -73,6 +73,11 @@
|
||||
</select>
|
||||
</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">
|
||||
{{ totalDocuments }} document{{ totalDocuments > 1 ? 's' : '' }} found
|
||||
</div>
|
||||
|
@ -37,6 +37,21 @@
|
||||
<span class="help-block" ng-show="editUserForm.email.$error.maxlength">Too long</span>
|
||||
</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 }">
|
||||
<label class="col-sm-2 control-label" for="inputPassword">Password</label>
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user