Edm0nd/edmond/plugins/taxref.py

95 lines
3 KiB
Python

import random
import urllib.parse
import requests
from edmond.plugin import Plugin
BASE_URL = "https://taxref.mnhn.fr/api"
class TaxrefPlugin(Plugin):
REQUIRED_CONFIGS = [
"commands", "not_found_reply", "reply", "ambiguous_reply"
]
def __init__(self, bot):
super().__init__(bot)
def on_pubmsg(self, event):
if not self.should_handle_command(event.arguments[0]):
return False
if self.command.ident == self.config["commands"][0]:
self.search_by_name(self.command.content, event.target)
return True
def search_by_name(self, name, target):
name = urllib.parse.quote(name.lower())
url = f"{BASE_URL}/taxa/search?scientificNames={name}&page=1&size=100"
response = requests.get(url)
if response.status_code != 200:
self.signal_failure(target)
return
data = response.json()
items = data.get("_embedded", {}).get("taxa", [])
if not items:
self.bot.say(target, self.config["not_found_reply"])
return
if len(items) == 1:
# Only one result: use it.
item_to_use = items[0]
else:
# More than one result: if the results contain a corresponding
# species, use it, else return names for sub-species etc.
species_items = []
for item in items:
if item["rankId"] == "ES":
species_items.append(item)
if len(species_items) == 1:
item_to_use = species_items[0]
else:
reply = self.config["ambiguous_reply"]
append = ""
if len(items) > 5:
append = f"… (+{len(items)})"
items = items[:5]
reply += ", ".join(
item["scientificName"] for item in items
)
if append:
reply += append
self.bot.say(target, reply)
return
reply = self.config["reply"].format(
sci_name=item_to_use["scientificName"],
fr_name=item_to_use["frenchVernacularName"],
family=item_to_use["familyName"],
cd_nom=item_to_use["id"],
cd_ref=item_to_use["referenceId"],
)
self.bot.say(target, reply)
# If there are media available, show one!
m_url = item_to_use.get("_links", {}) .get("media", {}) .get("href")
if not m_url:
return
response = requests.get(m_url)
if response.status_code != 200:
self.signal_failure(target)
return
media_data = response.json()
items = media_data.get("_embedded", {}).get("media", [])
if not items:
return
random_item = random.choice(items)
media_href = random_item.get("_links", {}).get("file", {}).get("href")
if not media_href:
return
self.bot.say(target, "📷 " + media_href)