fixes #96, downloads now work on safari and firefox
This commit is contained in:
parent
a06369ab06
commit
85b8f5b589
5 changed files with 64 additions and 54 deletions
|
@ -42,7 +42,7 @@ function Nav(props) {
|
|||
if (props.project.id) {
|
||||
return (
|
||||
<li className="nav__item">
|
||||
<a className="nav__export" onClick={props.exportProjectAsZip}>
|
||||
<a className="nav__export" onClick={() => props.exportProjectAsZip(props.project.id)}>
|
||||
Download
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import * as ActionTypes from '../../../constants';
|
||||
import { browserHistory } from 'react-router';
|
||||
import axios from 'axios';
|
||||
import JSZip from 'jszip';
|
||||
import JSZipUtils from 'jszip-utils';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { showToast, setToastText } from './toast';
|
||||
import { setUnsavedChanges, justOpenedProject, resetJustOpenedProject } from './ide';
|
||||
|
||||
|
@ -127,53 +124,9 @@ export function createProject() {
|
|||
};
|
||||
}
|
||||
|
||||
function buildZip(state) {
|
||||
const zip = new JSZip();
|
||||
const rootFile = state.files.find(file => file.name === 'root');
|
||||
const numFiles = state.files.filter(file => file.fileType !== 'folder').length;
|
||||
const files = state.files;
|
||||
const projectName = state.project.name;
|
||||
let numCompletedFiles = 0;
|
||||
|
||||
function addFileToZip(file, path) {
|
||||
if (file.fileType === 'folder') {
|
||||
const newPath = file.name === 'root' ? path : `${path}${file.name}/`;
|
||||
file.children.forEach(fileId => {
|
||||
const childFile = files.find(f => f.id === fileId);
|
||||
(() => {
|
||||
addFileToZip(childFile, newPath);
|
||||
})();
|
||||
});
|
||||
} else {
|
||||
if (file.url) {
|
||||
JSZipUtils.getBinaryContent(file.url, (err, data) => {
|
||||
zip.file(`${path}${file.name}`, data, { binary: true });
|
||||
numCompletedFiles += 1;
|
||||
if (numCompletedFiles === numFiles) {
|
||||
zip.generateAsync({ type: 'blob' }).then((content) => {
|
||||
saveAs(content, `${projectName}.zip`);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
zip.file(`${path}${file.name}`, file.content);
|
||||
numCompletedFiles += 1;
|
||||
if (numCompletedFiles === numFiles) {
|
||||
zip.generateAsync({ type: 'blob' }).then((content) => {
|
||||
saveAs(content, `${projectName}.zip`);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
addFileToZip(rootFile, '/');
|
||||
}
|
||||
|
||||
export function exportProjectAsZip() {
|
||||
return (dispatch, getState) => {
|
||||
const state = getState();
|
||||
buildZip(state);
|
||||
};
|
||||
export function exportProjectAsZip(projectId) {
|
||||
const win = window.open(`${ROOT_URL}/projects/${projectId}/zip`, '_blank');
|
||||
win.focus();
|
||||
}
|
||||
|
||||
export function newProject() {
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
"node": ">=4"
|
||||
},
|
||||
"dependencies": {
|
||||
"archiver": "^1.1.0",
|
||||
"async": "^2.0.0",
|
||||
"axios": "^0.12.0",
|
||||
"babel-core": "^6.8.0",
|
||||
|
@ -76,13 +77,10 @@
|
|||
"eslint-loader": "^1.3.0",
|
||||
"express": "^4.13.4",
|
||||
"express-session": "^1.13.0",
|
||||
"file-saver": "^1.3.2",
|
||||
"file-type": "^3.8.0",
|
||||
"htmlhint": "^0.9.13",
|
||||
"js-beautify": "^1.6.4",
|
||||
"jshint": "^2.9.2",
|
||||
"jszip": "^3.0.0",
|
||||
"jszip-utils": "0.0.2",
|
||||
"lodash": "^4.16.4",
|
||||
"loop-protect": "git+https://git@github.com/sagar-sm/loop-protect.git",
|
||||
"moment": "^2.14.1",
|
||||
|
@ -102,6 +100,7 @@
|
|||
"redux": "^3.5.2",
|
||||
"redux-form": "^5.3.3",
|
||||
"redux-thunk": "^2.1.0",
|
||||
"request": "^2.76.0",
|
||||
"s3-policy": "^0.2.0",
|
||||
"shortid": "^2.2.6",
|
||||
"srcdoc-polyfill": "^0.2.0",
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import Project from '../models/project';
|
||||
import User from '../models/user';
|
||||
import archiver from 'archiver';
|
||||
import request from 'request';
|
||||
|
||||
|
||||
export function createProject(req, res) {
|
||||
let projectValues = {
|
||||
|
@ -99,3 +102,56 @@ export function getProjectsForUser(req, res) {
|
|||
return res.json([]);
|
||||
}
|
||||
}
|
||||
|
||||
function buildZip(project, req, res) {
|
||||
const zip = archiver('zip');
|
||||
const rootFile = project.files.find(file => file.name === 'root');
|
||||
const numFiles = project.files.filter(file => file.fileType !== 'folder').length;
|
||||
const files = project.files;
|
||||
const projectName = project.name;
|
||||
let numCompletedFiles = 0;
|
||||
|
||||
zip.on('error', function(err) {
|
||||
res.status(500).send({error: err.message});
|
||||
});
|
||||
|
||||
res.attachment(`${project.name}.zip`);
|
||||
zip.pipe(res);
|
||||
|
||||
function addFileToZip(file, path) {
|
||||
if (file.fileType === 'folder') {
|
||||
const newPath = file.name === 'root' ? path : `${path}${file.name}/`;
|
||||
file.children.forEach(fileId => {
|
||||
const childFile = files.find(f => f.id === fileId);
|
||||
(() => {
|
||||
addFileToZip(childFile, newPath);
|
||||
})();
|
||||
});
|
||||
} else {
|
||||
if (file.url) {
|
||||
request({ method: 'GET', url: file.url, encoding: null }, (err, response, body) => {
|
||||
zip.append(body, { name: `${path}${file.name}` });
|
||||
numCompletedFiles += 1;
|
||||
if (numCompletedFiles === numFiles) {
|
||||
zip.finalize();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
zip.append(file.content, { name: `${path}${file.name}` });
|
||||
numCompletedFiles += 1;
|
||||
if (numCompletedFiles === numFiles) {
|
||||
zip.finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
addFileToZip(rootFile, '/');
|
||||
}
|
||||
|
||||
export function downloadProjectAsZip(req, res) {
|
||||
Project.findById(req.params.project_id, (err, project) => {
|
||||
//save project to some path
|
||||
buildZip(project, req, res);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -15,4 +15,6 @@ router.route('/projects').get(ProjectController.getProjects);
|
|||
|
||||
router.route('/:username/projects').get(ProjectController.getProjectsForUser);
|
||||
|
||||
router.route('/projects/:project_id/zip').get(ProjectController.downloadProjectAsZip);
|
||||
|
||||
export default router;
|
||||
|
|
Loading…
Reference in a new issue