Add manual aliasing to External.

This commit is contained in:
Young Hahn 2011-05-24 15:09:58 -04:00
parent a29f407c3e
commit 6e2d0e1b22
2 changed files with 54 additions and 79 deletions

View File

@ -15,38 +15,36 @@ var constants = ((!process.EEXIST) >= 1) ?
{ EEXIST: process.EEXIST }; { EEXIST: process.EEXIST };
function External(env, uri) { function External(env, uri, alias) {
var local = !(/^https?:\/\//i.test(uri)); var local = !(/^https?:\/\//i.test(uri));
if (local) { local && (uri = path.join(env.local_data_dir, uri));
uri = path.join(env.local_data_dir, uri); alias = (env.alias && alias) || crypto.createHash('md5').update(uri).digest('hex');
} alias += path.extname(uri);
if (External.instances[uri]) return External.instances[uri];
this.uri = uri; this.uri = uri;
this.env = env; this.env = env;
this.alias = alias;
this.format = path.extname(uri).toLowerCase(); this.format = path.extname(uri).toLowerCase();
this.type = External.findType(this.format); this.type = External.findType(this.format);
this._callbacks = []; this.processor = External.processors[this.format];
this.done = false; this.tmp = local
? this.uri
: path.join(this.env.data_dir, this.alias);
External.mkdirp(this.env.data_dir, 0755); if (External.instances[this.path()]) {
return External.instances[this.path()];
if (local) {
this.localFile();
} else { } 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); sys.inherits(External, EventEmitter);
External.instances = {}; External.instances = {};
External.prototype.invokeCallbacks = function(err) { External.prototype.invokeCallbacks = function(err) {
delete External.instances[this.uri]; delete External.instances[this.path()];
if (err) { if (err) {
this.emit('err', err); this.emit('err', err);
} else { } 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() { Step(function() {
// Only treat files as local that don't have to be processed. fs.stat(that.tmp, this);
this.isLocal = !External.processors[this.format]; },
function(err, t) {
this.tempPath = this.uri; if (t) return this();
fs.stat(this.tempPath, this.processFile.bind(this)); if (local) throw new Error('File not found.');
}; return (new get(that.uri)).toDisk(that.tmp, this);
},
External.prototype.downloadFile = function() { function(err) {
this.tempPath = path.join( if (err) throw err;
this.env.data_dir, if (that.processor) return that.processor(that.tmp, that.path(), this);
crypto.createHash('md5').update(this.uri).digest('hex') + this();
path.extname(this.uri)); },
function(err) {
fs.stat(this.path(), function(err, stats) { that.invokeCallbacks(err);
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)
);
}
}
}; };
External.prototype.path = function() { External.prototype.path = function() {
if (this.isLocal) { return this.processor
return this.tempPath; ? path.join(this.env.data_dir, External.destinations[this.format](this.alias))
} else { : this.tmp;
return path.join(
this.env.data_dir,
(External.destinations[this.format] ||
External.destinations['default'])(this.uri)
);
}
}; };
External.prototype.findDataFile = function(callback) { External.prototype.findDataFile = function(callback) {
@ -258,11 +225,11 @@ External.findType = function(ext) {
// Destinations are names in the data_dir/cache directory. // Destinations are names in the data_dir/cache directory.
External.destinations = {}; External.destinations = {};
External.destinations['default'] = function(uri) { External.destinations['default'] = function(alias) {
return crypto.createHash('md5').update(uri).digest('hex') + path.extname(uri); return alias;
}; };
External.destinations['.zip'] = function(uri) { External.destinations['.zip'] = function(alias) {
return crypto.createHash('md5').update(uri).digest('hex'); return path.basename(alias, path.extname(alias));
}; };
External.processors = {}; External.processors = {};
@ -273,7 +240,6 @@ External.processors['default'] = function(tempPath, destPath, callback) {
fs.rename(tempPath, destPath, callback); fs.rename(tempPath, destPath, callback);
} }
}; };
External.processors['.zip'] = function(tempPath, destPath, callback) { External.processors['.zip'] = function(tempPath, destPath, callback) {
try { try {
sys.debug('unzipping file'); 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 callback
); );
}; };

View File

@ -15,6 +15,7 @@ require.paths.unshift(path.join(__dirname, '..', 'lib'));
// This is node-only for the time being. // This is node-only for the time being.
carto.Renderer = function Renderer(env) { carto.Renderer = function Renderer(env) {
env = _.extend({}, env); env = _.extend({}, env);
if (!env.alias) env.alias = false;
if (!env.data_dir) env.data_dir = '/tmp/'; if (!env.data_dir) env.data_dir = '/tmp/';
if (!env.local_data_dir) env.local_data_dir = ''; if (!env.local_data_dir) env.local_data_dir = '';
if (!env.validation_data) env.validation_data = false; 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.')); 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('err', next)
external.once('complete', function(external) { external.once('complete', function(external) {
external.findDataFile(function(err, file) { external.findDataFile(function(err, file) {
@ -124,7 +125,7 @@ carto.Renderer = function Renderer(env) {
// TODO: handle stylesheet externals // TODO: handle stylesheet externals
// that fail. // that fail.
var next = group(); 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) { external.once('complete', function(external) {
m.Stylesheet[k] = external.path(); m.Stylesheet[k] = external.path();
next(); next();