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

Create JSZip object from .zip file. #7

Closed
flying-sheep opened this issue Oct 21, 2011 · 13 comments
Closed

Create JSZip object from .zip file. #7

flying-sheep opened this issue Oct 21, 2011 · 13 comments

Comments

@flying-sheep
Copy link

This stackoverflow answer links to a javascript class the does the reverse: Opening zip files and extracting files from it for further use.

It would be great to have a two-way zipfile object that can be created from a file, modified and downloaded as a file.

PS: the fix would answer my question here.

@dduponchel
Copy link
Collaborator

I personally like the idea :)
I can work on it, if Stuk is interested by this feature.
If we add this, jszip API will need to change a bit : the "load-modify-generate" workflow requires more control on the included files (a get method ? ability to change directly a file ?).

@flying-sheep
Copy link
Author

currently we have this constructor:

JSZip(compression_method) or JSZip()

i propose the change:

JSZip(data_string_or_compression_method) or JSZip()

It sniffs what the string is (looks for magic number or if it is one of the supported compression methods or something), and if it detects zipped data, it reads the compression method from the file and creates the JSZip object. Else it creates an empty JSZip object with the specified or default compression method.


also currently we have these “public” methods:

  • .add(name, data, options)
    returns JSZip object this was called upon
  • .folder(name)
    returns child-JSZip object with the folder as root
  • .find(needle)
    returns an arrow of matching objects of the type {name: string, data: string, dir: true/false}
  • .remove(needle)
    recursively removes matching files/folders
    returns JSZip object this was called upon
  • .generate(asBytes)
    returns zip file from data.

i love this api, so i’d like to keep most of it. my proposed change is the following:

merge .find/.add and .find/.folder (eliminate find and rename add to file):

  • calling .file(path: string) returns the corresponding file,
    calling .file(path: regex) returns an array of matching files (like find does now),
    calling .file(path: string, data) or .file(path: string, data, options) adds the file to the matching folder, generating folders on the fly if needed, and returns the JSZip object it was called upon for chaining (kinda like add does now)
  • calling .folder(path: string) creates the folder and returns a JSZip object with the generated folder as root, which is linked to the JSZip object it was called upon (like folder does now)
    calling .folder(needle: regex) creates a list of JSZip objects that correspond to existing folders that match the regex, without creating new ones.

the file options would maybe contain a “force replacement” option. apart from that we don’t need much, except maybe a shortcut for .file(/[^/]+/) for finding all first-level files, e.g. .file()… but what do you think? maybe we should handle it like jquery, where each file list and folder list is an JSZip object itself.

@dduponchel
Copy link
Collaborator

JSZip(data_string_or_compression_method) or JSZip()

I don't think trying to auto-detect the input is a good idea (same type (string) for compression method and data string).
The compression method should be only needed when generating the zip, so I think the generate() method is a better place. The compression currently occurs when adding a file but we should change that : giving access to a compressed content is not really useful.
What do you think of generate(asBytes) becoming generate(options) ? Where default options are :

{
    asBytes : false,
    compression : 'STORE'
}

The rest of your proposition sounds good to me !

@flying-sheep
Copy link
Author

you are of course right about generate being the better place. that’s the way to go.

the autodetection would work nicely, though. we’d just have to sniff the string.

@Stuk
Copy link
Owner

Stuk commented Nov 21, 2011

These are all absolutely great ideas, and I love the direction going on here. If anyone fancies hacking along these lines I will happily welcome the changes. I'm going to see if I can get some spare time this week to start bringing things up to date.

@dduponchel
Copy link
Collaborator

I should finish the code/doc/tests for the new API this week end :)

@flying-sheep
Copy link
Author

awesome!

dduponchel added a commit to dduponchel/jszip that referenced this issue Nov 26, 2011
dduponchel added a commit to dduponchel/jszip that referenced this issue Nov 26, 2011
@dduponchel
Copy link
Collaborator

You can see the updated doc at http://dduponchel.github.com/jszip/ and the code on my branch develop. I'm waiting your feedback !

dduponchel added a commit to dduponchel/jszip that referenced this issue Nov 28, 2011
The ajax code has been tested in :
- IE 6 / 7 / 8 / 9
- the lastest firefox
- firefox 3.6
- the lastest opera
- the lastest chromium
- the lastest safari

The tests pass in all those browsers (except in IE 9 : the utf8 test was
broken, I didn't fixed it).
@Stuk
Copy link
Owner

Stuk commented Nov 29, 2011

Cheers! I'm in the middle of moving house/country at the moment, so it will take me a while to get a moment look at the code, sorry!

dduponchel added a commit to dduponchel/jszip that referenced this issue Dec 17, 2011
Zip64 are generated for big files (> 4GiB, not really useful in a
browser) and when a stream is compressed (the zip utility doesn't know
the size, and uses zip64 for the worst case scenario).

Two other changes :
- The parser now read things backward (end of central dir, central dir,
  local files). Reading the file backward seems odd, but the zip format
  was designed to be read like that (and I have less troubles doing so).
- I also enforced the Stuk's coding style (to be coherent with the other
  files).
@flying-sheep
Copy link
Author

hi, i have some problems with it. i tested it with jquery’s ajax function via python’s SimpleHTTPServer (to get around possible permission issues with local files). i used the following code:

$.ajax({
    url: "packs/johnsmith_v8.4.zip",
    dataType: "text",
    success: function(data){
        var testZip = new JSZip(data);
        console.log(testZip.file("terrain.png"));
    }
});

and this zip file (saved locally)

i get the error

End of stream reached (stream length = 4044001, asked index = 4324726). Corrupted zip ?

but zipinfo -v says:

Zip archive file size:                   4334859 (000000000042250Bh)
Actual end-cent-dir record offset:       4334837 (00000000004224F5h)
Expected end-cent-dir record offset:     4334837 (00000000004224F5h)

what cuts the stream? is it some kind of encoding issue?

PS: i tried with some more .zips, but to no avail.

@dduponchel
Copy link
Collaborator

Hi,

That's a known issue : the browser tries to parse the ajax response as text and break it (issue #6).

The solution for firefox/chrome/opera is to use
mimeType:'text/plain; charset=x-user-defined'
instead of
dataType: "text"

The easiest way to test in IE might be to add a test case in test/index.html : the zip files are now (on my branch develop) loaded via ajax calls.

I should add a note in the documentation as the issue is not obvious !

@flying-sheep
Copy link
Author

sorry for not looking into other issues blush. thanks to you it works fine now:

$.ajaxSetup({
    mimeType: "text/plain; charset=x-user-defined",
    error: function(req, status, error) { console.error(error); }
});

@Stuk
Copy link
Owner

Stuk commented Mar 14, 2012

Now implemented thanks to the above pull request.

@Stuk Stuk closed this as completed Mar 14, 2012
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

3 participants