419 lines
14 KiB
Python
419 lines
14 KiB
Python
"""
|
|
dragon-bot
|
|
|
|
Our discord bot. Many of its actions are handled by separate modules which are
|
|
then imported into the main bot
|
|
"""
|
|
|
|
import os
|
|
import requests
|
|
|
|
import core_utils
|
|
import decide
|
|
import define_word
|
|
import discord
|
|
import docker
|
|
import doggos
|
|
import eight_ball
|
|
import excuse
|
|
import get_from_reddit
|
|
import help_methods
|
|
import lewds
|
|
import questions
|
|
import role_check
|
|
import set_avatar
|
|
import stock
|
|
import wallpaper
|
|
import weather
|
|
|
|
# Client object
|
|
client = discord.Client()
|
|
tokens = {
|
|
'test': 'MzQ1MjkwMTI5OTQ4Mjc4Nzg0.DG5IBw._9umb82PrL22bPe7GjmHClU-NtU',
|
|
'prod': 'MzkxNzgxMzAxNDE5NjM4Nzg0.DRdqXg.6khdRte3rsToWTYiFN-_64M2l_c'
|
|
}
|
|
dragon_environment = os.getenv('DRAGON_ENV')
|
|
|
|
debug = dragon_environment == 'test'
|
|
@client.event
|
|
async def on_ready():
|
|
# Update the bot's status
|
|
await client.change_presence(
|
|
game=discord.Game(name='Type !help to see what I can do')
|
|
)
|
|
|
|
if not debug:
|
|
await client.edit_profile(avatar=set_avatar.change_bots_avatar())
|
|
|
|
print("\n********************************")
|
|
print("\nDRAGON BOT RUNNING IN {} MODE".format(dragon_environment.upper()))
|
|
print("\n********************************")
|
|
|
|
if debug:
|
|
print("\nPress control+c to exit the bot")
|
|
print("Followed by control+d or by typing")
|
|
print("'exit' to exit the docker container\n\n")
|
|
|
|
|
|
@client.event
|
|
async def on_message(message):
|
|
def is_me(m):
|
|
"""
|
|
is_me(m)
|
|
|
|
Takes a message as an argument and checks that the author of the message
|
|
is the same as the person who initiated the command
|
|
"""
|
|
return m.author == message.author
|
|
|
|
|
|
|
|
def generate_embed(embed_url=None, embed_title=None, embed_description=None, embed_color=None):
|
|
"""
|
|
generate_embed(embed_url=None, embed_title=None, embed_description=None, embed_color=None)
|
|
|
|
Generates a discord embed object based on the URL passed in
|
|
Optionally, you can set the title and description text for the embed object.
|
|
"""
|
|
|
|
if not embed_description and embed_url:
|
|
embed_description="[Direct Link]({})".format(embed_url)
|
|
|
|
if not embed_color:
|
|
embed_color=discord.Color.gold()
|
|
|
|
embed = discord.Embed(
|
|
title=embed_title,
|
|
description=embed_description,
|
|
color=embed_color,
|
|
type='rich'
|
|
)
|
|
if embed_url:
|
|
embed.set_image(url=embed_url)
|
|
|
|
return embed
|
|
|
|
|
|
if client.user.mentioned_in(message):
|
|
await client.send_message(
|
|
message.channel,
|
|
"{} ```{}```".format(
|
|
message.author.mention,
|
|
questions.answer_question(message.content)
|
|
)
|
|
)
|
|
|
|
# Read messages and look for mentions of subreddits
|
|
for word in message.content.split():
|
|
if message.author != client.user:
|
|
if '/r/' in word or 'r/' in word:
|
|
try:
|
|
subreddit = word.split('/')[-1]
|
|
# Try and request the page to check that it actually exists
|
|
get_from_reddit.get_image(boards=subreddit, nsfw=True)
|
|
await client.send_message(message.channel, "https://reddit.com/r/{}".format(subreddit))
|
|
except:
|
|
pass
|
|
|
|
if message.content.startswith('!8ball'):
|
|
await client.send_message(
|
|
message.channel,
|
|
eight_ball.check_8ball(message.content)
|
|
)
|
|
|
|
if message.content.startswith('!avatar'):
|
|
profile = [message.author]
|
|
if len(message.mentions):
|
|
profile = message.mentions
|
|
|
|
# Code stolen from this reddit post
|
|
# https://www.reddit.com/r/discordapp/comments/74bb4z/retrieve_a_mentioned_users_avatar_using_discordpy
|
|
for user in profile:
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(
|
|
embed_title="{}#{}".format(user.name, user.discriminator),
|
|
embed_url=user.avatar_url.replace('.webp', '.png'),
|
|
embed_description="[Direct Link]({})".format(user.avatar_url.replace('.webp', '.png'))
|
|
)
|
|
)
|
|
|
|
if message.content.startswith('!clap'):
|
|
await client.delete_message(message)
|
|
await client.send_message(
|
|
message.channel,
|
|
"{}".format(':clap:'.join(message.content.split()[1:]))
|
|
)
|
|
|
|
if message.content.startswith('!cleanup'):
|
|
if not role_check.cleanup_permissions(message.author.roles):
|
|
await client.send_message(message.channel, 'You cant do that')
|
|
return
|
|
|
|
def is_bot(m):
|
|
return m.author == client.user
|
|
await client.purge_from(message.channel, limit=10, check=is_bot)
|
|
|
|
if message.content.startswith('!decide'):
|
|
await client.send_message(
|
|
message.channel,
|
|
"{} {}".format(
|
|
message.author.mention,
|
|
decide.decide(message.content)
|
|
)
|
|
)
|
|
|
|
if message.content.startswith('!define'):
|
|
await client.send_message(
|
|
message.channel,
|
|
define_word.get_definition(message.content)
|
|
)
|
|
|
|
if message.content.startswith('!dog'):
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(embed_url=doggos.get_dog())
|
|
)
|
|
|
|
if message.content.startswith('!excuse'):
|
|
await client.send_message(message.channel, excuse.get_excuse())
|
|
|
|
if message.content.startswith('!emoji'):
|
|
if not role_check.is_admin(message.author.roles):
|
|
await client.send_message(
|
|
message.channel,
|
|
"You dont have permission to create emojis"
|
|
)
|
|
return
|
|
|
|
emoji_staging = '/tmp/emoji'
|
|
|
|
try:
|
|
command, url, emoji_name = message.content.split()
|
|
except Exception:
|
|
await client.send_message(
|
|
message.channel,
|
|
help_methods.get_help_message('emoji')
|
|
)
|
|
return
|
|
try:
|
|
# Attempt to upload the emoji
|
|
await client.delete_message(message)
|
|
await client.send_message(
|
|
message.channel,
|
|
"emoji successfully uploaded! Heres how it looks in a sentence {}".format(
|
|
await client.create_custom_emoji(
|
|
server=message.server,
|
|
name=emoji_name,
|
|
image=open(core_utils.download_image(url, emoji_staging), "rb").read()
|
|
)
|
|
)
|
|
)
|
|
|
|
except Exception:
|
|
await client.send_message(
|
|
message.channel,
|
|
"I wasnt able to upload that image as an emoji. Sorry"
|
|
)
|
|
os.remove(emoji_staging)
|
|
return
|
|
|
|
if message.content.startswith('!greentext'):
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(
|
|
embed_title='>implying this actually happened',
|
|
embed_color=discord.Color.green(),
|
|
embed_url=get_from_reddit.get_image(boards=['greentext', '4chan'])
|
|
)
|
|
)
|
|
|
|
if message.content.startswith('!help'):
|
|
await client.send_message(message.channel, "ok {}, check your private messages".format(message.author.mention))
|
|
await client.send_message(
|
|
message.author,
|
|
help_methods.parse_message(message.content)
|
|
)
|
|
|
|
if message.content.startswith('!homepage'):
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(embed_url=wallpaper.fcking_homepage())
|
|
)
|
|
|
|
if message.content.startswith('!lewd'):
|
|
if 'nsfw' in message.channel.name:
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(
|
|
embed_url=lewds.get_lewd(),
|
|
embed_title="{} is being lewd".format(message.author.name)
|
|
)
|
|
)
|
|
else:
|
|
await client.send_message(
|
|
message.channel,
|
|
'You can only use this command in NSFW channels'
|
|
)
|
|
|
|
if message.content.startswith('!weather'):
|
|
await client.send_message(
|
|
message.channel,
|
|
weather.parse_loc(message.content)
|
|
)
|
|
|
|
if message.content.startswith('!stock'):
|
|
await client.send_message(
|
|
message.channel,
|
|
stock.parse_share(message.content)
|
|
)
|
|
|
|
if message.content.startswith('!pout'):
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(embed_url=get_from_reddit.get_image('pout'))
|
|
)
|
|
|
|
if message.content.startswith('!r'):
|
|
subreddit = message.content.split()[-1]
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(
|
|
embed_title="Heres a random image from /r/{}".format(subreddit),
|
|
embed_url=get_from_reddit.get_image(subreddit)
|
|
)
|
|
)
|
|
|
|
if message.content.startswith('!smug'):
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(embed_url=get_from_reddit.get_image('smuganimegirls'))
|
|
)
|
|
|
|
if message.content.startswith('!source'):
|
|
await client.send_message(
|
|
message.channel,
|
|
"https://gitlab.com/ldooks/dragon-bot"
|
|
)
|
|
|
|
if message.content.startswith('!purge'):
|
|
num = 20
|
|
if len(message.content.split()) > 1:
|
|
try:
|
|
num = int(message.content.split()[1])
|
|
except ValueError:
|
|
await client.send_message(
|
|
message.channel,
|
|
"You need to give me a number, you entered {}".format(
|
|
message.content.split()[1]
|
|
)
|
|
)
|
|
return
|
|
await client.purge_from(message.channel, limit=num, check=is_me)
|
|
|
|
if message.content.startswith('!roles'):
|
|
await client.send_message(
|
|
message.channel,
|
|
"ok {}. Check your PMs".format(message.author.mention)
|
|
)
|
|
await client.send_message(
|
|
message.author,
|
|
"```{}```".format(' '.join(list(map(lambda x: x.name, message.author.roles))))
|
|
)
|
|
|
|
if message.content.startswith('!wallpaper'):
|
|
await client.send_message(
|
|
message.channel,
|
|
embed=generate_embed(embed_url=wallpaper.get_wall(message.content))
|
|
)
|
|
|
|
|
|
if message.content.startswith('!docker'):
|
|
# Check permissions
|
|
if not role_check.docker_permissions(message.author.roles):
|
|
await client.send_message(
|
|
message.channel,
|
|
"You dont have permission to run docker commands"
|
|
)
|
|
return
|
|
|
|
if len(message.content.split()) == 1:
|
|
actions = ['restart', 'status', 'logs']
|
|
await client.send_message(
|
|
message.channel,
|
|
"\nSupported actions:\n{}".format(", ".join(actions))
|
|
)
|
|
else:
|
|
docker_client = docker.from_env()
|
|
minecraft_container = docker_client.containers.get('beyondreality')
|
|
|
|
# Figure out what action they want to take
|
|
action = message.content.split()[1]
|
|
if action == 'restart':
|
|
await client.send_message(
|
|
message.channel,
|
|
"{}, restart the container? [!yes/!no]".format(
|
|
message.author.mention)
|
|
)
|
|
|
|
confirm_restart = await client.wait_for_message(
|
|
author=message.author,
|
|
channel=message.channel,
|
|
content='!yes'
|
|
)
|
|
|
|
if confirm_restart:
|
|
await client.send_message(
|
|
message.channel,
|
|
"Sending restart action to {} container".format(
|
|
minecraft_container.name
|
|
)
|
|
)
|
|
|
|
minecraft_container.restart()
|
|
|
|
if action == 'status':
|
|
await client.send_message(
|
|
message.channel,
|
|
"{} container is {}".format(
|
|
minecraft_container.name,
|
|
minecraft_container.status
|
|
)
|
|
)
|
|
|
|
if action == 'logs':
|
|
if len(message.content.split()) == 3:
|
|
num_lines = int(message.content.split()[2])
|
|
else:
|
|
num_lines = 10
|
|
|
|
log_stream = minecraft_container.logs(
|
|
tail=num_lines
|
|
).decode('utf-8')
|
|
|
|
if len(log_stream) >= num_lines:
|
|
await client.send_message(
|
|
message.channel,
|
|
"Pulling last {} lines from {} container".format(
|
|
num_lines,
|
|
minecraft_container.name
|
|
)
|
|
)
|
|
|
|
await client.send_message(
|
|
message.channel,
|
|
"```{}```".format(
|
|
minecraft_container.logs(
|
|
tail=num_lines
|
|
).decode('utf-8')
|
|
)
|
|
)
|
|
|
|
else:
|
|
await client.send_message(
|
|
message.channel,
|
|
"There arent {} lines of output yet".format(num_lines)
|
|
)
|
|
|
|
client.run(tokens[dragon_environment])
|