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.

74 lines
2.6KB

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