Compare commits

...

30 commits

Author SHA1 Message Date
Robert 53414148a2 removed number reactions 2020-03-24 16:58:03 +01:00
Robert 6b0c044c40 Safety features 2020-03-24 16:23:22 +01:00
Robert 444957dddf Changed Wolfram input 2020-02-20 23:58:09 +01:00
Robert 526d9d72ef Added Wolfram! 2020-02-20 22:52:00 +01:00
Robert 5c4c6631ba added rnn 2020-02-05 17:04:49 +01:00
Robert 03fc4cadff Added gridlines to graph 2020-02-03 16:41:30 +01:00
root a4aaa134bb Changed conversion 2020-02-02 14:41:45 +01:00
Lauchmelder23 e12609a6be Nothing 2020-02-01 23:13:56 +01:00
Robert a7a92f5b51 Added encryption 2020-01-22 21:22:20 +01:00
Robert a3e318d4e5 added math 2020-01-12 17:32:24 +01:00
root bd8cfa44d4 New inspirobot alias, fixed timezone 2020-01-11 21:43:38 +01:00
Robert Altner b9b2b5c8b8 added responses 2020-01-11 21:31:50 +01:00
Robert Altner 6cfa3c5210 enhanced schedule 2020-01-11 20:01:14 +01:00
Robert Altner 8a4ef6947a enhanced schedule 2020-01-11 19:59:19 +01:00
Robert Altner 83b59c0fbc changed USA 2020-01-11 17:34:27 +01:00
Robert Altner 8f70e65b92 improved smart 2020-01-10 21:15:10 +01:00
Robert Altner 72f6bb2fd3 improved smart 2020-01-10 20:23:22 +01:00
Robert Altner 956d5eef3f added smartness 2020-01-10 19:39:45 +01:00
Robert 584d1e1914 added scheduling 2020-01-09 03:26:59 +01:00
Robert 01d75cf600 added responses 2020-01-09 03:03:18 +01:00
Robert 0ee1c17a07 changed quotes API 2020-01-09 02:42:35 +01:00
Robert f786f29141 added quotes..... 2020-01-09 02:36:45 +01:00
Robert 08cc01ca70 tweaked carbon cooldown 2020-01-09 00:03:16 +01:00
Robert 28ccb8b10f added cooldown to carbon 2020-01-08 23:53:04 +01:00
Robert 81c299dffb Added carbon API! 2020-01-08 23:49:57 +01:00
Robert 75d5a3c664 Added help command 2020-01-08 21:18:17 +01:00
Robert 5a440d91ab Fixed infentation bug 2020-01-08 17:56:11 +01:00
Robert 3724ff485e Removed leftover pring statement 2020-01-08 17:54:04 +01:00
Robert b23fa1aa60 Improved Translation 2020-01-08 17:44:19 +01:00
Robert 937dd76fe7 Added translations 2020-01-08 17:09:10 +01:00
27 changed files with 720 additions and 17 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
*.json
*.txt
*.png
__pycache__

81
api/carbon.py Normal file
View file

@ -0,0 +1,81 @@
import requests
import numpy as np
import matplotlib.pyplot as plt
import datetime
from util import logging
def current_level() -> []:
url = "https://api.carbonintensity.org.uk/intensity"
response = requests.get(url)
if not response.ok:
logging.error(f"Failed to access Carbon API: {response.status_code} [{url}]")
data = response.json()["data"][0]
return [data["from"], data["intensity"]["forecast"], data["intensity"]["actual"], data["intensity"]["index"]]
def level_at(date: str) -> []:
url = f"https://api.carbonintensity.org.uk/intensity/date/{date}"
response = requests.get(url)
if not response.ok:
logging.error(f"Failed to access Carbon API: {response.status_code} [{url}]")
return []
if len(response.json()["data"]) == 0:
return []
data = response.json()["data"][0]
return [data["from"], data["intensity"]["forecast"], data["intensity"]["actual"], data["intensity"]["index"]]
def level_from_to(start: str, stop: str) -> str:
url = f"https://api.carbonintensity.org.uk/intensity/{start}/{stop}"
response = requests.get(url)
if not response.ok:
logging.error(f"Failed to access Carbon API: {response.status_code} [{url}]")
return ""
if len(response.json()["data"]) == 0:
return []
data = response.json()["data"]
x = []
measured = []
indices = []
for i in range(len(data)):
intensity = data[i]["intensity"]
x.append(datetime.datetime.strptime(data[i]["from"], "%Y-%m-%dT%H:%MZ"))
measured.append(intensity["actual"])
indices.append(intensity["index"])
curr_color = indices[0]
curr_color_index = 0
for i in range(len(measured)):
if indices[i] != curr_color:
color = ""
if curr_color == "very low":
color = "#5bcc32"
if curr_color == "low":
color = "#87cc32"
if curr_color == "moderate":
color = "#ccc932"
if curr_color == "high":
color = "#cc8e32"
if curr_color == "very high":
color = "#cc4f32"
plt.plot(x[curr_color_index:i+1], measured[curr_color_index:i+1], color)
curr_color_index = i
curr_color = indices[i]
plt.xlabel("Time & Date")
plt.ylabel("Carbon Intensity [gCO2/kWh]")
plt.xticks(rotation=45)
plt.gcf().subplots_adjust(bottom=0.2)
plt.grid(b=True)
plt.savefig("plot.png")
plt.clf()
return "plot.png"

14
api/quote.py Normal file
View file

@ -0,0 +1,14 @@
import requests
import random
from util import logging
def fetch_quote() -> tuple:
url = "https://favqs.com/api/qotd"
response = requests.get(url)
if not response.ok:
logging.error(f"Failed to access Quotes API: {response.status_code} [{url}]")
return ()
data = response.json()
return (data["quote"]["body"], data["quote"]["author"])

72
api/thesaurus.py Normal file
View file

@ -0,0 +1,72 @@
import requests
import re, random
import nltk
import threading, queue
from util import logging, config
key = config.settings["api_keys"]["thesaurus"]
url = f"http://thesaurus.altervista.org/thesaurus/v1?key={key}&language=en_US&output=json&word="
def start_thread(target, args):
q = queue.Queue()
def wrapper():
q.put(target(args))
t = threading.Thread(target=wrapper)
t.start()
return q
def thesaurufy_sentence(sentence):
symbols = nltk.word_tokenize(sentence)
tags = nltk.pos_tag(symbols)
if len(symbols) == 0:
return ""
queues = []
for i in range(0, len(symbols)):
queues.append(start_thread(target = handle_token, args=(tags[i])))
for i in range(0, len(symbols)):
symbols[i] = queues[i].get()
return "".join(symbols)
def handle_token(args):
token = args
if not token[0].isalpha():
return token[0]
if token[1] != "NN" and token[1] != "VB" and token[1] != "VBG" and token[1] != "VBP" and token[1] != "JJ" and token[1] != "RB":
return (" " + token[0])
response = requests.get(url + token[0])
if not response.ok:
# logging.warning(f"Thesaurus API returned {response.status_code} ({url + token[0]})")
return (" " + token[0])
responses = response.json()["response"]
condition = ""
if token[1] == "JJ":
condition = "(adj)"
elif token[1] == "RB":
condition = "(adv)"
elif token[1] == "NN":
condition = "(noun)"
else:
condition = "(verb)"
try:
words = random.choice([a for a in responses if a["list"]["category"] == condition])["list"]["synonyms"].split("|")
except:
return (" " + token[0])
# print(words)
word = words[random.randint(0, len(words) - 1)]
if "(" in word:
if "antonym" in word.split("(")[1].lower():
return (" " + token[0])
word = word.split("(")[0][:-1]
return (" " + word)

50
api/translation.py Normal file
View file

@ -0,0 +1,50 @@
'''
This file provides the functionality for
the translation function, by first converting the
country/language name to an ISO369-1 language identifier
and then translating it using the Yandex Translation API
'''
import requests, urllib.parse
from util import logging, config
import pycountry
api_key = config.settings["api_keys"]["yandex"]
langs = pycountry.languages
def name_to_ISO(name: str) -> str:
alpha = ""
for language in langs:
if language.name.lower() == name.lower():
try:
alpha = language.alpha_2
break
except:
logging.warning(f"Tried to get alpha2 code of unknown language {language}")
return alpha
def ISO_to_name(ISO: str) -> str:
name = ""
for language in langs:
try:
if language.alpha_2.lower() == ISO.lower():
try:
name = language.name
break
except:
logging.warning(f"Tried to get name of unknown language code {ISO}")
except:
# i dont care tbh
pass
return name
def translate(text: str, lang: str) -> (str, str):
url_encoded_text = urllib.parse.quote(text)
url = f"https://translate.yandex.net/api/v1.5/tr.json/translate?key={api_key}&text={url_encoded_text}&lang={lang}"
response = requests.get(url)
if not response.ok:
logging.error(f"Failed to contact Yandex API: {response.status_code}")
return ""
return (response.json()["text"][0], response.json()["lang"])

20
bot.py
View file

@ -23,7 +23,7 @@ logging.info(f"Total {total}, Failed {failed}\n")
client = commands.Bot(command_prefix=config.settings["prefix"], case_insensitive=True)
@client.command()
@client.command(name="load", description="Loads a cog", usage="load <Cog>")
@commands.is_owner()
async def load(ctx : commands.Context, extension : str):
try:
@ -32,7 +32,7 @@ async def load(ctx : commands.Context, extension : str):
except:
await ctx.message.add_reaction("👎")
@client.command()
@client.command(name="unload", description="Unoads a cog", usage="unload <Cog>")
@commands.is_owner()
async def unload(ctx : commands.Context, extension : str):
try:
@ -41,7 +41,7 @@ async def unload(ctx : commands.Context, extension : str):
except:
await ctx.message.add_reaction("👎")
@client.command()
@client.command(name="reload", description="Reoads a cog", usage="reload <Cog>")
@commands.is_owner()
async def reload(ctx : commands.Context, extension : str):
try:
@ -59,6 +59,20 @@ async def on_ready():
total = 0
failed = 0
# Load all cogs on startup
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
total += 1
cog = f"cogs.{filename[:-3]}"
try:
client.load_extension(cog)
logging.info(f"Trying {cog}.....Success!")
except Exception as e:
logging.info(f"Trying {cog}.....Failed!")
logging.error(str(e))
failed += 1
# Load "fun" cogs
for filename in os.listdir("./cogs/fun"):
if filename.endswith(".py"):

40
cogs/api/carbon.py Normal file
View file

@ -0,0 +1,40 @@
import discord
from discord.ext import commands
from api import carbon
from util import embed
class Carbon(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.group(name="carbon", usage="carbon [subcommand]", description="Can accumulate data about carbon levels in the UK")
@commands.cooldown(1, 5)
async def carbon(self, ctx):
pass
@carbon.command(name="now", usage="carbon now", description="Gets the latest available carbon intensity data")
async def now(self, ctx):
data = carbon.current_level()
await ctx.send(embed=embed.make_embed_fields_footer("Carbon intensity in the UK", f"The current carbon intensity is considered **{data[3]}**.", f"{data[0]} | All values in gCO2/kWh", ("Measured", data[2]), ("Predicted", data[1])))
@carbon.command(name="at", usage="carbon at <Date>", description="Gets the carbon levels at the given date (YYYY-MM-DD)")
async def at(self, ctx: discord.Client, date: str):
data = carbon.level_at(date)
if len(data) == 0:
await ctx.send(embed=embed.make_error_embed(f"There is no data available for {date}."))
else:
await ctx.send(embed=embed.make_embed_fields_footer("Carbon intensity in the UK", f"The carbon intensity for that date is considered **{data[3]}**.", f"{data[0]} | All values in gCO2/kWh", ("Measured", data[2]), ("Predicted", data[1])))
@carbon.command(name="during", usage="carbon during <Start> <Stop>", description="Creates a diagram about carbon levels in the given time period (YYYY-MM-DD)")
@commands.cooldown(1, 25)
async def during(self, ctx: discord.Client, start: str, stop: str):
path = carbon.level_from_to(start, stop)
if path == "":
await ctx.send(embed=embed.make_error_embed(f"There is no data available for the given time period."))
else:
data = embed.make_embed_image("Carbon intensity in the UK", path)
await ctx.send(embed=data[0], file=data[1])
def setup(client: discord.Client):
client.add_cog(Carbon(client))

View file

@ -14,7 +14,7 @@ class Inspirobot(commands.Cog):
def __init__(self, client : discord.Client):
self.client = client
@commands.command(name="Inspirobot", description="Sends a randomly generated inspirational quote", aliases=["inspiration", "inspiro"])
@commands.command(name="inspirobot", description="Sends a randomly generated inspirational quote", usage="inspirobot", aliases=["inspiration", "inspiro", "insp"])
@commands.cooldown(1, 5)
async def inspirobot(self, ctx : commands.Context):
image = inspirobot.get_inspirational_quote()
@ -25,5 +25,11 @@ class Inspirobot(commands.Cog):
embed.set_image(url=image)
await ctx.send(embed=embed)
@commands.command(name="test", dscription="Who cares tbh")
@commands.cooldown(1, 3)
async def test(self, ctx):
await self.client.get_channel(621378664977793024).send("Test")
await ctx.send(self.client.name)
def setup(client : discord.Client):
client.add_cog(Inspirobot(client))
client.add_cog(Inspirobot(client))

View file

@ -12,7 +12,7 @@ class Nasa(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.command(name="APOD", description="Posts NASA's picture of the day.")
@commands.command(name="apod", description="Posts NASA's picture of the day.", usage="apod")
@commands.cooldown(1, 30)
async def apod(self, ctx: commands.Context):
url = nasa.image_of_the_day()

24
cogs/api/quote.py Normal file
View file

@ -0,0 +1,24 @@
import discord
from discord.ext import commands
from util import embed, config
from api import quote
class Quote(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.command(name="quote", description="Sends a random quote", usage="quote", aliases=["q"])
@commands.cooldown(1, 2)
async def quote(self, ctx: commands.Context):
please_kill_me = quote.fetch_quote()
if len(please_kill_me) == 0:
await ctx.send(embed=embed.make_error_embed("Something went wrong while fetching a random quote"))
return
end_my_life = discord.Embed(title=f'"{please_kill_me[0]}"', colour=int(config.settings["color"], 16))
end_my_life.set_footer(text=please_kill_me[1])
await ctx.send(embed=end_my_life)
def setup(client: discord.Client):
client.add_cog(Quote(client))

View file

@ -11,7 +11,7 @@ class Steam(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.command(name="SteamLevel", description="Finds the steam level of a user", usage="SteamLevel <Vanity URL>", aliases=["level"])
@commands.command(name="steamlevel", description="Finds the steam level of a user", usage="steamlevel <Vanity URL>", aliases=["level"])
@commands.cooldown(1, 2)
async def SteamLevel(self, ctx: commands.Context, vanity_url: str):
level = steam.get_steam_level(vanity_url)

18
cogs/api/thesaurus.py Normal file
View file

@ -0,0 +1,18 @@
import discord
from discord.ext import commands
from api import thesaurus
class Thesaurus(commands.Cog):
def __init__(self, client):
self.client = client
@commands.command(name="thesaurus", description="Makes you smarter.", usage="thesaurus <message>", aliases=["saurus", "thes"])
@commands.cooldown(1, 3)
async def thesaurus(self, ctx, *message):
loading = await ctx.send("Thinking...")
saurus = thesaurus.thesaurufy_sentence(" ".join(message))
await loading.edit(content=saurus)
def setup(client):
client.add_cog(Thesaurus(client))

32
cogs/api/translation.py Normal file
View file

@ -0,0 +1,32 @@
import discord
from discord.ext import commands
from util import checking, embed
from api import translation
class Translation(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.command(name="translate", description="Translates the given text", usage="translate <Language> <Text>", aliases=["tl"])
@commands.check(checking.is_author_bot)
async def translate(self, ctx: commands.Context, language: str, *message: str):
# Get language code
code = translation.name_to_ISO(language)
text = ' '.join(message)
if code == "":
await ctx.send(embed=embed.make_error_embed(f"There is no language named **{language}**."))
return
response = translation.translate(text, code)
if len(response) == 0:
await ctx.send(embed=embed.make_error_embed(f"The translation API doesn't support **{language}**."))
return
translated = response[0]
direction = response[1].split("-")
_from = translation.ISO_to_name(direction[0])
_to = translation.ISO_to_name(direction[1])
await ctx.send(embed=embed.make_embed_field(f"{_from} -> {_to}", None, text, translated))
def setup(client: discord.Client):
client.add_cog(Translation(client))

View file

@ -65,12 +65,12 @@ class AutoConvert(commands.Cog):
for currency in self.currencies:
if currency == element[1]:
continue
currency_string += f"{self.convert_currency(element[1], currency, element[0])}{currency}, "
embed.add_field(name=str(element[0])+element[1], value=currency_string[:-2])
currency_string += f"{currency}{self.convert_currency(element[1], currency, element[0])}, "
embed.add_field(name=element[1]+str(element[0]), value=currency_string[:-2])
if not empty:
await message.channel.send(embed=embed)
def setup(client: discord.Client):
client.add_cog(AutoConvert(client))
client.add_cog(AutoConvert(client))

View file

@ -12,7 +12,7 @@ class Coinflip(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.command(name="coinflip", description="Flips a coin and reacts with the result", aliases=["coin", "flip"])
@commands.command(name="coinflip", description="Flips a coin and reacts with the result", usage="coin", aliases=["coin", "flip"])
async def coinflip(self, ctx: commands.Context):
if random.randint(0, 1) == 0:
await ctx.message.add_reaction("🌑")

34
cogs/fun/encryption.py Normal file
View file

@ -0,0 +1,34 @@
import discord
from discord.ext import commands
from util import embed
class Encryption(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.command(name="rot", description="Applies the ROT encryption", usage="rot [number] [message]")
@commands.cooldown(1, 2)
async def rot(self, ctx: commands.Context, shift: str, *message: str):
if not shift.isnumeric():
await ctx.send(embed=embed.make_error_embed(f"{shift} is not a number."))
return
shift = int(shift)
if (shift < 1) or (shift > 25):
await ctx.send(embed=embed.make_error_embed("That's too much rotation. Stop it."))
return
old_message = list(' '.join(message))
for i in range(0, len(old_message)):
if not old_message[i].isalpha():
continue
if old_message[i].isupper():
old_message[i] = chr(ord('A') + ((ord(old_message[i]) + shift - ord('A')) % 26))
else:
old_message[i] = chr(ord('a') + ((ord(old_message[i]) + shift - ord('a')) % 26))
await ctx.send(''.join(old_message))
def setup(client: discord.Client):
client.add_cog(Encryption(client))

20
cogs/fun/math.py Normal file
View file

@ -0,0 +1,20 @@
import discord
from discord.ext import commands
from sympy import preview
from util import embed
class Math(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
@commands.command(name="latex", description="Transforms a latex(math!) expression to an image", usage="latex <latex>", aliases=["lat", "tex", "l"])
@commands.cooldown(1, 5)
async def latex(self, ctx: commands.Context, *expr: str):
preview(f"$${' '.join(expr)}$$", viewer='file', filename='latex.png', euler=False)
result = embed.make_embed_image("LaTeX", "latex.png")
await ctx.send(embed=result[0], file=result[1])
def setup(client: discord.Client):
client.add_cog(Math(client))

View file

@ -29,9 +29,9 @@ class Reactions(commands.Cog):
await message.add_reaction("🇨🇳")
if "america" in message.content.lower() or " usa" in message.content.lower():
await message.add_reaction("🇬")
await message.add_reaction("🇦")
await message.add_reaction("🇾")
await message.add_reaction("🇺🇸")
await message.add_reaction("🔫")
await message.add_reaction("🦅")
if "extremejoy" in message.content.lower():

32
cogs/fun/responses.py Normal file
View file

@ -0,0 +1,32 @@
import discord
from discord.ext import commands
class Responses(commands.Cog):
def __init__(self, client):
self.client = client
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
if message.author == self.client.user:
return
# @applesauce
if ("<@!568271450176356352>" in message.content) and ("<@!657709911337074698>" in message.content):
await message.channel.send(f"Stop pinging us {message.author.mention} <:pinged:451198700832817202>")
return
"""
if message.author.id == 478006431589728259:
if message.content == "<@&380535423233032193> NUMBERS REEEEEEEE":
await message.channel.send(f"<@&380535423233032193> {message.author.mention} REEEEEEEE")
if message.content == "<@&380535423233032193> <:nockgun:352019166288543745> 🔢":
await message.channel.send(f"<@&380535423233032193> <:nockgun:352019166288543745> {message.author.mention}")
if message.content == "<@&380535423233032193> is NOT for numbers":
await message.channel.send(f"<@&380535423233032193> ***IS*** for numbers")
"""
def setup(client):
client.add_cog(Responses(client))

35
cogs/fun/safety.py Normal file
View file

@ -0,0 +1,35 @@
import discord
from discord.ext import commands
from util import embed, logging
import time
class Safety(commands.Cog):
def __init__(self, client):
self.client = client
self.msg_buffer = [".", ".", ".", ".", ".", "."]
self.ping = "<@&380535423233032193>"
self.channel = 439466964625391637
self.last_action = 0
@commands.Cog.listener()
async def on_message(self, message):
if message.channel.id != self.channel:
return
if (time.time() - self.last_action) < 10:
return
if self.ping in message.content:
for msg in self.msg_buffer:
if self.ping in msg:
# Ping not adequately spaced
await message.channel.send(embed=embed.make_embed("Coronavirus Safety Information", "Due to the ongoing pandemic, please remember to space your NaughtyStep pings at least six messages apart.\n Thank you."))
self.last_action = time.time()
break
self.msg_buffer.pop(0)
self.msg_buffer.append(message.content)
def setup(client):
client.add_cog(Safety(client))

51
cogs/fun/schedule.py Normal file
View file

@ -0,0 +1,51 @@
import discord
import time
import asyncio
from discord.ext import commands
from datetime import datetime, timedelta
from random import randrange
from util import logging
def ceil_dt(dt, delta):
return dt + (datetime.min - dt) % delta
def random_date(start, end):
"""
This function will return a random datetime between two datetime
objects.
"""
delta = end - start
int_delta = (delta.days * 24 * 60 * 60) + delta.seconds
random_second = randrange(int_delta)
return start + timedelta(seconds=random_second)
class Schedule(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
self.threads = 0
self.THREAD_LIMIT = 20
async def call_event(self, sleep_time: int, name: str, user: discord.User, channel: discord.TextChannel):
await asyncio.sleep(sleep_time)
await channel.send(f"{user.mention} Your event \"{name}\" starts now!")
self.threads -= 1
@commands.command(name="schedule", description="Schedules an event", usage="schedule <name>", aliases=["s"])
@commands.cooldown(1, 3)
async def schedule(self, ctx: commands.Context, *name: str):
date = ceil_dt(random_date(datetime.now(), datetime.now() + timedelta(days=7)), timedelta(minutes=15))
await ctx.send(f"I scheduled \"{' '.join(name)}\" for **{date.strftime('%d.%m.%Y %H:%M CET')}**")
if self.threads <= self.THREAD_LIMIT:
seconds = (date - datetime.now()).seconds
await self.call_event(seconds, ' '.join(name), ctx.message.author, ctx.message.channel)
self.threads += 1
logging.info(f"Scheduled new event in {seconds} seconds. Current events: {self.threads}")
else:
logging.warning("Schedule: Event limit reached. Async function was not called.")
def setup(client: discord.Client):
client.add_cog(Schedule(client))

26
cogs/fun/wolfram.py Normal file
View file

@ -0,0 +1,26 @@
import discord
from discord.ext import commands
from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl, wlexpr
from util import embed
class WolframAlpha(commands.Cog):
def __init__(self, client):
self.client = client
self.session = WolframLanguageSession()
def __del__(self):
self.session.terminate()
@commands.command(name="WolframLanguage", description="Evaluates WolframLanguage expressions (Not to be confused with WolframAlpha!)", usage="WolframLanguage <expression>", aliases=["wl"])
async def WolframLanguage(self, ctx, *, expr):
msg = await ctx.send(embed=embed.make_embed("WolframLanguage", "Thinking..."))
evaluate = self.session.evaluate(expr)
self.session.evaluate(wl.Export("eval.png", evaluate, "PNG"))
await msg.delete()
data = embed.make_embed_image("Result", "eval.png")
await ctx.send(embed=data[0], file=data[1])
def setup(client):
client.add_cog(WolframAlpha(client))

106
cogs/help.py Normal file
View file

@ -0,0 +1,106 @@
import discord
from discord.ext import commands
from util import config, embed, logging
class SetupHelp(commands.Cog):
def __init__(self, client: discord.Client):
self.client = client
self._original_help_command = client.help_command
client.help_command = Help()
client.help_command.cog = self
class Help(commands.MinimalHelpCommand):
async def command_not_found(self, string: str):
await self.context.send(embed=embed.make_error_embed("Command not found"))
async def subcommand_not_found(self, command, string):
await self.context.send(embed=embed.make_error_embed("Command not found"))
async def send_cog_help(self, cog):
await self.context.send(embed=embed.make_error_embed("Command not found"))
async def send_group_help(self, group):
try:
subcmds = ""
if group.commands != []:
for command in group.commands:
subcmds += "`" + command.name + "`, "
subcmds = subcmds[:-2]
else:
subcmds = "`None`"
alias = ""
if group.aliases != []:
for i in range(len(group.aliases)):
if i == len(group.aliases) - 1:
alias = alias + '`' + group.aliases[i] + '`'
else:
alias = alias + '`' + group.aliases[i] + '`' + ', '
else:
alias = "`None`"
await self.context.send(embed=embed.make_embed_fields_ninl(group.name, group.description, ("Usage", f"`{config.settings['prefix']}{group.usage}`"), ("Aliases", alias), ("Subcommands", subcmds)))
except Exception as e:
logging.error(str(e))
await self.context.send(embed=embed.make_error_embed("Command not found"))
async def send_command_help(self, command):
try:
alias = ""
if command.aliases != []:
for i in range(len(command.aliases)):
if i == len(command.aliases) - 1:
alias = alias + '`' + command.aliases[i] + '`'
else:
alias = alias + '`' + command.aliases[i] + '`' + ', '
else:
alias = "`None`"
command_name = command.name
if command.parent != None:
command_name += f" ({command.parent})"
await self.context.send(embed=embed.make_embed_fields_ninl(command_name, command.description, ("Usage", f"`{config.settings['prefix']}{command.usage}`"), ("Aliases", alias)))
except Exception as e:
logging.error(str(e))
await self.context.send(embed=embed.make_error_embed("Command not found"))
async def send_bot_help(self, mapping):
# get list of commands
cmds = []
prefix = config.settings['prefix']
for cog, cog_commands in mapping.items():
cmds = cmds + cog_commands
cog = cog # Just so that the warning goes away
newCmds = []
for item in cmds:
newCmds.append(str(item))
newCmds = sorted(newCmds)
finalCmds = []
for item in newCmds:
try:
finalCmds.append(item)
except:
pass
cmdString = ""
if len(finalCmds) != 0:
for i in range(len(finalCmds)):
if i == len(finalCmds)-1:
cmdString = cmdString + '`' + finalCmds[i] + '`'
else:
cmdString = cmdString + '`' + finalCmds[i] + '`' + ', '
if cmdString != "":
await self.context.send(embed=embed.make_embed_field('Help', f'To get further information about a command use `{prefix}help <Command>`', "Commands", cmdString, inline=False))
else:
await self.context.send(embed=embed.make_error_embed("No commands found."))
def setup(client: discord.Client):
client.add_cog(SetupHelp(client))

5
data/count.py Normal file
View file

@ -0,0 +1,5 @@
count=0
with open('naughty_step.txt', 'r') as file:
for line in file:
count += len(line)
print(count)

3
screenlog.0 Normal file
View file

@ -0,0 +1,3 @@
root@h2864412:~/DeepBlue# cd screscreen -X
Please specify a command.
root@h2864412:~/DeepBlue#

View file

@ -8,6 +8,4 @@ from discord.ext import commands
from util import logging
def is_author_bot(ctx : commands.Context) -> bool:
if ctx.message.author.bot:
return False
return True
return (not ctx.author.bot)

41
util/embed.py Normal file
View file

@ -0,0 +1,41 @@
import discord
from util import config
def make_error_embed(message: str) -> discord.Embed:
embed = discord.Embed(title="Error", description=message, colour=int(config.settings["err_color"], 16))
return embed
def make_embed(title: str, desc: str) -> discord.Embed:
embed = discord.Embed(title=title, description=desc, colour=int(config.settings["color"], 16))
return embed
def make_embed_field(title: str, desc: str, field_name: str, field_val: str, inline: bool = True) -> discord.Embed:
embed = discord.Embed(title=title, description=desc, colour=int(config.settings["color"], 16))
embed.add_field(name=field_name, value=field_val, inline=inline)
return embed
def make_embed_fields(title: str, desc: str, *fields: tuple) -> discord.Embed:
embed = discord.Embed(title=title, description=desc, colour=int(config.settings["color"], 16))
for name, value in fields:
embed.add_field(name=name, value=value)
return embed
def make_embed_fields_footer(title: str, desc: str, footer: str, *fields: tuple) -> discord.Embed:
embed = discord.Embed(title=title, description=desc, colour=int(config.settings["color"], 16))
embed.set_footer(text=footer)
for name, value in fields:
embed.add_field(name=name, value=value)
return embed
def make_embed_fields_ninl(title: str, desc: str, *fields: tuple) -> discord.Embed:
embed = discord.Embed(title=title, description=desc, colour=int(config.settings["color"], 16), inline=False)
for name, value in fields:
embed.add_field(name=name, value=value, inline=False)
return embed
def make_embed_image(title: str, path: str) -> (discord.Embed, discord.File):
embed = discord.Embed(title=title, colour=int(config.settings["color"], 16))
attachment = discord.File(path, filename="image.png")
embed.set_image(url='attachment://image.png')
return (embed, attachment)