Skip to content
This repository has been archived by the owner on Mar 5, 2021. It is now read-only.

[WIP] Provide an easy way for user to import a project.. #150

Closed
wants to merge 5 commits into from

Conversation

Ilphrin
Copy link

@Ilphrin Ilphrin commented Sep 27, 2016

...to fix #46

@Ilphrin Ilphrin changed the title [WIPProvide an easy way for user to import a project.. [WIP] Provide an easy way for user to import a project.. Sep 27, 2016
Copy link
Contributor

@elisee elisee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi and thanks a lot for the PR!

This is looking good overall! made a bunch of initial comments, please address them or reply and then I'll test and look into the manifest / actualIndex thingy you mentioned in #46.

button(disabled).open-project= t("hub:openProject")
button(disabled).edit-project= t("hub:editDetails.title")

form(style="display: none")
input.file-select(type="file", accept="application.zip")
Copy link
Contributor

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 application/zip instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe we can have a more specific class name like project-archive-select

button(disabled).open-project= t("hub:openProject")
button(disabled).edit-project= t("hub:editDetails.title")

form(style="display: none")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best to use hidden rather than CSS

let target = event.target as HTMLInputElement;
if (target.files.length === 0) return;

let reader = new FileReader();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target and reader can be made const too.

let reader = new FileReader();

reader.onload = function(evnt) {
socket.emit("import:projects", {name: target.files[0].name.split(".")[0], data: (evnt.target as any).result});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to have spaces inside curly brackets

package.json Outdated
@@ -56,6 +56,7 @@
"socket.io": "^1.4.4",
"tab-strip": "^2.3.0",
"tv4": "^1.2.7",
"unzip": "^0.1.11",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have yauzl (which stands for "yet another unzip library"), would be better to reuse it rather than add a dependency on another ZIP lib.

@@ -190,4 +199,29 @@ export default class RemoteHubClient extends BaseRemoteClient {
else callback(null);
});
};

private onImportProject = (data: ImportProjectData) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extra space after the =


private onImportProject = (data: ImportProjectData) => {

fs.writeFile(path.join(this.server.projectsPath, "project.zip"), data.data as string, (err) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit dangerous to write the ZIP file directly inside the project folder, since it could be overwritten by another import at the same time. If saving it to disk is actually needed (can't we unzip from memory?), would be best to save it in the system's temporary folder with a random name. We might already do that elsewhere, look for yauzl usage I guess.

})
.on("close", () => {
this.server.loadProject(data.name, (err: Error) => {
if (err) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use explicit if (err != null) throughout the codebase rather than implicit boolean coercion.

if (err) {
console.log(err);
}
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding #46 (comment):

I think you'll need to change loadProject in ProjectHub.ts to pass you the newly initialized project server as a second argument, then you can access the manifest (which contains name, description, etc. to send it to clients for display in the hub).

For actualIndex, I think after loading the project, we'll need to add the ProjectHub's data.projects so that it shows up in the list, and that will give you that index. If that's too confusing I can take care of it.

@Ilphrin
Copy link
Author

Ilphrin commented Oct 4, 2016

Hi!
Thanks for your review! I'm am changing my modifications, and use yauzl instead of unzip. I need to other dependencies to make it work: node-temp for temporary folder management, and copy-dir to move the content of the extracted folder, may I add them as dependencies with npm? :)

  unzip -> yauzl
  Use node-temp to create a temporary directory
  Use node-mv to move the directory
@Ilphrin
Copy link
Author

Ilphrin commented Oct 6, 2016

@elisee Can you explain what you mean by adding data.projects?

  - Based on review from elisee
  - Use copy-dir, temp and yauzl
Copy link
Contributor

@elisee elisee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking pretty good, listed a few more things to fix and hopefully made it clearer what's required re. the manifest.

@@ -14,6 +21,10 @@ interface ProjectDetails {
icon: Buffer;
}
interface AddProjectCallback { (err: string, projectId?: string): any; };
interface ImportProjectData {
name: string;
data: string;
Copy link
Contributor

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.

Copy link
Author

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!

});
zipFile.on("end", () => {
// move the extracted content into the projects' folder
copydir(path.join(dirPath, rootFolderName), path.join(this.server.projectsPath, rootFolderName), (err: Error) => {
Copy link
Contributor

Choose a reason for hiding this comment

The 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 fs.rename on the root dir? Seems better to avoid having a copy lying around, even if it's in a temp folder.

Copy link
Author

Choose a reason for hiding this comment

The 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:

Error: EXDEV: cross-device link not permitted, rename '/tmp/project1161019-14225-1cpphb6/dodgell-master/' -> '/home/ilphrin/Jeux/superpowers/core/projects/dodgell-master/'

I didn't find a solution to this, so I tried copying the folder and then it worked

copydir(path.join(dirPath, rootFolderName), path.join(this.server.projectsPath, rootFolderName), (err: Error) => {
if (err != null) throw err;
this.server.loadProject(rootFolderName, (err: Error, manifest: SupCore.Data.ProjectManifest) => {
if (err != null) throw err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we still need to:

  • Add the project manifest to this.server.projects (see here:
    this.server.data.projects.add(manifest, sortedIndex, (err: string, actualIndex: number) => {
    ). This will make it appear in the list when people reload the page.
  • And then we need to notify all people already connected to the hub of the new project (see
    this.server.io.in("sub:projects").emit("add:projects", manifest, actualIndex);
    ).

Otherwise the new project will be imported but you'll need to restart the server before it can be joined.

@elisee
Copy link
Contributor

elisee commented Nov 7, 2019

Closing since this has seen no activity in years.

@elisee elisee closed this Nov 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

client: Provide a very easy way to import a project
2 participants