Skip to content
This repository has been archived by the owner on Dec 16, 2023. It is now read-only.

Commit

Permalink
Bug fixes galore.
Browse files Browse the repository at this point in the history
  • Loading branch information
assaf committed Oct 24, 2012
1 parent 87170b6 commit 5f03879
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 60 deletions.
54 changes: 30 additions & 24 deletions lib/passbook.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
var applyImageMethods = require("./images");
var Crypto = require("crypto");
var execFile = require("child_process").execFile;
var EventEmitter = require("events").EventEmitter;
var inherits = require("util").inherits;
var File = require("fs");
var HTTP = require("http");
var HTTPS = require("https");
Expand Down Expand Up @@ -109,8 +111,10 @@ Passbook.prototype.pipe = function(output, callback) {
var self = this;
var zip = new Zip(output);

zip.on("close", callback);
zip.on("error", callback);
if (callback) {
zip.on("close", callback);
zip.on("error", callback);
}

// Validate before attempting to create
this.validate();
Expand All @@ -129,18 +133,16 @@ Passbook.prototype.pipe = function(output, callback) {

var expecting = 0;
var lastError;
var images = this.images;
for (var key in images) {
(function(key) {
var filename = key.replace(/2x$/, "@2x") + ".png";
addImage(zip, filename, images[key], function(error) {
--expecting;
if (error)
lastError = error;
if (expecting == 0)
done(lastError);
});
})(key);
for (var key in this.images) {
var filename = key.replace(/2x$/, "@2x") + ".png";
var source = this.images[key];
addImage(addFile(filename), source, function(error) {
--expecting;
if (error)
lastError = error;
if (expecting === 0)
done(lastError);
});
++expecting;
}

Expand All @@ -157,35 +159,34 @@ Passbook.prototype.pipe = function(output, callback) {
};


function addImage(zip, filename, source, callback) {
var file = zip.addFile(filename);
function addImage(file, source, callback) {
if (typeof(source) == "string" || source instanceof String) {
if (/^https?:/i.test(source)) {
// URL
var protocol = /^https:/i.test(source) ? HTTPS : HTTP;
protocol.get(source, function(response) {
response.pipe(file);
response.on("end", callback);
file.on("close", callback);
}).on("error", callback);
} else {
// Assume filename
var input = File.createReadStream(source);
input.pipe(file);
input.on("close", callback);
input.on("error", callback);
file.on("close", callback);
file.end(File.readFileSync(source));
//File.createReadStream(source).pipe(file);
}
} else if (source instanceof Buffer) {
file.end(buffer);
callback();
} else if (typeof(source) == "function") {
try {
source(file, callback);
source(file);
file.on("close", callback);
} catch (error) {
callback(error);
}
} else {
// image is not a supported type
done(new Error("Cannot load image " + filename + ", must be String (filename), Buffer or function"));
callback(new Error("Cannot load image " + file.filename + ", must be String (filename), Buffer or function"));
}
}

Expand Down Expand Up @@ -255,11 +256,16 @@ function SHAWriteStream(manifest, filename, output) {
this.manifest = manifest;
this.filename = filename;
this.sha = Crypto.createHash("sha1");
output.on("close", this.emit.bind(this, "close"));
output.on("error", this.emit.bind(this, "error"));
}

inherits(SHAWriteStream, EventEmitter);

SHAWriteStream.prototype.write = function(buffer, encoding) {
this.output.write(buffer, encoding);
this.sha.update(buffer, encoding);
return this.output.write(buffer, encoding);
return true;
};

SHAWriteStream.prototype.end = function(buffer, encoding) {
Expand Down
66 changes: 40 additions & 26 deletions lib/zip.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// file.write(buffer);
// file.end();
// zip.close();
//
// See http://www.pkware.com/documents/casestudies/APPNOTE.TXT


var EventEmitter = require("events").EventEmitter;
Expand Down Expand Up @@ -100,6 +102,8 @@ Zip.prototype._flush = function() {
centralDirectorySize += size;
}
this._writeEndOfCentralDirectory(centralDirectoryOffset, centralDirectorySize);
// Once this buffer is out, we're done with the output stream
this.output.end();
};


Expand Down Expand Up @@ -172,15 +176,40 @@ Zip.prototype._writeEndOfCentralDirectory = function(offsetOfCentralDirectory, s
// .ZIP file comment length
write16(buffer, 0, 20);
this._writeBuffer(buffer);

// Once this buffer is out, we're done with the output stream
this.output.end();
};


// -- Buffered output --


// Returns true if this is the active file.
Zip.prototype.isActive = function(file) {
if (this._active == file)
return true;
if (!this._active) {
this._actie = file;
return true;
}
return false;
};


// Pass the active batton to the next file, or emit drain event.
Zip.prototype.nextActive = function() {
this._active = null;
for (var i in this._files) {
var file = this._files[i];
if (!file._flushed) {
// New active file and flush it
file._flush();
return;
}
}
// No files open or need flushing, emit drain event
this.emit("drain");
};


// Write buffer to output stream.
Zip.prototype._writeBuffer = function(buffer) {
this._offset += buffer.length;
Expand Down Expand Up @@ -233,7 +262,9 @@ function File(zip, filename, modified) {
file._compressedLength += buffer.length;
zip._writeBuffer(buffer);
});
this._deflate.on("end", this._doneWritingFile.bind(this));
this._deflate.on("end", function(buffer) {
file._doneWritingFile();
});
}

inherits(File, EventEmitter);
Expand All @@ -251,13 +282,9 @@ File.prototype.write = function(buffer, encoding) {
var offset = (this._crc ^ buffer[i]) & 0xFF;
this._crc = (this._crc >>> 8) ^ CRC32[offset];
}
this._compressedLength += buffer.length;
this._uncompressedLength += buffer.length;

var zip = this.zip;
if (!zip._active)
zip._active = this;

if (zip._active == this) {
if (this.zip.isActive(this)) {
// This is the active file: write the header first, then write this buffer.
if (this._wroteHeader) {
this._deflate.write(buffer);
Expand All @@ -283,7 +310,7 @@ File.prototype.end = function(buffer, encoding) {
this.write(buffer, encoding);

this.writable = false;
if (this.zip._active == this) {
if (this.zip.isActive(this)) {
// This is the active file: write the header first, then flush the file.
if (this._wroteHeader) {
this._flush();
Expand Down Expand Up @@ -371,23 +398,10 @@ File.prototype._flush = function() {
// Called when we're done writing the deflated file, takes care of writing data
// descriptor and activating the next file.
File.prototype._doneWritingFile = function() {
this._writeDataDescriptor();
// No longer the active file
this.zip._active = null;
this._flushed = true;
this._writeDataDescriptor();
this.emit("close");

// Do we have any more unflushed file?
for (var i in this.zip._files) {
var file = this.zip._files[i];
if (file != this && !file._flushed) {
// This is now the active file, flush it
file._flush();
return;
}
}
// No files open or need flushing, emit drain event
this.zip.emit("drain");
this.zip.nextActive();
};


Expand Down
17 changes: 7 additions & 10 deletions test/passbook_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe("Passbook", function() {
serialNumber: "123456",
organizationName: "Acme flowers",
description: "20% of black roses"
}
};
});

describe("from template", function() {
Expand Down Expand Up @@ -104,21 +104,18 @@ describe("Passbook", function() {
before(function(done) {
var passbook = this.template.createPassbook(this.fields);
passbook.loadImagesFrom(__dirname + "/resources");
passbook.generate(function(error, buffer) {
if (error)
done(error);
else
File.writeFile("/tmp/passbook.pkpass", buffer, done);
})

if (File.existsSync("/tmp/passbook.pkpass"))
File.unlinkSync("/tmp/passbook.pkpass");
var file = File.createWriteStream("/tmp/passbook.pkpass");
passbook.pipe(file, done);
});

it("should be a valid ZIP", function(done) {
execFile("unzip", ["-t", "/tmp/passbook.pkpass"], function(error, stdout) {
if (error)
error = new Error(stdout);
done(error);
})
});
});

it("should contain pass.json", function(done) {
Expand Down Expand Up @@ -155,7 +152,7 @@ describe("Passbook", function() {
execFile("signpass", ["-v", "/tmp/passbook.pkpass"], function(error, stdout) {
assert(/\*\*\* SUCCEEDED \*\*\*/.test(stdout), stdout);
done();
})
});
});

it("should contain the icon", function(done) {
Expand Down

0 comments on commit 5f03879

Please sign in to comment.