Skip to content

Commit

Permalink
Merge pull request #9 from blocktrail/local-cache
Browse files Browse the repository at this point in the history
add a way to cache fontello results
  • Loading branch information
gillbeits authored Apr 13, 2017
2 parents 515c003 + b61ab3e commit 8e1d890
Showing 1 changed file with 97 additions and 38 deletions.
135 changes: 97 additions & 38 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
var
HOST = 'http://fontello.com',

fs = require('fs'),
crypto = require('crypto'),
needle = require('needle'),
through2 = require('through2'),
AdmZip = require('adm-zip'),
Expand All @@ -29,57 +31,114 @@ function fontello (opts) {
return through2.obj(function (file, enc, callback) {
var self = this;

var stream = through2.obj(function (file) {
if (!file.toString()) {
throw new PluginError(PLUGIN_NAME, "No session at Fontello for zip archive");
}
var process = function (zipContents, callback) {
var
zip = new AdmZip(zipContents),
zipEntries = zip.getEntries()
;

needle.get(opts.host + "/" + file.toString() + "/get", function(error, response) {
if (error) {
throw error;
}
zipEntries.forEach(function (zipEntry) {
var dirName, fileName, pathName, _ref;

if (zipEntry.isDirectory) return;

var
zip = new AdmZip(response.body),
zipEntries = zip.getEntries()
;
pathName = zipEntry.entryName;
dirName = (_ref = path.dirname(pathName).match(/\/([^\/]*)$/)) != null ? _ref[1] : void 0;
fileName = path.basename(pathName);

zipEntries.forEach(function(zipEntry) {
var dirName, fileName, pathName, _ref;
if (opts.assetsOnly && !dirName) return;

if (zipEntry.isDirectory) return;
var content = zipEntry.getData();
if (opts['font'] && opts['font'] != 'font' && path.extname(fileName) == '.css') {
content = new Buffer(String(content).replace(new RegExp('\.\.\/font\/', 'g'), '../' + opts['font'] + '/'));
}

pathName = zipEntry.entryName;
dirName = (_ref = path.dirname(pathName).match(/\/([^\/]*)$/)) != null ? _ref[1] : void 0;
fileName = path.basename(pathName);
var file = new $.File({
cwd: "./",
path: (dirName ? ((opts[dirName] ? opts[dirName] : dirName) + '/') : '') + fileName,
contents: content
});
self.push(file);
});

if (opts.assetsOnly && !dirName) return;
callback();
};

var fetchFromHost = function (callback) {
var stream = through2.obj(function (file) {
if (!file.toString()) {
throw new PluginError(PLUGIN_NAME, "No session at Fontello for zip archive");
}

needle.get(opts.host + "/" + file.toString() + "/get", function (error, response) {
if (error) {
throw error;
}

var content = zipEntry.getData();
if (opts['font'] && opts['font'] != 'font' && path.extname(fileName) == '.css') {
content = new Buffer(String(content).replace(new RegExp('\.\.\/font\/', 'g'), '../' + opts['font'] + '/'));
// store in cache if configured
if (opts.cache) {
opts.cache.set(configHash, response.body);
}

var file = new $.File({
cwd : "./",
path : (dirName ? ((opts[dirName] ? opts[dirName] : dirName) + '/') : '')+ fileName,
contents: content
});
self.push(file);
process(response.body, callback);
});
});

callback();
needle.post(opts.host, {
config: {
buffer: file.contents,
filename: 'fontello.json',
content_type: 'application/json'
}
}, {multipart: true}).pipe(stream);
};

// create SHA256 of the contents of the config file
var configHash = crypto.createHash('sha256').update(file.contents).digest('hex');

// use cache if configured
if (opts.cache) {
// check cache first
opts.cache.get(configHash, function (error, cachedResponseBody) {
// on cache err or empty response use normal fetch
if (error || !cachedResponseBody) {
fetchFromHost(callback);
} else {
$.log('using cached fontello zip for config with sha1: ' + configHash);
process(cachedResponseBody, callback);
}
});
});

needle.post(opts.host, {
config: {
buffer: file.contents,
filename: 'fontello.json',
content_type: 'application/json'
}
}, { multipart: true }).pipe(stream);
} else {
fetchFromHost(callback);
}
});
}

/**
* simple file-system based cache
*
* @param cacheDir
* @returns {{get: 'get', set: 'set'}}
*/
fontello.simpleFsCache = function(cacheDir) {
if (!fs.lstatSync(cacheDir).isDirectory()) {
fs.mkdirSync(cacheDir);
}

return {
'get': function(file, cb) {
fs.readFile(path.join(cacheDir, file + ".cached.zip"), function(err, result) {
if (err || !result) {
cb();
} else {
cb(null, result);
}
});
},
'set': function(file, response) {
fs.writeFile(path.join(cacheDir, file + ".cached.zip"), response, function noop() {});
}
}
};

module.exports = fontello;

0 comments on commit 8e1d890

Please sign in to comment.