Skip to content

Commit 1eebfe2

Browse files
author
Max Burnette
committed
add folder download support
1 parent fb1f265 commit 1eebfe2

File tree

4 files changed

+55
-6
lines changed

4 files changed

+55
-6
lines changed

app/api/Datasets.scala

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,7 +2070,7 @@ class Datasets @Inject()(
20702070
*/
20712071
def enumeratorFromDataset(dataset: Dataset, chunkSize: Int = 1024 * 8,
20722072
compression: Int = Deflater.DEFAULT_COMPRESSION, bagit: Boolean,
2073-
user : Option[User], fileIDs: Option[List[UUID]])
2073+
user : Option[User], fileIDs: Option[List[UUID]], folderId: Option[UUID])
20742074
(implicit ec: ExecutionContext): Enumerator[Array[Byte]] = {
20752075
implicit val pec = ec.prepare()
20762076
val dataFolder = if (bagit) "data/" else ""
@@ -2086,8 +2086,10 @@ class Datasets @Inject()(
20862086
listFilesInFolder(fids, List.empty, dataFolder, filenameMap, inputFiles)
20872087
}
20882088
case None => {
2089-
// TODO: folderId match ...
2090-
listFilesInFolder(dataset.files, dataset.folders, dataFolder, filenameMap, inputFiles)
2089+
folderId match {
2090+
case Some(fid) => listFilesInFolder(List.empty, List(fid), dataFolder, filenameMap, inputFiles)
2091+
case None => listFilesInFolder(dataset.files, dataset.folders, dataFolder, filenameMap, inputFiles)
2092+
}
20912093
}
20922094
}
20932095

