Files
aikaterna-cogs/dictionary/dictionary.py
2021-04-07 11:48:42 -07:00

131 lines
4.6 KiB
Python

import aiohttp
from bs4 import BeautifulSoup
import logging
import re
from redbot.core import commands
from redbot.core.utils.chat_formatting import pagify
log = logging.getLogger("red.aikaterna.dictionary")
class Dictionary(commands.Cog):
"""Word, yo
Parts of this cog are adapted from the PyDictionary library."""
async def red_delete_data_for_user(self, **kwargs):
""" Nothing to delete """
return
def __init__(self, bot):
self.bot = bot
self.session = aiohttp.ClientSession()
def cog_unload(self):
self.bot.loop.create_task(self.session.close())
async def _get_soup_object(self, url):
try:
async with self.session.request("GET", url) as response:
return BeautifulSoup(await response.text(), "html.parser")
except Exception:
log.error("Error fetching dictionary.py related webpage", exc_info=True)
return None
@commands.command()
async def antonym(self, ctx, *, word: str):
"""Displays antonyms for a given word."""
search_term = word.split(" ", 1)[0]
result = await self._antonym(ctx, search_term)
if not result:
await ctx.send("This word is not in the dictionary.")
return
result_text = "*, *".join(result)
msg = f"Antonyms for **{search_term}**: *{result_text}*"
for page in pagify(msg, delims=["\n"]):
await ctx.send(page)
async def _antonym(self, ctx, word):
data = await self._get_soup_object(f"http://www.thesaurus.com/browse/{word}")
if not data:
return await ctx.send("Error fetching data.")
section = data.find_all("ul", {"class": "css-1dnnh8h e1ccqdb60"})
antonyms = section[0].text.split()
return antonyms
@commands.command()
async def define(self, ctx, *, word: str):
"""Displays definitions of a given word."""
search_msg = await ctx.send("Searching...")
search_term = word.split(" ", 1)[0]
result = await self._definition(ctx, search_term)
str_buffer = ""
if not result:
await search_msg.delete()
await ctx.send("This word is not in the dictionary.")
return
for key in result:
str_buffer += f"\n**{key}**: \n"
counter = 1
j = False
for val in result[key]:
if val.startswith("("):
str_buffer += f"{str(counter)}. *{val})* "
counter += 1
j = True
else:
if j:
str_buffer += f"{val}\n"
j = False
else:
str_buffer += f"{str(counter)}. {val}\n"
counter += 1
await search_msg.delete()
for page in pagify(str_buffer, delims=["\n"]):
await ctx.send(page)
async def _definition(self, ctx, word):
data = await self._get_soup_object(f"http://wordnetweb.princeton.edu/perl/webwn?s={word}")
if not data:
return await ctx.send("Error fetching data.")
types = data.findAll("h3")
length = len(types)
lists = data.findAll("ul")
out = {}
if not lists:
return
for a in types:
reg = str(lists[types.index(a)])
meanings = []
for x in re.findall(r">\s\((.*?)\)\s<", reg):
if "often followed by" in x:
pass
elif len(x) > 5 or " " in str(x):
meanings.append(x)
name = a.text
out[name] = meanings
return out
async def _synonym(self, ctx, word):
data = await self._get_soup_object(f"http://www.thesaurus.com/browse/{word}")
if not data:
return await ctx.send("Error fetching data.")
section = data.find_all("ul", {"class": "css-1l7o0dd e1ccqdb60"})
synonyms = section[0].text.split()
return synonyms
@commands.command()
async def synonym(self, ctx, *, word: str):
"""Displays synonyms for a given word."""
search_term = word.split(" ", 1)[0]
result = await self._synonym(ctx, search_term)
if not result:
await ctx.send("This word is not in the dictionary.")
return
result_text = "*, *".join(result)
msg = f"Synonyms for **{search_term}**: *{result_text}*"
for page in pagify(msg, delims=["\n"]):
await ctx.send(page)