diff --git a/config.json.example b/config.json.example index 3be70ff..76601cd 100644 --- a/config.json.example +++ b/config.json.example @@ -165,7 +165,8 @@ "commands": ["taxref"], "not_found_reply": "Not found!", "reply": "{sci_name}, {fr_name}, {family}, {cd_nom}, {cd_ref}", - "ambiguous_reply": "Ambiguous! It can be: " + "ambiguous_reply": "Ambiguous! It can be: ", + "unnamed_species": "(no name)" }, "translate": { "commands": ["translate"], diff --git a/edmond/plugins/taxref.py b/edmond/plugins/taxref.py index cfca36c..c5fff84 100644 --- a/edmond/plugins/taxref.py +++ b/edmond/plugins/taxref.py @@ -11,7 +11,8 @@ BASE_URL = "https://taxref.mnhn.fr/api" class TaxrefPlugin(Plugin): REQUIRED_CONFIGS = [ - "commands", "not_found_reply", "reply", "ambiguous_reply" + "commands", "not_found_reply", "reply", "ambiguous_reply", + "unnamed_species" ] def __init__(self, bot): @@ -26,8 +27,12 @@ class TaxrefPlugin(Plugin): 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" + name = name.lower() + enc_name = urllib.parse.quote(name) + url = ( + f"{BASE_URL}/taxa/search?scientificNames={enc_name}" + "&page=1&size=100" + ) response = requests.get(url) if response.status_code != 200: self.signal_failure(target) @@ -49,32 +54,49 @@ class TaxrefPlugin(Plugin): for item in items: if item["rankId"] == "ES": species_items.append(item) - if len(species_items) == 1: + num_species = len(species_items) + self.bot.log_d(f"{num_species} species.") + if num_species == 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 + # If there are several species, check if one of them has the + # exact same name; else show an ambiguous reply. + species_with_same_name = [ + item for item in species_items + if item["scientificName"].lower() == name + ] + if len(species_with_same_name) != 1: + self.show_ambiguous_reply(species_items, target) + return + item_to_use = species_with_same_name[0] + + unnamed = self.config["unnamed_species"] reply = self.config["reply"].format( sci_name=item_to_use["scientificName"], - fr_name=item_to_use["frenchVernacularName"], + fr_name=item_to_use["frenchVernacularName"] or unnamed, 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") + self.show_images(item_to_use, target) + + def show_ambiguous_reply(self, items, target): + """Show a reply with potential species.""" + 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) + + def show_images(self, item, target): + """If there are media available, show one!""" + m_url = item.get("_links", {}) .get("media", {}) .get("href") if not m_url: return