From d724677c9f44c40ea02315ef123f2b8a77d64e16 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 15 Jan 2019 20:07:20 -0500 Subject: [PATCH] Support extracting wiki info from tag and key --- modules/services/osm_wikibase.js | 14 ++++---- modules/ui/tag_reference.js | 57 ++++++++++++++++++------------ test/spec/services/osm_wikibase.js | 21 ++++++++++- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/modules/services/osm_wikibase.js b/modules/services/osm_wikibase.js index 27b9cef3f..e17c36c0d 100644 --- a/modules/services/osm_wikibase.js +++ b/modules/services/osm_wikibase.js @@ -1,6 +1,6 @@ import _debounce from 'lodash-es/debounce'; import _forEach from 'lodash-es/forEach'; -import _ from 'lodash-es'; +import _map from 'lodash-es/map'; import { json as d3_json } from 'd3-request'; @@ -95,12 +95,12 @@ export default { * @param property string e.g. 'P31' for monolingual wiki page title */ monolingualClaimToValueObj: function(entity, property) { - if (!entity.claims[property]) return undefined; - return _ - .chain(entity.claims[property]) - .keyBy(function (o) { return o.mainsnak.datavalue.value.language; }) - .mapValues(function (o) { return o.mainsnak.datavalue.value.text; }) - .value(); + if (!entity || !entity.claims[property]) return undefined; + return entity.claims[property].reduce(function(acc, obj) { + var value = obj.mainsnak.datavalue.value; + acc[value.language] = value.text; + return acc; + }, {}); }, diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index d4b312a7b..69df2ce4d 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -50,32 +50,43 @@ export function uiTagReference(tag) { title: 'Special:Redirect/file/' + image }; } - var wiki = wikibase.monolingualClaimToValueObj(entity, 'P31'); - if (wiki) { - if (wiki[langCode]) { - result.wiki = {title: wiki[langCode], text: 'wiki_reference'}; - } else { - // If exact language code was not found, try to find the first portion - // BUG: in some cases, a more elaborate fallback logic might be needed - var prefix = langCode.split('-', 2)[0]; - if (wiki[prefix]) { - result.wiki = {title: wiki[prefix], text: 'wiki_reference'}; - } else if (wiki.en) { - result.wiki = {title: wiki.en, text: 'wiki_en_reference'}; - } - } - if (result.wiki) { - result.wiki.text = t('inspector.' + result.wiki.text); - } else { - // When neither local nor EN are there, use first available - var lng = _findKey(wiki); - if (lng) { - result.wiki = {title: wiki[lng], text: t('inspector.wiki_lng_reference', {lng: lng})}; - } - } + } + + // Helper method to get wiki info if a given language exists + function getWikiInfo(wiki, langCode, msg) { + if (wiki && wiki[langCode]) { + return {title: wiki[langCode], text: t(msg)}; } } + function getAnyWikiInfo(wiki) { + if (!wiki) return; + var lng = _findKey(wiki); + if (lng) { + return {title: wiki[lng], text: t('inspector.wiki_lng_reference', {lng: lng})}; + } + } + + // Try to get a wiki page from tag data item first, followed by the corresponding key data item. + // If neither tag nor key data item contain a wiki page in the needed language nor English, + // get the first found wiki page from either the tag or the key item. + var tagWiki = wikibase.monolingualClaimToValueObj(data.tag, 'P31'); + var keyWiki = wikibase.monolingualClaimToValueObj(data.key, 'P31'); + + // If exact language code does not exist, try to find the first part before the '-' + // BUG: in some cases, a more elaborate fallback logic might be needed + var langPrefix = langCode.split('-', 2)[0]; + + result.wiki = + getWikiInfo(tagWiki, langCode, 'inspector.wiki_reference') || + getWikiInfo(tagWiki, langPrefix, 'inspector.wiki_reference') || + getWikiInfo(tagWiki, 'en', 'inspector.wiki_en_reference') || + getWikiInfo(keyWiki, langCode, 'inspector.wiki_reference') || + getWikiInfo(keyWiki, langPrefix, 'inspector.wiki_reference') || + getWikiInfo(keyWiki, 'en', 'inspector.wiki_en_reference') || + getAnyWikiInfo(tagWiki) || + getAnyWikiInfo(keyWiki); + return result; } diff --git a/test/spec/services/osm_wikibase.js b/test/spec/services/osm_wikibase.js index 61951abba..dc58ae094 100644 --- a/test/spec/services/osm_wikibase.js +++ b/test/spec/services/osm_wikibase.js @@ -246,7 +246,15 @@ describe('iD.serviceOsmWikibase', function () { type: 'statement', rank: 'normal' } - ] + ], + P31: [ + {mainsnak: {datavalue: {value: {text: 'Cs:Key:bridge:movable', language: 'cs'}}}}, + {mainsnak: {datavalue: {value: {text: 'DE:Key:bridge:movable', language: 'de'}}}}, + {mainsnak: {datavalue: {value: {text: 'FR:Key:bridge:movable', language: 'fr'}}}}, + {mainsnak: {datavalue: {value: {text: 'JA:Key:bridge:movable', language: 'ja'}}}}, + {mainsnak: {datavalue: {value: {text: 'Pl:Key:bridge:movable', language: 'pl'}}}}, + {mainsnak: {datavalue: {value: {text: 'Key:bridge:movable', language: 'en'}}}}, + ], }, sitelinks: { wiki: { @@ -319,4 +327,15 @@ describe('iD.serviceOsmWikibase', function () { expect(wikibase.claimToValue(keyData(), 'P6', 'de')).to.eql('Q14'); }); + it('gets monolingual value from entity as an object', function () { + expect(wikibase.monolingualClaimToValueObj(tagData(), 'P31')).to.eql({ + cs: 'Cs:Key:bridge:movable', + de: 'DE:Key:bridge:movable', + fr: 'FR:Key:bridge:movable', + ja: 'JA:Key:bridge:movable', + pl: 'Pl:Key:bridge:movable', + en: 'Key:bridge:movable', + }); + }); + });