Skip to content

Commit 44b3c6c

Browse files
committed
feat: download multiple files apps
1 parent eff3773 commit 44b3c6c

File tree

2 files changed

+175
-68
lines changed

2 files changed

+175
-68
lines changed

public/app/config/mapping.js

+65-33
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,67 @@
11
module.exports = {
2-
'https://utwente.graasp.eu/preproduction/calculator/build/calculator.html':
3-
'https://utwente.graasp.eu/preproduction/calculator/build/calculator.one.html',
4-
'https://utwente.graasp.eu/preproduction/inputBox/build/inputBox.html':
5-
'https://utwente.graasp.eu/preproduction/inputBox/build/inputBox.one.html',
6-
'https://utwente.graasp.eu/preproduction/hypothesis/build/hypothesis.html':
7-
'https://utwente.graasp.eu/preproduction/hypothesis/build/hypothesis.one.html',
8-
'https://utwente.graasp.eu/preproduction/nameTheFrame/build/nameTheFrame.html':
9-
'https://utwente.graasp.eu/preproduction/nameTheFrame/build/nameTheFrame.one.html',
10-
'https://utwente.graasp.eu/preproduction/observationTool/build/observationTool.html':
11-
'https://utwente.graasp.eu/preproduction/observationTool/build/observationTool.one.html',
12-
'https://utwente.graasp.eu/preproduction/refquest/build/quizTool.html':
13-
'https://utwente.graasp.eu/preproduction/refquest/build/quizTool.one.html',
14-
'https://utwente.graasp.eu/preproduction/sharedWiki/build/sharedWiki.html':
15-
'https://utwente.graasp.eu/preproduction/sharedWiki/build/sharedWiki.one.html',
16-
'https://utwente.graasp.eu/preproduction/tableTool/build/tableTool.html':
17-
'https://utwente.graasp.eu/preproduction/tableTool/build/tableTool.one.html',
18-
19-
'https://utwente.graasp.eu/production/calculator/build/calculator.html':
20-
'https://utwente.graasp.eu/production/calculator/build/calculator.one.html',
21-
'https://utwente.graasp.eu/production/inputBox/build/inputBox.html':
22-
'https://utwente.graasp.eu/production/inputBox/build/inputBox.one.html',
23-
'https://utwente.graasp.eu/production/hypothesis/build/hypothesis.html':
24-
'https://utwente.graasp.eu/production/hypothesis/build/hypothesis.one.html',
25-
'https://utwente.graasp.eu/production/nameTheFrame/build/nameTheFrame.html':
26-
'https://utwente.graasp.eu/production/nameTheFrame/build/nameTheFrame.one.html',
27-
'https://utwente.graasp.eu/production/observationTool/build/observationTool.html':
28-
'https://utwente.graasp.eu/production/observationTool/build/observationTool.one.html',
29-
'https://utwente.graasp.eu/production/refquest/build/quizTool.html':
30-
'https://utwente.graasp.eu/production/refquest/build/quizTool.one.html',
31-
'https://utwente.graasp.eu/production/sharedWiki/build/sharedWiki.html':
32-
'https://utwente.graasp.eu/production/sharedWiki/build/sharedWiki.one.html',
33-
'https://utwente.graasp.eu/production/tableTool/build/tableTool.html':
34-
'https://utwente.graasp.eu/production/tableTool/build/tableTool.one.html',
2+
'https://utwente.graasp.eu/preproduction/calculator/build/calculator.html': {
3+
url:
4+
'https://utwente.graasp.eu/preproduction/calculator/build/calculator.one.html',
5+
},
6+
'https://utwente.graasp.eu/preproduction/inputBox/build/inputBox.html': {
7+
url:
8+
'https://utwente.graasp.eu/preproduction/inputBox/build/inputBox.one.html',
9+
},
10+
'https://utwente.graasp.eu/preproduction/hypothesis/build/hypothesis.html': {
11+
url:
12+
'https://utwente.graasp.eu/preproduction/hypothesis/build/hypothesis.one.html',
13+
},
14+
'https://utwente.graasp.eu/preproduction/nameTheFrame/build/nameTheFrame.html': {
15+
url:
16+
'https://utwente.graasp.eu/preproduction/nameTheFrame/build/nameTheFrame.one.html',
17+
},
18+
'https://utwente.graasp.eu/preproduction/observationTool/build/observationTool.html': {
19+
url:
20+
'https://utwente.graasp.eu/preproduction/observationTool/build/observationTool.one.html',
21+
},
22+
'https://utwente.graasp.eu/preproduction/refquest/build/quizTool.html': {
23+
url:
24+
'https://utwente.graasp.eu/preproduction/refquest/build/quizTool.one.html',
25+
},
26+
'https://utwente.graasp.eu/preproduction/tableTool/build/tableTool.html': {
27+
url:
28+
'https://utwente.graasp.eu/preproduction/tableTool/build/tableTool.one.html',
29+
},
30+
'https://utwente.graasp.eu/production/calculator/build/calculator.html': {
31+
url:
32+
'https://utwente.graasp.eu/production/calculator/build/calculator.one.html',
33+
},
34+
'https://utwente.graasp.eu/production/inputBox/build/inputBox.html': {
35+
url:
36+
'https://utwente.graasp.eu/production/inputBox/build/inputBox.one.html',
37+
},
38+
'https://utwente.graasp.eu/production/hypothesis/build/hypothesis.html': {
39+
url:
40+
'https://utwente.graasp.eu/production/hypothesis/build/hypothesis.one.html',
41+
},
42+
'https://utwente.graasp.eu/production/nameTheFrame/build/nameTheFrame.html': {
43+
url:
44+
'https://utwente.graasp.eu/production/nameTheFrame/build/nameTheFrame.one.html',
45+
},
46+
'https://utwente.graasp.eu/production/observationTool/build/observationTool.html': {
47+
url:
48+
'https://utwente.graasp.eu/production/observationTool/build/observationTool.one.html',
49+
},
50+
'https://utwente.graasp.eu/production/refquest/build/quizTool.html': {
51+
url:
52+
'https://utwente.graasp.eu/production/refquest/build/quizTool.one.html',
53+
},
54+
'https://utwente.graasp.eu/production/tableTool/build/tableTool.html': {
55+
url:
56+
'https://utwente.graasp.eu/production/tableTool/build/tableTool.one.html',
57+
},
58+
'https://utwente.graasp.eu/production/sharedWiki/build/sharedWiki.html': {
59+
url:
60+
'https://utwente.graasp.eu/production/sharedWiki/build/sharedWiki.one.html',
61+
},
62+
'https://apps.graasp.eu/5acb589d0d5d9464081c2d46/5d84ba5978f7f92b3d219b60/latest/index.html': {
63+
main: 'index.html',
64+
name: 'file-drop',
65+
url: 'http://localhost/build/build.zip',
66+
},
3567
};

