Chitanda-Bot / cogs /utilities.py
E5K7's picture
Initial commit: Discord bot with hybrid commands, Flask keep-alive, and Docker support
7cc32a6
import discord
from discord.ext import commands
import random
import requests
from datetime import timedelta
import re
import json
import asyncio
import os
from datetime import datetime
from dateutil.relativedelta import relativedelta
import bs4
import wikipedia
import html
import aiohttp
from cogs.functions import *
bot_embed_color = 0x4548a8
with open('config.json') as f:
config = json.load(f)
UNITS = {'s':'seconds', 'm':'minutes', 'h':'hours', 'd':'days', 'w':'weeks'}
def convert_to_seconds(s):
return int(timedelta(**{
UNITS.get(m.group('unit').lower(), 'seconds'): float(m.group('val'))
for m in re.finditer(r'(?P<val>\d+(\.\d+)?)(?P<unit>[smhdw]?)', s, flags=re.I)
}).total_seconds())
extreme_ip_api_key = os.getenv('EXTREME_IP_API_KEY')
timezone_api_key = os.getenv('TIMEZONE_API_KEY')
edamam_api_recipe_app_id = os.getenv('EDAMAM_API_RECIPE_APP_ID')
edamam_api_recipe_app_key = os.getenv('EDAMAM_API_RECIPE_APP_KEY')
class Utilities(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command()
async def ping(self, ctx):
"""Check the bot's latency"""
latency = round(self.bot.latency * 1000)
embed = discord.Embed(
title="🏓 Pong!",
description=f"Latency: `{latency}ms`",
color=bot_embed_color
)
await ctx.reply(embed=embed)
@commands.hybrid_command(aliases=['ethereum'])
async def eth(self, ctx):
"""Get current Ethereum price"""
r = requests.get('https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD,EUR')
r = r.json()
usd = r['USD']
eur = r['EUR']
em = discord.Embed(description=f'USD: `{str(usd)}$`\nEUR: `{str(eur)}€`')
em.set_author(name='Ethereum', icon_url='https://cdn.disnakeapp.com/attachments/271256875205525504/374282740218200064/2000px-Ethereum_logo.png')
await ctx.reply(embed=em)
@commands.hybrid_command(aliases=['bitcoin'])
async def btc(self, ctx):
"""Get current Bitcoin price"""
r = requests.get('https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD,EUR')
r = r.json()
usd = r['USD']
eur = r['EUR']
em = discord.Embed(description=f'USD: `{str(usd)}$`\nEUR: `{str(eur)}€`')
em.set_author(name='Bitcoin', icon_url='https://cdn.discordapp.com/attachments/271256875205525504/374282740218200064/2000px-Ethereum_logo.png')
await ctx.reply(embed=em)
@commands.hybrid_command()
async def pingweb(self, ctx, website: str):
"""Check if a website is up"""
if website is None:
embed=discord.Embed(title="Error!", description="You didn't enter a website to ping for ;-;", color=0x243e7b)
await ctx.send(embed=embed)
else:
try:
r = requests.get(website).status_code
except Exception as e:
await ctx.send(f'''Error raised :- ```{e}```''')
if r == 404:
await ctx.send(f'Site is down, responded with a status code of {r}')
else:
await ctx.send(f'Site is up, responded with a status code of {r}')
@commands.hybrid_command(aliases=['pfp', 'avatar'])
async def av(self, ctx, *, user: discord.Member):
"""Get a user's avatar"""
av = user.display_avatar.url
embed = discord.Embed(title="{}'s pfp".format(user.name), description="Here it is!", color=bot_embed_color)
embed.set_image(url=av)
await ctx.send(embed=embed)
@commands.hybrid_command(aliases=['server', 'serverinfo'])
async def sinfo(self, ctx):
"""Get server information"""
embed = discord.Embed(title=f"{ctx.guild.name}", description="Here is the server info :-", color=bot_embed_color)
embed.add_field(name="Server created at", value=f"{ctx.guild.created_at}")
embed.add_field(name="Server Owner", value=f"{ctx.guild.owner}")
embed.add_field(name="Member Count", value=f"{ctx.guild.member_count}")
embed.add_field(name="Server ID", value=f"{ctx.guild.id}")
embed.set_thumbnail(url=ctx.guild.icon.url if ctx.guild.icon else None)
await ctx.reply(embed=embed)
@commands.hybrid_command(aliases = ["timezone", "timing"])
async def time(self, ctx, * , location: str):
"""Get current time for a location"""
details = location.replace(" ", "+")
r = requests.get(f"https://timezone.abstractapi.com/v1/current_time/?api_key={timezone_api_key}&location={details}")
res = r.json()
timezone_location = str(res['timezone_location'])
raw_time = str(res['datetime'])
datetime_time = datetime.strptime(raw_time, "%Y-%m-%d %H:%M:%S")
time = str(datetime_time.strftime("%I:%M %p"))
date = str(datetime_time.strftime("%d %B %Y"))
embedVar = discord.Embed(title=f"Time in {location} is {time}", description=f'''{date}\nTimezone - {timezone_location}''', color=bot_embed_color)
embedVar.set_thumbnail(url="https://i.pinimg.com/originals/26/be/b0/26beb09153b8df233d82e66bef3edfbb.jpg")
await ctx.reply(embed=embedVar)
@commands.hybrid_command()
async def recipe(self, ctx, *, food_name: str):
"""Search for a recipe"""
food = food_name.replace(" ", "+")
api_url = f"https://api.edamam.com/api/recipes/v2?type=public&q={food}&app_id={edamam_api_recipe_app_id}&app_key={edamam_api_recipe_app_key}"
async with aiohttp.ClientSession() as session:
async with session.get(api_url) as resp:
res = await resp.json()
ing = res['hits'][0]['recipe']['ingredients']
naam = res["hits"][0]["recipe"]["label"]
url = res["hits"][0]["recipe"]["url"]
image = res["hits"][0]["recipe"]["image"]
inge = ""
for ingredient in ing:
inge += f"{ingredient['text']}\n-------\n"
embed = discord.Embed(title=naam, url=url, description=inge, color=bot_embed_color)
embed.set_thumbnail(url=image)
await ctx.reply(embed=embed)
@commands.hybrid_command(aliases=['geolocate', 'iptogeo', 'iptolocation', 'ip2geo', 'ip'])
async def geoip(self, ctx, *, ipaddr: str = '1.3.3.7'):
"""Get geolocation info for an IP address"""
r = requests.get(f'http://extreme-ip-lookup.com/json/{ipaddr}?key={extreme_ip_api_key}')
geo = r.json()
em = discord.Embed()
fields = [
{'name': 'IP', 'value': geo['query']},
{'name': 'ipType', 'value': geo['ipType']},
{'name': 'Country', 'value': geo['country']},
{'name': 'City', 'value': geo['city']},
{'name': 'Continent', 'value': geo['continent']},
{'name': 'Country', 'value': geo['country']},
{'name': 'IPName', 'value': geo['ipName']},
{'name': 'ISP', 'value': geo['isp']},
{'name': 'Latitute', 'value': geo['lat']},
{'name': 'Longitude', 'value': geo['lon']},
{'name': 'Org', 'value': geo['org']},
{'name': 'Region', 'value': geo['region']},
{'name': 'Status', 'value': geo['status']},
]
for field in fields:
if field['value']:
em.add_field(name=field['name'], value=field['value'], inline=True)
return await ctx.send(embed=em)
@commands.hybrid_command(aliases=['wikiped', 'wikipedia'])
async def wiki(self, ctx, *, query: str):
"""Search Wikipedia"""
global wikipedia_language
wikipedia_language = "en"
try:
page=wikipedia.page(wikipedia.search(query)[0])
except wikipedia.exceptions.DisambiguationError as e:
counter=0
while page is None:
try:
page=wikipedia.page(e.options[counter])
except:
counter+=1
except IndexError as e:
await ctx.send(languages[guild_language.setdefault(str(ctx.guild.id), "en")]["wikipedia_page_error"])
print(e)
return
summary=page.summary.split("\n")[0]
if len(summary)>2048:
summary=summary[:2045]+"..."
embed=discord.Embed(colour=0xfefefe,
title=page.title,
description=summary,
url=page.url,)
embed.set_author(name="Wikipedia",
icon_url="https://upload.wikimedia.org/wikipedia/commons/d/de/Wikipedia_Logo_1.0.png",
url="https://www.wikipedia.org/")
if page.images:
embed.set_thumbnail(url=page.images[0])
await ctx.send(embed=embed)
@commands.hybrid_command()
async def truth(self, ctx, rating: str = None):
"""Get a truth question (ratings: pg, pg13, r)"""
if rating is None:
r = requests.get(f"https://api.truthordarebot.xyz/api/truth")
res = r.json()
Tile = f"Here is a truth for you"
Desc = res['question']
embed=discord.Embed(title=Tile, description=Desc, color=bot_embed_color)
await ctx.reply(embed=embed)
else:
try:
r = requests.get(f"https://api.truthordarebot.xyz/api/truth/?rating={rating}")
res = r.json()
Tile = f"Here is a {rating} rated question for you"
Desc = res['question']
embed=discord.Embed(title=Tile, description=Desc, color=bot_embed_color)
await ctx.reply(embed=embed)
except:
await ctx.reply("Please send a valid rating!! Valid parameters are `pg`,`pg13`,`r`")
@commands.hybrid_command()
async def question(self, ctx):
"""Get a random trivia question"""
r = requests.get('https://opentdb.com/api.php?amount=1')
res = json.loads(r.text)
question1 = res['results'][0]['question']
question = html.unescape(question1)
correct_answer = res['results'][0]['correct_answer']
category = res['results'][0]['category']
difficulty = res['results'][0]['difficulty']
em = discord.Embed(title=category, description=question,colour=bot_embed_color)
em.add_field(name="Correct Answer :-", value=f"||{correct_answer}||")
em.set_footer(text=f"Difficulty : {difficulty}")
await ctx.reply(embed=em)
@commands.hybrid_command()
async def dare(self, ctx, rating: str = None):
"""Get a dare (ratings: pg, pg13, r)"""
if rating is None:
r = requests.get(f"https://api.truthordarebot.xyz/api/dare")
res = r.json()
Tile = f"Here is a dare for you"
Desc = res['question']
embed=discord.Embed(title=Tile, description=Desc, color=bot_embed_color)
await ctx.reply(embed=embed)
else:
try:
r = requests.get(f"https://api.truthordarebot.xyz/api/dare/?rating={rating}")
res = r.json()
Tile = f"Here is a {rating} rated question for you"
Desc = res['question']
embed=discord.Embed(title=Tile, description=Desc, color=bot_embed_color)
await ctx.reply(embed=embed)
except:
await ctx.reply("Please send a valid rating!! Valid parameters are `pg`,`pg13`,`r`")
@commands.hybrid_command()
async def pypi(self, ctx, package: str):
"""Search for a Python package on PyPI"""
r = requests.get(f"https://pypi.org/pypi/{package}/json")
try:
res = r.json()
author = res['info']['author']
embed = discord.Embed(title=res['info']['name'], url = f"https://pypi.org/project/{package}/", description=f"{res['info']['summary']}\n\n\n", color=bot_embed_color)
embed.set_author(name="PyPI", url="https://pypi.org/", icon_url="https://thumbs.dreamstime.com/b/python-icon-filled-python-icon-website-design-mobile-app-development-python-icon-filled-development-collection-155362649.jpg")
embed.add_field(name="More Details :- \n\n", value=res['info']['home_page'], inline=False)
embed.set_thumbnail(url=f"https://pypi.org/static/images/twitter.6fecba6f.jpg")
await ctx.reply(embed=embed)
except:
embed = discord.Embed(title="Package Not Found!", description="Please check the spelling of the package name and try again!", color=bot_embed_color)
await ctx.reply(embed=embed)
@commands.hybrid_command()
async def remind(self, ctx, time: str = None, *, reminder: str = None):
"""Set a reminder"""
time = convert_to_seconds(s=time)
if time > 0:
embedVar = discord.Embed(title=f"Reminding in {time} seconds!", description=f"Reason: {reminder}", color=bot_embed_color)
await ctx.reply(embed=embedVar)
await asyncio.sleep(time)
embed = discord.Embed(title=f"Reminder!", description=f"Reason: {reminder}", color=bot_embed_color)
await ctx.reply(f"{ctx.author.mention}", embed=embed)
else:
embed = discord.Embed(title="Invalid Time!", description="Please enter a valid time!", color=bot_embed_color)
await ctx.reply(embed=embed)
@commands.hybrid_command(aliases=['gni', 'gno', 'recognise', 'recognize'])
async def musicrecognise(self, ctx, *, musicurl: str = None):
"""Recognize a song from audio file or URL"""
if musicurl is None:
if not ctx.message.attachments:
await ctx.reply("Please provide a music file or a link to a music file!")
return
attachment = ctx.message.attachments[0]
musicurl = attachment.url
await download_mp3(musicurl)
data = await music_recognition("./assets/audio.mp3")
em = discord.Embed(title=data['songname'], url=data['yturl'], color=bot_embed_color)
em.description = data['artist']
em.set_thumbnail(url=data['thumbnail'])
await ctx.reply(embed=em)
async def setup(bot):
await bot.add_cog(Utilities(bot))