Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions client/modules/IDE/actions/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ export function exportProjectAsZip(projectId) {
win.focus();
}

export function exportAllProjectsAsZip(user) {
const win = window.open(`${ROOT_URL}/${user.id}/projects/all/zip`, '_blank');
win.focus();
}

export function resetProject() {
return {
type: ActionTypes.RESET_PROJECT
Expand Down
7 changes: 7 additions & 0 deletions client/modules/User/pages/DashboardView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class DashboardView extends React.Component {
super(props);
this.closeAccountPage = this.closeAccountPage.bind(this);
this.createNewSketch = this.createNewSketch.bind(this);
this.downloadAll = this.downloadAll.bind(this);
this.gotoHomePage = this.gotoHomePage.bind(this);
this.toggleCollectionCreate = this.toggleCollectionCreate.bind(this);
this.state = {
Expand All @@ -51,6 +52,10 @@ class DashboardView extends React.Component {
this.props.newProject();
}

downloadAll() {
this.props.exportAllProjectsAsZip(this.props.user);
}

gotoHomePage() {
browserHistory.push('/');
}
Expand Down Expand Up @@ -109,6 +114,7 @@ class DashboardView extends React.Component {
{t('DashboardView.NewSketch')}
</Button>
)}
<Button onClick={this.downloadAll}>Download All</Button>
<SketchSearchbar />
</React.Fragment>
);
Expand Down Expand Up @@ -185,6 +191,7 @@ const mapDispatchToProps = {

DashboardView.propTypes = {
newProject: PropTypes.func.isRequired,
exportAllProjectsAsZip: PropTypes.func.isRequired,
location: PropTypes.shape({
pathname: PropTypes.string.isRequired
}).isRequired,
Expand Down
70 changes: 66 additions & 4 deletions server/controllers/project.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,11 @@ function bundleExternalLibs(project, zip, callback) {
const { data } = await axios.get(src, {
responseType: 'arraybuffer'
});
zip.append(data, { name: filename });
zip.append(data, {
name: project.projectName
? `${project.projectName}/${filename}`
: filename
});
scriptTag.src = filename;
} catch (err) {
console.log(err);
Expand All @@ -233,6 +237,7 @@ function bundleExternalLibs(project, zip, callback) {
jsdom.env(indexHtml.content, (innerErr, window) => {
const indexHtmlDoc = window.document;
const scriptTags = indexHtmlDoc.getElementsByTagName('script');

numScriptTags = scriptTags.length;
for (let i = 0; i < numScriptTags; i += 1) {
resolveScriptTagSrc(scriptTags[i], indexHtmlDoc);
Expand All @@ -244,7 +249,7 @@ function bundleExternalLibs(project, zip, callback) {
});
}

function buildZip(project, req, res) {
function buildZip(project, req, res, isBundle = false) {
const zip = archiver('zip');
const rootFile = project.files.find((file) => file.name === 'root');
const numFiles = project.files.filter((file) => file.fileType !== 'folder')
Expand Down Expand Up @@ -294,9 +299,55 @@ function buildZip(project, req, res) {
}
}

bundleExternalLibs(project, zip, () => {
addFileToZip(rootFile, '/');
if (isBundle) {
for (let i = 0; i < rootFile.children.length; i += 1) {
const childId = rootFile.children[i];
const projectRoot = files.find((file) => file.id === childId);
const projectFiles = files.filter((file) =>
projectRoot.children.includes(file.id)
);

bundleExternalLibs(
{
files: projectFiles,
projectName: projectRoot.name
},
zip,
i === rootFile.children.length - 1
? () => {}
: () => {
addFileToZip(rootFile, '/');
}
);
}
} else {
bundleExternalLibs(project, zip, () => {
addFileToZip(rootFile, '/');
});
}
}

function combineProjects(projects) {
const parentFolder = {
name: 'root',
fileType: 'folder',
children: []
};
const parentProject = {
name: 'p5_projects_export_all',
files: [parentFolder]
};

projects.forEach((project) => {
const { files, name } = project;
const rootFile = files.find((file) => file.name === 'root');

rootFile.name = name;
parentProject.files.push(...files);
parentFolder.children.push(rootFile.id);
});

return parentProject;
}

export function downloadProjectAsZip(req, res) {
Expand All @@ -305,3 +356,14 @@ export function downloadProjectAsZip(req, res) {
buildZip(project, req, res);
});
}

export function downloadAllProjectsAsZip(req, res) {
getProjectsForUserId(req.params.user_id)
.then((projects) => {
const combinedProjects = combineProjects(projects);
buildZip(combinedProjects, req, res, true);
})
.catch((err) => {
console.log(err);
});
}
5 changes: 5 additions & 0 deletions server/routes/project.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ router.get('/:username/projects', ProjectController.getProjectsForUser);

router.get('/projects/:project_id/zip', ProjectController.downloadProjectAsZip);

router.get(
'/:user_id/projects/all/zip',
ProjectController.downloadAllProjectsAsZip
);

export default router;