@@ -2426,7 +2428,7 @@ class Datasets @Inject()(
24262428

24272429
// Use custom enumerator to create the zip file on the fly
24282430
// Use a 1MB in memory byte array
2429-
Ok.chunked(enumeratorFromDataset(dataset,1024*1024, compression, bagit, user, None)).withHeaders(
2431+
Ok.chunked(enumeratorFromDataset(dataset,1024*1024, compression, bagit, user, None, None)).withHeaders(
24302432
CONTENT_TYPE -> "application/zip",
24312433
CONTENT_DISPOSITION -> (FileUtils.encodeAttachment(dataset.name+ ".zip", request.headers.get("user-agent").getOrElse("")))
24322434
)
@@ -2450,7 +2452,7 @@ class Datasets @Inject()(
24502452

24512453
// Use custom enumerator to create the zip file on the fly
24522454
// Use a 1MB in memory byte array
2453-
Ok.chunked(enumeratorFromDataset(dataset,1024*1024, -1, bagit, user, Some(fileIDs))).withHeaders(
2455+
Ok.chunked(enumeratorFromDataset(dataset,1024*1024, -1, bagit, user, Some(fileIDs), None)).withHeaders(
24542456
CONTENT_TYPE -> "application/zip",
24552457
CONTENT_DISPOSITION -> (FileUtils.encodeAttachment(dataset.name+ " (Partial).zip", request.headers.get("user-agent").getOrElse("")))
24562458
)
@@ -2462,6 +2464,36 @@ class Datasets @Inject()(
24622464
}
24632465
}
24642466

2467+
def downloadFolder(id: UUID, folderId: UUID) = PermissionAction(Permission.DownloadFiles, Some(ResourceRef(ResourceRef.dataset, id))) { implicit request =>
2468+
implicit val user = request.user
2469+
datasets.get(id) match {
2470+
case Some(dataset) => {
2471+
val bagit = play.api.Play.configuration.getBoolean("downloadDatasetBagit").getOrElse(true)
2472+
2473+
// Increment download count for each file in folder
2474+
folders.get(folderId) match {
2475+
case Some(fo) => {
2476+
fo.files.foreach(fid => files.incrementDownloads(fid, user))
2477+
2478+
// Use custom enumerator to create the zip file on the fly
2479+
// Use a 1MB in memory byte array
2480+
Ok.chunked(enumeratorFromDataset(dataset,1024*1024, -1, bagit, user, None, Some(folderId))).withHeaders(
2481+
CONTENT_TYPE -> "application/zip",
2482+
CONTENT_DISPOSITION -> (FileUtils.encodeAttachment(dataset.name+ " ( "+fo.name+" Folder).zip", request.headers.get("user-agent").getOrElse("")))
2483+
)
2484+
}
2485+
case None => NotFound
2486+
}
2487+
2488+
2489+
}
2490+
// If the dataset wasn't found by ID
2491+
case None => {
2492+
NotFound
2493+
}
2494+
}
2495+
}
2496+
24652497
def updateAccess(id:UUID, access:String) = PermissionAction(Permission.PublicDataset, Some(ResourceRef(ResourceRef.dataset, id))) { implicit request =>
24662498
implicit val user = request.user
24672499
user match {

app/controllers/Application.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ class Application @Inject() (files: FileService, collections: CollectionService,
334334
api.routes.javascript.Datasets.detachFile,
335335
api.routes.javascript.Datasets.download,
336336
api.routes.javascript.Datasets.downloadPartial,
337+
api.routes.javascript.Datasets.downloadFolder,
337338
api.routes.javascript.Datasets.getPreviews,
338339
api.routes.javascript.Datasets.updateAccess,
339340
api.routes.javascript.Datasets.addFileEvent,

app/views/folders/listitem.scala.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ <h3 id="[email protected]" class="hiddencomplete">
2626
</div>
2727

2828
<div class="row">
29-
<div class="col-md-12 col-lg-12 col-sm-12">
29+
<div class="col-md-8 col-lg-8 col-sm-8">
3030
<ul class="list-unstyled">
3131
<li>
3232
<span class="glyphicon glyphicon-folder-close"></span> @folder.folders.length
@@ -44,6 +44,21 @@ <h3 id="[email protected]" class="hiddencomplete">
4444
</li>
4545
</ul>
4646
</div>
47+
<div class="col-md-4 col-lg-4 col-sm-4">
48+
<ul class="list-unstyled">
49+
@if(Permission.checkPermission(Permission.DownloadFiles, ResourceRef(ResourceRef.dataset, folder.parentDatasetId))) {
50+
<li>
51+
<button id="downloadButton" onclick="window.open(jsRoutes.api.Datasets.downloadFolder('@folder.parentDatasetId', '@folder.id').url, '_blank');" class="btn btn-link" title="Download and enjoy this file.">
52+
<span class="glyphicon glyphicon-save"></span> Download
53+
</button>
54+
</li>
55+
} else {
56+
<li>
57+
<div class="inline" title="No permission to download the folder">
58+
<button disabled class="btn btn-link"><span class="glyphicon glyphicon-save"></span> Download</button>
59+
</div>
60+
</li>
61+
}
4762
</div>
4863
</div>
4964
</div>

conf/routes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ POST /api/datasets/:id/files
575575
POST /api/datasets/:id/urls @api.Datasets.uploadToDatasetJSON(id: UUID)
576576
GET /api/datasets/:id/download @api.Datasets.download(id: UUID, compression: Int ?= -1, tracking: Boolean ?= true)
577577
GET /api/datasets/:id/downloadPartial @api.Datasets.downloadPartial(id: UUID, fileList: String)
578+
GET /api/datasets/:id/downloadFolder @api.Datasets.downloadFolder(id: UUID, folderId: UUID)
578579
POST /api/datasets/:id/comment @api.Datasets.comment(id: UUID)
579580
POST /api/datasets/:id/reindex @api.Datasets.reindex(id:UUID, recursive: Boolean ?= true)
580581
POST /api/datasets/:id/follow @api.Datasets.follow(id: UUID)

0 commit comments

Comments
 (0)