From e36143b61c5e8fec9bd81f80dda02e4a2c05dfc7 Mon Sep 17 00:00:00 2001 From: jendib Date: Mon, 30 Nov 2015 00:08:47 +0100 Subject: [PATCH] Closes #41: File upload error handling + used storage updated --- .../docs/rest/resource/FileResource.java | 18 ++++++++----- .../app/docs/controller/DocumentDefault.js | 19 ++++++++++++-- .../src/app/docs/controller/DocumentEdit.js | 25 +++++++++++++++---- .../docs/controller/DocumentViewContent.js | 21 +++++++++++++--- .../sismics/docs/rest/TestFileResource.java | 2 ++ 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java index 694ed8f8..69052f27 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java @@ -165,7 +165,8 @@ public class FileResource extends BaseResource { // Always return OK JsonObjectBuilder response = Json.createObjectBuilder() .add("status", "ok") - .add("id", fileId); + .add("id", fileId) + .add("size", fileData.length); return Response.ok().entity(response.build()).build(); } catch (Exception e) { throw new ServerException("FileError", "Error adding a file", e); @@ -303,11 +304,16 @@ public class FileResource extends BaseResource { JsonArrayBuilder files = Json.createArrayBuilder(); for (File fileDb : fileList) { - files.add(Json.createObjectBuilder() - .add("id", fileDb.getId()) - .add("mimetype", fileDb.getMimeType()) - .add("document_id", JsonUtil.nullable(fileDb.getDocumentId())) - .add("create_date", fileDb.getCreateDate().getTime())); + try { + files.add(Json.createObjectBuilder() + .add("id", fileDb.getId()) + .add("mimetype", fileDb.getMimeType()) + .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() diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentDefault.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentDefault.js index 361ef241..6d9c7715 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/DocumentDefault.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentDefault.js @@ -3,7 +3,7 @@ /** * 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 Restangular.one('app').get().then(function(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); }) .success(function (data) { + // Update local model with real data 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) { $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(); }); return false; diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js index c9141ec7..139689ef 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js @@ -142,8 +142,8 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $ success: function(response) { deferred.resolve(response); }, - error: function(jqXHR, textStatus, errorThrown) { - deferred.reject(errorThrown); + error: function(jqXHR) { + deferred.reject(jqXHR); }, xhr: function() { var myXhr = $.ajaxSettings.xhr(); @@ -155,8 +155,23 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $ // Update progress bar and title on progress var startProgress = $scope.fileProgress; - deferred.promise.then(null, null, function(e) { - var done = 1 - (e.total - e.position) / e.total; + deferred.promise.then(function(data) { + // 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); $scope.fileProgress = startProgress + done * chunk; $rootScope.pageTitle = Math.round($scope.fileProgress) + '% - Sismics Docs'; @@ -170,7 +185,7 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $ var then = function() { key++; if ($scope.newFiles[key]) { - sendFile(key).then(then); // TODO Handle upload error + sendFile(key).then(then); } else { $scope.fileIsUploading = false; $scope.fileProgress = 0; diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js index 44fbe3ff..6bddae9b 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js @@ -3,7 +3,7 @@ /** * 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. */ @@ -55,6 +55,10 @@ angular.module('docs').controller('DocumentViewContent', function ($scope, $stat $dialog.messageBox(title, msg, btns, function (result) { if (result == 'ok') { Restangular.one('file', file.id).remove().then(function () { + // File deleted, decrease used quota + $rootScope.userInfo.storage_current -= file.size; + + // Update local data $scope.loadFiles(); }); } @@ -109,11 +113,22 @@ angular.module('docs').controller('DocumentViewContent', function ($scope, $stat id: $stateParams.id } }) - .progress(function (e) { + .progress(function(e) { 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.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'; + } }); }; }); \ No newline at end of file diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java index 9d48fe41..f4e851b3 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java @@ -68,6 +68,7 @@ public class TestFileResource extends BaseJerseyTest { MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class); file1Id = json.getString("id"); Assert.assertNotNull(file1Id); + Assert.assertEquals(163510l, json.getJsonNumber("size").longValue()); } } @@ -135,6 +136,7 @@ public class TestFileResource extends BaseJerseyTest { JsonArray files = json.getJsonArray("files"); Assert.assertEquals(2, files.size()); 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")); // Reorder files