forked from pelias/api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchangeLanguage.js
136 lines (111 loc) · 3.82 KB
/
changeLanguage.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
var field = require('../helper/fieldValue');
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.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 ){
// update name.default to the request language (if available)
if (req.clean.lang.defaulted === false) {
translateNameDefault(doc, req.clean.lang.iso6391);
}
// 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');
}
// update name.default with the corresponding translation if available
function translateNameDefault(doc, lang) {
if (lang && _.has(doc, 'name.' + lang)) {
doc.name.default = field.getStringValue(doc.name[lang]);
}
}
module.exports = setup;