From 6e2d0e1b220065019213ee71ab04616aa9906cd8 Mon Sep 17 00:00:00 2001 From: Young Hahn Date: Tue, 24 May 2011 15:09:58 -0400 Subject: [PATCH] Add manual aliasing to External. --- lib/carto/external.js | 128 +++++++++++++++++------------------------- lib/carto/renderer.js | 5 +- 2 files changed, 54 insertions(+), 79 deletions(-) diff --git a/lib/carto/external.js b/lib/carto/external.js index 9c288b4..e31cda9 100644 --- a/lib/carto/external.js +++ b/lib/carto/external.js @@ -15,38 +15,36 @@ var constants = ((!process.EEXIST) >= 1) ? { EEXIST: process.EEXIST }; -function External(env, uri) { +function External(env, uri, alias) { var local = !(/^https?:\/\//i.test(uri)); - if (local) { - uri = path.join(env.local_data_dir, uri); - } - - if (External.instances[uri]) return External.instances[uri]; + local && (uri = path.join(env.local_data_dir, uri)); + alias = (env.alias && alias) || crypto.createHash('md5').update(uri).digest('hex'); + alias += path.extname(uri); this.uri = uri; this.env = env; + this.alias = alias; this.format = path.extname(uri).toLowerCase(); this.type = External.findType(this.format); - this._callbacks = []; - this.done = false; + this.processor = External.processors[this.format]; + this.tmp = local + ? this.uri + : path.join(this.env.data_dir, this.alias); - External.mkdirp(this.env.data_dir, 0755); - - if (local) { - this.localFile(); + if (External.instances[this.path()]) { + return External.instances[this.path()]; } else { - this.downloadFile(); + External.instances[this.path()] = this; + External.mkdirp(this.env.data_dir, 0755); + this.processFile(local); } - - External.instances[this.uri] = this; } sys.inherits(External, EventEmitter); External.instances = {}; External.prototype.invokeCallbacks = function(err) { - delete External.instances[this.uri]; - + delete External.instances[this.path()]; if (err) { this.emit('err', err); } else { @@ -54,65 +52,34 @@ External.prototype.invokeCallbacks = function(err) { } }; +External.prototype.processFile = function(local) { + var that = this; + fs.stat(that.path(), function(err, p) { + if (p) return that.invokeCallbacks(); -External.prototype.localFile = function() { - // Only treat files as local that don't have to be processed. - this.isLocal = !External.processors[this.format]; - - this.tempPath = this.uri; - fs.stat(this.tempPath, this.processFile.bind(this)); -}; - -External.prototype.downloadFile = function() { - this.tempPath = path.join( - this.env.data_dir, - crypto.createHash('md5').update(this.uri).digest('hex') + - path.extname(this.uri)); - - fs.stat(this.path(), function(err, stats) { - if (err) { - // This file does not yet exist. Download it! - (new get(this.uri)).toDisk( - this.tempPath, - this.processFile.bind(this)); - } else { - this.invokeCallbacks(null); - } - }.bind(this)); -}; - -External.prototype.processFile = function(err) { - if (err) { - this.invokeCallbacks(err); - } else { - if (this.isLocal) { - this.invokeCallbacks(null); - } else { - (External.processors[this.format] || External.processors['default'])( - this.tempPath, - this.path(), - function(err) { - if (err) { - this.invokeCallbacks(err); - } else { - this.invokeCallbacks(null); - } - }.bind(this) - ); - } - } + Step(function() { + fs.stat(that.tmp, this); + }, + function(err, t) { + if (t) return this(); + if (local) throw new Error('File not found.'); + return (new get(that.uri)).toDisk(that.tmp, this); + }, + function(err) { + if (err) throw err; + if (that.processor) return that.processor(that.tmp, that.path(), this); + this(); + }, + function(err) { + that.invokeCallbacks(err); + }); + }); }; External.prototype.path = function() { - if (this.isLocal) { - return this.tempPath; - } else { - return path.join( - this.env.data_dir, - (External.destinations[this.format] || - External.destinations['default'])(this.uri) - ); - } + return this.processor + ? path.join(this.env.data_dir, External.destinations[this.format](this.alias)) + : this.tmp; }; External.prototype.findDataFile = function(callback) { @@ -258,11 +225,11 @@ External.findType = function(ext) { // Destinations are names in the data_dir/cache directory. External.destinations = {}; -External.destinations['default'] = function(uri) { - return crypto.createHash('md5').update(uri).digest('hex') + path.extname(uri); +External.destinations['default'] = function(alias) { + return alias; }; -External.destinations['.zip'] = function(uri) { - return crypto.createHash('md5').update(uri).digest('hex'); +External.destinations['.zip'] = function(alias) { + return path.basename(alias, path.extname(alias)); }; External.processors = {}; @@ -273,7 +240,6 @@ External.processors['default'] = function(tempPath, destPath, callback) { fs.rename(tempPath, destPath, callback); } }; - External.processors['.zip'] = function(tempPath, destPath, callback) { try { sys.debug('unzipping file'); @@ -314,6 +280,14 @@ External.processors['.zip'] = function(tempPath, destPath, callback) { }); }); }, + function(err) { + if (err) throw err; + if (path.dirname(tempPath) === path.dirname(destPath)) { + fs.unlink(tempPath, this); + } else { + this(); + } + }, callback ); }; diff --git a/lib/carto/renderer.js b/lib/carto/renderer.js index 1b325c3..a46770f 100644 --- a/lib/carto/renderer.js +++ b/lib/carto/renderer.js @@ -15,6 +15,7 @@ require.paths.unshift(path.join(__dirname, '..', 'lib')); // This is node-only for the time being. carto.Renderer = function Renderer(env) { env = _.extend({}, env); + if (!env.alias) env.alias = false; if (!env.data_dir) env.data_dir = '/tmp/'; if (!env.local_data_dir) env.local_data_dir = ''; if (!env.validation_data) env.validation_data = false; @@ -91,7 +92,7 @@ carto.Renderer = function Renderer(env) { return next(new Error('Layer does not have a datasource to download.')); } - var external = new External(that.env, l.Datasource.file); + var external = new External(that.env, l.Datasource.file, l.name); external.once('err', next) external.once('complete', function(external) { external.findDataFile(function(err, file) { @@ -124,7 +125,7 @@ carto.Renderer = function Renderer(env) { // TODO: handle stylesheet externals // that fail. var next = group(); - var external = new External(that.env, s); + var external = new External(that.env, s, path.basename(s)); external.once('complete', function(external) { m.Stylesheet[k] = external.path(); next();