-
Notifications
You must be signed in to change notification settings - Fork 151
[WIP] Provide an easy way for user to import a project.. #150
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,11 +1,18 @@ | ||||||
import * as async from "async"; | ||||||
import * as fs from "fs"; | ||||||
import * as path from "path"; | ||||||
import * as mkdirp from "mkdirp"; | ||||||
|
||||||
import { server as serverConfig } from "./config"; | ||||||
import ProjectHub from "./ProjectHub"; | ||||||
import BaseRemoteClient from "./BaseRemoteClient"; | ||||||
|
||||||
/* tslint:disable */ | ||||||
const yauzl = require("yauzl"); | ||||||
const temp = require("temp").track(); | ||||||
const copydir = require("copy-dir"); | ||||||
/* tslint:enable */ | ||||||
|
||||||
interface ProjectDetails { | ||||||
name: string; | ||||||
description: string; | ||||||
|
@@ -14,6 +21,10 @@ interface ProjectDetails { | |||||
icon: Buffer; | ||||||
} | ||||||
interface AddProjectCallback { (err: string, projectId?: string): any; }; | ||||||
interface ImportProjectData { | ||||||
name: string; | ||||||
data: string; | ||||||
}; | ||||||
|
||||||
export default class RemoteHubClient extends BaseRemoteClient { | ||||||
constructor(public server: ProjectHub, socket: SocketIO.Socket) { | ||||||
|
@@ -24,6 +35,7 @@ export default class RemoteHubClient extends BaseRemoteClient { | |||||
// Projects | ||||||
this.socket.on("add:projects", this.onAddProject); | ||||||
this.socket.on("edit:projects", this.onEditProject); | ||||||
this.socket.on("import:projects", this.onImportProject); | ||||||
} | ||||||
|
||||||
// TODO: Implement roles and capabilities | ||||||
|
@@ -190,4 +202,60 @@ export default class RemoteHubClient extends BaseRemoteClient { | |||||
else callback(null); | ||||||
}); | ||||||
}; | ||||||
|
||||||
private onImportProject = (data: ImportProjectData) => { | ||||||
// Import a project with a zip archive | ||||||
// 1] Extract the content of the zip file in a temporary folder | ||||||
// 2] Move the extracted content into the projects' folder | ||||||
|
||||||
// Extract the content of the zip file in a temporary folder | ||||||
temp.mkdir("project", (err: Error, dirPath: any) => { | ||||||
const inputPath = path.join(dirPath, "project.zip"); | ||||||
let rootFolderName: string = null; | ||||||
fs.writeFile(inputPath, data.data, (err) => { | ||||||
if (err) throw err; | ||||||
|
||||||
yauzl.open(inputPath, { lazyEntries: true }, (err: Error, zipFile: any) => { | ||||||
if (err != null) throw err; | ||||||
|
||||||
zipFile.readEntry(); | ||||||
zipFile.on("entry", (entry: any) => { | ||||||
if (rootFolderName === null) { | ||||||
rootFolderName = entry.fileName; | ||||||
} | ||||||
|
||||||
if (/\/$/.test(entry.fileName)) { | ||||||
mkdirp(path.join(dirPath, entry.fileName), (err: Error) => { | ||||||
if (err != null) throw err; | ||||||
zipFile.readEntry(); | ||||||
}); | ||||||
} | ||||||
else { | ||||||
zipFile.openReadStream(entry, (err: Error, readStream: NodeJS.ReadableStream) => { | ||||||
if (err != null) throw err; | ||||||
|
||||||
mkdirp(path.dirname(path.join(dirPath, entry.fileName)), (err: Error) => { | ||||||
if (err != null) throw err; | ||||||
|
||||||
readStream.pipe(fs.createWriteStream(path.join(dirPath, entry.fileName))); | ||||||
readStream.on("end", () => { | ||||||
zipFile.readEntry(); | ||||||
}); | ||||||
}); | ||||||
}); | ||||||
} | ||||||
}); | ||||||
zipFile.on("end", () => { | ||||||
// move the extracted content into the projects' folder | ||||||
copydir(path.join(dirPath, rootFolderName), path.join(this.server.projectsPath, rootFolderName), (err: Error) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any reason why we want to copy rather than just doing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, when I tried with fs.rename I had a crash on the server side with on error like this:
I didn't find a solution to this, so I tried copying the folder and then it worked |
||||||
if (err != null) throw err; | ||||||
this.server.loadProject(rootFolderName, (err: Error, manifest: SupCore.Data.ProjectManifest) => { | ||||||
if (err != null) throw err; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we still need to:
Otherwise the new project will be imported but you'll need to restart the server before it can be joined. |
||||||
}); | ||||||
}); | ||||||
}); | ||||||
}); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding #46 (comment): I think you'll need to change For |
||||||
}); | ||||||
}); | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a
Buffer
not a string? Since it's an ArrayBuffer on the client-side, should be converted to a NodeJS Bon the server-side.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oups, it was an inattention mistake. I change this!