Skip to content

Commit 890a10b

Browse files
authored
Merge pull request #3909 from OpenNeuroOrg/3907-recursive-flag-downloads
fix(app): Use recursive: true for native file API downloads
2 parents 83699d4 + 66426b1 commit 890a10b

2 files changed

Lines changed: 41 additions & 62 deletions

File tree

packages/openneuro-app/src/scripts/dataset/download/download-native.js

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -43,65 +43,48 @@ class DownloadAbortError extends Error {
4343
let downloadCanceled
4444

4545
/**
46-
* Recursive download for file trees via browser file access API
46+
* Download for file trees via browser file access API
4747
*/
4848
const downloadTree = async (
4949
{ datasetId, snapshotTag, client, dirHandle, toastId },
5050
path = "",
51-
tree = null,
5251
) => {
5352
const filesToDownload = await downloadDataset(client)({
5453
datasetId,
5554
snapshotTag,
56-
tree,
5755
})
5856
for (const [_index, file] of filesToDownload.entries()) {
5957
const downloadPath = path ? `${path}/${file.filename}` : file.filename
60-
if (file.directory) {
61-
// Next tree level
62-
await downloadTree(
63-
{
58+
// Regular file
59+
if (downloadCanceled) {
60+
throw new DownloadAbortError("Download canceled by user request")
61+
}
62+
const fileHandle = await openFileTree(
63+
dirHandle,
64+
path ? `${path}/${file.filename}` : file.filename,
65+
)
66+
// Skip files which are already complete
67+
if (fileHandle.size == file.size) continue
68+
const writable = await fileHandle.createWritable()
69+
const { body, status, statusText } = await fetch(file.urls[0])
70+
let loaded = 0
71+
const progress = new TransformStream({
72+
transform(chunk, controller) {
73+
downloadToastUpdate(toastId, loaded / file.size, {
6474
datasetId,
6575
snapshotTag,
66-
client,
67-
dirHandle,
68-
toastId,
69-
},
70-
downloadPath,
71-
file.key,
72-
)
76+
downloadPath,
77+
dirName: dirHandle.name,
78+
})
79+
loaded += chunk.length
80+
controller.enqueue(chunk)
81+
},
82+
})
83+
if (status === 200) {
84+
await body.pipeThrough(progress).pipeTo(writable)
7385
} else {
74-
// Regular file
75-
if (downloadCanceled) {
76-
throw new DownloadAbortError("Download canceled by user request")
77-
}
78-
const fileHandle = await openFileTree(
79-
dirHandle,
80-
path ? `${path}/${file.filename}` : file.filename,
81-
)
82-
// Skip files which are already complete
83-
if (fileHandle.size == file.size) continue
84-
const writable = await fileHandle.createWritable()
85-
const { body, status, statusText } = await fetch(file.urls[0])
86-
let loaded = 0
87-
const progress = new TransformStream({
88-
transform(chunk, controller) {
89-
downloadToastUpdate(toastId, loaded / file.size, {
90-
datasetId,
91-
snapshotTag,
92-
downloadPath,
93-
dirName: dirHandle.name,
94-
})
95-
loaded += chunk.length
96-
controller.enqueue(chunk)
97-
},
98-
})
99-
if (status === 200) {
100-
await body.pipeThrough(progress).pipeTo(writable)
101-
} else {
102-
Sentry.captureException(statusText)
103-
return requestFailureToast(file.filename)
104-
}
86+
Sentry.captureException(statusText)
87+
return requestFailureToast(file.filename)
10588
}
10689
}
10790
}

packages/openneuro-app/src/scripts/dataset/download/download-query.js

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
import { gql } from "@apollo/client"
22

33
export const DOWNLOAD_DATASET = gql`
4-
query downloadDraft($datasetId: ID!, $tree: String) {
5-
dataset(id: $datasetId) {
6-
id
7-
draft {
4+
query downloadDraft($datasetId: ID!) {
5+
dataset(id: $datasetId) {
86
id
9-
files(tree: $tree) {
7+
draft {
108
id
11-
key
12-
directory
13-
filename
14-
size
15-
urls
9+
files(recursive: true) {
10+
id
11+
directory
12+
filename
13+
size
14+
urls
15+
}
1616
}
1717
}
1818
}
19-
}
2019
`
2120

2221
export const DOWNLOAD_SNAPSHOT = gql`
23-
query downloadSnapshot($datasetId: ID!, $tag: String!, $tree: String) {
22+
query downloadSnapshot($datasetId: ID!, $tag: String!) {
2423
snapshot(datasetId: $datasetId, tag: $tag) {
2524
id
26-
files(tree: $tree) {
25+
files(recursive: true) {
2726
id
28-
key
2927
directory
3028
filename
3129
size
@@ -36,14 +34,13 @@ export const DOWNLOAD_SNAPSHOT = gql`
3634
`
3735

3836
export const downloadDataset =
39-
(client) => async ({ datasetId, snapshotTag, tree = null }) => {
37+
(client) => async ({ datasetId, snapshotTag }) => {
4038
if (snapshotTag) {
4139
const { data } = await client.query({
4240
query: DOWNLOAD_SNAPSHOT,
4341
variables: {
4442
datasetId,
4543
tag: snapshotTag,
46-
tree: tree,
4744
},
4845
})
4946
return data.snapshot.files
@@ -52,7 +49,6 @@ export const downloadDataset =
5249
query: DOWNLOAD_DATASET,
5350
variables: {
5451
datasetId,
55-
tree,
5652
},
5753
})
5854
return data.dataset.draft.files

0 commit comments

Comments
 (0)