spacedeck-open/routes/api/space_exports.js

252 lines
7.3 KiB
JavaScript

"use strict";
var config = require('config');
const db = require('../../models/db');
var mailer = require('../../helpers/mailer');
var uploader = require('../../helpers/uploader');
var space_render = require('../../helpers/space-render');
var phantom = require('../../helpers/phantom');
var async = require('async');
var moment = require('moment');
var fs = require('fs');
var _ = require("underscore");
var archiver = require('archiver');
var request = require('request');
var url = require("url");
var path = require("path");
var crypto = require('crypto');
var glob = require('glob');
var gm = require('gm');
var sanitizeHtml = require('sanitize-html');
var express = require('express');
var router = express.Router({mergeParams: true});
// JSON MAPPINGS
var userMapping = {
_id: 1,
nickname: 1,
email: 1,
avatar_thumb_uri: 1
};
var spaceMapping = {
_id: 1,
name: 1,
thumbnail_url: 1
};
var roleMapping = {
"none": 0,
"viewer": 1,
"editor": 2,
"admin": 3
}
router.get('/png', function(req, res, next) {
var triggered = new Date();
var s3_filename = "s" + req.space._id + "/" + "thumb_" + triggered.getTime() + ".jpg";
if (!req.space.thumbnail_updated_at || req.space.thumbnail_updated_at < req.space.updated_at || !req.space.thumbnail_url) {
db.Space.update({ thumbnail_updated_at: triggered }, {where : {"_id": req.space._id }});
phantom.takeScreenshot(req.space, "png", function(local_path) {
var localResizedFilePath = local_path + ".thumb.jpg";
gm(local_path).resize(640, 480).quality(70.0).autoOrient().write(localResizedFilePath, function(err) {
if (err) {
console.error("[space screenshot] resize error: ", err);
res.status(500).send("Error taking screenshot.");
return;
}
uploader.uploadFile(s3_filename, "image/jpeg", localResizedFilePath, function(err, thumbnailUrl) {
if (err) {
console.error("[space screenshot] upload error. filename: " + s3_filename + " details: ", err);
res.status(500).send("Error uploading screenshot.");
return;
}
var oldUrl = req.space.thumbnail_url;
db.Space.update({ thumbnail_url: thumbnailUrl }, {where : {"_id": req.space._id }}).then(() => {
res.redirect(thumbnailUrl);
try {
if (oldUrl) {
var oldPath = url.parse(oldUrl).pathname;
uploader.removeFile(oldPath, function(err, res) {});
}
fs.unlinkSync(local_path);
} catch (e) {
console.error(e);
}
});
try {
fs.unlinkSync(localResizedFilePath);
} catch (e) {
console.error(e);
}
});
});
},
function() {
// on_error
console.error("[space screenshot] could not create screenshot for space " + req.space_id);
res.status(404).send("Not found");
});
} else {
res.redirect(req.space.thumbnail_url);
}
});
function make_export_filename(space, extension) {
return space.name.replace(/[^\w]/g, '') + "-" + space._id + "-" + moment().format("YYYYMMDD-HH-mm-ss") + "." + extension;
}
router.get('/pdf', function(req, res, next) {
var s3_filename = make_export_filename(req.space, "pdf");
phantom.takeScreenshot(req.space, "pdf", function(local_path) {
uploader.uploadFile(s3_filename, "application/pdf", local_path, function(err, url) {
res.status(201).json({
url: url
});
fs.unlink(local_path);
});
}, (err) => {
res.status(500).json({
error: "PDF could not created (500)"
});
});
});
router.get('/zip', function(req, res, next) {
Artifact.find({
space_id: req.space._id
}, function(err, artifacts) {
if (!artifacts || !artifacts.length || err) {
res.status(404).json({
"error": "no artifacts"
});
return;
}
var localPath = "/tmp/" + req.space._id;
try {
var files = fs.readdirSync(localPath);
for (var i = 0; i < files.length; i++) {
console.log("[zip export] unlink old file: ", localPath + "/" + files[i]);
if (files[i] != "." && files[i] != "..") {
fs.unlinkSync(localPath + "/" + files[i]);
}
}
fs.rmdirSync(localPath);
} catch (e) {
console.error(e);
}
var used_filenames = {};
fs.mkdir(localPath, function(err, cb) {
async.eachLimit(artifacts, 10, function(artifact, cb) {
try {
if (artifact.payload_uri) {
if (artifact.payload_uri.indexOf("https://") > -1 || artifact.payload_uri.indexOf("http://") > -1) {
var parsed = url.parse(artifact.payload_uri);
var fileName = path.basename(parsed.pathname) || "file.bin";
if (fileName.length > 128) {
fileName = fileName.substr(fileName.length - 128);
}
if (used_filenames[fileName]) {
// if there is a fileName collision, we insert a number before the extension
// to differentiate
var ext = path.extname(fileName);
fileName = path.basename(fileName, ext) + "_" + (parseInt(Math.random() * 10000)) + ext;
}
used_filenames[fileName] = true;
//fix for old artifacts where no .pdf is in the filename
if (artifact.mime == "application/pdf" && fileName.indexOf(".pdf") < 0) {
fileName = fileName + ".pdf";
}
if (artifact.mime == "image/png" && fileName.indexOf(".png") < 0) {
fileName = fileName + ".png";
}
var localFilePath = localPath + '/' + fileName;
request
.get(artifact.payload_uri)
.on('error', function(err) {
console.error(err);
cb(null, artifact.payload_uri);
})
.on('end', function() {
cb(null, artifact.payload_uri);
}).pipe(fs.createWriteStream(localFilePath));
} else {
cb(null, artifact.payload_uri);
}
} else {
cb(null, artifact.payload_uri);
}
} catch (e) {
console.log(e);
cb(null);
}
}, function(err, payloads) {
var outputPath = '/tmp/' + req.space._id + '.zip';
var output = fs.createWriteStream(outputPath);
var archive = archiver('zip');
output.on('close', function() {
var name = make_export_filename(req.space, "zip");
uploader.uploadFile(name, "application/zip", outputPath, function(err, url) {
res.status(201).json({
url: url
});
try {
fs.unlink(outputPath);
} catch (e) {
console.error(e);
}
});
});
archive.on('error', function(err) {
console.error(err);
});
archive.pipe(output);
archive.directory(localPath, false, {
date: new Date()
});
archive.finalize();
});
});
});
});
router.get('/html', function(req, res) {
db.Artifact.findAll({where: {
space_id: req.space._id
}}).then(function(artifacts) {
var space = req.space;
res.send(space_render.render_space_as_html(space, artifacts));
});
});
module.exports = router;