Compare commits

...

3 commits

Author SHA1 Message Date
dece a8b1b811c5 taxref: add function to get scientific name 2022-07-06 17:18:28 +02:00
dece b333b5d944 shrlok: fix bad kwarg 2022-07-06 17:18:01 +02:00
dece 274dd61b1a config.json.example: fix typo 2022-07-06 17:17:41 +02:00
3 changed files with 65 additions and 15 deletions

View file

@ -67,7 +67,7 @@
}, },
"horoscope": { "horoscope": {
"commands": ["horoscope"], "commands": ["horoscope"],
"meditation": "/me looks at the starts", "meditation": "/me looks at the stars",
"url": "http://zwergf.elynx.fr/bots/horobot/", "url": "http://zwergf.elynx.fr/bots/horobot/",
"delay": 2 "delay": 2
}, },
@ -162,7 +162,7 @@
"snore_rate": 1.0 "snore_rate": 1.0
}, },
"taxref": { "taxref": {
"commands": ["taxref"], "commands": ["taxref", "scientifize"],
"not_found_reply": "Not found!", "not_found_reply": "Not found!",
"reply": "{sci_name}, {fr_name}, {family}, {cd_nom}, {cd_ref}", "reply": "{sci_name}, {fr_name}, {family}, {cd_nom}, {cd_ref}",
"ambiguous_reply": "Ambiguous! It can be: ", "ambiguous_reply": "Ambiguous! It can be: ",

View file

@ -39,5 +39,5 @@ class ShrlokPlugin(Plugin):
except OSError as exc: except OSError as exc:
self.bot.log_e(f"Can't post text file: {exc}") self.bot.log_e(f"Can't post text file: {exc}")
return None return None
url = response.decode().replace(self.file_root, self.url_root, count=1) url = response.decode().replace(self.file_root, self.url_root, 1)
return url return url

View file

@ -22,11 +22,20 @@ class TaxrefPlugin(Plugin):
if not self.should_handle_command(event.arguments[0]): if not self.should_handle_command(event.arguments[0]):
return False return False
# "taxref"
if self.command.ident == self.config["commands"][0]: if self.command.ident == self.config["commands"][0]:
self.search_by_name(self.command.content, event.target) self.search_by_name(self.command.content, event.target)
# "scientifize"
if self.command.ident == self.config["commands"][1]:
self.find_scientific_name(self.command.content, event.target)
return True return True
def search_by_name(self, name, target): def search_by_name(self, name, target):
"""Get species data from a scientific name.
Try to disambiguate the results by focusing on species only and their
scientific name.
"""
name = name.lower() name = name.lower()
enc_name = urllib.parse.quote(name) enc_name = urllib.parse.quote(name)
url = ( url = (
@ -66,7 +75,8 @@ class TaxrefPlugin(Plugin):
if item["scientificName"].lower() == name if item["scientificName"].lower() == name
] ]
if len(species_with_same_name) != 1: if len(species_with_same_name) != 1:
self.show_ambiguous_reply(species_items, target) reply = self.get_ambiguous_reply(species_items)
self.bot.say(target, reply)
return return
item_to_use = species_with_same_name[0] item_to_use = species_with_same_name[0]
@ -80,9 +90,10 @@ class TaxrefPlugin(Plugin):
) )
self.bot.say(target, reply) self.bot.say(target, reply)
self.show_images(item_to_use, target) if (images_reply := self.get_images_reply(item_to_use)):
self.bot.say(target, images_reply)
def show_ambiguous_reply(self, items, target): def get_ambiguous_reply(self, items):
"""Show a reply with potential species.""" """Show a reply with potential species."""
reply = self.config["ambiguous_reply"] reply = self.config["ambiguous_reply"]
append = "" append = ""
@ -92,25 +103,64 @@ class TaxrefPlugin(Plugin):
reply += ", ".join(item["scientificName"] for item in items) reply += ", ".join(item["scientificName"] for item in items)
if append: if append:
reply += append reply += append
self.bot.say(target, reply) return reply
def show_images(self, item, target): def get_images_reply(self, item):
"""If there are media available, show one!""" """If there are media available, return one in a message.
m_url = item.get("_links", {}) .get("media", {}) .get("href")
Return a string with an URL to an image if one is available, or an
None if no image could be found or we encountered an error.
"""
m_url = item.get("_links", {}).get("media", {}).get("href")
if not m_url: if not m_url:
return return None
response = requests.get(m_url) response = requests.get(m_url)
if response.status_code != 200: if response.status_code != 200:
self.signal_failure(target) return None
return
media_data = response.json() media_data = response.json()
items = media_data.get("_embedded", {}).get("media", []) items = media_data.get("_embedded", {}).get("media", [])
if not items: if not items:
return return None
random_item = random.choice(items) random_item = random.choice(items)
media_href = random_item.get("_links", {}).get("file", {}).get("href") media_href = random_item.get("_links", {}).get("file", {}).get("href")
if not media_href: if not media_href:
return None
return "📷 " + media_href
def find_scientific_name(self, name, target):
"""Find a corresponding scientific name for a vernacular name."""
name = name.lower()
enc_name = urllib.parse.quote(name)
url = (
f"{BASE_URL}/taxa/search?frenchVernacularNames={enc_name}"
"&page=1&size=100"
)
response = requests.get(url)
if response.status_code != 200:
self.signal_failure(target)
return return
self.bot.say(target, "📷 " + media_href) 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.
reply = items[0].get("scientificName")
else:
# More than one result? For simplicity sake, use the shrlok plugin
# if available or just show an ambiguous response.
if (shrlok := self.bot.get_plugin("shrlok")):
text = "\n".join(
f"{i['frenchVernacularName']}{i['scientificName']}"
for i in items
) + "\n"
reply = shrlok.post_text(text)
else:
reply = self.get_ambiguous_reply(items)
self.bot.say(target, reply)