public/app/download.js

+110-35
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
const _ = require('lodash');
22
const request = require('request-promise');
3+
const { promisify } = require('util');
34
const cheerio = require('cheerio');
5+
const extract = require('extract-zip');
46
const download = require('download');
57
const providers = require('./config/providers');
68
const logger = require('./logger');
79
const mapping = require('./config/mapping');
8-
const { DEFAULT_PROTOCOL, DEFAULT_LANG } = require('./config/config');
10+
11+
const {
12+
DEFAULT_PROTOCOL,
13+
DEFAULT_LANG,
14+
APPLICATION,
15+
} = require('./config/config');
916
const {
1017
getExtension,
1118
isDownloadable,
@@ -15,7 +22,7 @@ const {
1522

1623
const getDownloadUrl = async ({ url, lang }) => {
1724
let proxied = false;
18-
providers.forEach(provider => {
25+
providers.forEach((provider) => {
1926
if (url.includes(provider)) {
2027
proxied = true;
2128
}
@@ -42,63 +49,131 @@ const getDownloadUrl = async ({ url, lang }) => {
4249
return false;
4350
};
4451

52+
const downloadFile = async ({
53+
ext,
54+
hash,
55+
relativeSpacePath,
56+
absoluteSpacePath,
57+
url,
58+
}) => {
59+
const fileName = `${hash}.${ext}`;
60+
const relativeFilePath = `${relativeSpacePath}/${fileName}`;
61+
const absoluteFilePath = `${absoluteSpacePath}/${fileName}`;
62+
63+
// eslint-disable-next-line no-await-in-loop
64+
const fileAvailable = await isFileAvailable(absoluteFilePath);
65+
66+
// if the file is available, point this resource to its path
67+
if (!fileAvailable) {
68+
logger.debug(`downloading ${url}`);
69+
// eslint-disable-next-line no-await-in-loop
70+
await download(url, absoluteSpacePath, {
71+
filename: fileName,
72+
});
73+
logger.debug(`downloaded ${url} to ${absoluteFilePath}`);
74+
}
75+
76+
// returning this indicates that resource was downloaded successfully
77+
return relativeFilePath;
78+
};
79+
80+
const downloadApplication = async ({
81+
ext,
82+
relativeSpacePath,
83+
absoluteSpacePath,
84+
app,
85+
}) => {
86+
const { name, url, main } = app;
87+
// generate hash to save file
88+
const tmpZipName = `application.${ext}`;
89+
const tmpZipPath = `${absoluteSpacePath}/${tmpZipName}`;
90+
const absoluteMainFilePath = `${absoluteSpacePath}/${name}/${main}`;
91+
92+
// eslint-disable-next-line no-await-in-loop
93+
const fileAvailable = await isFileAvailable(absoluteMainFilePath);
94+
95+
// if the file is available, point this resource to its path
96+
if (!fileAvailable) {
97+
logger.debug(`downloading application ${url}`);
98+
// eslint-disable-next-line no-await-in-loop
99+
await download(url, absoluteSpacePath, {
100+
filename: tmpZipName,
101+
});
102+
logger.debug(`downloaded application ${url} to ${tmpZipPath}`);
103+
}
104+
// unzip application files
105+
try {
106+
await promisify(extract)(tmpZipPath, {
107+
dir: `${absoluteSpacePath}/${name}`,
108+
});
109+
} catch (e) {
110+
console.log(e);
111+
return false;
112+
}
113+
114+
// returning this indicates that resource was downloaded successfully
115+
const relativeMainFilePath = `${relativeSpacePath}/${name}/${main}`;
116+
return relativeMainFilePath;
117+
};
118+
45119
const downloadResource = async ({
46120
resource,
47121
absoluteSpacePath,
48122
lang,
49123
relativeSpacePath,
50124
}) => {
51125
if (resource && isDownloadable(resource)) {
52-
let { url } = resource;
53-
126+
const { url } = resource;
127+
let resourceObj = { url };
54128
// check mappings for files
55129
if (mapping[url]) {
56-
url = mapping[url];
130+
resourceObj = mapping[url];
57131
}
58132

59133
// download from proxy url if available
60134
// eslint-disable-next-line no-await-in-loop
61-
const downloadUrl = await getDownloadUrl({ url, lang });
135+
const downloadUrl = await getDownloadUrl({ url: resourceObj.url, lang });
62136
if (downloadUrl) {
63-
url = downloadUrl;
137+
resourceObj.url = downloadUrl;
64138
}
65139

66140
// default to https
67-
if (url.startsWith('//')) {
68-
url = `https:${url}`;
141+
if (resourceObj.url.startsWith('//')) {
142+
resourceObj.url = `https:${resourceObj.url}`;
69143
}
70144

71145
// get extension to save file
72-
const ext = getExtension(resource);
146+
const ext = getExtension({
147+
url: resourceObj.url,
148+
mimeType: resource.mimeType,
149+
});
73150

74-
// only download if extension is present
75-
if (ext) {
76-
// generate hash to save file
77-
const hash = generateHash(resource);
78-
const fileName = `${hash}.${ext}`;
79-
const relativeFilePath = `${relativeSpacePath}/${fileName}`;
80-
const absoluteFilePath = `${absoluteSpacePath}/${fileName}`;
81-
82-
// eslint-disable-next-line no-await-in-loop
83-
const fileAvailable = await isFileAvailable(absoluteFilePath);
84-
85-
// if the file is available, point this resource to its path
86-
if (!fileAvailable) {
87-
logger.debug(`downloading ${url}`);
88-
// eslint-disable-next-line no-await-in-loop
89-
await download(url, absoluteSpacePath, {
90-
filename: fileName,
91-
});
92-
logger.debug(`downloaded ${url} to ${absoluteSpacePath}/${fileName}`);
93-
}
151+
if (_.isNil(ext)) {
152+
return false;
153+
}
94154

95-
// returning this indicates that resource was downloaded successfully
96-
return {
97-
asset: relativeFilePath,
155+
// generate hash to save file
156+
const hash = generateHash(resource);
157+
let asset = null;
158+
if (ext === 'zip' && resource.category === APPLICATION) {
159+
asset = await downloadApplication({
160+
ext,
161+
relativeSpacePath,
162+
absoluteSpacePath,
163+
app: resourceObj,
164+
});
165+
}
166+
// only download if extension is present
167+
else if (ext) {
168+
asset = await downloadFile({
169+
ext,
98170
hash,
99-
};
171+
relativeSpacePath,
172+
absoluteSpacePath,
173+
url: resourceObj.url,
174+
});
100175
}
101-
return false;
176+
return { asset, hash };
102177
}
103178
return false;
104179
};

0 commit comments

Comments
 (0)