Set KML folder name to the requested filename.

Closes #115. Includes testcase.
This commit is contained in:
Sandro Santilli 2013-11-05 17:29:02 +01:00
parent 3c03099e8d
commit 2abb136258
6 changed files with 35 additions and 9 deletions

View File

@ -2,6 +2,7 @@
------------------
* Still set a meaningful X-Cache-Channel with cache_policy=persist (#105)
* Fix wrong projection in KML exports for manually altered tables (#116)
* Set KML folder name to the requested filename (#115)
1.6.0 - 2013-10-02
------------------

View File

@ -11,7 +11,7 @@ p._fileExtension = "csv";
p.generate = function(options, callback) {
var o = options;
this.toOGR_SingleFile(o.database, o.user_id, o.gn, o.sql, o.skipfields, 'CSV', 'csv', callback);
this.toOGR_SingleFile(o.database, o.user_id, o.gn, o.sql, o.skipfields, 'CSV', 'csv', o.filename, callback);
};
module.exports = csv;

View File

@ -18,7 +18,7 @@ p._needSRS = true;
p.generate = function(options, callback) {
var o = options;
this.toOGR_SingleFile(o.database, o.user_id, o.gn, o.sql, o.skipfields, 'KML', 'kml', callback);
this.toOGR_SingleFile(o.database, o.user_id, o.gn, o.sql, o.skipfields, 'KML', 'kml', o.filename, callback);
};
module.exports = kml;

View File

@ -46,6 +46,7 @@ ogr.prototype = {
options.dbname,
options.user_id,
options.gn,
this.generateMD5(options.filename),
this.generateMD5(options.sql)].concat(options.skipfields).join(':');
},
@ -58,7 +59,7 @@ ogr.prototype = {
};
// Internal function usable by all OGR-driven outputs
ogr.prototype.toOGR = function(dbname, user_id, gcol, sql, skipfields, out_format, out_filename, callback) {
ogr.prototype.toOGR = function(dbname, user_id, gcol, sql, skipfields, out_format, out_filename, out_layername, callback) {
var ogr2ogr = 'ogr2ogr'; // FIXME: make configurable
var dbhost = global.settings.db_host;
var dbport = global.settings.db_port;
@ -156,6 +157,8 @@ ogr.prototype.toOGR = function(dbname, user_id, gcol, sql, skipfields, out_forma
ogrargs.push('-nlt', type);
}
ogrargs.push('-nln', out_layername);
var child = spawn(ogr2ogr, ogrargs);
/*
@ -194,15 +197,16 @@ console.log('ogr2ogr ' + _.map(ogrargs, function(x) { return "'" + x + "'"; }).j
);
};
ogr.prototype.toOGR_SingleFile = function(dbname, user_id, gcol, sql, skipfields, fmt, ext, callback) {
// TODO: simplify to take an options object
ogr.prototype.toOGR_SingleFile = function(dbname, user_id, gcol, sql, skipfields, fmt, ext, layername, callback) {
var tmpdir = global.settings.tmpDir || '/tmp';
var reqKey = [ fmt, dbname, user_id, gcol, this.generateMD5(sql) ].concat(skipfields).join(':');
var reqKey = [ fmt, dbname, user_id, gcol, this.generateMD5(layername), this.generateMD5(sql) ].concat(skipfields).join(':');
var outdirpath = tmpdir + '/sqlapi-' + process.pid + '-' + reqKey;
var dumpfile = outdirpath + ':cartodb-query.' + ext;
// TODO: following tests:
// - fetch query with no "the_geom" column
this.toOGR(dbname, user_id, gcol, sql, skipfields, fmt, dumpfile, callback);
this.toOGR(dbname, user_id, gcol, sql, skipfields, fmt, dumpfile, layername, callback);
};
ogr.prototype.sendResponse = function(opts, callback) {

View File

@ -45,7 +45,7 @@ p.toSHP = function (dbname, user_id, gcol, sql, skipfields, filename, callback)
},
function spawnDumper(err) {
if ( err ) throw err;
fmtObj.toOGR(dbname, user_id, gcol, sql, skipfields, 'ESRI Shapefile', shapefile, this);
fmtObj.toOGR(dbname, user_id, gcol, sql, skipfields, 'ESRI Shapefile', shapefile, filename, this);
},
function doZip(err) {
if ( err ) throw err;

View File

@ -87,6 +87,25 @@ var extractCoordinates = function(kml) {
return coo;
}
// Return the first folder name in KML
var extractFolderName = function(kml) {
// Strip namespace:
//https://github.com/polotek/libxmljs/issues/212
kml = kml.replace(/ xmlns=[^>]*>/, '>');
var doc = libxmljs.parseXmlString(kml);
//console.log("doc: " + doc);
if ( ! doc ) return;
var coo = doc.get("//Document/Folder/name");
//console.log("coo: " + coo);
if ( ! coo ) return;
coo = coo.text();
//console.log("coo: " + coo);
if ( ! coo ) return;
return coo;
}
// KML tests
test('KML format, unauthenticated', function(done){
@ -179,6 +198,8 @@ test('KML format, unauthenticated, custom filename', function(done){
var cd = res.header('Content-Disposition');
assert.equal(true, /^attachment/.test(cd), 'KML is not disposed as attachment: ' + cd);
assert.equal(true, /filename=kmltest.kml/gi.test(cd), 'Unexpected KML filename: ' + cd);
var name = extractFolderName(res.body);
assert.equal(name, "kmltest");
done();
});
});
@ -247,7 +268,7 @@ test('GET /api/v1/sql as kml with no rows', function(done){
method: 'GET'
},{ }, function(res){
assert.equal(res.statusCode, 200, res.body);
var body = '<?xml version="1.0" encoding="utf-8" ?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Folder><name>sql_statement</name></Folder></Document></kml>';
var body = '<?xml version="1.0" encoding="utf-8" ?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Folder><name>cartodb_query</name></Folder></Document></kml>';
assert.equal(res.body.replace(/\n/g,''), body);
done();
});
@ -264,7 +285,7 @@ test('GET /api/v1/sql as kml with ending semicolon', function(done){
method: 'GET'
},{ }, function(res){
assert.equal(res.statusCode, 200, res.body);
var body = '<?xml version="1.0" encoding="utf-8" ?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Folder><name>sql_statement</name></Folder></Document></kml>';
var body = '<?xml version="1.0" encoding="utf-8" ?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Folder><name>cartodb_query</name></Folder></Document></kml>';
assert.equal(res.body.replace(/\n/g,''), body);
done();
});