Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: importFileSystem/exportFileSystem #7

Closed
richardanaya opened this issue Feb 22, 2012 · 12 comments
Closed

Feature: importFileSystem/exportFileSystem #7

richardanaya opened this issue Feb 22, 2012 · 12 comments

Comments

@richardanaya
Copy link

There are two functions that would be super useful for this project
#1 Decompress zip to filesystem api folder path
#2 Create zip from filesystem api folder path

@gildas-lormeau
Copy link
Owner

I guess you're talking about ZipEntry.prototype.import* and ZipEntry.prototype.export* methods? Aren't you?

@richardanaya
Copy link
Author

They definitely look like what i'm looking for. Something like:

importFileSystem(file,path,onEnd,onProgress,onError)
exportFileSystem(path,onEnd,onProgress,onError)

@gildas-lormeau
Copy link
Owner

Note that a ZipEntry object is a directory into the zip file. So you can import a zip into a directory of the filesystem and export any directory (recursively) of the filesystem into a zip.

You can find an usage example of this API here:
https://github.com/gildas-lormeau/zip.js/blob/master/WebContent/tests/test10.js

I'm pretty sure that's what you want... Did I miss something?

@richardanaya
Copy link
Author

Maybe you can help simplify something I'm doing. I don't see an importFile that does the three things i'm doing:

  • takes in a zip file ( that could come from an input element )
  • emits progress
  • writes the zips heirarchy out to a specific path

Take a look:

    var importFileSystem = function(fs, file,onEnd,onProgress,onError){
            function createFile(fileName, callback) {
                var path = fileName;
                var pathFolder = path.slice(0, path.lastIndexOf('/'));
                var name = path.slice(path.lastIndexOf('/') 1);

                //recursively create direcotiries until we're where we want to be, then write file
                function writeFileToDir(rootDirEntry, folders) {
                  // Throw out './' or '/' and move on to prevent something like '/foo/.//bar'.
                  if (folders[0] == '.' || folders[0] == '') {
                    folders = folders.slice(1);
                  }
                  rootDirEntry.getDirectory(folders[0], {create: false}, function(dirEntry) {
                    // Recursively add the new subfolder (if we still have another to create).
                    if (folders.length-1>0) {
                      writeFileToDir(dirEntry, folders.slice(1));
                    }
                    else {
                        dirEntry.getFile(name, {
                            create : true
                        }, function(zipFile) {
                            callback(zipFile);
                        });
                    }
                  }, function(){
                      rootDirEntry.getDirectory(folders[0], {create: true}, function(dirEntry) {
                      // Recursively add the new subfolder (if we still have another to create).
                      if (folders.length-1>0) {
                        writeFileToDir(dirEntry, folders.slice(1));
                      }
                      else {
                          dirEntry.getFile(name, {
                              create : true
                          }, function(zipFile) {
                              callback(zipFile);
                          });
                      }
                    }, onError);
                  });
                };

                var p = pathFolder.split('/');
                var prefixPath = rootDirName.split('/');

                //remove the first folder name which is the root folder name
                p.splice(0,1);
                //remove blanks and add to path
                for(var i = prefixPath.length-1; i >=0; i--){
                    if(prefixPath[i] !=''){
                        p.splice(0,0,prefixPath[i])
                    }
                }
                writeFileToDir(fs.root, p); // fs.root is a DirectoryEntry.
            }

            var getEntries = function(file, onend) {
                zip.createReader(new zip.BlobReader(file), function(zipReader) {
                    zipReader.getEntries(onend);
                }, onerror);
            };

            var getEntryFile = function(entry, creationMethod, onend, onprogress) {
                var writer, zipFileEntry;

                function getData() {
                    entry.getData(writer, function() {
                        onend(zipFileEntry.toURL());
                    }, onprogress);
                }

                createFile(entry.filename,function(fileEntry) {
                    zipFileEntry = fileEntry;
                    writer = new zip.FileWriter(zipFileEntry);
                    getData();
                });
            };

            function download(entry, complete) {
                getEntryFile(entry, creationMethodInput.value, function(blobURL, revokeBlobURL) {
                    console.log('file loaded: ' blobURL);
                    complete();
                });
            };


            getEntries(file, function(entries) {
                var count = 0;
                var readNextEntry = null;
                readNextEntry = function() {
                    if( count >= entries.length){
                        onEnd();
                        return;
                    }
                    var entry = entries[count];
                    //is not a directory
                    if(!(entry.filename.slice(-1)=='/')){
                        var onDownloadEnd = function(){
                            onProgress(entry,count,entries.length);
                            count = count   1;
                            readNextEntry();
                        };
                        download(entry, onDownloadEnd);
                    }
                    //if it is a directory, just skip
                    else {
                        onProgress(entry,count,entries.length);
                        count = count   1;
                        readNextEntry();
                    }
                }
                readNextEntry();
            });
        }

