mirror of
https://github.com/sismics/docs.git
synced 2024-11-25 15:17:57 +01:00
Download all files from a document as ZIP
This commit is contained in:
parent
ae566018d6
commit
34e3ac5478
@ -56,4 +56,29 @@ public class MimeTypeUtil {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file extension linked to a MIME type.
|
||||
*
|
||||
* @param mimeType MIME type
|
||||
* @return File extension
|
||||
*/
|
||||
public static String getFileExtension(String mimeType) {
|
||||
switch (mimeType) {
|
||||
case MimeType.APPLICATION_ZIP:
|
||||
return "zip";
|
||||
case MimeType.IMAGE_GIF:
|
||||
return "gif";
|
||||
case MimeType.IMAGE_JPEG:
|
||||
return "jpg";
|
||||
case MimeType.IMAGE_PNG:
|
||||
return "png";
|
||||
case MimeType.IMAGE_X_ICON:
|
||||
return "ico";
|
||||
case MimeType.APPLICATION_PDF:
|
||||
return "pdf";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,2 @@
|
||||
- Automatic backup system using Quartz (server)
|
||||
- Handle error while uploading a file
|
||||
- Download all files as zip (docs & share)
|
||||
|
@ -11,6 +11,8 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.ws.rs.Consumes;
|
||||
@ -372,4 +374,75 @@ public class FileResource extends BaseResource {
|
||||
.header("Expires", new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z").format(new Date().getTime() + 3600000 * 24))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all files from a document, zipped.
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @return Response
|
||||
* @throws JSONException
|
||||
*/
|
||||
@GET
|
||||
@Path("zip")
|
||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||
public Response zip(
|
||||
@QueryParam("id") String documentId,
|
||||
@QueryParam("share") String shareId) throws JSONException {
|
||||
authenticate();
|
||||
|
||||
// Get the document
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
Document document;
|
||||
try {
|
||||
document = documentDao.getDocument(documentId);
|
||||
|
||||
// Check document visibility
|
||||
ShareDao shareDao = new ShareDao();
|
||||
if (!shareDao.checkVisibility(document, principal.getId(), shareId)) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
} catch (NoResultException e) {
|
||||
throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", documentId));
|
||||
}
|
||||
|
||||
// Get files and user associated with this document
|
||||
FileDao fileDao = new FileDao();
|
||||
UserDao userDao = new UserDao();
|
||||
final List<File> fileList = fileDao.getByDocumentId(documentId);
|
||||
final User user = userDao.getById(document.getUserId());
|
||||
|
||||
// Create the ZIP stream
|
||||
StreamingOutput stream = new StreamingOutput() {
|
||||
@Override
|
||||
public void write(OutputStream outputStream) throws IOException, WebApplicationException {
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
|
||||
// Add each file to the ZIP stream
|
||||
int index = 0;
|
||||
for (File file : fileList) {
|
||||
java.io.File storedfile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), file.getId()).toFile();
|
||||
InputStream fileInputStream = new FileInputStream(storedfile);
|
||||
|
||||
// Add the decrypted file to the ZIP stream
|
||||
try (InputStream decryptedStream = EncryptionUtil.decryptInputStream(fileInputStream, user.getPrivateKey())) {
|
||||
ZipEntry zipEntry = new ZipEntry(index + "." + MimeTypeUtil.getFileExtension(file.getMimeType()));
|
||||
zipOutputStream.putNextEntry(zipEntry);
|
||||
ByteStreams.copy(decryptedStream, zipOutputStream);
|
||||
zipOutputStream.closeEntry();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new WebApplicationException(e);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
outputStream.close();
|
||||
}
|
||||
};
|
||||
|
||||
// Write to the output
|
||||
return Response.ok(stream)
|
||||
.header("Content-Type", "application/zip")
|
||||
.header("Content-Disposition", "attachment; filename=\"" + document.getTitle().replaceAll("\\W+", "_") + ".zip\"")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,13 @@
|
||||
</div>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>{{ document.title }} <small>{{ document.create_date | date: 'yyyy-MM-dd' }}</small> <img ng-if="document" ng-src="img/flag/{{ document.language }}.png" title="{{ document.language }}" /></h1>
|
||||
<h1>
|
||||
{{ document.title }} <small>{{ document.create_date | date: 'yyyy-MM-dd' }}</small>
|
||||
<img ng-if="document" ng-src="img/flag/{{ document.language }}.png" title="{{ document.language }}" />
|
||||
<a ng-href="../api/file/zip?id={{ document.id }}" class="btn btn-default" title="Download all files">
|
||||
<span class="glyphicon glyphicon-compressed"></span>
|
||||
</a>
|
||||
</h1>
|
||||
<p>
|
||||
<button class="btn btn-sm btn-info" ng-click="share()">
|
||||
<span class="glyphicon glyphicon-share"></span> Share
|
||||
|
@ -1,7 +1,12 @@
|
||||
<div class="row">
|
||||
<div class="well col-md-12">
|
||||
<div class="page-header">
|
||||
<h1>{{ document.title }} <small>{{ document.create_date | date: 'yyyy-MM-dd' }}</small></h1>
|
||||
<h1>
|
||||
{{ document.title }} <small>{{ document.create_date | date: 'yyyy-MM-dd' }}</small>
|
||||
<a ng-href="../api/file/zip?id={{ document.id }}&share={{ $stateParams.shareId }}" class="btn btn-default" title="Download all files">
|
||||
<span class="glyphicon glyphicon-compressed"></span>
|
||||
</a>
|
||||
</h1>
|
||||
<ul class="list-inline">
|
||||
<li ng-repeat="tag in document.tags"><span class="label label-info" ng-style="{ 'background': tag.color }">{{ tag.name }}</span></li>
|
||||
</ul>
|
||||
|
@ -160,6 +160,16 @@ public class TestFileResource extends BaseJerseyTest {
|
||||
Assert.assertEquals(file2Id, files.getJSONObject(0).getString("id"));
|
||||
Assert.assertEquals(file1Id, files.getJSONObject(1).getString("id"));
|
||||
|
||||
// Get a ZIP from all files
|
||||
fileResource = resource().path("/file/zip");
|
||||
fileResource.addFilter(new CookieAuthenticationFilter(file1AuthenticationToken));
|
||||
getParams = new MultivaluedMapImpl();
|
||||
getParams.putSingle("id", document1Id);
|
||||
response = fileResource.queryParams(getParams).get(ClientResponse.class);
|
||||
is = response.getEntityInputStream();
|
||||
fileBytes = ByteStreams.toByteArray(is);
|
||||
Assert.assertEquals(MimeType.APPLICATION_ZIP, MimeTypeUtil.guessMimeType(fileBytes));
|
||||
|
||||
// Deletes a file
|
||||
fileResource = resource().path("/file/" + file1Id);
|
||||
fileResource.addFilter(new CookieAuthenticationFilter(file1AuthenticationToken));
|
||||
|
Loading…
Reference in New Issue
Block a user