""" 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 animals import core_utils import decide import define_word import discord import docker import eight_ball import emoji import excuse import get_from_reddit import gitlab import help_methods import lewds import quake import questions import role_check import set_avatar import stock import tts import wallpaper import weather # Client object client = discord.Client() 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('!birb'): await client.send_message( message.channel, embed=generate_embed(embed_url=animals.get_birb()) ) 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=animals.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 manage emojis" ) return await emoji.parse_message(client, message) 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=['classic4chan', 'greentext', '4chan']) ) ) if message.content.startswith('!help'): if len(message.content.split()) > 1: await client.send_message( message.channel, help_methods.parse_message(message.content) ) else: await client.send_message( message.channel, embed=help_methods.get_help_embed(client) ) if message.content.startswith('!homepage'): await client.send_message( message.channel, embed=generate_embed(embed_url=wallpaper.fcking_homepage()) ) if message.content.startswith('!invite'): # 43200 = 12 hours invite = await client.create_invite( destination=message.channel, max_uses=1, max_age=43200 ) await client.send_message(message.channel, invite) if message.content.startswith('!issue'): await client.send_message( message.channel, gitlab.parse_message(message) ) 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('!quake'): if len(message.content.split()) == 1: return await client.send_message( message.channel, help_methods.get_help_message('quake') ) await client.send_message( message.channel, embed=quake.parse_message(message) ) 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, "http://luker.zzzz.io/gitlab/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('!tts'): if message.content.split()[1] == 'langs': await client.send_message( message.channel, "Ok {}, check your DMs".format(message.author.mention) ) return await client.send_message( message.author, tts.get_all_langs() ) await client.send_file( message.channel, tts.text_to_speech(message.content), filename="A Message From {}.mp3".format(message.author.name) ) os.remove('/tmp/memes.mp3') 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('!minecraft'): # 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', 'map'] await client.send_message( message.channel, "\nSupported actions:```\n{}```".format(", ".join(actions)) ) else: docker_client = docker.from_env() try: minecraft_container = docker_client.containers.get('beyondreality') except: await client.send_message( message.channel, "The minecraft server is not running" ) return # Figure out what action they want to take action = message.content.split()[1] if action == 'restart': await client.send_message( message.channel, "{}, restart the server? [!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 {} server".format( minecraft_container.name ) ) minecraft_container.restart() if action == 'status': await client.send_message( message.channel, "{} server 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 the {} server ".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) ) if action == 'map': await client.send_message( message.channel, "http://luker.zzzz.io/minecraft" ) client.run(os.getenv('token'))