forked from zaclys/searxng
[enh] multilingual wikidata
disambiguation and tags are in local language TOFIX: needs to query the api every time to know each label's name
This commit is contained in:
parent
c553523f5b
commit
93ef11adc0
|
@ -7,15 +7,16 @@ from searx.utils import format_date_by_locale
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dateutil.parser import parse as dateutil_parse
|
from dateutil.parser import parse as dateutil_parse
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
|
from lxml.html import fromstring
|
||||||
|
|
||||||
|
|
||||||
logger = logger.getChild('wikidata')
|
logger = logger.getChild('wikidata')
|
||||||
result_count = 1
|
result_count = 1
|
||||||
wikidata_host = 'https://www.wikidata.org'
|
wikidata_host = 'https://www.wikidata.org'
|
||||||
|
url_search = wikidata_host \
|
||||||
|
+ '/wiki/Special:ItemDisambiguation?{query}'
|
||||||
|
|
||||||
wikidata_api = wikidata_host + '/w/api.php'
|
wikidata_api = wikidata_host + '/w/api.php'
|
||||||
url_search = wikidata_api \
|
|
||||||
+ '?action=query&list=search&format=json'\
|
|
||||||
+ '&srnamespace=0&srprop=sectiontitle&{query}'
|
|
||||||
url_detail = wikidata_api\
|
url_detail = wikidata_api\
|
||||||
+ '?action=wbgetentities&format=json'\
|
+ '?action=wbgetentities&format=json'\
|
||||||
+ '&props=labels%7Cinfo%7Csitelinks'\
|
+ '&props=labels%7Cinfo%7Csitelinks'\
|
||||||
|
@ -23,22 +24,27 @@ url_detail = wikidata_api\
|
||||||
+ '&{query}'
|
+ '&{query}'
|
||||||
url_map = 'https://www.openstreetmap.org/'\
|
url_map = 'https://www.openstreetmap.org/'\
|
||||||
+ '?lat={latitude}&lon={longitude}&zoom={zoom}&layers=M'
|
+ '?lat={latitude}&lon={longitude}&zoom={zoom}&layers=M'
|
||||||
|
url_entity_label = wikidata_api\
|
||||||
|
+ '?action=wbgetentities&format=json&props=labels&{query}'
|
||||||
|
|
||||||
|
wikidata_ids_xpath = '//div/ul[@class="wikibase-disambiguation"]/li/a/@title'
|
||||||
|
|
||||||
|
|
||||||
def request(query, params):
|
def request(query, params):
|
||||||
|
language = params['language'].split('_')[0]
|
||||||
|
if language == 'all':
|
||||||
|
language = 'en'
|
||||||
|
|
||||||
params['url'] = url_search.format(
|
params['url'] = url_search.format(
|
||||||
query=urlencode({'srsearch': query,
|
query=urlencode({'label': query,
|
||||||
'srlimit': result_count}))
|
'language': language}))
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
def response(resp):
|
def response(resp):
|
||||||
results = []
|
results = []
|
||||||
search_res = json.loads(resp.text)
|
html = fromstring(resp.content)
|
||||||
|
wikidata_ids = html.xpath(wikidata_ids_xpath)
|
||||||
wikidata_ids = set()
|
|
||||||
for r in search_res.get('query', {}).get('search', {}):
|
|
||||||
wikidata_ids.add(r.get('title', ''))
|
|
||||||
|
|
||||||
language = resp.search_params['language'].split('_')[0]
|
language = resp.search_params['language'].split('_')[0]
|
||||||
if language == 'all':
|
if language == 'all':
|
||||||
|
@ -49,7 +55,7 @@ def response(resp):
|
||||||
|
|
||||||
htmlresponse = get(url)
|
htmlresponse = get(url)
|
||||||
jsonresponse = json.loads(htmlresponse.content)
|
jsonresponse = json.loads(htmlresponse.content)
|
||||||
for wikidata_id in wikidata_ids:
|
for wikidata_id in wikidata_ids[:result_count]:
|
||||||
results = results + getDetail(jsonresponse, wikidata_id, language, resp.search_params['language'])
|
results = results + getDetail(jsonresponse, wikidata_id, language, resp.search_params['language'])
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
@ -82,7 +88,7 @@ def getDetail(jsonresponse, wikidata_id, language, locale):
|
||||||
claims = result.get('claims', {})
|
claims = result.get('claims', {})
|
||||||
official_website = get_string(claims, 'P856', None)
|
official_website = get_string(claims, 'P856', None)
|
||||||
if official_website is not None:
|
if official_website is not None:
|
||||||
urls.append({'title': 'Official site', 'url': official_website})
|
urls.append({'title': get_label('P856', language), 'url': official_website})
|
||||||
results.append({'title': title, 'url': official_website})
|
results.append({'title': title, 'url': official_website})
|
||||||
|
|
||||||
wikipedia_link_count = 0
|
wikipedia_link_count = 0
|
||||||
|
@ -124,8 +130,9 @@ def getDetail(jsonresponse, wikidata_id, language, locale):
|
||||||
'Commons wiki',
|
'Commons wiki',
|
||||||
get_wikilink(result, 'commonswiki'))
|
get_wikilink(result, 'commonswiki'))
|
||||||
|
|
||||||
|
# Location
|
||||||
add_url(urls,
|
add_url(urls,
|
||||||
'Location',
|
get_label('P625', language),
|
||||||
get_geolink(claims, 'P625', None))
|
get_geolink(claims, 'P625', None))
|
||||||
|
|
||||||
add_url(urls,
|
add_url(urls,
|
||||||
|
@ -169,15 +176,15 @@ def getDetail(jsonresponse, wikidata_id, language, locale):
|
||||||
|
|
||||||
postal_code = get_string(claims, 'P281', None)
|
postal_code = get_string(claims, 'P281', None)
|
||||||
if postal_code is not None:
|
if postal_code is not None:
|
||||||
attributes.append({'label': 'Postal code(s)', 'value': postal_code})
|
attributes.append({'label': get_label('P281', language), 'value': postal_code})
|
||||||
|
|
||||||
date_of_birth = get_time(claims, 'P569', locale, None)
|
date_of_birth = get_time(claims, 'P569', locale, None)
|
||||||
if date_of_birth is not None:
|
if date_of_birth is not None:
|
||||||
attributes.append({'label': 'Date of birth', 'value': date_of_birth})
|
attributes.append({'label': get_label('P569', language), 'value': date_of_birth})
|
||||||
|
|
||||||
date_of_death = get_time(claims, 'P570', locale, None)
|
date_of_death = get_time(claims, 'P570', locale, None)
|
||||||
if date_of_death is not None:
|
if date_of_death is not None:
|
||||||
attributes.append({'label': 'Date of death', 'value': date_of_death})
|
attributes.append({'label': get_label('P570', language), 'value': date_of_death})
|
||||||
|
|
||||||
if len(attributes) == 0 and len(urls) == 2 and len(description) == 0:
|
if len(attributes) == 0 and len(urls) == 2 and len(description) == 0:
|
||||||
results.append({
|
results.append({
|
||||||
|
@ -321,3 +328,16 @@ def get_wiki_firstlanguage(result, wikipatternid):
|
||||||
if k.endswith(wikipatternid) and len(k) == (2 + len(wikipatternid)):
|
if k.endswith(wikipatternid) and len(k) == (2 + len(wikipatternid)):
|
||||||
return k[0:2]
|
return k[0:2]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_label(entity_id, language):
|
||||||
|
url = url_entity_label.format(query=urlencode({'ids': entity_id,
|
||||||
|
'languages': language + '|en'}))
|
||||||
|
|
||||||
|
response = get(url)
|
||||||
|
jsonresponse = json.loads(response.text)
|
||||||
|
label = jsonresponse.get('entities', {}).get(entity_id, {}).get('labels', {}).get(language, {}).get('value', None)
|
||||||
|
if label is None:
|
||||||
|
label = jsonresponse['entities'][entity_id]['labels']['en']['value']
|
||||||
|
|
||||||
|
return label
|
||||||
|
|
Loading…
Reference in New Issue