on master help sign in
[enh] multilingual wikidata

disambiguation and tags are in local language TOFIX: needs to query the api every time to know each label's name

commit93ef11adc0c4653c8fadd4b4dc7c38a74f4cdbd6 authora01200356 <a01200356@itesm.mx> dateFri 3 Jun 2016, 22:39 (10 years ago) parentc553523
1 file changed+36−16
searx/engines/wikidata.py+36−16
searx/engines/wikidata.py+36−16
@@ -7,15 +7,16 @@ from searx.utils import format_date_by_locale
77from datetime import datetime
88from dateutil.parser import parse as dateutil_parse
99from urllib import urlencode
10+from lxml.html import fromstring
1011
1112
1213logger = logger.getChild('wikidata')
1314result_count = 1
1415wikidata_host = 'https://www.wikidata.org'
16+url_search = wikidata_host \
17+ + '/wiki/Special:ItemDisambiguation?{query}'
18+
1519wikidata_api = wikidata_host + '/w/api.php'
16−url_search = wikidata_api \
17− + '?action=query&list=search&format=json'\
18− + '&srnamespace=0&srprop=sectiontitle&{query}'
1920url_detail = wikidata_api\
2021 + '?action=wbgetentities&format=json'\
2122 + '&props=labels%7Cinfo%7Csitelinks'\
@@ -23,22 +24,27 @@ url_detail = wikidata_api\
2324 + '&{query}'
2425url_map = 'https://www.openstreetmap.org/'\
2526 + '?lat={latitude}&lon={longitude}&zoom={zoom}&layers=M'
27+url_entity_label = wikidata_api\
28+ + '?action=wbgetentities&format=json&props=labels&{query}'
29+
30+wikidata_ids_xpath = '//div/ul[@class="wikibase-disambiguation"]/li/a/@title'
2631
2732
2833def request(query, params):
34+ language = params['language'].split('_')[0]
35+ if language == 'all':
36+ language = 'en'
37+
2938 params['url'] = url_search.format(
30− query=urlencode({'srsearch': query,
31− 'srlimit': result_count}))
39+ query=urlencode({'label': query,
40+ 'language': language}))
3241 return params
3342
3443
3544def response(resp):
3645 results = []
37− search_res = json.loads(resp.text)
38−
39− wikidata_ids = set()
40− for r in search_res.get('query', {}).get('search', {}):
41− wikidata_ids.add(r.get('title', ''))
46+ html = fromstring(resp.content)
47+ wikidata_ids = html.xpath(wikidata_ids_xpath)
4248
4349 language = resp.search_params['language'].split('_')[0]
4450 if language == 'all':
@@ -49,7 +55,7 @@ def response(resp):
4955
5056 htmlresponse = get(url)
5157 jsonresponse = json.loads(htmlresponse.content)
52− for wikidata_id in wikidata_ids:
58+ for wikidata_id in wikidata_ids[:result_count]:
5359 results = results + getDetail(jsonresponse, wikidata_id, language, resp.search_params['language'])
5460
5561 return results
@@ -82,7 +88,7 @@ def getDetail(jsonresponse, wikidata_id, language, locale):
8288 claims = result.get('claims', {})
8389 official_website = get_string(claims, 'P856', None)
8490 if official_website is not None:
85− urls.append({'title': 'Official site', 'url': official_website})
91+ urls.append({'title': get_label('P856', language), 'url': official_website})
8692 results.append({'title': title, 'url': official_website})
8793
8894 wikipedia_link_count = 0
@@ -124,8 +130,9 @@ def getDetail(jsonresponse, wikidata_id, language, locale):
124130 'Commons wiki',
125131 get_wikilink(result, 'commonswiki'))
126132
133+ # Location
127134 add_url(urls,
128− 'Location',
135+ get_label('P625', language),
129136 get_geolink(claims, 'P625', None))
130137
131138 add_url(urls,
@@ -169,15 +176,15 @@ def getDetail(jsonresponse, wikidata_id, language, locale):
169176
170177 postal_code = get_string(claims, 'P281', None)
171178 if postal_code is not None:
172− attributes.append({'label': 'Postal code(s)', 'value': postal_code})
179+ attributes.append({'label': get_label('P281', language), 'value': postal_code})
173180
174181 date_of_birth = get_time(claims, 'P569', locale, None)
175182 if date_of_birth is not None:
176− attributes.append({'label': 'Date of birth', 'value': date_of_birth})
183+ attributes.append({'label': get_label('P569', language), 'value': date_of_birth})
177184
178185 date_of_death = get_time(claims, 'P570', locale, None)
179186 if date_of_death is not None:
180− attributes.append({'label': 'Date of death', 'value': date_of_death})
187+ attributes.append({'label': get_label('P570', language), 'value': date_of_death})
181188
182189 if len(attributes) == 0 and len(urls) == 2 and len(description) == 0:
183190 results.append({
@@ -321,3 +328,16 @@ def get_wiki_firstlanguage(result, wikipatternid):
321328 if k.endswith(wikipatternid) and len(k) == (2 + len(wikipatternid)):
322329 return k[0:2]
323330 return None
331+
332+
333+def get_label(entity_id, language):
334+ url = url_entity_label.format(query=urlencode({'ids': entity_id,
335+ 'languages': language + '|en'}))
336+
337+ response = get(url)
338+ jsonresponse = json.loads(response.text)
339+ label = jsonresponse.get('entities', {}).get(entity_id, {}).get('labels', {}).get(language, {}).get('value', None)
340+ if label is None:
341+ label = jsonresponse['entities'][entity_id]['labels']['en']['value']
342+
343+ return label