@richardanaya
Copy link
Author

Been looking through the code and experimenting. I think another way to rephrase my problem:

I am trying:

a) unzip a zip file
b) get a FileEntry that represents the root directory of the zip file structure
c) then fs.root.moveTo(zipFileEntry,"blah"); to move it into my browsers file system using filesystem api and have the unzipped files completely there

@gildas-lormeau
Copy link
Owner

Is see, I did not understand you wanted to unzip the file into a directory of the HTML5 sandboxed filesystem (and zip files from a directory). You are right, this feature is not yet available.

But it is really an interesting feature so I'll try to add it soon in zip-fs.js soon.

Thanks :)

@richardanaya
Copy link
Author

Here is the other function

var exportFileSystem = function(filesystem, path, onEnd, onError) {
    var zipFs = new zip.fs.FS();

    var createTempFile = function(callback) {
        var tmpFilename = "tmp.zip";
        function create() {
            filesystem.root.getFile(tmpFilename, {
                create : true
            }, function(zipFile) {
                callback(zipFile);
            });
        }

        filesystem.root.getFile(tmpFilename, null, function(entry) {
            entry.remove(create, create);
        }, create);
    };

    var addToZip = function(parentFolder, entry, onEnding) {
        if (entry.isDirectory) {
            console.log('adding directory '   entry.name);
            var dir = parentFolder.addDirectory(entry.name);
            var dirReader = entry.createReader();
            dirReader.readEntries(function(entries) {
                var count = entries.length;
                var c = 0;
                for (var i = 0; i < entries.length; i  ) {
                    var childEntry = entries[i];
                    var done = function() {
                        c = c   1;
                        if (c == count) {
                            onEnding();
                        }
                    };
                    addToZip(dir, childEntry, done);
                }
            });
        } else if (entry.isFile) {
            console.log('adding file '   entry.name);
            parentFolder.addBlob(entry.name, entry);
            onEnding();
        }
    };

    //recursively create direcotiries until we're where we want to be, then write file
    var findDirectory = function(rootDirEntry, folders) {
        var findDirectoryHelper = function(dirEntry) {
            // Recursively add the new subfolder (if we still have another to create).
            if (folders.length - 1 > 0) {
                findDirectory(dirEntry, folders.slice(1));
            }
            else {
                var complete = function() {
                    createTempFile(function(fileEntry){
                        zipFs.root.exportFile(fileEntry,function() {
                            onEnd(fileEntry);
                        });
                    });
                };
                addToZip(zipFs.root, dirEntry, complete);
            }
        };
        // Throw out './' or '/' and move on to prevent something like '/foo/.//bar'.
        if (folders[0] == '.' || folders[0] == '') {
            folders = folders.slice(1);
        }
        rootDirEntry.getDirectory(folders[0], {create: false}, findDirectoryHelper, onError);
    };

    var p = path.split('/');
    findDirectory(filesystem.root, p)
};

@gildas-lormeau
Copy link
Owner

I added those features in latest commits in zip-fs.js. Actually, it has been totally rewritten in order to match the existing zip-fs API.

Now, with zip-fs you can use:

  • ZipEntry.prototype.addFileEntry to import an HTML5 DirectoryEntry (or FileEntry) content into a directory (or file) of the zip.
  • ZipEntry.prototype.getFileEntry to export a directory (or file) content from the zip into an HTML5 DirectoryEntry (or FileEntry).

@richardanaya
Copy link
Author

Awesome!

@webmutation
Copy link

Can i use those two methods to write sub-folder with files in them?

I want to simply open a zip file and create on the filesystem everything that is there... including sub-folders, hierarchy. Just like you unzip with a desktop utility. unzip here. where here is the sand-boxed file system. Thanks

@gildas-lormeau
Copy link
Owner

Yes, ZipEntry.prototype.getFileEntry is the method you need; here is a code example.

@Naa007
Copy link

Naa007 commented Mar 4, 2015

Am new to HTML5 file system. I tried your example but facing lot of issues... can i get sample project that takes zip (uploading) as input and extracts the zip file in sandbox of html5 filesystem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants