| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  | # SPDX-License-Identifier: AGPL-3.0-or-later | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | """
 | 
					
						
							|  |  |  |  PubMed (Scholar publications) | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 14:20:47 +01:00
										 |  |  | from flask_babel import gettext | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | from lxml import etree | 
					
						
							|  |  |  | from datetime import datetime | 
					
						
							| 
									
										
										
										
											2020-08-06 17:42:46 +02:00
										 |  |  | from urllib.parse import urlencode | 
					
						
							| 
									
										
										
											
												[httpx] replace searx.poolrequests by searx.network
settings.yml:
* outgoing.networks:
   * can contains network definition
   * propertiers: enable_http, verify, http2, max_connections, max_keepalive_connections,
     keepalive_expiry, local_addresses, support_ipv4, support_ipv6, proxies, max_redirects, retries
   * retries: 0 by default, number of times searx retries to send the HTTP request (using different IP & proxy each time)
   * local_addresses can be "192.168.0.1/24" (it supports IPv6)
   * support_ipv4 & support_ipv6: both True by default
     see https://github.com/searx/searx/pull/1034
* each engine can define a "network" section:
   * either a full network description
   * either reference an existing network
* all HTTP requests of engine use the same HTTP configuration (it was not the case before, see proxy configuration in master)
											
										 
											2021-04-05 10:43:33 +02:00
										 |  |  | from searx.network import get | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  | # about | 
					
						
							|  |  |  | about = { | 
					
						
							|  |  |  |     "website": 'https://www.ncbi.nlm.nih.gov/pubmed/', | 
					
						
							|  |  |  |     "wikidata_id": 'Q1540899', | 
					
						
							|  |  |  |     "official_api_documentation": { | 
					
						
							|  |  |  |         'url': 'https://www.ncbi.nlm.nih.gov/home/develop/api/', | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |         'comment': 'More info on api: https://www.ncbi.nlm.nih.gov/books/NBK25501/', | 
					
						
							| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  |     }, | 
					
						
							|  |  |  |     "use_official_api": True, | 
					
						
							|  |  |  |     "require_api_key": False, | 
					
						
							|  |  |  |     "results": 'XML', | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | categories = ['science'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  | base_url = ( | 
					
						
							|  |  |  |     'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi' + '?db=pubmed&{query}&retstart={offset}&retmax={hits}' | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | # engine dependent config | 
					
						
							|  |  |  | number_of_results = 10 | 
					
						
							|  |  |  | pubmed_url = 'https://www.ncbi.nlm.nih.gov/pubmed/' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def request(query, params): | 
					
						
							|  |  |  |     # basic search | 
					
						
							|  |  |  |     offset = (params['pageno'] - 1) * number_of_results | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |     string_args = dict(query=urlencode({'term': query}), offset=offset, hits=number_of_results) | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     params['url'] = base_url.format(**string_args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return params | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def response(resp): | 
					
						
							|  |  |  |     results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # First retrieve notice of each result | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |     pubmed_retrieve_api_url = ( | 
					
						
							|  |  |  |         'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?' + 'db=pubmed&retmode=xml&id={pmids_string}' | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 14:20:47 +01:00
										 |  |  |     pmids_results = etree.XML(resp.content) | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  |     pmids = pmids_results.xpath('//eSearchResult/IdList/Id') | 
					
						
							|  |  |  |     pmids_string = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for item in pmids: | 
					
						
							|  |  |  |         pmids_string += item.text + ',' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     retrieve_notice_args = dict(pmids_string=pmids_string) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     retrieve_url_encoded = pubmed_retrieve_api_url.format(**retrieve_notice_args) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 14:20:47 +01:00
										 |  |  |     search_results_xml = get(retrieve_url_encoded).content | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  |     search_results = etree.XML(search_results_xml).xpath('//PubmedArticleSet/PubmedArticle/MedlineCitation') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for entry in search_results: | 
					
						
							|  |  |  |         title = entry.xpath('.//Article/ArticleTitle')[0].text | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pmid = entry.xpath('.//PMID')[0].text | 
					
						
							|  |  |  |         url = pubmed_url + pmid | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             content = entry.xpath('.//Abstract/AbstractText')[0].text | 
					
						
							|  |  |  |         except: | 
					
						
							| 
									
										
										
										
											2017-11-01 14:20:47 +01:00
										 |  |  |             content = gettext('No abstract is available for this publication.') | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         #  If a doi is available, add it to the snipppet | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             doi = entry.xpath('.//ELocationID[@EIdType="doi"]')[0].text | 
					
						
							| 
									
										
										
										
											2017-11-01 14:20:47 +01:00
										 |  |  |             content = 'DOI: {doi} Abstract: {content}'.format(doi=doi, content=content) | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if len(content) > 300: | 
					
						
							| 
									
										
										
										
											2020-11-16 09:43:23 +01:00
										 |  |  |             content = content[0:300] + "..." | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  |         # TODO: center snippet on query term | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |         res_dict = {'url': url, 'title': title, 'content': content} | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 20:48:10 +01:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |             publishedDate = datetime.strptime( | 
					
						
							|  |  |  |                 entry.xpath('.//DateCreated/Year')[0].text | 
					
						
							|  |  |  |                 + '-' | 
					
						
							|  |  |  |                 + entry.xpath('.//DateCreated/Month')[0].text | 
					
						
							|  |  |  |                 + '-' | 
					
						
							|  |  |  |                 + entry.xpath('.//DateCreated/Day')[0].text, | 
					
						
							|  |  |  |                 '%Y-%m-%d', | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2017-12-01 20:48:10 +01:00
										 |  |  |             res_dict['publishedDate'] = publishedDate | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 22:09:33 +02:00
										 |  |  |         results.append(res_dict) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return results |