diff --git a/helpers/importer.js b/helpers/importer.js new file mode 100644 index 0000000000000000000000000000000000000000..90eb2a919cf0b367726d7afff1f4ade19acd0bff --- /dev/null +++ b/helpers/importer.js @@ -0,0 +1,103 @@ +'use strict'; + +const extract = require('extract-zip') +const config = require('config') +const fs = require('fs') +const path = require('path') + +require('../models/schema') + +module.exports = { + importZIP: function(user, zipPath) { + + // 1. extract zip to local storage folder + // 2. read spaces.json from this folder + // 3. iterate through spaces and read all their artifact jsons + // 4. fixup storage paths + // 5. replace creator id by user._id + + let relativeImportDir = 'import_'+user._id + let importDir = path.resolve(config.get('storage_local_path')+'/'+config.get('storage_bucket')+'/'+relativeImportDir) + + if (!fs.existsSync(importDir)) { + fs.mkdirSync(importDir) + } + + extract(zipPath, {dir: importDir}, function(err) { + if (err) { + console.log(err) + return + } + console.log('[import] extracted to',importDir) + + let spacesJson = fs.readFileSync(importDir+'/spaces.json') + let spaces = JSON.parse(spacesJson) + var homeFolderId = null + + console.log('[import] spaces:',spaces.length) + + // pass 1: find homefolder + for (var i=0; i<spaces.length; i++) { + let space = spaces[i] + if (!space.parent_space_id) { + homeFolderId = space._id + break + } + } + + console.log("[import] homeFolderId:",homeFolderId) + + for (var i=0; i<spaces.length; i++) { + let space = spaces[i] + + if (space.parent_space_id) { + let artifacts = JSON.parse(fs.readFileSync(importDir+'/'+space._id+'_artifacts.json')) + console.log('[import] space',space._id,'artifacts:',artifacts.length) + + let q = {_id: space._id} + space.creator = user._id + delete space.__v + + // transplant homefolder + console.log("parent:",space.parent_space_id) + if (space.parent_space_id+"" == homeFolderId+"") { + space.parent_space_id = user.home_folder_id + } + + Space.findOneAndUpdate(q, space, {upsert: true}, function(err,res) { + if (err) console.log("[import] space upsert err:",err) + }) + + for (var j=0; j<artifacts.length; j++) { + let a = artifacts[j] + + let q = {_id: a._id} + a.creator = user._id + delete a.__v + delete a.payload_thumbnail_big_uri + + let prefix = "/storage/"+relativeImportDir+"/"+space._id+"_files/" + if (a.thumbnail_uri && a.thumbnail_uri[0]!='/') a.thumbnail_uri = prefix + a.thumbnail_uri + if (a.payload_uri && a.payload_uri[0]!='/') a.payload_uri = prefix + a.payload_uri + if (a.payload_thumbnail_web_uri && a.payload_thumbnail_web_uri[0]!='/') a.payload_thumbnail_web_uri = prefix + a.payload_thumbnail_web_uri + if (a.payload_thumbnail_medium_uri && a.payload_thumbnail_medium_uri[0]!='/') a.payload_thumbnail_medium_uri = prefix + a.payload_thumbnail_medium_uri + + if (a.payload_alternatives) { + for (var k=0; k<a.payload_alternatives.length; k++) { + let alt = a.payload_alternatives[k] + + if (alt.payload_uri && alt.payload_uri[0]!='/') alt.payload_uri = prefix + alt.payload_uri + if (alt.payload_thumbnail_web_uri && alt.payload_thumbnail_web_uri[0]!='/') alt.payload_thumbnail_web_uri = prefix + alt.payload_thumbnail_web_uri + if (alt.payload_thumbnail_medium_uri && alt.payload_thumbnail_medium_uri[0]!='/') alt.payload_thumbnail_medium_uri = prefix + alt.payload_thumbnail_medium_uri + } + } + + Artifact.findOneAndUpdate(q, a, {upsert: true}, function(err,res) { + if (err) console.log("[import] artifact upsert err:",err) + }) + } + } + } + }) + } +} diff --git a/package.json b/package.json index e6b38d18214bca852d0ded9b9f999a62948b4f77..efe0f87e4f5dde78ac904e804c539e910254721f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "debug": "~2.6.3", "execSync": "latest", "express": "~4.13.0", + "extract-zip": "^1.6.6", "glob": "7.1.1", "gm": "1.23.0", "googleapis": "18.0.0", diff --git a/routes/api/space_artifacts.js b/routes/api/space_artifacts.js index e71445639580d50adc081f7e50b000d4e3b826f2..d3e5006c091cf106e5a27e64a8e729ca75c0a33a 100644 --- a/routes/api/space_artifacts.js +++ b/routes/api/space_artifacts.js @@ -59,7 +59,9 @@ router.get('/', (req, res) => { "nickname": 1, "email": 1 }).exec((err, user) => { - a['user'] = user.toObject(); + if (user) { + a['user'] = user.toObject(); + } cb(err, a); }); } else { diff --git a/routes/api/users.js b/routes/api/users.js index 8140bcc4a40d4aeace337d42053264b75efadf03..d8e995caef9ce55ca5ba6e21e5c73dc132525271 100644 --- a/routes/api/users.js +++ b/routes/api/users.js @@ -5,6 +5,7 @@ require('../../models/schema'); var mailer = require('../../helpers/mailer'); var uploader = require('../../helpers/uploader'); +var importer = require('../../helpers/importer'); var bcrypt = require('bcryptjs'); var crypo = require('crypto'); @@ -467,4 +468,13 @@ router.post('/:user_id/confirm', function(req, res, next) { res.sendStatus(201); }); +router.get('/:user_id/import', function(req, res, next) { + if (req.query.zip) { + res.send("importing"); + importer.importZIP(req.user, req.query.zip); + } else { + res.sendStatus(400); + } +}); + module.exports = router;