You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 line
2.4KB

  1. #!/usr/bin/python3
  2. import requests
  3. import sys
  4. import textwrap
  5. # Fetch JSON from url and run it through transform, pretty printing errors
  6. # and the data worked on as exhaustively as possible.
  7. def json_query(url, transform, params={}):
  8. try:
  9. result = requests.get(url, params)
  10. except ConnectionError:
  11. print("Network connection error.")
  12. sys.exit(1)
  13. try:
  14. data = result.json()
  15. except JSONDecodeError as err:
  16. print('Error when decoding JSON:\nFrom endpoint ' + url + ':\n' + err + '\n' + result + '\n')
  17. sys.exit(1)
  18. try:
  19. return transform(data)
  20. except (IndexError, KeyError) as err:
  21. print('Error when traversing JSON:\nFrom endpoint ' + url + ':\n' + err)
  22. pprint.PrettyPrinter(indent=2).pprint(data)
  23. sys.exit(1)
  24. # Search wikipedia for string, returning at most max_results results
  25. # or the empty list if no matches where returned.
  26. def page_search(string, max_results):
  27. params = {
  28. 'q' : string,
  29. 'limit' : max_results
  30. }
  31. return json_query('https://en.wikipedia.org/w/rest.php/v1/search/page', lambda data: data['pages'], params)
  32. # Get a JSON object for the titled page, containing page metadata and a text summary.
  33. def get_page_with_summary(title):
  34. return json_query('https://en.wikipedia.org/api/rest_v1/page/summary/' + title, lambda data: data)
  35. # Get a list of the links from a page. For a disambiguation page, this means
  36. # a list of the links to individual pages.
  37. def get_page_links(title):
  38. params = {
  39. 'action' : 'query',
  40. 'titles' : title,
  41. 'prop' : 'links',
  42. 'format' : 'json'
  43. }
  44. return json_query('https://en.wikipedia.org/w/api.php', lambda data: list(data['query']['pages'].values())[0]['links'], params)
  45. def main():
  46. arg = ' '.join(sys.argv[1:])
  47. if not arg:
  48. print("Usage: wikipedia <list of search terms>")
  49. sys.exit(1)
  50. else:
  51. results = page_search(arg, 1)
  52. if results:
  53. page = get_page_with_summary(results[0]['title'])
  54. if page['type'] == 'disambiguation':
  55. print('Ambiguous result, please clarify:\n ' + '\n '.join([link['title'] for link in get_page_links(page['title'])]))
  56. else:
  57. print(page['title'] + ':\n\n' + textwrap.fill(page['extract'], width=80))
  58. else:
  59. print('No result found.')
  60. sys.exit(1)
  61. if __name__ == '__main__':
  62. main()