From b41ea20fd6e29e217fbd6a77dbb0da7ce94846e7 Mon Sep 17 00:00:00 2001 From: Ruben de Vries Date: Wed, 21 Dec 2016 15:58:09 +0100 Subject: [PATCH 1/2] add opts.cache to be able to cache locally based on hash of config file --- lib/index.js | 107 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/lib/index.js b/lib/index.js index 27da3d9..93d9286 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,6 +5,7 @@ var HOST = 'http://fontello.com', + crypto = require('crypto'), needle = require('needle'), through2 = require('through2'), AdmZip = require('adm-zip'), @@ -29,56 +30,86 @@ 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; + + pathName = zipEntry.entryName; + dirName = (_ref = path.dirname(pathName).match(/\/([^\/]*)$/)) != null ? _ref[1] : void 0; + fileName = path.basename(pathName); - var - zip = new AdmZip(response.body), - zipEntries = zip.getEntries() - ; + if (opts.assetsOnly && !dirName) return; - zipEntries.forEach(function(zipEntry) { - var dirName, fileName, pathName, _ref; + 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'] + '/')); + } + + var file = new $.File({ + cwd: "./", + path: (dirName ? ((opts[dirName] ? opts[dirName] : dirName) + '/') : '') + fileName, + contents: content + }); + self.push(file); + }); - if (zipEntry.isDirectory) return; + callback(); + }; - pathName = zipEntry.entryName; - dirName = (_ref = path.dirname(pathName).match(/\/([^\/]*)$/)) != null ? _ref[1] : void 0; - fileName = path.basename(pathName); + 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"); + } - if (opts.assetsOnly && !dirName) return; + 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); + } }); } From b61ab3e316a5389af423166187880954daae8572 Mon Sep 17 00:00:00 2001 From: Ruben de Vries Date: Wed, 21 Dec 2016 16:44:40 +0100 Subject: [PATCH 2/2] add simple file-system based cache that can be used --- lib/index.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/index.js b/lib/index.js index 93d9286..63855a6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,6 +5,7 @@ var HOST = 'http://fontello.com', + fs = require('fs'), crypto = require('crypto'), needle = require('needle'), through2 = require('through2'), @@ -113,4 +114,31 @@ function fontello (opts) { }); } +/** + * 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;