wikicommons.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. """Wikimedia Commons (images)
  3. """
  4. import datetime
  5. from urllib.parse import urlencode
  6. # about
  7. about = {
  8. "website": 'https://commons.wikimedia.org/',
  9. "wikidata_id": 'Q565',
  10. "official_api_documentation": 'https://commons.wikimedia.org/w/api.php',
  11. "use_official_api": True,
  12. "require_api_key": False,
  13. "results": 'JSON',
  14. }
  15. categories = ['images']
  16. search_type = 'images'
  17. base_url = "https://commons.wikimedia.org"
  18. search_prefix = (
  19. '?action=query'
  20. '&format=json'
  21. '&generator=search'
  22. '&gsrnamespace=6'
  23. '&gsrprop=snippet'
  24. '&prop=info|imageinfo'
  25. '&iiprop=url|size|mime'
  26. '&iiurlheight=180' # needed for the thumb url
  27. )
  28. paging = True
  29. number_of_results = 10
  30. search_types = {
  31. 'images': 'bitmap|drawing',
  32. 'videos': 'video',
  33. 'audio': 'audio',
  34. 'files': 'multimedia|office|archive|3d',
  35. }
  36. def request(query, params):
  37. language = 'en'
  38. if params['language'] != 'all':
  39. language = params['language'].split('-')[0]
  40. if search_type not in search_types:
  41. raise ValueError(f"Unsupported search type: {search_type}")
  42. filetype = search_types[search_type]
  43. args = {
  44. 'uselang': language,
  45. 'gsrlimit': number_of_results,
  46. 'gsroffset': number_of_results * (params["pageno"] - 1),
  47. 'gsrsearch': f"filetype:{filetype} {query}",
  48. }
  49. params["url"] = f"{base_url}/w/api.php{search_prefix}&{urlencode(args, safe=':|')}"
  50. return params
  51. def response(resp):
  52. results = []
  53. json = resp.json()
  54. if not json.get("query", {}).get("pages"):
  55. return results
  56. for item in json["query"]["pages"].values():
  57. imageinfo = item["imageinfo"][0]
  58. title = item["title"].replace("File:", "").rsplit('.', 1)[0]
  59. result = {
  60. 'url': imageinfo["descriptionurl"],
  61. 'title': title,
  62. 'content': item["snippet"],
  63. }
  64. if search_type == "images":
  65. result['template'] = 'images.html'
  66. result['img_src'] = imageinfo["url"]
  67. result['thumbnail_src'] = imageinfo["thumburl"]
  68. result['resolution'] = f'{imageinfo["width"]} x {imageinfo["height"]}'
  69. else:
  70. result['thumbnail'] = imageinfo["thumburl"]
  71. if search_type == "videos":
  72. result['template'] = 'videos.html'
  73. if imageinfo.get('duration'):
  74. result['length'] = datetime.timedelta(seconds=int(imageinfo['duration']))
  75. result['iframe_src'] = imageinfo['url']
  76. elif search_type == "files":
  77. result['template'] = 'files.html'
  78. result['metadata'] = imageinfo['mime']
  79. result['size'] = imageinfo['size']
  80. elif search_type == "audio":
  81. result['iframe_src'] = imageinfo['url']
  82. results.append(result)
  83. return results