From ddb5c1b193c0aa2adbb2bf300abbf8ab4c62b495 Mon Sep 17 00:00:00 2001 From: Adriene Hutchins Date: Mon, 23 Mar 2020 20:22:37 -0400 Subject: [PATCH] Split specialty code into new cog, fixed DMs issue --- extensions/botlist.py | 4 +- extensions/search.py | 280 +++++----------------------------------- extensions/specialty.py | 225 ++++++++++++++++++++++++++++++++ 3 files changed, 261 insertions(+), 248 deletions(-) create mode 100644 extensions/specialty.py diff --git a/extensions/botlist.py b/extensions/botlist.py index b5496f0..f06efa4 100644 --- a/extensions/botlist.py +++ b/extensions/botlist.py @@ -158,14 +158,14 @@ class BotList(commands.Cog, name='Bot List'): """Updates statistics on botlists.""" msg = await ctx.send(" **Updating...**") - responses = await self._update_logic() + await self._update_logic() await msg.edit(content="**Updated!**") @tasks.loop(minutes=30.0) async def update_stats(self): """Automatically updates statistics every 15 minutes.""" - responses = await self._update_logic() + await self._update_logic() def cog_unload(self): self.update_stats.cancel() diff --git a/extensions/search.py b/extensions/search.py index cdfa498..781bd71 100644 --- a/extensions/search.py +++ b/extensions/search.py @@ -9,12 +9,10 @@ import discord from discord.ext import commands import aiohttp import random -from urllib import parse -import sys from typing import List -class Search(commands.Cog): +class Search(commands.Cog, name="Basic"): """Searches the web for a variety of different resources.""" def __init__(self, bot): @@ -114,12 +112,14 @@ class Search(commands.Cog): else: amt = len(results) + # Remove no-no sites if not is_nsfw: for r in results[0:7]: for n in nono_sites: if n in r['url']: results.remove(r) + # Escape stuff query = discord.utils.escape_mentions(query) query = discord.utils.escape_markdown(query) @@ -186,271 +186,69 @@ class Search(commands.Cog): # Reached if passes all checks return True + async def _basic_search(self, ctx, query: str, + category: str = None): + """Base search message generation.""" + + async with ctx.typing(): + is_nsfw = ( + ctx.channel.is_nsfw() if hasattr(ctx.channel, 'is_nsfw') + else False + ) + + msg = await self._search_logic(query, is_nsfw, category) + await ctx.send(msg) + + await self.info( + content=( + f"**{ctx.author}** searched for `{query}` " + f"in \"{ctx.guild}\" and got this:" + f"\n\n{msg}" + ), + name="Search Results" + ) + @commands.command() async def search(self, ctx, *, query: str): """Search online for general results.""" - async with ctx.typing(): - msg = await self._search_logic(query, ctx.channel.is_nsfw()) - await self.info( - content=f"**{ctx.author}** searched for `{query}` in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - await ctx.send(msg) + await self._basic_search(ctx, query) @commands.command(aliases=['video']) async def videos(self, ctx, *, query: str): """Search online for videos.""" - async with ctx.typing(): - msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'videos') - await self.info( - content=f"**{ctx.author}** searched for `{query}` videos in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - await ctx.send(msg) + await self._basic_search(ctx, query, 'videos') @commands.command() async def music(self, ctx, *, query: str): """Search online for music.""" - async with ctx.typing(): - msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'music') - await self.info( - content=f"**{ctx.author}** searched for `{query}` music in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - await ctx.send(msg) + await self._basic_search(ctx, query, 'music') @commands.command(aliases=['file']) async def files(self, ctx, *, query: str): """Search online for files.""" - async with ctx.typing(): - msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'files') - await self.info( - content=f"**{ctx.author}** searched for `{query}` files in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - await ctx.send(msg) + await self._basic_search(ctx, query, 'files') @commands.command(aliases=['image']) async def images(self, ctx, *, query: str): """Search online for images.""" - # Handling - async with ctx.typing(): - msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'images') - await self.info( - content=f"**{ctx.author}** searched for `{query}` images in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - await ctx.send(msg) + await self._basic_search(ctx, query, 'images') @commands.command() async def it(self, ctx, *, query: str): """Search online for IT-related information.""" - # Handling - async with ctx.typing(): - msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'it') - await self.info( - content=f"**{ctx.author}** searched for `{query}` IT in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - await ctx.send(msg) + await self._basic_search(ctx, query, 'it') @commands.command(aliases=['map']) async def maps(self, ctx, *, query: str): """Search online for map information.""" - # Handling - async with ctx.typing(): - msg = await self._search_logic(query, ctx.channel.is_nsfw(), 'map') - await self.info( - content=f"**{ctx.author}** searched for `{query}` maps in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - await ctx.send(msg) - - @commands.command(aliases=['urban', 'ud']) - async def urbandictionary(self, ctx, *, query: str): - """Pull data from Urban Dictionary.""" - - # Handling - async with ctx.typing(): - number = 1 - if " | " in query: - query, number = query.rsplit(" | ", 1) - search = parse.quote(query) - async with aiohttp.ClientSession() as session: - async with session.get(f"http://api.urbandictionary.com/v0/define?term={search}") as resp: - resp = await resp.json() - if not resp["list"]: - await ctx.send(f"`{query}`` couldn't be found on Urban Dictionary.") - else: - try: - top_result = resp["list"][int(number) - 1] - embed = discord.Embed(title=top_result["word"], description=top_result["definition"][0:425] + "...", - url=top_result["permalink"], color=ctx.author.color) - if top_result["example"]: - embed.add_field(name="Example:", - value=top_result["example"][0:100] + "...", inline=False) - embed.add_field(name="👍", value = top_result["thumbs_up"]) - embed.add_field(name="👎", value = top_result["thumbs_down"]) - - - embed.set_author(name=top_result["author"], - icon_url="https://apprecs.org/gp/images/app-icons/300/2f/info.tuohuang.urbandict.jpg") - number = str(int(number) + 1) - embed.set_footer(text=str(len( - resp["list"])) + f" results were found. To see a different result, use {ctx.prefix}ud {query} | {number}.") - try: - - await ctx.send(f"**{top_result['word']}** - <{top_result['permalink']}>", embed=embed) - - except Exception as e: - await ctx.send(top_result["definition"]) - except Exception as e: - print(e) - - @commands.command() - async def anime(self, ctx, *, query: str): - """Lookup anime information online, uses the public API.""" - base = "https://kitsu.io/api/edge/" - # Handling - async with ctx.typing(): - async with aiohttp.ClientSession() as session: - async with session.get(base + "anime", params={"filter[text]": query}) as resp: - resp = await resp.json() - resp = resp['data'] - if not resp: - return await ctx.send("The requested anime coudn't be found") - - anime = resp[0] - title = f'{anime["attributes"]["canonicalTitle"]}' - anime_id = anime["id"] - url = f"https://kitsu.io/anime/{anime_id}" - thing = '' if not anime['attributes'][ - 'endDate'] else f' to {anime["attributes"]["endDate"]}' - - embed = discord.Embed( - title=f"{title}", color=ctx.author.color, url=url) - embed.description = anime["attributes"]["synopsis"][0:425] + "..." - embed.add_field(name="Average Rating", - value=anime["attributes"]["averageRating"]) - embed.add_field(name="Popularity Rank", - value=anime["attributes"]["popularityRank"]) - embed.add_field(name="Age Rating", - value=anime["attributes"]["ageRating"]) - embed.add_field( - name="Status", value=anime["attributes"]["status"]) - - embed.add_field( - name="Aired", value=f"{anime['attributes']['startDate']}{thing}") - embed.add_field(name="Episodes", - value=anime['attributes']["episodeCount"]) - embed.add_field( - name="Type", value=anime['attributes']["showType"]) - embed.set_thumbnail( - url=anime['attributes']["posterImage"]["original"]) - embed.set_footer( - text=f"Requested by {ctx.author.name} | Powered by kitsu.io", icon_url=ctx.author.avatar_url_as(format="png")) - try: - - await ctx.send(f"**{title}** - <{url}>", embed=embed) - - except Exception as e: - - aired = f"{anime['attributes']['startDate']}{thing}" - template = f""" -url: {url} -Title: {title} -Average Rating: {anime["attributes"]["averageRating"]} -Popularity Rank: {anime["attributes"]["popularityRank"]} -Age Rating: {anime["attributes"]["ageRating"]} -Status: {anime["attributes"]["status"]} -Aired: {aired} -Type: {anime['attributes']["showType"]} - - -Powered by kitsu.io""" - await ctx.send(template) - - await session.close() - - @commands.command() - async def manga(self, ctx, *, query: str): - """Lookup manga information online, uses the public API.""" - base = "https://kitsu.io/api/edge/" - # Handling - async with ctx.typing(): - async with aiohttp.ClientSession() as session: - async with session.get(base + "manga", params={"filter[text]": query}) as resp: - resp = await resp.json() - resp = resp['data'] - if not resp: - return await ctx.send("The requested manga coudn't be found") - - manga = resp[0] - title = f'{manga["attributes"]["canonicalTitle"]}' - manga_id = manga["id"] - url = f"https://kitsu.io/manga/{manga_id}" - - embed = discord.Embed( - title=f"{title}", color=ctx.author.color, url=url) - embed.description = manga["attributes"]["synopsis"][0:425] + "..." - if manga["attributes"]["averageRating"]: - embed.add_field(name="Average Rating", - value=manga["attributes"]["averageRating"]) - embed.add_field(name="Popularity Rank", - value=manga["attributes"]["popularityRank"]) - if manga["attributes"]["ageRating"]: - embed.add_field(name="Age Rating", - value=manga["attributes"]["ageRating"]) - embed.add_field( - name="Status", value=manga["attributes"]["status"]) - thing = '' if not manga['attributes'][ - 'endDate'] else f' to {manga["attributes"]["endDate"]}' - embed.add_field( - name="Published", value=f"{manga['attributes']['startDate']}{thing}") - if manga['attributes']['chapterCount']: - embed.add_field(name="Chapters", - value=manga['attributes']["chapterCount"]) - embed.add_field( - name="Type", value=manga['attributes']["mangaType"]) - embed.set_thumbnail( - url=manga['attributes']["posterImage"]["original"]) - - try: - - await ctx.send(f"**{title}** - <{url}>", embed=embed) - - except Exception as e: - - aired = f"{manga['attributes']['startDate']}{thing}" - template = f""" -url: {url} -Title: {title} -Average Rating: {manga["attributes"]["averageRating"]} -Popularity Rank: {manga["attributes"]["popularityRank"]} -Age Rating: {manga["attributes"]["ageRating"]} -Status: {manga["attributes"]["status"]} -Aired: {aired} -Type: {manga['attributes']["showType"]} - - -Powered by kitsu.io""" - await ctx.send(template) - - await session.close() + await self._basic_search(ctx, query, 'maps') @commands.command() @commands.is_owner() @@ -493,19 +291,9 @@ Powered by kitsu.io""" # Prepares term term = ctx.message.content.replace(ctx.prefix, '', 1) term = term.lstrip(' ') + # Does search - is_nsfw = ctx.channel.is_nsfw() if hasattr(ctx.channel, 'is_nsfw') else False - msg = await self._search_logic(term, is_nsfw) - - # Logging - await self.info( - content=f"**{ctx.author}** searched for `{term}` in \"{ctx.guild}\" and got this:" - f"\n\n{msg}", - name="Search Results" - ) - - # Sends result - await ctx.send(msg) + await self._basic_search(ctx, term) def setup(bot): diff --git a/extensions/specialty.py b/extensions/specialty.py new file mode 100644 index 0000000..eac9b9b --- /dev/null +++ b/extensions/specialty.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- + +# Search Functionality +# Provides search results from SearX + +'''Search Cog''' + +import discord +from discord.ext import commands +import aiohttp +from urllib import parse + + +class SpecialtySearch(commands.Cog, name="Specialty"): + """Provides specialty search tools for various different specific sites.""" + + def __init__(self, bot): + + # Main Stuff + self.bot = bot + self.info = bot.logging.info + self.warn = bot.logging.warn + self.request = bot.request + self.emoji = "\u2728" + + @commands.command(aliases=['urban', 'ud']) + async def urbandictionary(self, ctx, *, query: str): + """Look up terms on Urban Dictionary.""" + + # Handling + async with ctx.typing(): + + number = 1 + + if " | " in query: + query, number = query.rsplit(" | ", 1) + search = parse.quote(query) + + async with self.request.get(f"http://api.urbandictionary.com/v0/define?term={search}") as resp: + + resp = await resp.json() + + query = discord.utils.escape_mentions(query) + query = discord.utils.escape_markdown(query) + + if not resp["list"]: + await ctx.send(f"`{query}`` couldn't be found on Urban Dictionary.") + else: + try: + top_result = resp["list"][int(number) - 1] + embed = discord.Embed( + title=top_result["word"], + description=top_result["definition"][0:425] + "...", + url=top_result["permalink"], + color=ctx.author.color + ) + if top_result["example"]: + embed.add_field(name="Example:", + value=top_result["example"][0:100] + "...", inline=False) + embed.add_field( + name="👍", value=top_result["thumbs_up"]) + embed.add_field( + name="👎", value=top_result["thumbs_down"]) + + embed.set_author(name=top_result["author"], + icon_url="https://apprecs.org/gp/images/app-icons/300/2f/info.tuohuang.urbandict.jpg") + number = str(int(number) + 1) + embed.set_footer(text=str(len( + resp["list"])) + f" results were found. To see a different result, use {ctx.prefix}ud {query} | {number}.") + try: + + await ctx.send( + f"**{top_result['word']}** - " + f"<{top_result['permalink']}>", + embed=embed + ) + + except Exception: + await ctx.send(top_result["definition"]) + except Exception as e: + print(e) + + @commands.command() + async def anime(self, ctx, *, query: str): + """Look up anime information.""" + base = "https://kitsu.io/api/edge/" + + # Handling + async with ctx.typing(): + async with self.request.get(base + "anime", params={"filter[text]": query}) as resp: + + resp = await resp.json() + resp = resp['data'] + + query = discord.utils.escape_mentions(query) + query = discord.utils.escape_markdown(query) + + if not resp: + return await ctx.send(f"No results for `{query}`.") + + anime = resp[0] + title = f'{anime["attributes"]["canonicalTitle"]}' + anime_id = anime["id"] + url = f"https://kitsu.io/anime/{anime_id}" + thing = '' if not anime['attributes'][ + 'endDate'] else f' to {anime["attributes"]["endDate"]}' + + embed = discord.Embed( + title=f"{title}", + color=ctx.author.color, + rl=url + ) + embed.description = anime["attributes"]["synopsis"][0:425] + "..." + embed.add_field(name="Average Rating", + value=anime["attributes"]["averageRating"]) + embed.add_field(name="Popularity Rank", + value=anime["attributes"]["popularityRank"]) + embed.add_field(name="Age Rating", + value=anime["attributes"]["ageRating"]) + embed.add_field( + name="Status", value=anime["attributes"]["status"]) + + embed.add_field( + name="Aired", value=f"{anime['attributes']['startDate']}{thing}") + embed.add_field(name="Episodes", + value=anime['attributes']["episodeCount"]) + embed.add_field( + name="Type", value=anime['attributes']["showType"]) + embed.set_thumbnail( + url=anime['attributes']["posterImage"]["original"]) + embed.set_footer( + text=f"Requested by {ctx.author.name} | Powered by kitsu.io", icon_url=ctx.author.avatar_url_as(format="png")) + try: + + await ctx.send(f"**{title}** - <{url}>", embed=embed) + + except Exception as e: + + aired = f"{anime['attributes']['startDate']}{thing}" + template = f""" +url: {url} +Title: {title} +Average Rating: {anime["attributes"]["averageRating"]} +Popularity Rank: {anime["attributes"]["popularityRank"]} +Age Rating: {anime["attributes"]["ageRating"]} +Status: {anime["attributes"]["status"]} +Aired: {aired} +Type: {anime['attributes']["showType"]} + + +Powered by kitsu.io""" + await ctx.send(template) + + @commands.command() + async def manga(self, ctx, *, query: str): + """Look up manga information.""" + + base = "https://kitsu.io/api/edge/" + + # Handling + async with ctx.typing(): + async with aiohttp.ClientSession() as session: + async with session.get(base + "manga", params={"filter[text]": query}) as resp: + + resp = await resp.json() + resp = resp['data'] + if not resp: + return await ctx.send("The requested manga coudn't be found") + + manga = resp[0] + title = f'{manga["attributes"]["canonicalTitle"]}' + manga_id = manga["id"] + url = f"https://kitsu.io/manga/{manga_id}" + + embed = discord.Embed( + title=f"{title}", color=ctx.author.color, url=url) + embed.description = manga["attributes"]["synopsis"][0:425] + "..." + if manga["attributes"]["averageRating"]: + embed.add_field(name="Average Rating", + value=manga["attributes"]["averageRating"]) + embed.add_field(name="Popularity Rank", + value=manga["attributes"]["popularityRank"]) + if manga["attributes"]["ageRating"]: + embed.add_field(name="Age Rating", + value=manga["attributes"]["ageRating"]) + embed.add_field( + name="Status", value=manga["attributes"]["status"]) + thing = '' if not manga['attributes'][ + 'endDate'] else f' to {manga["attributes"]["endDate"]}' + embed.add_field( + name="Published", value=f"{manga['attributes']['startDate']}{thing}") + if manga['attributes']['chapterCount']: + embed.add_field(name="Chapters", + value=manga['attributes']["chapterCount"]) + embed.add_field( + name="Type", value=manga['attributes']["mangaType"]) + embed.set_thumbnail( + url=manga['attributes']["posterImage"]["original"]) + + try: + + await ctx.send(f"**{title}** - <{url}>", embed=embed) + + except Exception as e: + + aired = f"{manga['attributes']['startDate']}{thing}" + template = f""" +url: {url} +Title: {title} +Average Rating: {manga["attributes"]["averageRating"]} +Popularity Rank: {manga["attributes"]["popularityRank"]} +Age Rating: {manga["attributes"]["ageRating"]} +Status: {manga["attributes"]["status"]} +Aired: {aired} +Type: {manga['attributes']["showType"]} + + +Powered by kitsu.io""" + await ctx.send(template) + + await session.close() + + +def setup(bot): + bot.add_cog(SpecialtySearch(bot))