mirror of
https://github.com/sismics/docs.git
synced 2024-11-25 23:27:57 +01:00
Closes #208: display file content + fix filename encoding
This commit is contained in:
parent
55a4bb7621
commit
be1c2a7b90
@ -54,6 +54,7 @@ public class FileCreatedAsyncListener {
|
|||||||
FormatHandler formatHandler = FormatHandlerUtil.find(file.getMimeType());
|
FormatHandler formatHandler = FormatHandlerUtil.find(file.getMimeType());
|
||||||
if (formatHandler == null) {
|
if (formatHandler == null) {
|
||||||
log.error("Format unhandled: " + file.getMimeType());
|
log.error("Format unhandled: " + file.getMimeType());
|
||||||
|
FileUtil.endProcessingFile(file.getId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ public class FileCreatedAsyncListener {
|
|||||||
});
|
});
|
||||||
if (user.get() == null) {
|
if (user.get() == null) {
|
||||||
// The user has been deleted meanwhile
|
// The user has been deleted meanwhile
|
||||||
|
FileUtil.endProcessingFile(file.getId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ import javax.ws.rs.core.StreamingOutput;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
@ -119,7 +120,7 @@ public class FileResource extends BaseResource {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String name = fileBodyPart.getContentDisposition() != null ?
|
String name = fileBodyPart.getContentDisposition() != null ?
|
||||||
fileBodyPart.getContentDisposition().getFileName() : null;
|
URLDecoder.decode(fileBodyPart.getContentDisposition().getFileName(), "UTF-8") : null;
|
||||||
String fileId = FileUtil.createFile(name, unencryptedFile, fileSize, documentDto == null ?
|
String fileId = FileUtil.createFile(name, unencryptedFile, fileSize, documentDto == null ?
|
||||||
null : documentDto.getLanguage(), principal.getId(), documentId);
|
null : documentDto.getLanguage(), principal.getId(), documentId);
|
||||||
|
|
||||||
@ -449,7 +450,7 @@ public class FileResource extends BaseResource {
|
|||||||
* @apiGroup File
|
* @apiGroup File
|
||||||
* @apiParam {String} id File ID
|
* @apiParam {String} id File ID
|
||||||
* @apiParam {String} share Share ID
|
* @apiParam {String} share Share ID
|
||||||
* @apiParam {String="web","thumb"} [size] Size variation
|
* @apiParam {String="web","thumb","content"} [size] Size variation
|
||||||
* @apiSuccess {Object} file The file data is the whole response
|
* @apiSuccess {Object} file The file data is the whole response
|
||||||
* @apiError (client) SizeError Size must be web or thumb
|
* @apiError (client) SizeError Size must be web or thumb
|
||||||
* @apiError (client) ForbiddenError Access denied or document not visible
|
* @apiError (client) ForbiddenError Access denied or document not visible
|
||||||
@ -469,10 +470,8 @@ public class FileResource extends BaseResource {
|
|||||||
@QueryParam("size") String size) {
|
@QueryParam("size") String size) {
|
||||||
authenticate();
|
authenticate();
|
||||||
|
|
||||||
if (size != null) {
|
if (size != null && !Lists.newArrayList("web", "thumb", "content").contains(size)) {
|
||||||
if (!Lists.newArrayList("web", "thumb").contains(size)) {
|
throw new ClientException("SizeError", "Size must be web, thumb or content");
|
||||||
throw new ClientException("SizeError", "Size must be web or thumb");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the file
|
// Get the file
|
||||||
@ -484,6 +483,12 @@ public class FileResource extends BaseResource {
|
|||||||
String mimeType;
|
String mimeType;
|
||||||
boolean decrypt;
|
boolean decrypt;
|
||||||
if (size != null) {
|
if (size != null) {
|
||||||
|
if (size.equals("content")) {
|
||||||
|
return Response.ok(Strings.nullToEmpty(file.getContent()))
|
||||||
|
.header(HttpHeaders.CONTENT_TYPE, "text/plain")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
storedFile = DirectoryUtil.getStorageDirectory().resolve(fileId + "_" + size);
|
storedFile = DirectoryUtil.getStorageDirectory().resolve(fileId + "_" + size);
|
||||||
mimeType = MimeType.IMAGE_JPEG; // Thumbnails are JPEG
|
mimeType = MimeType.IMAGE_JPEG; // Thumbnails are JPEG
|
||||||
decrypt = true; // Thumbnails are encrypted
|
decrypt = true; // Thumbnails are encrypted
|
||||||
|
@ -153,7 +153,7 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
|
|||||||
var file = $scope.newFiles[key];
|
var file = $scope.newFiles[key];
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append('id', data.id);
|
formData.append('id', data.id);
|
||||||
formData.append('file', file, file.name);
|
formData.append('file', file, encodeURIComponent(file.name));
|
||||||
|
|
||||||
// Send the file
|
// Send the file
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -70,6 +70,13 @@ angular.module('docs').controller('FileModalView', function ($uibModalInstance,
|
|||||||
window.open('../api/file/' + $stateParams.fileId + '/data');
|
window.open('../api/file/' + $stateParams.fileId + '/data');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the file content a new window.
|
||||||
|
*/
|
||||||
|
$scope.openFileContent = function () {
|
||||||
|
window.open('../api/file/' + $stateParams.fileId + '/data?size=content');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print the file.
|
* Print the file.
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
/**!
|
/**!
|
||||||
|
* =======================================================================
|
||||||
|
* Sismics Docs patch applied to encode filenames with encodeURIComponent.
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
* AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
|
* AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
|
||||||
* progress, resize, thumbnail, preview, validation and CORS
|
* progress, resize, thumbnail, preview, validation and CORS
|
||||||
* @author Danial <danial.farid@gmail.com>
|
* @author Danial <danial.farid@gmail.com>
|
||||||
@ -272,7 +276,7 @@ ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http,
|
|||||||
key = split[0];
|
key = split[0];
|
||||||
}
|
}
|
||||||
config._fileKey = config._fileKey || key;
|
config._fileKey = config._fileKey || key;
|
||||||
formData.append(key, file, file.ngfName || file.name);
|
formData.append(key, file, file.ngfName || encodeURIComponent(file.name));
|
||||||
} else {
|
} else {
|
||||||
if (angular.isObject(val)) {
|
if (angular.isObject(val)) {
|
||||||
if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;
|
if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
<div class="btn btn-default handle"><span class="fas fa-arrows-alt-h"></span></div>
|
<div class="btn btn-default handle"><span class="fas fa-arrows-alt-h"></span></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="v-align">
|
<div class="v-align" ng-show="document.writable">
|
||||||
<div uib-dropdown>
|
<div uib-dropdown>
|
||||||
<button class="btn btn-default" uib-dropdown-toggle>
|
<button class="btn btn-default" uib-dropdown-toggle>
|
||||||
<span class="fas fa-ellipsis-v"></span>
|
<span class="fas fa-ellipsis-v"></span>
|
||||||
|
@ -22,12 +22,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<button type="button" class="btn btn-default" ng-click="printFile()">
|
<button type="button" class="btn btn-default" uib-tooltip="Print this file" tooltip-append-to-body="true" ng-click="printFile()">
|
||||||
<span class="fas fa-print"></span>
|
<span class="fas fa-print"></span>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-default" ng-click="openFile()">
|
<button type="button" class="btn btn-default" uib-tooltip="Download this file" tooltip-append-to-body="true" ng-click="openFile()">
|
||||||
<span class="fas fa-download"></span>
|
<span class="fas fa-download"></span>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" uib-tooltip="Show text content" tooltip-append-to-body="true" ng-click="openFileContent()">
|
||||||
|
<span class="fas fa-eye"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -429,6 +429,8 @@ input[readonly].share-link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.settings-content {
|
.settings-content {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
.well {
|
.well {
|
||||||
box-shadow: 0 7px 14px 0 rgba(50,50,93,.1), 0 3px 6px 0 rgba(0,0,0,.07);
|
box-shadow: 0 7px 14px 0 rgba(50,50,93,.1), 0 3px 6px 0 rgba(0,0,0,.07);
|
||||||
background: none;
|
background: none;
|
||||||
|
@ -580,6 +580,16 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
Assert.assertTrue(fileBytes.length > 0); // Images rendered from PDF differ in size from OS to OS due to font issues
|
Assert.assertTrue(fileBytes.length > 0); // Images rendered from PDF differ in size from OS to OS due to font issues
|
||||||
Assert.assertEquals(MimeType.IMAGE_JPEG, MimeTypeUtil.guessMimeType(fileBytes, null));
|
Assert.assertEquals(MimeType.IMAGE_JPEG, MimeTypeUtil.guessMimeType(fileBytes, null));
|
||||||
|
|
||||||
|
// Get the content data
|
||||||
|
response = target().path("/file/" + file1Id + "/data")
|
||||||
|
.queryParam("size", "content")
|
||||||
|
.request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPlainToken)
|
||||||
|
.get();
|
||||||
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
|
is = (InputStream) response.getEntity();
|
||||||
|
Assert.assertTrue(new String(ByteStreams.toByteArray(is)).contains("love"));
|
||||||
|
|
||||||
// Export a document in PDF format
|
// Export a document in PDF format
|
||||||
response = target().path("/document/" + document1Id + "/pdf")
|
response = target().path("/document/" + document1Id + "/pdf")
|
||||||
.queryParam("margin", "10")
|
.queryParam("margin", "10")
|
||||||
|
@ -106,6 +106,14 @@ public class TestFileResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals(MimeType.IMAGE_JPEG, MimeTypeUtil.guessMimeType(fileBytes, null));
|
Assert.assertEquals(MimeType.IMAGE_JPEG, MimeTypeUtil.guessMimeType(fileBytes, null));
|
||||||
Assert.assertTrue(fileBytes.length > 0);
|
Assert.assertTrue(fileBytes.length > 0);
|
||||||
|
|
||||||
|
// Get the content data
|
||||||
|
response = target().path("/file/" + file1Id + "/data")
|
||||||
|
.queryParam("size", "content")
|
||||||
|
.request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
|
||||||
|
.get();
|
||||||
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
|
|
||||||
// Get the web data
|
// Get the web data
|
||||||
response = target().path("/file/" + file1Id + "/data")
|
response = target().path("/file/" + file1Id + "/data")
|
||||||
.queryParam("size", "web")
|
.queryParam("size", "web")
|
||||||
|
Loading…
Reference in New Issue
Block a user