https://github.com/tilemill-project/tilemill
Tip revision: a0ac3a68a3335111f055049d40a785bd05c2b3b4 authored by Young Hahn on 10 February 2011, 15:38:07 UTC
Revert "require node-compress for tilelive interaction branch" for next tag.
Revert "require node-compress for tilelive interaction branch" for next tag.
Tip revision: a0ac3a6
library-directory.js
// Plugin for using a local directory as a Library. Generates the payload for
// an AssetList REST endpoint consisting of asset models as well as pagination
// helpers.
var _ = require('underscore'),
fs = require('fs'),
url = require('url'),
path = require('path'),
querystring = require('querystring'),
Step = require('step');
module.exports = function(app, options, callback) {
// Recursive readdir. `callback(err, files)` is given a `files` array where
// each file is an object with `filename` and `stat` properties.
var lsR = function(basedir, callback) {
var files = [];
var ls = [];
Step(
function() {
fs.readdir(basedir, this);
},
function(err, data) {
if (data.length === 0) return this();
var group = this.group();
ls = _.map(data, function(v) {
return path.join(basedir, v);
});
_.each(ls, function(v) {
fs.stat(v, group());
});
},
function(err, stats) {
if (ls.length === 0) return this();
var group = this.group();
_.each(ls, function(v, k) {
var next = group();
if (stats[k].isDirectory()) {
lsR(v, next);
} else {
files.push({
filename: v,
stat: stats[k]
});
next();
}
});
},
function(err, sub) {
_.each(sub, function(v) {
v && (files = files.concat(v));
});
callback(err, files);
}
);
}
// Filter an array of files where filenames match regex `re`.
var lsFilter = function(files, re) {
return _.filter(files, function(f) {
return f.filename.match(re);
});
};
// Convert a list of files into asset models.
var toAssets = function(files, base_dir, port) {
return _.map(files, function(f) {
return {
url: url.format({
host: 'localhost:' + port,
protocol: 'http:',
pathname: path.join(
'/api/Library/'
+ options.id
+ '/files/'
+ querystring.escape(f.filename.replace(base_dir + '/', ''))
)
}),
bytes: (Math.ceil(parseInt(f.stat.size) / 1048576)) + ' MB',
id: path.basename(f.filename)
};
});
};
// Sort and slice to the specified page.
var paginate = function(objects, page, limit) {
return _.sortBy(objects, function(f) {
return f.id;
}).slice(page * limit, page * limit + limit);
};
// Generate the AssetList payload object.
lsR(options.directory_path, function(err, files) {
var assets = toAssets(
lsFilter(files, /(.zip|.json|.geojson|.shp|.vrt|.tiff?)/i),
options.directory_path,
require('settings').port
);
callback({
models: paginate(
assets,
options.page,
options.limit
),
page: options.page,
pageTotal: Math.ceil(assets.length / options.limit)
});
});
};