mirror of https://github.com/pelias/api.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.4 KiB
124 lines
3.4 KiB
var logger = require( 'pelias-logger' ).get( 'api' ); |
|
const _ = require('lodash'); |
|
|
|
/** |
|
example response from language web service: |
|
{ |
|
"101748479": { |
|
"wofid": 101748479, |
|
"placetype": "locality", |
|
"iso": "DE", |
|
"area": 0.031614, |
|
"lineage": { |
|
"continent_id": 102191581, |
|
"country_id": 85633111, |
|
"county_id": 102063261, |
|
"locality_id": 101748479, |
|
"macrocounty_id": 404227567, |
|
"region_id": 85682571 |
|
}, |
|
"rowid": 90425, |
|
"names": { |
|
"default": "München", |
|
"eng": "Munich" |
|
} |
|
}, |
|
} |
|
**/ |
|
|
|
function setup(service, should_execute) { |
|
return function controller(req, res, next) { |
|
if (!should_execute(req, res)) { |
|
return next(); |
|
} |
|
|
|
const start = Date.now(); |
|
service(req, res, (err, translations) => { |
|
// if there's an error, log it and bail |
|
if (err) { |
|
logger.info(`[middleware:language][error]`); |
|
logger.error(err); |
|
return next(); |
|
} |
|
|
|
logger.info('language', { |
|
response_time: Date.now() - start, |
|
language: req.clean.lang.iso6391, |
|
controller: 'language', //technically middleware, but this is consistent with other log lines |
|
}); |
|
|
|
// otherwise, update all the docs with translations |
|
updateDocs(req, res, _.defaultTo(translations, [])); |
|
next(); |
|
|
|
}); |
|
|
|
}; |
|
|
|
} |
|
|
|
// update documents using a translation map |
|
function updateDocs( req, res, translations ){ |
|
// this is the target language we will be translating to |
|
var requestLanguage = req.clean.lang.iso6393; |
|
|
|
// iterate over response documents |
|
res.data.forEach( function( doc, p ){ |
|
|
|
// skip invalid records |
|
if( !doc || !doc.parent ){ return; } |
|
|
|
// iterate over doc.parent.* attributes |
|
for( var attr in doc.parent ){ |
|
|
|
// match only attributes ending with '_id' |
|
var match = attr.match(/^(.*)_id$/); |
|
if( !match ){ continue; } |
|
|
|
// adminKey is the property name without the '_id' |
|
// eg. for 'country_id', adminKey would be 'country'. |
|
var adminKey = match[1]; |
|
var adminValues = doc.parent[adminKey]; |
|
|
|
// skip invalid/empty arrays |
|
if( !Array.isArray( adminValues ) || !adminValues.length ){ continue; } |
|
|
|
// iterate over adminValues (it's an array and can have more than one value) |
|
for( var i in adminValues ){ |
|
|
|
// find the corresponding key from the '_id' Array |
|
var id = doc.parent[attr][i]; |
|
if( !id ){ continue; } |
|
|
|
// id not found in translation service response |
|
if( !_.has(translations, id)){ |
|
logger.debug( `[language] [debug] failed to find translations for ${id}` ); |
|
continue; |
|
} |
|
|
|
// requested language is not available |
|
if (_.isEmpty(_.get(translations[id].names, requestLanguage, [] ))) { |
|
logger.debug( `[language] [debug] missing translation ${requestLanguage} ${id}` ); |
|
continue; |
|
} |
|
|
|
// translate 'parent.*' property |
|
adminValues[i] = translations[id].names[ requestLanguage ][0]; |
|
|
|
// if the record is an admin record we also translate |
|
// the 'name.default' property. |
|
if( adminKey === doc.layer ){ |
|
doc.name.default = translations[id].names[ requestLanguage ][0]; |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
// boolean function to check if changing the language is required |
|
function isLanguageChangeRequired( req, res ){ |
|
return req && res && res.data && res.data.length && |
|
req.hasOwnProperty('language'); |
|
} |
|
|
|
module.exports = setup;
|
|
|