Commit 34df6ff0 authored by A. Koch's avatar A. Koch

add archive functionality

parent cc18919b
......@@ -520,8 +520,7 @@
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"basic-auth": {
"version": "2.0.0",
......@@ -601,7 +600,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
......@@ -612,6 +610,11 @@
"resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz",
"integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ=="
},
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
......@@ -795,8 +798,7 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"concat-stream": {
"version": "1.6.2",
......@@ -1345,6 +1347,14 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
"requires": {
"pend": "1.2.0"
}
},
"figures": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
......@@ -1422,8 +1432,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"function-bind": {
"version": "1.1.1",
......@@ -1464,7 +1473,6 @@
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
......@@ -1604,7 +1612,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
......@@ -2196,7 +2203,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.11"
}
......@@ -2362,7 +2368,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
}
......@@ -2451,8 +2456,7 @@
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-is-inside": {
"version": "1.0.2",
......@@ -2475,6 +2479,11 @@
"pify": "2.3.0"
}
},
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
......@@ -2770,7 +2779,6 @@
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
"dev": true,
"requires": {
"glob": "7.1.2"
}
......@@ -3388,8 +3396,7 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"write": {
"version": "0.2.1",
......@@ -3415,6 +3422,23 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
},
"yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
"requires": {
"buffer-crc32": "0.2.13",
"fd-slicer": "1.1.0"
}
},
"yazl": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/yazl/-/yazl-2.4.3.tgz",
"integrity": "sha1-7CblzIfVYBud+EMtvdPNLlFzoHE=",
"requires": {
"buffer-crc32": "0.2.13"
}
},
"yerror": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/yerror/-/yerror-2.1.0.tgz",
......
const
yazl = require('yazl'),
yauzl = require('yauzl'),
path = require('path'),
fs = require('mz/fs'),
rimraf = require('rimraf'),
os = require('os'),
send = require('@polka/send-type'),
{ Assert } = require('mbjs-utils')
module.exports.setupArchives = (app, mapService, annotationService) => {
app.post('/archives/maps', async (req, res) => {
let data = {}
const request = {
params: {
id: req.body.uuid
}
}
await mapService.getHandler(request, async result => {
if (result.error) return send(res, result.code)
data.map = result.data
await annotationService.find({ 'target.id': data.map.uuid }, async result => {
if (result.error) return send(res, result.code)
data.annotations = result.annotations
const filePath = await exports.createArchive(data)
res.setHeader('Content-Type', 'application/zip')
const file = fs.createReadStream(filePath)
file.pipe(res)
})
})
})
}
module.exports.createArchive = async (data) => {
Assert.isType(data.map, 'object', 'data.map must be object')
Assert.ok(Array.isArray(data.annotations), 'data.annotations must be array')
const
dir = path.join(os.tmpdir(), `map_archive_${data.map.uuid}`),
archive = new yazl.ZipFile()
try {
await rimraf(dir)
}
catch (e) { /* ignored */ }
await fs.mkdir(dir)
await fs.mkdir(path.join(dir, 'map'))
await fs.mkdir(path.join(dir, 'annotations'))
const mapfile = path.join('map', `${data.map.uuid}.json`)
await fs.writeFile(mapfile, JSON.stringify(data.map))
archive.addFile(path.join(dir, mapfile), mapfile)
for (let a of data.annotations) {
const annofile = path.join('annotations', `${a.uuid}.json`)
await fs.writeFile(path.join(dir, annofile), JSON.stringify(a))
archive.addFile(path.join(dir, annofile), annofile)
}
const archivePath = `${dir}.zip`
await new Promise((resolve, reject) => {
archive.outputStream.pipe(fs.createWriteStream(archivePath))
.on('error', err => {
reject(err)
})
.on('close', () => {
resolve()
})
})
return archivePath
}
module.exports.readArchive = archivePath => {
yauzl.open(archivePath, {lazyEntries: true}, function (err, zipfile) {
if (err) throw err
zipfile.readEntry()
zipfile.on('entry', function (entry) {
if (/\/$/.test(entry.fileName)) {
// Directory file names end with '/'.
// Note that entires for directories themselves are optional.
// An entry's fileName implicitly requires its parent directories to exist.
zipfile.readEntry()
}
else {
// file entry
zipfile.openReadStream(entry, function (err, readStream) {
if (err) throw err
readStream.on('end', function () {
zipfile.readEntry()
})
})
}
})
})
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment