Errbot plugin for fetching random dog pictures, optionally by breed. Forked from https://github.com/archertech/err-dog
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.

185 lines
6.8KB

  1. import logging
  2. import requests
  3. import json
  4. from errbot import botcmd, BotPlugin
  5. class Doggo(BotPlugin):
  6. """Fetch random dog image URLs"""
  7. min_err_version = '3.0.0' # Optional, but recommended
  8. BASE_URL = 'https://dog.ceo/api'
  9. breeds = {}
  10. @botcmd(split_args_with=' ')
  11. def doggo(self, msg, args):
  12. """
  13. Fetches a random dog image, optionally of given <breed>, or of given <breed> <sub-breed>
  14. """
  15. url = '{}/breeds/image/random'.format(self.BASE_URL)
  16. if len(args) > 0 and args[0]:
  17. breed = args[0]
  18. if not self.breeds:
  19. args.append('calledbyfunction')
  20. self.reloadbreeds(msg, args)
  21. if breed in self.breeds.keys():
  22. url = '{}/breed/{}/images/random'.format(self.BASE_URL, breed)
  23. else:
  24. return 'Breed not found: {}. List breeds with !listbreeds'.format(breed)
  25. # But what if user passed us a sub-breed?
  26. if len(args) > 1 and args[1]:
  27. subbreed = args[1]
  28. if len(self.breeds[breed]) == 0:
  29. if 'calledbyfunction' not in args:
  30. args.append('calledbyfunction')
  31. self.reloadsubbreeds(msg, args)
  32. if len(self.breeds[breed]) == 0:
  33. return 'No sub-breeds available for {}, so we cannot use {}.'.format(breed, subbreed)
  34. if subbreed in self.breeds[breed]:
  35. url = '{}/breed/{}/{}/images/random'.format(self.BASE_URL, breed, subbreed)
  36. else:
  37. return 'Sub-breed of {} not found: {}. List sub-breeds with !listsubbreeds'.format(breed, subbreed)
  38. try:
  39. resp = requests.get(url)
  40. resp.raise_for_status()
  41. except requests.exceptions.HTTPError as e:
  42. logging.debug(e)
  43. return 'Unable to return a dog image'
  44. return resp.json()['message']
  45. @botcmd(split_args_with=' ')
  46. def listbreeds(self, msg, args):
  47. """
  48. DMs the user the breeds available for use in the random image fetcher
  49. """
  50. if not self.breeds:
  51. args.append('calledbyfunction')
  52. self.reloadbreeds(msg, args)
  53. if not self.breeds:
  54. return 'Unable to load breeds list'
  55. # Send the output to the user to prevent spamming the channel
  56. direct_to_user = self.build_identifier(str(msg.frm))
  57. for breed in sorted(self.breeds.keys()):
  58. self.send(direct_to_user, breed)
  59. @botcmd(admin_only=True,split_args_with=' ')
  60. def reloadbreeds(self, msg, args):
  61. """
  62. Admin-only; forces reload of the breeds currently available
  63. """
  64. url = '{}/breeds/list'.format(self.BASE_URL)
  65. try:
  66. resp = requests.get(url)
  67. resp.raise_for_status()
  68. except requests.exceptions.HTTPError as e:
  69. logging.debug(e)
  70. return 'Unable to load breeds list'
  71. data = resp.json()['message']
  72. if not isinstance(data, list):
  73. return 'Unable to load breeds list'
  74. for breed in data:
  75. self.breeds[breed] = []
  76. if 'calledbyfunction' not in args:
  77. # Tell user command was successful
  78. direct_to_user = self.build_identifier(str(msg.frm))
  79. self.send(direct_to_user, "Breed list successfully loaded")
  80. @botcmd(split_args_with=' ')
  81. def listsubbreeds(self, msg, args):
  82. """
  83. DMs the user the sub-breeds available for a given `<breed>`
  84. """
  85. if len(args) > 0 and args[0]:
  86. breed = args[0]
  87. if not self.breeds:
  88. args.append('calledbyfunction')
  89. self.reloadbreeds(msg, args)
  90. if not self.breeds:
  91. return 'Unable to load sub-breeds list'
  92. if breed not in self.breeds.keys():
  93. return 'Breed not found: {}. List breeds with !listbreeds'.format(breed)
  94. else:
  95. return 'Please tell me the breed for which you want sub-breeds, like: *!listsubbreeds terrier*'
  96. # Send the output to the user to prevent spamming the channel
  97. direct_to_user = self.build_identifier(str(msg.frm))
  98. if len(self.breeds[breed]) == 0:
  99. args.append('calledbyfunction')
  100. self.reloadsubbreeds(msg, args)
  101. if len(self.breeds[breed]) == 0:
  102. return 'No sub-breeds available for {}.'.format(breed)
  103. for subbreed in sorted(self.breeds[breed]):
  104. self.send(direct_to_user, subbreed)
  105. @botcmd(admin_only=True, split_args_with=' ')
  106. def reloadsubbreeds(self, msg, args):
  107. """
  108. Admin-only; forces reload of the sub-breeds available for the given <breed>
  109. """
  110. if len(args) > 0 and args[0]:
  111. breed = args[0]
  112. if not self.breeds:
  113. self.reloadbreeds(msg, args)
  114. if not self.breeds:
  115. return 'Unable to load breeds list'
  116. if breed in self.breeds.keys():
  117. url = '{}/breed/{}/list'.format(self.BASE_URL, breed)
  118. else:
  119. return 'Breed not found: {}. List breeds with !listbreeds'.format(breed)
  120. else:
  121. return 'Please tell me the breed for which you want sub-breeds, like: *!reloadsubbreeds terrier*'
  122. try:
  123. resp = requests.get(url)
  124. resp.raise_for_status()
  125. except requests.exceptions.HTTPError as e:
  126. logging.debug(e)
  127. return 'Unable to load sub-breeds list'
  128. data = resp.json()['message']
  129. if not isinstance(data, list):
  130. return 'Unable to load sub-breeds list'
  131. self.breeds[breed] = data
  132. if 'calledbyfunction' not in args:
  133. # Tell user command was successful
  134. direct_to_user = self.build_identifier(str(msg.frm))
  135. self.send(direct_to_user, "Sub-breed list successfully loaded")
  136. @botcmd(split_args_with=' ')
  137. def listallbreeds(self, msg, args):
  138. """
  139. DMs the user the list of all breeds & sub-breeds available for use in the random image fetcher
  140. """
  141. if not self.breeds:
  142. args.append('calledbyfunction')
  143. self.reloadbreeds(msg, args)
  144. if not self.breeds:
  145. return 'Unable to load breeds list'
  146. direct_to_user = self.build_identifier(str(msg.frm))
  147. for breed in self.breeds:
  148. if len(self.breeds[breed]) == 0:
  149. args[0] = breed
  150. args[1] = 'calledbyfunction'
  151. self.reloadsubbreeds(msg, args)
  152. if len(self.breeds[breed]) == 0:
  153. self.send(direct_to_user, breed)
  154. else:
  155. for subbreed in self.breeds[breed]:
  156. self.send(direct_to_user, breed + " " + subbreed)