Closes #41: File upload error handling + used storage updated

This commit is contained in:
jendib 2015-11-30 00:08:47 +01:00
parent aa97253ec7
commit e36143b61c
5 changed files with 69 additions and 16 deletions

View File

@ -165,7 +165,8 @@ public class FileResource extends BaseResource {
// Always return OK // Always return OK
JsonObjectBuilder response = Json.createObjectBuilder() JsonObjectBuilder response = Json.createObjectBuilder()
.add("status", "ok") .add("status", "ok")
.add("id", fileId); .add("id", fileId)
.add("size", fileData.length);
return Response.ok().entity(response.build()).build(); return Response.ok().entity(response.build()).build();
} catch (Exception e) { } catch (Exception e) {
throw new ServerException("FileError", "Error adding a file", e); throw new ServerException("FileError", "Error adding a file", e);
@ -303,11 +304,16 @@ public class FileResource extends BaseResource {
JsonArrayBuilder files = Json.createArrayBuilder(); JsonArrayBuilder files = Json.createArrayBuilder();
for (File fileDb : fileList) { for (File fileDb : fileList) {
files.add(Json.createObjectBuilder() try {
.add("id", fileDb.getId()) files.add(Json.createObjectBuilder()
.add("mimetype", fileDb.getMimeType()) .add("id", fileDb.getId())
.add("document_id", JsonUtil.nullable(fileDb.getDocumentId())) .add("mimetype", fileDb.getMimeType())
.add("create_date", fileDb.getCreateDate().getTime())); .add("document_id", JsonUtil.nullable(fileDb.getDocumentId()))
.add("create_date", fileDb.getCreateDate().getTime())
.add("size", Files.size(DirectoryUtil.getStorageDirectory().resolve(fileDb.getId()))));
} catch (IOException e) {
throw new ServerException("FileError", "Unable to get the size of " + fileDb.getId(), e);
}
} }
JsonObjectBuilder response = Json.createObjectBuilder() JsonObjectBuilder response = Json.createObjectBuilder()

View File

@ -3,7 +3,7 @@
/** /**
* Document default controller. * Document default controller.
*/ */
angular.module('docs').controller('DocumentDefault', function($scope, $state, Restangular, $upload) { angular.module('docs').controller('DocumentDefault', function($scope, $rootScope, $state, Restangular, $upload) {
// Load app data // Load app data
Restangular.one('app').get().then(function(data) { Restangular.one('app').get().then(function(data) {
$scope.app = data; $scope.app = data;
@ -73,7 +73,18 @@ angular.module('docs').controller('DocumentDefault', function($scope, $state, Re
newfile.progress = parseInt(100.0 * e.loaded / e.total); newfile.progress = parseInt(100.0 * e.loaded / e.total);
}) })
.success(function (data) { .success(function (data) {
// Update local model with real data
newfile.id = data.id; newfile.id = data.id;
newfile.size = data.size;
// New file uploaded, increase used quota
$rootScope.userInfo.storage_current += data.size;
})
.error(function (data) {
newfile.status = 'Upload error';
if (data.type == 'QuotaReached') {
newfile.status += ' - Quota reached';
}
}); });
}; };
@ -90,7 +101,11 @@ angular.module('docs').controller('DocumentDefault', function($scope, $state, Re
$scope.deleteFile = function ($event, file) { $scope.deleteFile = function ($event, file) {
$event.stopPropagation(); $event.stopPropagation();
Restangular.one('file', file.id).remove().then(function () { Restangular.one('file', file.id).remove().then(function() {
// File deleted, decrease used quota
$rootScope.userInfo.storage_current -= file.size;
// Update local data
$scope.loadFiles(); $scope.loadFiles();
}); });
return false; return false;

View File

@ -142,8 +142,8 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
success: function(response) { success: function(response) {
deferred.resolve(response); deferred.resolve(response);
}, },
error: function(jqXHR, textStatus, errorThrown) { error: function(jqXHR) {
deferred.reject(errorThrown); deferred.reject(jqXHR);
}, },
xhr: function() { xhr: function() {
var myXhr = $.ajaxSettings.xhr(); var myXhr = $.ajaxSettings.xhr();
@ -155,8 +155,23 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
// Update progress bar and title on progress // Update progress bar and title on progress
var startProgress = $scope.fileProgress; var startProgress = $scope.fileProgress;
deferred.promise.then(null, null, function(e) { deferred.promise.then(function(data) {
var done = 1 - (e.total - e.position) / e.total; // New file uploaded, increase used quota
$rootScope.userInfo.storage_current += data.size;
}, function(data) {
// Error uploading a file, we stop here
$scope.alerts.unshift({
type: 'danger',
msg: 'Document successfully ' + ($scope.isEdit() ? 'edited' : 'added') + ' but some files cannot be uploaded'
+ (data.responseJSON.type == 'QuotaReached' ? ' - Quota reached' : '')
});
// Reset view and title
$scope.fileIsUploading = false;
$scope.fileProgress = 0;
$rootScope.pageTitle = 'Sismics Docs';
}, function(e) {
var done = 1 - (e.total - e.loaded) / e.total;
var chunk = 100 / _.size($scope.newFiles); var chunk = 100 / _.size($scope.newFiles);
$scope.fileProgress = startProgress + done * chunk; $scope.fileProgress = startProgress + done * chunk;
$rootScope.pageTitle = Math.round($scope.fileProgress) + '% - Sismics Docs'; $rootScope.pageTitle = Math.round($scope.fileProgress) + '% - Sismics Docs';
@ -170,7 +185,7 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
var then = function() { var then = function() {
key++; key++;
if ($scope.newFiles[key]) { if ($scope.newFiles[key]) {
sendFile(key).then(then); // TODO Handle upload error sendFile(key).then(then);
} else { } else {
$scope.fileIsUploading = false; $scope.fileIsUploading = false;
$scope.fileProgress = 0; $scope.fileProgress = 0;

View File

@ -3,7 +3,7 @@
/** /**
* Document view content controller. * Document view content controller.
*/ */
angular.module('docs').controller('DocumentViewContent', function ($scope, $stateParams, Restangular, $dialog, $state, $upload) { angular.module('docs').controller('DocumentViewContent', function ($scope, $rootScope, $stateParams, Restangular, $dialog, $state, $upload) {
/** /**
* Configuration for file sorting. * Configuration for file sorting.
*/ */
@ -55,6 +55,10 @@ angular.module('docs').controller('DocumentViewContent', function ($scope, $stat
$dialog.messageBox(title, msg, btns, function (result) { $dialog.messageBox(title, msg, btns, function (result) {
if (result == 'ok') { if (result == 'ok') {
Restangular.one('file', file.id).remove().then(function () { Restangular.one('file', file.id).remove().then(function () {
// File deleted, decrease used quota
$rootScope.userInfo.storage_current -= file.size;
// Update local data
$scope.loadFiles(); $scope.loadFiles();
}); });
} }
@ -109,11 +113,22 @@ angular.module('docs').controller('DocumentViewContent', function ($scope, $stat
id: $stateParams.id id: $stateParams.id
} }
}) })
.progress(function (e) { .progress(function(e) {
newfile.progress = parseInt(100.0 * e.loaded / e.total); newfile.progress = parseInt(100.0 * e.loaded / e.total);
}) })
.success(function (data) { .success(function(data) {
// Update local model with real data
newfile.id = data.id; newfile.id = data.id;
newfile.size = data.size;
// New file uploaded, increase used quota
$rootScope.userInfo.storage_current += data.size;
})
.error(function (data) {
newfile.status = 'Upload error';
if (data.type == 'QuotaReached') {
newfile.status += ' - Quota reached';
}
}); });
}; };
}); });

View File

@ -68,6 +68,7 @@ public class TestFileResource extends BaseJerseyTest {
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class); MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file1Id = json.getString("id"); file1Id = json.getString("id");
Assert.assertNotNull(file1Id); Assert.assertNotNull(file1Id);
Assert.assertEquals(163510l, json.getJsonNumber("size").longValue());
} }
} }
@ -135,6 +136,7 @@ public class TestFileResource extends BaseJerseyTest {
JsonArray files = json.getJsonArray("files"); JsonArray files = json.getJsonArray("files");
Assert.assertEquals(2, files.size()); Assert.assertEquals(2, files.size());
Assert.assertEquals(file1Id, files.getJsonObject(0).getString("id")); Assert.assertEquals(file1Id, files.getJsonObject(0).getString("id"));
Assert.assertEquals(163510l, files.getJsonObject(0).getJsonNumber("size").longValue());
Assert.assertEquals(file2Id, files.getJsonObject(1).getString("id")); Assert.assertEquals(file2Id, files.getJsonObject(1).getString("id"));
// Reorder files // Reorder files