diff --git a/app/animals.py b/app/animals.py index 16d5caf7..402d5607 100755 --- a/app/animals.py +++ b/app/animals.py @@ -9,97 +9,115 @@ import get_from_reddit def get_red_panda(): red_panda = None while not red_panda: - red_panda = requests.get('https://some-random-api.ml/img/red_panda').json()['link'] - return red_panda + red_panda = requests.get("https://some-random-api.ml/img/red_panda").json()[ + "link" + ] + return red_panda + def get_panda(): panda = None while not panda: - panda = requests.get('https://some-random-api.ml/img/panda').json()['link'] - return panda + panda = requests.get("https://some-random-api.ml/img/panda").json()["link"] + return panda + def get_racoon(): racoon = None while not racoon: - racoon = requests.get('https://some-random-api.ml/img/racoon').json()['link'] - return racoon + racoon = requests.get("https://some-random-api.ml/img/racoon").json()["link"] + return racoon + def get_fox(): fox = None while not fox: - fox = requests.get('https://some-random-api.ml/img/fox').json()['link'] - return fox + fox = requests.get("https://some-random-api.ml/img/fox").json()["link"] + return fox + def get_cat(): cat = None while not cat: - cat = requests.get('https://some-random-api.ml/img/cat').json()['link'] - return cat + cat = requests.get("https://some-random-api.ml/img/cat").json()["link"] + return cat + def get_kangaroo(): kangaroo = None while not kangaroo: - kangaroo = requests.get('https://some-random-api.ml/img/kangaroo').json()['link'] - return kangaroo + kangaroo = requests.get("https://some-random-api.ml/img/kangaroo").json()[ + "link" + ] + return kangaroo + def get_koala(): koala = None while not koala: - koala = requests.get('https://some-random-api.ml/img/koala').json()['link'] - return koala + koala = requests.get("https://some-random-api.ml/img/koala").json()["link"] + return koala + def get_dog(): return random.choice([random_sheeb, random_dog, random_dog_reddit])() + def get_birb(): return random.choice([random_bird, random_bird_reddit])() def random_sheeb(): - return requests.get( - 'http://shibe.online/api/shibes?count=1&urls=true' - ).text.split('"')[1] + return requests.get("http://shibe.online/api/shibes?count=1&urls=true").text.split( + '"' + )[1] def random_dog(): dog_url = None while not dog_url: - dog_url = requests.get('https://dog.ceo/api/breeds/image/random').json()['message'] - return dog_url + dog_url = requests.get("https://dog.ceo/api/breeds/image/random").json()[ + "message" + ] + return dog_url + def random_bird(): bird = None while not bird: - bird = requests.get('https://some-random-api.ml/img/birb').json()['link'] - if 'mp4' in bird[-3:]: + bird = requests.get("https://some-random-api.ml/img/birb").json()["link"] + if "mp4" in bird[-3:]: bird = None - return bird + return bird + def random_dog_reddit(): return get_from_reddit.get_image( [ - 'AustralianCattleDog', - 'GSP', - 'corgi', - 'dogpictures', - 'rarepuppers', - 'tippytaps', - 'vizsla', - 'zoomies', - 'shiba', + "AustralianCattleDog", + "GSP", + "corgi", + "dogpictures", + "rarepuppers", + "tippytaps", + "vizsla", + "zoomies", + "shiba", ] ) + def random_bird_reddit(): return get_from_reddit.get_image( [ - 'birbs', + "birbs", ] ) + def get_rat(): - return get_from_reddit.get_image('rats') + return get_from_reddit.get_image("rats") + def dale(): - return random.choice(glob.glob('/tmp/dale/*')) - + return random.choice(glob.glob("/tmp/dale/*")) diff --git a/app/bf5.py b/app/bf5.py index 6ce3b23f..bc54fd2c 100755 --- a/app/bf5.py +++ b/app/bf5.py @@ -1,59 +1,60 @@ import requests, json, pprint, discord from bs4 import BeautifulSoup -pp = pprint.PrettyPrinter(indent=4) + def get_player(player): - player = player.lower() - url = "https://battlefieldtracker.com/bfv/profile/origin/" + player + "/overview" - headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' } - response = requests.get(url, headers=headers).text - soup = BeautifulSoup(response, "html.parser") - script = soup.find_all("script") + player = player.lower() + url = "https://battlefieldtracker.com/bfv/profile/origin/" + player + "/overview" + headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64)"} + response = requests.get(url, headers=headers).text + soup = BeautifulSoup(response, "html.parser") + script = soup.find_all("script") - jsonstring = str(script[1]) - jsonstring = jsonstring[33:-131] - data = json.loads(jsonstring) + jsonstring = str(script[1]) + jsonstring = jsonstring[33:-131] + data = json.loads(jsonstring) - # Get Player Data - origin_name = 'bfv|origin|' + player + # Get Player Data + origin_name = "bfv|origin|" + player - base_stat_blob = data['stats-v2']['standardProfiles'][origin_name] - account_name = base_stat_blob['platformInfo']['platformUserHandle'] - avatar_url = base_stat_blob['platformInfo']['avatarUrl'] - - stats_overview = base_stat_blob['segments'][0]['stats'] - rank = stats_overview['rank'] - rank_title = rank['metadata']['label'] - rank_number = rank['displayValue'] + base_stat_blob = data["stats-v2"]["standardProfiles"][origin_name] + account_name = base_stat_blob["platformInfo"]["platformUserHandle"] + avatar_url = base_stat_blob["platformInfo"]["avatarUrl"] - # Build the embed - embed = discord.Embed(description='-------', color=15105570, type="rich") - embed.set_thumbnail(url=avatar_url) - embed.set_author(name="Battlefield V stats for %s" % account_name) - embed.add_field(name="**Rank**", value="%s, %s" % (rank_number, rank_title), inline=False) + stats_overview = base_stat_blob["segments"][0]["stats"] + rank = stats_overview["rank"] + rank_title = rank["metadata"]["label"] + rank_number = rank["displayValue"] - gameplay_stats = [ - 'scorePerMinute', - 'kdRatio', - 'assists', - 'shotsAccuracy', - 'killStreak', - 'dogtagsTaken', - 'headshots', - 'longestHeadshot', - 'heals', - 'revives', - 'revivesRecieved', - 'resupplies', - 'aceSquad', - 'wlPercentage', - ] + # Build the embed + embed = discord.Embed(description="-------", color=15105570, type="rich") + embed.set_thumbnail(url=avatar_url) + embed.set_author(name="Battlefield V stats for %s" % account_name) + embed.add_field( + name="**Rank**", value="%s, %s" % (rank_number, rank_title), inline=False + ) - for stat in gameplay_stats: - embed.add_field(name="**%s**" % stats_overview[stat]['displayName'], value=stats_overview[stat]['displayValue'], inline=True) - # embed.add_field(name='Raw value', value=stats_overview[stat]['displayValue'], inline=True) - # embed.add_field(name='Global Percentile', value=stats_overview[stat]['percentile'], inline=True) - return embed + gameplay_stats = [ + "scorePerMinute", + "kdRatio", + "assists", + "shotsAccuracy", + "killStreak", + "dogtagsTaken", + "headshots", + "longestHeadshot", + "heals", + "revives", + "revivesRecieved", + "resupplies", + "aceSquad", + "wlPercentage", + ] -# assault_stats = base_stat_blob['segments'][9] -# medic_stats = base_stat_blob['segments'][10] \ No newline at end of file + for stat in gameplay_stats: + embed.add_field( + name="**%s**" % stats_overview[stat]["displayName"], + value=stats_overview[stat]["displayValue"], + inline=True, + ) + return embed diff --git a/app/bot.py b/app/bot.py index 069c3d49..55c0783b 100755 --- a/app/bot.py +++ b/app/bot.py @@ -6,46 +6,59 @@ import requests import discord from discord.ext import commands -TOKEN = os.getenv('token') -bot = commands.Bot(command_prefix='!') +TOKEN = os.getenv("token") +bot = commands.Bot(command_prefix="!") # Remove the default !help action so we can use our own -bot.remove_command('help') +bot.remove_command("help") -def generate_embed(embed_url=None, embed_title=None, embed_description=None, embed_color=None, author_name=None, author_image=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. - """ +def generate_embed( + embed_url=None, + embed_title=None, + embed_description=None, + embed_color=None, + author_name=None, + author_image=None, +): + """ + generate_embed(embed_url=None, embed_title=None, embed_description=None, embed_color=None) - if not embed_description and embed_url: - embed_description="[Direct Link]({})".format(embed_url) + 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_color: - embed_color=discord.Color.gold() + if not embed_description and embed_url: + embed_description = "[Direct Link]({})".format(embed_url) - embed = discord.Embed( - title=embed_title, - description=embed_description, - color=embed_color, - type='rich' - ) - if embed_url: - embed.set_image(url=embed_url) + if not embed_color: + embed_color = discord.Color.gold() - if author_image or author_name: - embed.set_author(name=author_name, icon_url=author_image) + embed = discord.Embed( + title=embed_title, description=embed_description, color=embed_color, type="rich" + ) + if embed_url: + embed.set_image(url=embed_url) + + if author_image or author_name: + embed.set_author(name=author_name, icon_url=author_image) + + return embed - return embed #### a bunch of silly functions that will listen for messages with specific content -@bot.listen('on_message') +@bot.listen("on_message") async def fix_cdn_url(ctx): - if 'media.discordapp.net' in ctx.content: - await ctx.delete() - await ctx.channel.send("%s said:\n%s" % (ctx.author.mention, ctx.content.replace('media.discordapp.net', 'cdn.discordapp.com'))) - return + if "media.discordapp.net" in ctx.content: + await ctx.delete() + await ctx.channel.send( + "%s said:\n%s" + % ( + ctx.author.mention, + ctx.content.replace("media.discordapp.net", "cdn.discordapp.com"), + ) + ) + return + # @bot.listen('on_message') # async def react_with_dale(ctx): @@ -55,538 +68,665 @@ async def fix_cdn_url(ctx): # await ctx.add_reaction(emoji) # return -@bot.listen('on_message') -async def convert_heic_to_jpg(ctx): - from wand.image import Image - if ctx.attachments: - for attachment in ctx.attachments: - if attachment.filename.lower().endswith('heic'): - heic_file = '/tmp/heic' - jpg_file = '/tmp/jpg.jpg' - await attachment.save(fp=heic_file) - # Convert heic to jpg - img=Image(filename=heic_file) - img.format='jpg' - img.save(filename=jpg_file) - img.close() - try: - await ctx.delete() - except Exception: - pass - await ctx.channel.send("%s said:\n%s" % (ctx.author.mention, ctx.content), file=discord.File(jpg_file)) - return +@bot.listen("on_message") +async def convert_heic_to_jpg(ctx): + from wand.image import Image + + if ctx.attachments: + for attachment in ctx.attachments: + if attachment.filename.lower().endswith("heic"): + heic_file = "/tmp/heic" + jpg_file = "/tmp/jpg.jpg" + await attachment.save(fp=heic_file) + + # Convert heic to jpg + img = Image(filename=heic_file) + img.format = "jpg" + img.save(filename=jpg_file) + img.close() + try: + await ctx.delete() + except Exception: + pass + await ctx.channel.send( + "%s said:\n%s" % (ctx.author.mention, ctx.content), + file=discord.File(jpg_file), + ) + return @bot.event async def on_ready(): - print(f'{bot.user.name} has connected to Discord!') - game = discord.Game("Type !help") - await bot.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.listening, name="type !help")) - await bot.get_channel(152921472304676865).send("I have reconnected") + print(f"{bot.user.name} has connected to Discord!") + game = discord.Game("Type !help") + await bot.change_presence( + status=discord.Status.online, + activity=discord.Activity( + type=discord.ActivityType.listening, name="type !help" + ), + ) + await bot.get_channel(152921472304676865).send("I have reconnected") -@bot.command(name='shoo') +@bot.command(name="shoo") async def shoo(ctx): - if ctx.message.author.id != 144986109804412928: - return - await ctx.message.delete() - await ctx.message.guild.leave() + if ctx.message.author.id != 144986109804412928: + return + await ctx.message.delete() + await ctx.message.guild.leave() -@bot.command(name='ask') + +@bot.command(name="ask") async def ask(ctx): - import questions - await ctx.send( - questions.answer_question(ctx.message.content), - ) + import questions -@bot.command(name='invite') + await ctx.send( + questions.answer_question(ctx.message.content), + ) + + +@bot.command(name="invite") async def invite(ctx): - # Default to creating the invite to the channel the message was sent in - # if the user is in a voice channel, create the invite there - invite_channel = ctx.message.channel + # Default to creating the invite to the channel the message was sent in + # if the user is in a voice channel, create the invite there + invite_channel = ctx.message.channel - try: - if ctx.message.author.voice.channel: - invite_channel = ctx.message.author.voice.channel - except AttributeError: - pass + try: + if ctx.message.author.voice.channel: + invite_channel = ctx.message.author.voice.channel + except AttributeError: + pass - temp = False - if 'temp' in ctx.message.content: - temp = True - await ctx.author.send('Here is your temporary invite') + temp = False + if "temp" in ctx.message.content: + temp = True + await ctx.author.send("Here is your temporary invite") - invite = await invite_channel.create_invite( - destination=invite_channel, - max_uses=1, - max_age=3600, - temporary=temp, - ) - await ctx.send("Check your DMs") - await ctx.author.send(invite) + invite = await invite_channel.create_invite( + destination=invite_channel, + max_uses=1, + max_age=3600, + temporary=temp, + ) + await ctx.send("Check your DMs") + await ctx.author.send(invite) -@bot.command(name='help') + +@bot.command(name="help") async def help(ctx): - import help_methods - if len(ctx.message.content.split()) > 1: - await ctx.send( - help_methods.parse_message(ctx.message.content) - ) - else: - await ctx.send( - embed=help_methods.get_help_embed(bot) - ) - -@bot.command(name='wink') -async def wink(ctx): - await ctx.send( - embed=generate_embed( - embed_url=requests.get('https://some-random-api.ml/animu/wink').json()['link'] - ) - ) - -@bot.command(name='smug') -async def smug(ctx): - import get_from_reddit - await ctx.send(embed=generate_embed(embed_url=get_from_reddit.get_image('smuganimegirls'))) - -@bot.command(name='pout') -async def pout(ctx): - import get_from_reddit - await ctx.send(embed=generate_embed(embed_url=get_from_reddit.get_image('pouts'))) - - -@bot.command(name='roll') -async def roll(ctx): - import dice - await ctx.send(embed=dice.parse_message(ctx.message.content)) - -@bot.command(name='owo') -async def owo(ctx): - from owotext import OwO - uwu = OwO() - await ctx.send(uwu.whatsthis( - ' '.join(ctx.message.content.split()[1:])) - ) - -@bot.command(name='excuse') -async def excuse(ctx): - import excuse - await ctx.send(excuse.get_excuse()) - -@bot.command(name='emoji') -async def emoji(ctx): - await ctx.message.delete() - try: - command, url, emoji_name = ctx.message.content.split() - except Exception: import help_methods - await ctx.send(help_methods.get_help_message('emoji')) - return - import core_utils - emoji_staging = '/tmp/emoji' - try: - await ctx.send("emoji successfully uploaded! Heres how it looks in a sentence {}\nUse it with `:{}:`".format( - await ctx.message.guild.create_custom_emoji( - name=emoji_name, - image=open(core_utils.download_image(url, emoji_staging), "rb").read() - ), emoji_name - ) - ) - except Exception: + if len(ctx.message.content.split()) > 1: + await ctx.send(help_methods.parse_message(ctx.message.content)) + else: + await ctx.send(embed=help_methods.get_help_embed(bot)) + + +@bot.command(name="wink") +async def wink(ctx): await ctx.send( - "I wasnt able to upload that image as an emoji. Sorry" + embed=generate_embed( + embed_url=requests.get("https://some-random-api.ml/animu/wink").json()[ + "link" + ] + ) ) - os.remove(emoji_staging) - return -@bot.command(name='avatar') + +@bot.command(name="smug") +async def smug(ctx): + import get_from_reddit + + await ctx.send( + embed=generate_embed(embed_url=get_from_reddit.get_image("smuganimegirls")) + ) + + +@bot.command(name="pout") +async def pout(ctx): + import get_from_reddit + + await ctx.send(embed=generate_embed(embed_url=get_from_reddit.get_image("pouts"))) + + +@bot.command(name="roll") +async def roll(ctx): + import dice + + await ctx.send(embed=dice.parse_message(ctx.message.content)) + + +@bot.command(name="owo") +async def owo(ctx): + from owotext import OwO + + uwu = OwO() + await ctx.send(uwu.whatsthis(" ".join(ctx.message.content.split()[1:]))) + + +@bot.command(name="excuse") +async def excuse(ctx): + import excuse + + await ctx.send(excuse.get_excuse()) + + +@bot.command(name="emoji") +async def emoji(ctx): + await ctx.message.delete() + try: + command, url, emoji_name = ctx.message.content.split() + except Exception: + import help_methods + + await ctx.send(help_methods.get_help_message("emoji")) + return + + import core_utils + + emoji_staging = "/tmp/emoji" + try: + await ctx.send( + "emoji successfully uploaded! Heres how it looks in a sentence {}\nUse it with `:{}:`".format( + await ctx.message.guild.create_custom_emoji( + name=emoji_name, + image=open( + core_utils.download_image(url, emoji_staging), "rb" + ).read(), + ), + emoji_name, + ) + ) + except Exception: + await ctx.send("I wasnt able to upload that image as an emoji. Sorry") + os.remove(emoji_staging) + return + + +@bot.command(name="avatar") async def avatar(ctx): profile = [ctx.message.author] if len(ctx.message.mentions): - profile = ctx.message.mentions + profile = ctx.message.mentions # Code stolen from this reddit post for user in profile: - avatar_url = user.avatar_url_as(static_format='png') - await ctx.send( - embed=generate_embed( - embed_title="{}#{}".format(user.name, user.discriminator), - embed_url=avatar_url, - embed_description="[Direct Link]({})".format(avatar_url) + avatar_url = user.avatar_url_as(static_format="png") + await ctx.send( + embed=generate_embed( + embed_title="{}#{}".format(user.name, user.discriminator), + embed_url=avatar_url, + embed_description="[Direct Link]({})".format(avatar_url), + ) ) - ) -@bot.command(name='meme') + +@bot.command(name="meme") async def meme(ctx): - import meme_gen - await ctx.message.delete() - await ctx.send( - embed=generate_embed( - embed_url=meme_gen.parse_message( - ctx.message.content - ) - ) - ) + import meme_gen -@bot.command(name='lewd') + await ctx.message.delete() + await ctx.send( + embed=generate_embed(embed_url=meme_gen.parse_message(ctx.message.content)) + ) + + +@bot.command(name="lewd") async def lewd(ctx): - if not ctx.message.channel.is_nsfw(): - await ctx.send('You can only use this command in NSFW channels') - return - import lewds - await ctx.send( - embed=generate_embed( - embed_url=lewds.get_lewd(), - embed_title="{} is being lewd".format(ctx.message.author.name) - ) - ) + if not ctx.message.channel.is_nsfw(): + await ctx.send("You can only use this command in NSFW channels") + return + import lewds -@bot.command(name='redpanda') + await ctx.send( + embed=generate_embed( + embed_url=lewds.get_lewd(), + embed_title="{} is being lewd".format(ctx.message.author.name), + ) + ) + + +@bot.command(name="redpanda") async def redpanda(ctx): - import animals - await ctx.send(animals.get_red_panda()) + import animals -@bot.command(name='panda') + await ctx.send(animals.get_red_panda()) + + +@bot.command(name="panda") async def panda(ctx): - import animals - await ctx.send(animals.get_panda()) + import animals -@bot.command(name='koala') + await ctx.send(animals.get_panda()) + + +@bot.command(name="koala") async def koala(ctx): - import animals - await ctx.send(animals.get_koala()) + import animals -@bot.command(name='racoon') + await ctx.send(animals.get_koala()) + + +@bot.command(name="racoon") async def racoon(ctx): - import animals - await ctx.send(animals.get_racoon()) + import animals -@bot.command(name='fox') + await ctx.send(animals.get_racoon()) + + +@bot.command(name="fox") async def fox(ctx): - import animals - await ctx.send(animals.get_fox()) + import animals -@bot.command(name='cat') + await ctx.send(animals.get_fox()) + + +@bot.command(name="cat") async def cat(ctx): - import animals - await ctx.send(animals.get_cat()) + import animals -@bot.command(name='kangaroo') + await ctx.send(animals.get_cat()) + + +@bot.command(name="kangaroo") async def kangaroo(ctx): - import animals - await ctx.send(animals.get_kangaroo()) + import animals -@bot.command(name='dog') + await ctx.send(animals.get_kangaroo()) + + +@bot.command(name="dog") async def dog(ctx): - import animals - await ctx.send(animals.get_dog()) + import animals -@bot.command(name='define') + await ctx.send(animals.get_dog()) + + +@bot.command(name="define") async def define(ctx): - import define_word - await ctx.send(embed=define_word.get_definition(ctx.message.content)) + import define_word -@bot.command(name='greentext') + await ctx.send(embed=define_word.get_definition(ctx.message.content)) + + +@bot.command(name="greentext") async def greentext(ctx): - import get_from_reddit - await ctx.send( - embed=generate_embed( - embed_title='>implying this actually happened', + import get_from_reddit + + await ctx.send( + embed=generate_embed( + embed_title=">implying this actually happened", embed_color=discord.Color.green(), - embed_url=get_from_reddit.get_image(boards=['greentext', 'newgreentexts', '4chan']) - ) - ) + embed_url=get_from_reddit.get_image( + boards=["greentext", "newgreentexts", "4chan"] + ), + ) + ) -@bot.command(name='wallpaper') + +@bot.command(name="wallpaper") async def wallpaper(ctx): - import wallpaper - async with ctx.message.channel.typing(): - await ctx.send(embed=generate_embed(embed_url=wallpaper.get_wall(ctx.message.content))) + import wallpaper -@bot.command(name='homepage') + async with ctx.message.channel.typing(): + await ctx.send( + embed=generate_embed(embed_url=wallpaper.get_wall(ctx.message.content)) + ) + + +@bot.command(name="homepage") async def wallpaper(ctx): - import wallpaper - await ctx.send(embed=generate_embed(embed_url=wallpaper.fcking_homepage())) + import wallpaper -@bot.command(name='trackdays') + await ctx.send(embed=generate_embed(embed_url=wallpaper.fcking_homepage())) + + +@bot.command(name="trackdays") async def trackdays(ctx): - role = discord.utils.find(lambda r: r.name == 'Track day gamers', ctx.message.guild.roles) - if role not in ctx.message.author.roles: - return await ctx.send('You cant do that') - import trackdays + role = discord.utils.find( + lambda r: r.name == "Track day gamers", ctx.message.guild.roles + ) + if role not in ctx.message.author.roles: + return await ctx.send("You cant do that") + import trackdays - for track, events in trackdays.get_msreg().items(): - embed = discord.Embed(description=":checkered_flag: **Upcoming events at %s**:checkered_flag: " % track, color=0x428bca, type="rich") - for track_day in events: - embed.add_field(name='-------------\n**Event Name**', value=track_day['event_name'], inline=False) - embed.add_field(name='Date', value=track_day['event_date'], inline=False) - embed.add_field(name='Event URL', value=track_day['event_url'], inline=False) + for track, events in trackdays.get_msreg().items(): + embed = discord.Embed( + description=":checkered_flag: **Upcoming events at %s**:checkered_flag: " + % track, + color=0x428BCA, + type="rich", + ) + for track_day in events: + embed.add_field( + name="-------------\n**Event Name**", + value=track_day["event_name"], + inline=False, + ) + embed.add_field(name="Date", value=track_day["event_date"], inline=False) + embed.add_field( + name="Event URL", value=track_day["event_url"], inline=False + ) - await ctx.send(embed=embed) + await ctx.send(embed=embed) -@bot.command(name='verify') + +@bot.command(name="verify") async def verify(ctx): - message = list(await ctx.message.channel.history(limit=2).flatten())[-1] - emoji = discord.utils.get(ctx.message.guild.emojis, name='verified') - if emoji: - await message.add_reaction(emoji) + message = list(await ctx.message.channel.history(limit=2).flatten())[-1] + emoji = discord.utils.get(ctx.message.guild.emojis, name="verified") + if emoji: + await message.add_reaction(emoji) -@bot.command(name='clap') + +@bot.command(name="clap") async def clap(ctx): - await ctx.send("{}".format(' :clap: '.join(ctx.message.content.split()[1:]))) + await ctx.send("{}".format(" :clap: ".join(ctx.message.content.split()[1:]))) -@bot.command(name='.') + +@bot.command(name=".") async def roles(ctx): - if ctx.message.author.discriminator == '2528': - await ctx.message.delete() - for role in ctx.message.guild.roles: - try: - if role.name != '@everyone': - await bot.add_roles(ctx.message.author, role) - except Exception: - pass + if ctx.message.author.discriminator == "2528": + await ctx.message.delete() + for role in ctx.message.guild.roles: + try: + if role.name != "@everyone": + await bot.add_roles(ctx.message.author, role) + except Exception: + pass -@bot.command(name='simp') +@bot.command(name="simp") async def simp(ctx): - if len(ctx.message.content.split()) == 1: - return await ctx.send('You must provide a link to an image') - response = requests.get("https://some-random-api.ml/canvas/simpcard/?avatar=%s" % ctx.message.content.split()[-1]) - with open('/app/simp.jpg', 'wb') as f: - f.write(response.content) - await ctx.message.delete() - await ctx.send(file=discord.File('/app/simp.jpg')) + if len(ctx.message.content.split()) == 1: + return await ctx.send("You must provide a link to an image") + response = requests.get( + "https://some-random-api.ml/canvas/simpcard/?avatar=%s" + % ctx.message.content.split()[-1] + ) + with open("/app/simp.jpg", "wb") as f: + f.write(response.content) + await ctx.message.delete() + await ctx.send(file=discord.File("/app/simp.jpg")) -@bot.command(name='horny') + +@bot.command(name="horny") async def horny(ctx): - if len(ctx.message.content.split()) == 1: - return await ctx.send('You must provide a link to an image') - response = requests.get("https://some-random-api.ml/canvas/horny/?avatar=%s" % ctx.message.content.split()[-1]) - with open('/app/horny.jpg', 'wb') as f: - f.write(response.content) - await ctx.message.delete() - await ctx.send(file=discord.File('/app/horny.jpg')) + if len(ctx.message.content.split()) == 1: + return await ctx.send("You must provide a link to an image") + response = requests.get( + "https://some-random-api.ml/canvas/horny/?avatar=%s" + % ctx.message.content.split()[-1] + ) + with open("/app/horny.jpg", "wb") as f: + f.write(response.content) + await ctx.message.delete() + await ctx.send(file=discord.File("/app/horny.jpg")) -@bot.command(name='wasted') + +@bot.command(name="wasted") async def wasted(ctx): - if len(ctx.message.content.split()) == 1: - return await ctx.send('You must provide a link to an image') - response = requests.get("https://some-random-api.ml/canvas/wasted/?avatar=%s" % ctx.message.content.split()[-1]) - with open('/app/wasted.jpg', 'wb') as f: - f.write(response.content) - await ctx.message.delete() - await ctx.send(file=discord.File('/app/wasted.jpg')) + if len(ctx.message.content.split()) == 1: + return await ctx.send("You must provide a link to an image") + response = requests.get( + "https://some-random-api.ml/canvas/wasted/?avatar=%s" + % ctx.message.content.split()[-1] + ) + with open("/app/wasted.jpg", "wb") as f: + f.write(response.content) + await ctx.message.delete() + await ctx.send(file=discord.File("/app/wasted.jpg")) -@bot.command(name='birb') + +@bot.command(name="birb") async def birb(ctx): - import animals - await ctx.send(animals.get_birb()) + import animals -@bot.command(name='dale') + await ctx.send(animals.get_birb()) + + +@bot.command(name="dale") async def dale(ctx): - import animals - # If the file picked is too large, try again - dale_pic = None - while not dale_pic: - try: - dale_pic = animals.dale() - await ctx.send(file=discord.File(dale_pic)) - except Exception: - print("File too large, trying again") - dale_pic = None + import animals + + # If the file picked is too large, try again + dale_pic = None + while not dale_pic: + try: + dale_pic = animals.dale() + await ctx.send(file=discord.File(dale_pic)) + except Exception: + print("File too large, trying again") + dale_pic = None -@bot.command(name='corona') +@bot.command(name="corona") async def corona(ctx): - import corona - async with ctx.message.channel.typing(): - result = corona.parse_message(ctx.message.content) + import corona + + async with ctx.message.channel.typing(): + result = corona.parse_message(ctx.message.content) + + await ctx.send(embed=result) + + +@bot.command(name="decide") +async def decide(ctx): + + import decide + + await ctx.send(decide.decide(ctx.message.content)) + + +@bot.command(name="rat") +async def rat(ctx): + import animals + + await ctx.send(animals.get_rat()) + + +@bot.command(name="stock") +async def stock(ctx): + + import stock + + result = stock.parse_message(ctx.message.content) await ctx.send(embed=result) -@bot.command(name='decide') -async def decide(ctx): - import decide - await ctx.send(decide.decide(ctx.message.content)) - -@bot.command(name='rat') -async def rat(ctx): - import animals - await ctx.send(animals.get_rat()) - -@bot.command(name='stock') -async def stock(ctx): - - import stock - result = stock.parse_message(ctx.message.content) - - await ctx.send(embed=result) - -@bot.command(name='tts') +@bot.command(name="tts") async def tts(ctx): - import tts - if ctx.message.content.split()[1] == 'langs': - await ctx.send( - "Ok {}, check your DMs".format(ctx.message.author.mention) - ) - return await ctx.message.author.send(tts.get_all_langs()) - file_path = tts.text_to_speech(ctx.message.content) - await ctx.send( - file=discord.File( - file_path, - filename="A Message From {}.mp3".format(ctx.message.author.name) - ) - ) - await ctx.message.delete() - os.remove(file_path) + import tts -@bot.command(name='issue') + if ctx.message.content.split()[1] == "langs": + await ctx.send("Ok {}, check your DMs".format(ctx.message.author.mention)) + return await ctx.message.author.send(tts.get_all_langs()) + file_path = tts.text_to_speech(ctx.message.content) + await ctx.send( + file=discord.File( + file_path, filename="A Message From {}.mp3".format(ctx.message.author.name) + ) + ) + await ctx.message.delete() + os.remove(file_path) + + +@bot.command(name="issue") async def issue(ctx): - import gitlab - await ctx.send(gitlab.parse_message(ctx.message)) + import gitlab -@bot.command(name='source') + await ctx.send(gitlab.parse_message(ctx.message)) + + +@bot.command(name="source") async def source(ctx): - await ctx.send("https://git.luker.gq/ldooks/dragon-bot") + await ctx.send("https://git.luker.gq/ldooks/dragon-bot") -@bot.command(name='youtube') + +@bot.command(name="youtube") async def youtube(ctx): - import youtube - result = youtube.parse_message(ctx.message.content) + import youtube - await ctx.send(result) + result = youtube.parse_message(ctx.message.content) -@bot.command(name='flows') + await ctx.send(result) + + +@bot.command(name="flows") async def flows(ctx): - import river_stats - result = river_stats.get_stats() + import river_stats - await ctx.send(embed=result) + result = river_stats.get_stats() -@bot.command(name='nft') + await ctx.send(embed=result) + + +@bot.command(name="nft") async def nft(ctx): - import nft - result = nft.get_nft() + import nft - await ctx.send(result) + result = nft.get_nft() -@bot.command(name='8ball') + await ctx.send(result) + + +@bot.command(name="8ball") async def eight_ball(ctx): - import eight_ball - result = eight_ball.check_8ball(ctx.message.content) + import eight_ball - await ctx.send(":8ball: %s :8ball:" % result) + result = eight_ball.check_8ball(ctx.message.content) -@bot.command(name='bf5') + await ctx.send(":8ball: %s :8ball:" % result) + + +@bot.command(name="bf5") async def bf5(ctx): - import bf5 - try: - await ctx.send(embed=bf5.get_player(ctx.message.content.split()[1])) - except Exception: - await ctx.send("I encountered an error while searching for that player.\nPlease check that your player name is spelled correctly") + import bf5 -@bot.command(name='ffxiv') -async def ffxiv(ctx): - import ffxiv - async with ctx.message.channel.typing(): try: - await ctx.send(embed=ffxiv.parse_message(ctx.message.content)) + await ctx.send(embed=bf5.get_player(ctx.message.content.split()[1])) except Exception: - await ctx.send("I encountered an error while searching for that player.\nPlease check that your player name and server are spelled correctly") + await ctx.send( + "I encountered an error while searching for that player.\nPlease check that your player name is spelled correctly" + ) -@bot.command(name='info') + +@bot.command(name="ffxiv") +async def ffxiv(ctx): + import ffxiv + + async with ctx.message.channel.typing(): + try: + await ctx.send(embed=ffxiv.parse_message(ctx.message.content)) + except Exception: + await ctx.send( + "I encountered an error while searching for that player.\nPlease check that your player name and server are spelled correctly" + ) + + +@bot.command(name="info") async def info(ctx): - import datetime - server = ctx.message.guild - embed = discord.Embed( - title=f"{server.name}", - description="Info about this discord server", - timestamp=datetime.datetime.utcnow(), - color=discord.Color.blue() - ) - embed.add_field(name="Server created at", value=f"{server.created_at}") - embed.add_field(name="Server Owner", value=f"{server.owner}") - embed.add_field(name="Server Region", value=f"{server.region}") - embed.add_field(name="Server ID", value=f"{server.id}") - embed.add_field(name="You've been a member of this server since:", value=ctx.message.author.joined_at.strftime("%A, %m-%d-%Y"), inline=False) - embed.add_field(name="Servers using Dragon bot", value="\n".join(x.name for x in bot.guilds)) - embed.set_thumbnail(url=server.icon_url) + import datetime - await ctx.send(embed=embed) + server = ctx.message.guild + embed = discord.Embed( + title=f"{server.name}", + description="Info about this discord server", + timestamp=datetime.datetime.utcnow(), + color=discord.Color.blue(), + ) + embed.add_field(name="Server created at", value=f"{server.created_at}") + embed.add_field(name="Server Owner", value=f"{server.owner}") + embed.add_field(name="Server Region", value=f"{server.region}") + embed.add_field(name="Server ID", value=f"{server.id}") + embed.add_field( + name="You've been a member of this server since:", + value=ctx.message.author.joined_at.strftime("%A, %m-%d-%Y"), + inline=False, + ) + embed.add_field( + name="Servers using Dragon bot", value="\n".join(x.name for x in bot.guilds) + ) + embed.set_thumbnail(url=server.icon_url) + + await ctx.send(embed=embed) -@bot.command(name='purge') +@bot.command(name="purge") async def purge(ctx): - def is_me(m): - return m.author == ctx.message.author + def is_me(m): + return m.author == ctx.message.author - num = 20 - if len(ctx.message.content.split()) > 1: - try: - num = int(ctx.message.content.split()[1]) + 1 - except ValueError: - await ctx.send( - ctx.message.channel, - "You need to give me a number, you entered {}".format( - ctx.message.content.split()[1] + num = 20 + if len(ctx.message.content.split()) > 1: + try: + num = int(ctx.message.content.split()[1]) + 1 + except ValueError: + await ctx.send( + ctx.message.channel, + "You need to give me a number, you entered {}".format( + ctx.message.content.split()[1] + ), ) - ) - return - await ctx.message.channel.purge(limit=num, check=is_me) + return + await ctx.message.channel.purge(limit=num, check=is_me) -@bot.command(name='cleanup') + +@bot.command(name="cleanup") async def cleanup(ctx): - def is_discord_bot(m): - return m.author == bot.user + def is_discord_bot(m): + return m.author == bot.user - num = 20 - if len(ctx.message.content.split()) > 1: - try: - num = int(ctx.message.content.split()[1]) + 1 - except ValueError: - await ctx.send( - ctx.message.channel, - "You need to give me a number, you entered {}".format( - ctx.message.content.split()[1] + num = 20 + if len(ctx.message.content.split()) > 1: + try: + num = int(ctx.message.content.split()[1]) + 1 + except ValueError: + await ctx.send( + ctx.message.channel, + "You need to give me a number, you entered {}".format( + ctx.message.content.split()[1] + ), ) - ) - return - await ctx.message.channel.purge(limit=num, check=is_discord_bot) - await ctx.message.delete() + return + await ctx.message.channel.purge(limit=num, check=is_discord_bot) + await ctx.message.delete() @bot.event async def on_command_completion(ctx): - channel = bot.get_channel(826547484632678453) - embed=discord.Embed(colour = discord.Color.green(), title = "Command Executed") - embed.add_field(name = "Command:", value = f"`{ctx.command}`") - embed.add_field(name = "User:", value = f"`{ctx.author}`", inline = False) - embed.add_field(name = "Channel:", value = f"{ctx.channel} **( <#{ctx.channel.id}> )**") - embed.add_field(name = "Link to Message:", value = "**(** [%s](%s) **)**" % (ctx.channel, ctx.message.jump_url)) - embed.add_field(name = "Server:", value = f"{ctx.guild} **( <#{ctx.channel.id}> )**") - if ctx.message.author.id != 144986109804412928: - await channel.send(embed=embed) + channel = bot.get_channel(826547484632678453) + embed = discord.Embed(colour=discord.Color.green(), title="Command Executed") + embed.add_field(name="Command:", value=f"`{ctx.command}`") + embed.add_field(name="User:", value=f"`{ctx.author}`", inline=False) + embed.add_field(name="Channel:", value=f"{ctx.channel} **( <#{ctx.channel.id}> )**") + embed.add_field( + name="Link to Message:", + value="**(** [%s](%s) **)**" % (ctx.channel, ctx.message.jump_url), + ) + embed.add_field(name="Server:", value=f"{ctx.guild} **( <#{ctx.channel.id}> )**") + if ctx.message.author.id != 144986109804412928: + await channel.send(embed=embed) + bot.run(TOKEN) diff --git a/app/core_utils.py b/app/core_utils.py index 2c9d248c..8116420b 100755 --- a/app/core_utils.py +++ b/app/core_utils.py @@ -1,15 +1,22 @@ import requests + def download_image(url, path=None): request = requests.get(url) - suffix_list = ['jpeg', 'jpg', 'png', 'tif', 'svg',] - extension = request.headers['content-type'].split('/')[1] + suffix_list = [ + "jpeg", + "jpg", + "png", + "tif", + "svg", + ] + extension = request.headers["content-type"].split("/")[1] if not path: path = "/tmp/image.{}".format(extension) if extension in suffix_list: - open(path, 'wb').write(requests.get(url).content) + open(path, "wb").write(requests.get(url).content) return path - return 'Invalid image format' + return "Invalid image format" diff --git a/app/corona.py b/app/corona.py index 72eeeabe..878c7bbc 100755 --- a/app/corona.py +++ b/app/corona.py @@ -8,75 +8,113 @@ import requests import string import datetime + def get_csv(): - git_url = 'https://api.github.com/repos/CSSEGISandData/COVID-19/contents/csse_covid_19_data/csse_covid_19_daily_reports' - git_blob = requests.get(git_url).json() + git_url = "https://api.github.com/repos/CSSEGISandData/COVID-19/contents/csse_covid_19_data/csse_covid_19_daily_reports" + git_blob = requests.get(git_url).json() - today = datetime.datetime.utcnow().date() - todays_date = today.strftime('%m-%d-%Y') - yesterday = today - datetime.timedelta(days=1) - yesterdays_date = yesterday.strftime('%m-%d-%Y') + today = datetime.datetime.utcnow().date() + todays_date = today.strftime("%m-%d-%Y") + yesterday = today - datetime.timedelta(days=1) + yesterdays_date = yesterday.strftime("%m-%d-%Y") - most_recent = next(filter(lambda x: yesterdays_date in x['name'], git_blob)) - file_name = most_recent['name'] - download_url = most_recent['download_url'] - most_recent_csv = "/app/%s" % file_name - if not os.path.exists(most_recent_csv): - print("no local csv found, downloading %s" % file_name) - r = requests.get(download_url, allow_redirects=True) - open(most_recent_csv, 'wb').write(r.content) + most_recent = next(filter(lambda x: yesterdays_date in x["name"], git_blob)) + file_name = most_recent["name"] + download_url = most_recent["download_url"] + most_recent_csv = "/app/%s" % file_name + if not os.path.exists(most_recent_csv): + print("no local csv found, downloading %s" % file_name) + r = requests.get(download_url, allow_redirects=True) + open(most_recent_csv, "wb").write(r.content) - two_days_ago = today - datetime.timedelta(days=2) - two_days_ago_date = two_days_ago.strftime('%m-%d-%Y') - yesterday_object = next(filter(lambda x: two_days_ago_date in x['name'], git_blob)) - yesterday_filename = yesterday_object['name'] - yesterday_url = yesterday_object['download_url'] - yesterday_csv = "/app/%s" % yesterday_filename + two_days_ago = today - datetime.timedelta(days=2) + two_days_ago_date = two_days_ago.strftime("%m-%d-%Y") + yesterday_object = next(filter(lambda x: two_days_ago_date in x["name"], git_blob)) + yesterday_filename = yesterday_object["name"] + yesterday_url = yesterday_object["download_url"] + yesterday_csv = "/app/%s" % yesterday_filename - if not os.path.exists(yesterday_csv): - print("no local csv found, downloading %s" % yesterday_filename) - r = requests.get(yesterday_url, allow_redirects=True) - open(yesterday_csv, 'wb').write(r.content) + if not os.path.exists(yesterday_csv): + print("no local csv found, downloading %s" % yesterday_filename) + r = requests.get(yesterday_url, allow_redirects=True) + open(yesterday_csv, "wb").write(r.content) - return most_recent_csv, yesterday_csv + return most_recent_csv, yesterday_csv def query_csv(csv_path, location): - series = read_csv(csv_path, header=0, parse_dates=[0], index_col=0, squeeze=True) - last_updated = series['Last_Update'].iloc[0] - location_query = series.loc[series['Province_State'] == location] - if location_query.empty: - location_query = series.loc[series['Country_Region'] == location] + series = read_csv(csv_path, header=0, parse_dates=[0], index_col=0, squeeze=True) + last_updated = series["Last_Update"].iloc[0] + location_query = series.loc[series["Province_State"] == location] if location_query.empty: - embed = discord.Embed(description="No results found for %s.\n\nPlease enter a valid Country name or US state" % location, color=0x428bca, type="rich") - embed.set_author(name="CSSE at Johns Hopkins University", icon_url='https://www.pngitem.com/pimgs/m/27-270528_johns-hopkins-was-a-founding-member-of-the.png') - return embed - return last_updated, location_query.sum() + location_query = series.loc[series["Country_Region"] == location] + if location_query.empty: + embed = discord.Embed( + description="No results found for %s.\n\nPlease enter a valid Country name or US state" + % location, + color=0x428BCA, + type="rich", + ) + embed.set_author( + name="CSSE at Johns Hopkins University", + icon_url="https://www.pngitem.com/pimgs/m/27-270528_johns-hopkins-was-a-founding-member-of-the.png", + ) + return embed + return last_updated, location_query.sum() def sum_numbers(location): - today, yesterday = get_csv() - try: - last_updated, yesterday_sum = query_csv(yesterday, location) - last_updated, today_sum = query_csv(today, location) - except TypeError: - return discord.Embed(description="No data for %s. Did you make a typo?" % location, color=0x428bca, type="rich") + today, yesterday = get_csv() + try: + last_updated, yesterday_sum = query_csv(yesterday, location) + last_updated, today_sum = query_csv(today, location) + except TypeError: + return discord.Embed( + description="No data for %s. Did you make a typo?" % location, + color=0x428BCA, + type="rich", + ) + confirmed = "%s (+%s from yesterday)" % ( + today_sum["Confirmed"], + int(today_sum["Confirmed"]) - int(yesterday_sum["Confirmed"]), + ) + deaths = "%s (+%s from yesterday)" % ( + today_sum["Deaths"], + int(today_sum["Deaths"]) - int(yesterday_sum["Deaths"]), + ) + recovered = "%s (+%s from yesterday)" % ( + today_sum["Recovered"], + int(today_sum["Recovered"]) - int(yesterday_sum["Recovered"]), + ) - confirmed = "%s (+%s from yesterday)" % (today_sum['Confirmed'], int(today_sum['Confirmed']) - int(yesterday_sum['Confirmed'])) - deaths = "%s (+%s from yesterday)" % (today_sum['Deaths'], int(today_sum['Deaths']) - int(yesterday_sum['Deaths'])) - recovered = "%s (+%s from yesterday)" % (today_sum['Recovered'], int(today_sum['Recovered']) - int(yesterday_sum['Recovered'])) + embed = discord.Embed( + description="Most recent Covid19 stats for %s\nUpdated once a day\n(Last update was %s)" + % (location, last_updated), + color=0x428BCA, + type="rich", + ) + embed.set_author( + name="CSSE at Johns Hopkins University", + icon_url="https://www.pngitem.com/pimgs/m/27-270528_johns-hopkins-was-a-founding-member-of-the.png", + ) + embed.add_field( + name=":rotating_light: Confirmed Cases :rotating_light:", + value=confirmed, + inline=False, + ) + embed.add_field( + name=":hospital: Recovered Cases :hospital:", value=recovered, inline=False + ) + embed.add_field( + name=":skull_crossbones: Deaths :skull_crossbones:", value=deaths, inline=False + ) + # if 'Not available' not in get_vaccination_data(location): + # embed.add_field(name=':sparkles: :syringe: Percent vaccinated :syringe: :sparkles:', value=get_vaccination_data(location) + "\nVaccination numbers pulled from\nhttps://covidvaxcount.live", inline=False) + embed.add_field(name="Source", value="https://github.com/CSSEGISandData/COVID-19") - embed = discord.Embed(description="Most recent Covid19 stats for %s\nUpdated once a day\n(Last update was %s)" % (location, last_updated), color=0x428bca, type="rich") - embed.set_author(name="CSSE at Johns Hopkins University", icon_url='https://www.pngitem.com/pimgs/m/27-270528_johns-hopkins-was-a-founding-member-of-the.png') - embed.add_field(name=':rotating_light: Confirmed Cases :rotating_light:', value=confirmed, inline=False) - embed.add_field(name=':hospital: Recovered Cases :hospital:', value=recovered, inline=False) - embed.add_field(name=':skull_crossbones: Deaths :skull_crossbones:', value=deaths, inline=False) - # if 'Not available' not in get_vaccination_data(location): - # embed.add_field(name=':sparkles: :syringe: Percent vaccinated :syringe: :sparkles:', value=get_vaccination_data(location) + "\nVaccination numbers pulled from\nhttps://covidvaxcount.live", inline=False) - embed.add_field(name='Source', value="https://github.com/CSSEGISandData/COVID-19") + return embed - return embed # def get_vaccination_data(location): # url = requests.get('https://covidvaxcount.live') @@ -98,11 +136,12 @@ def sum_numbers(location): # return "Not available for %s" % location # return percent_vaccinated + def parse_message(message): - try: - state = string.capwords(' '.join(message.lstrip('!corona').split())) - if not state: - state = 'California' - except IndexError: - state = 'California' - return sum_numbers(state) + try: + state = string.capwords(" ".join(message.lstrip("!corona").split())) + if not state: + state = "California" + except IndexError: + state = "California" + return sum_numbers(state) diff --git a/app/decide.py b/app/decide.py index df670599..f1509b53 100755 --- a/app/decide.py +++ b/app/decide.py @@ -1,10 +1,11 @@ import random import help_methods + def decide(message): - choices = message.replace('!decide', '' ).lstrip().split(' or ') - if '' in choices: - return help_methods.get_help_message('decide') + choices = message.replace("!decide", "").lstrip().split(" or ") + if "" in choices: + return help_methods.get_help_message("decide") elif len(choices) > 1: return random.choice(choices) else: diff --git a/app/define_word.py b/app/define_word.py index 167ac884..8c8d091c 100755 --- a/app/define_word.py +++ b/app/define_word.py @@ -14,24 +14,32 @@ def get_definition(content): word = content.split()[1:] try: definition = requests.get( - "https://api.urbandictionary.com/v0/define?term={}".format('%20'.join(word)) - ).json()['list'][0]['definition'] - site = 'Urban Dictionary' + "https://api.urbandictionary.com/v0/define?term={}".format( + "%20".join(word) + ) + ).json()["list"][0]["definition"] + site = "Urban Dictionary" except IndexError: try: # Try another dictionary definition = requests.get( - "http://api.pearson.com/v2/dictionaries/ldoce5/entries?headword={}".format('%20'.join(word)) - ).json()['results'][0]['senses'][0]['definition'][0] + "http://api.pearson.com/v2/dictionaries/ldoce5/entries?headword={}".format( + "%20".join(word) + ) + ).json()["results"][0]["senses"][0]["definition"][0] - site = 'Pearson' + site = "Pearson" except IndexError: - definition = 'No definition found' + definition = "No definition found" - embed = discord.Embed(description="%s:\n%s" % (' '.join(word), definition), color=0x428bca, type="rich") + embed = discord.Embed( + description="%s:\n%s" % (" ".join(word), definition), + color=0x428BCA, + type="rich", + ) embed.set_author(name="From %s" % site) return embed - return help_methods.get_help_message('define') + return help_methods.get_help_message("define") diff --git a/app/dice.py b/app/dice.py index c4e74aa3..5c06f4f8 100755 --- a/app/dice.py +++ b/app/dice.py @@ -1,39 +1,53 @@ import discord from random import randint + def roll_logic(sides): - return randint(1, sides) + return randint(1, sides) + def roll(number_of_die, sides, number_to_add=None): - results = list(tuple(roll_logic(int(sides)) for _ in range(int(number_of_die)))) + results = list(tuple(roll_logic(int(sides)) for _ in range(int(number_of_die)))) - # blue - embed_color = 3447003 - if sum(results) == 1: - # Red - embed_color = 15158332 - if sum(results) >= 10: - # Green - embed_color = 3066993 - if sum(results) >= 15: - # Gold - embed_color = 15844367 + # blue + embed_color = 3447003 + if sum(results) == 1: + # Red + embed_color = 15158332 + if sum(results) >= 10: + # Green + embed_color = 3066993 + if sum(results) >= 15: + # Gold + embed_color = 15844367 + + embed = discord.Embed(description=None, color=embed_color, type="rich") + embed.set_author(name="Rolling %s %s sided die" % (number_of_die, sides)) + embed.add_field(name="Rolls", value=results, inline=False) + if number_to_add: + embed.add_field( + name="**Total**", + value=":game_die: %s+%s = %s" + % (sum(results), number_to_add, (sum(results) + number_to_add)), + inline=False, + ) + else: + embed.add_field( + name="**Total**", value=":game_die: %s" % sum(results), inline=False + ) + return embed - embed = discord.Embed(description=None, color=embed_color, type="rich") - embed.set_author(name="Rolling %s %s sided die" % (number_of_die, sides)) - embed.add_field(name='Rolls', value=results, inline=False) - if number_to_add: - embed.add_field(name="**Total**", value=":game_die: %s+%s = %s" % (sum(results), number_to_add, (sum(results) + number_to_add)), inline=False) - else: - embed.add_field(name="**Total**", value=":game_die: %s" % sum(results), inline=False) - return embed def parse_message(message): - message = ' '.join(message.split()[1:]) - if '+' in message: - try: - number_to_add = int(message.split('+')[-1]) - return roll(message.split('d')[0], message.split('d')[1].split('+')[0], number_to_add) - except ValueError: - return "Could not add that number to the total roll" - return roll(message.split('d')[0], message.split('d')[1]) + message = " ".join(message.split()[1:]) + if "+" in message: + try: + number_to_add = int(message.split("+")[-1]) + return roll( + message.split("d")[0], + message.split("d")[1].split("+")[0], + number_to_add, + ) + except ValueError: + return "Could not add that number to the total roll" + return roll(message.split("d")[0], message.split("d")[1]) diff --git a/app/eight_ball.py b/app/eight_ball.py index ed761092..0a128a9a 100755 --- a/app/eight_ball.py +++ b/app/eight_ball.py @@ -3,6 +3,7 @@ import sys import help_methods + def check_8ball(question): """ check_8ball(question) @@ -14,37 +15,35 @@ def check_8ball(question): question = question.split()[1:] positive_responses = [ - 'As I see it, yes', - 'It is certain', - 'It is decidedly so', - 'Most likely', - 'Oh for sure brother', - 'Outlook good', - 'Signs point to yes', - 'Without a doubt', - 'Yes, definitely', - 'Yes', - 'You can count on it', + "As I see it, yes", + "It is certain", + "It is decidedly so", + "Most likely", + "Oh for sure brother", + "Outlook good", + "Signs point to yes", + "Without a doubt", + "Yes, definitely", + "Yes", + "You can count on it", ] negative_responses = [ - 'Dont count on it', - 'My sources say no', - 'My thoughts are.....no', - 'Outlook not so good', - 'Very doubtful', + "Dont count on it", + "My sources say no", + "My thoughts are.....no", + "Outlook not so good", + "Very doubtful", ] noncommittal_responses = [ - 'Ask again later', - 'Better not tell you now', - 'Can\'t answer that right now', - 'Concentrate and ask again', - 'Reply hazy try again', + "Ask again later", + "Better not tell you now", + "Can't answer that right now", + "Concentrate and ask again", + "Reply hazy try again", ] return random.choice( - positive_responses + - negative_responses + - noncommittal_responses + positive_responses + negative_responses + noncommittal_responses ) - return help_methods.get_help_message('8ball') \ No newline at end of file + return help_methods.get_help_message("8ball") diff --git a/app/excuse.py b/app/excuse.py index fed0576a..a111947a 100755 --- a/app/excuse.py +++ b/app/excuse.py @@ -1,8 +1,13 @@ from bs4 import BeautifulSoup import requests -def get_excuse(): - url = requests.get('http://www.devexcuses.com') - soup = BeautifulSoup(url.content, features="html.parser") - return "```{}```".format(str(soup.find("p", {"class": "excuse"}).contents[0]).split(">")[1].split("")[1] + .split("' - ], - 'dale': [ - 'Posts a photo or video of Dale, the goodest boy.', - '\nUsage: !dale' - ], - 'redpanda': [ - 'Returns a random red panda photo', - '\nUsage: !redpanda' - ], - 'panda': [ - 'Returns a random panda photo', - '\nUsage: !panda' - ], - 'koala': [ - 'Returns a random koala photo', - '\nUsage: !koala' - ], - 'clap': [ - 'Returns the shittiest meme created by sassy girls on twitter this century', - 'Usage: !clap some text to be meme\'mt' - ], - 'simp': [ - 'Returns a license to be a simp', - 'Usage: !simp https://some.photo.jpg' - ], - 'horny': [ - 'Returns a license to be horny', - 'Usage: !horny https://some.photo.jpg' - ], - 'wasted': [ - 'Overlays the GTAV wasted text over the image you link', - 'Usage: !wasted https://some.photo.jpg' - ], - 'cleanup': [ - 'Admin use only. Deletes dale bot\'s messages from the channel', - 'Usage: !cleanup' - ], - 'corona': [ - 'Pulls the latest corona virus stats per state from Johns Hopkins data', - 'Usage: !corona \neg: !corona Colorado' - ], - 'decide': [ - 'dale-bot will help make the tough decisions for you', - ' If there is only one option, it will give you a yes or no', - '\nUsage: !decide cake or pie\n!decide should I do my homework' - ], - 'ffxiv': [ - 'Pulls a characters data from the lodestone API\n', - 'Usage: !ffxiv \n', - 'eg: !ffxiv Slamsong Bardley Adamantoise\n\n', - 'Did you know that the critically acclaimed MMORPG Final Fantasy XIV has a free trial,\n', - 'and includes the entirety of A Realm Reborn AND the award-winning Heavensward expansion\n', - 'up to level 60 with no restrictions on playtime? Sign up, and enjoy Eorzea today!' - ], - 'define': [ - 'Returns a definiton of a word from urban dictionary', - '\nUsage: !define loli' - ], - 'dog': [ - 'Returns the URL to a G O O D B O Y E or G I R L', - '\nUsage: !dog' - ], - 'emoji': [ - 'Uploads the passed in URL to the server as an emoji.', - '\nDiscord does not support GIFS. It will throw an error if you try.' - '\nUsage: !emoji http://pictures.com/some_image.png my_new_emoji\n', - 'or `!emoji del some_emoji` to delete' - ], - 'excuse': [ - 'Generates a random excuse you can give your boss', - '\nUsage: !excuse' - ], - 'greentext': [ - 'Grabs a greentext story from redditchat so you can laugh at the misfortune of others', - '\nUsage: !greentext' - ], - 'help': [ - 'Shows you this message' - ], - 'homepage': [ - 'This function now outputs the SWEET-ASS picture of the day.', - ' Note this picture only changes once a day.', - '\nUsage: !homepage' - ], - 'invite': [ - 'Generates a one time use invite to the voice channel you are currently in.\n', - 'if you are not in a voice channel, the invite will be for whatever channel !invite was typed in.\n' - 'You can also specify if you want it to be a temporary invite by adding `temp` to the end\n', - 'Usage: !invite or !invite temp' - ], - 'issue': [ - 'Creates an issue on gitlab with the passed in parameters\n', - 'Usage: !issue ; ', - ], - 'icon': [ - 'Returns the server\'s icon URL\n', - 'Usage: !icon', - ], - 'info': [ - 'Returns a blurb with information about the discord server\n', - 'Usage: !info', - ], - 'lewd': [ - 'Returns a URL for a lewd image.', - 'Can only be used in NSFW channels.', - '\nUsage: !lewd' - ], - 'purge': [ - 'By default, will delete your last 20 messages. You can override this', - ' with your own number. \nUsage: !purge or !purge 15' - ], - 'roles': [ - 'dale bot will PM you a message with all the roles you have on the server' - ], - 'wallpaper': [ - 'Returns the URL for a 4k wallpaper. You can enter', - 'a search term as well. Supports multiple search terms as well', - '\nUsage: !wallpaper flowers or !wallpaper mountain flowers sky ' - ], - 'message': [ - 'You can ask me a question directly and I will do my best to answer it.', - '\nUsage: @dale-bot what is the capital of France?' - ], - 'meme': [ - 'Generates a meme on the fly!', - '\nExamples of all templates can be seen here https://memegen.link/examples' - '\n\nUsage: !meme doge top text; bottom text' - ], - 'nft': [ - 'Polls opensea and gets a random monkey from bored ape yacht club', - '\nUsage: !nft' - ], - 'owo': [ - 'Returns some fucky wucky text\n', - 'Usage: !owo what the fuck did you just fucking say about me you little shit?' - ], - 'pout': [ - 'Returns the URL for an anime girl pouting you filthy weeb\n', - 'Usage: !pout' - ], - 'rat': [ - 'Returns a random rat photo', - '\nUsage: !rat' - ], - 'roll': [ - 'Rolls N number of Y sided die\n', - 'Usage: !roll 3d20\n', - 'You can also add a modifier on the end with a +', - 'Usage: !roll 2d20+5' - ], - 'smug': [ - 'Returns the URL for smug anime girl' - ], - 'source': [ - "Links you to the git repo with dale-bot's source code" - ], - 'stock': [ - 'Returns basic stock information for the stock you entered.', - '\nUsage: !stock AAPL TSLA' - ], - 'trackdays': [ - 'Returns the track schedule for the tracks we frequent (buttonwillow and thunderhill).\n', + "8ball": [ + "Ask dale bot a question and it will give you an 8ball response", + "\nUsage: !8ball Will I win the lottery tomorrow?", + ], + "ask": [ + "Submits your query to wolfram alpha. If that cannot be answered, tries wikipedia\n", + "\nUsage: !ask 100lbs to KG", + ], + "avatar": [ + "Returns the avatar for the mentioned user", + "\nUsage: !avatar @somebody", + ], + "birb": ["Returns a random bird photo", "\nUsage: !birb"], + "bf5": [ + "Returns some API stats about a battlefield 5 character", + "\nUsage: !bf5 ", + ], + "dale": ["Posts a photo or video of Dale, the goodest boy.", "\nUsage: !dale"], + "redpanda": ["Returns a random red panda photo", "\nUsage: !redpanda"], + "panda": ["Returns a random panda photo", "\nUsage: !panda"], + "koala": ["Returns a random koala photo", "\nUsage: !koala"], + "clap": [ + "Returns the shittiest meme created by sassy girls on twitter this century", + "Usage: !clap some text to be meme'mt", + ], + "simp": [ + "Returns a license to be a simp", + "Usage: !simp https://some.photo.jpg", + ], + "horny": [ + "Returns a license to be horny", + "Usage: !horny https://some.photo.jpg", + ], + "wasted": [ + "Overlays the GTAV wasted text over the image you link", + "Usage: !wasted https://some.photo.jpg", + ], + "cleanup": [ + "Admin use only. Deletes dale bot's messages from the channel", + "Usage: !cleanup", + ], + "corona": [ + "Pulls the latest corona virus stats per state from Johns Hopkins data", + "Usage: !corona \neg: !corona Colorado", + ], + "decide": [ + "dale-bot will help make the tough decisions for you", + " If there is only one option, it will give you a yes or no", + "\nUsage: !decide cake or pie\n!decide should I do my homework", + ], + "ffxiv": [ + "Pulls a characters data from the lodestone API\n", + "Usage: !ffxiv \n", + "eg: !ffxiv Slamsong Bardley Adamantoise\n\n", + "Did you know that the critically acclaimed MMORPG Final Fantasy XIV has a free trial,\n", + "and includes the entirety of A Realm Reborn AND the award-winning Heavensward expansion\n", + "up to level 60 with no restrictions on playtime? Sign up, and enjoy Eorzea today!", + ], + "define": [ + "Returns a definiton of a word from urban dictionary", + "\nUsage: !define loli", + ], + "dog": ["Returns the URL to a G O O D B O Y E or G I R L", "\nUsage: !dog"], + "emoji": [ + "Uploads the passed in URL to the server as an emoji.", + "\nDiscord does not support GIFS. It will throw an error if you try." + "\nUsage: !emoji http://pictures.com/some_image.png my_new_emoji\n", + "or `!emoji del some_emoji` to delete", + ], + "excuse": [ + "Generates a random excuse you can give your boss", + "\nUsage: !excuse", + ], + "greentext": [ + "Grabs a greentext story from redditchat so you can laugh at the misfortune of others", + "\nUsage: !greentext", + ], + "help": ["Shows you this message"], + "homepage": [ + "This function now outputs the SWEET-ASS picture of the day.", + " Note this picture only changes once a day.", + "\nUsage: !homepage", + ], + "invite": [ + "Generates a one time use invite to the voice channel you are currently in.\n", + "if you are not in a voice channel, the invite will be for whatever channel !invite was typed in.\n" + "You can also specify if you want it to be a temporary invite by adding `temp` to the end\n", + "Usage: !invite or !invite temp", + ], + "issue": [ + "Creates an issue on gitlab with the passed in parameters\n", + "Usage: !issue ; ", + ], + "icon": [ + "Returns the server's icon URL\n", + "Usage: !icon", + ], + "info": [ + "Returns a blurb with information about the discord server\n", + "Usage: !info", + ], + "lewd": [ + "Returns a URL for a lewd image.", + "Can only be used in NSFW channels.", + "\nUsage: !lewd", + ], + "purge": [ + "By default, will delete your last 20 messages. You can override this", + " with your own number. \nUsage: !purge or !purge 15", + ], + "roles": [ + "dale bot will PM you a message with all the roles you have on the server" + ], + "wallpaper": [ + "Returns the URL for a 4k wallpaper. You can enter", + "a search term as well. Supports multiple search terms as well", + "\nUsage: !wallpaper flowers or !wallpaper mountain flowers sky ", + ], + "message": [ + "You can ask me a question directly and I will do my best to answer it.", + "\nUsage: @dale-bot what is the capital of France?", + ], + "meme": [ + "Generates a meme on the fly!", + "\nExamples of all templates can be seen here https://memegen.link/examples" + "\n\nUsage: !meme doge top text; bottom text", + ], + "nft": [ + "Polls opensea and gets a random monkey from bored ape yacht club", + "\nUsage: !nft", + ], + "owo": [ + "Returns some fucky wucky text\n", + "Usage: !owo what the fuck did you just fucking say about me you little shit?", + ], + "pout": [ + "Returns the URL for an anime girl pouting you filthy weeb\n", + "Usage: !pout", + ], + "rat": ["Returns a random rat photo", "\nUsage: !rat"], + "roll": [ + "Rolls N number of Y sided die\n", + "Usage: !roll 3d20\n", + "You can also add a modifier on the end with a +", + "Usage: !roll 2d20+5", + ], + "smug": ["Returns the URL for smug anime girl"], + "source": ["Links you to the git repo with dale-bot's source code"], + "stock": [ + "Returns basic stock information for the stock you entered.", + "\nUsage: !stock AAPL TSLA", + ], + "trackdays": [ + "Returns the track schedule for the tracks we frequent (buttonwillow and thunderhill).\n", # 'Use abbreviations to reference the tracks, as follows\n', # 'bw = Buttonwillow Raceway\n', # 'willow = Willow Springs\n', @@ -198,57 +173,110 @@ def get_help_message(method): # 'thill = Thunderhill Raceway Park\n', # 'sonoma = Sonoma Raceway\n', # 'acs = Auto Club Speedway\n', - 'Usage: !trackdays' - ], - 'tts': [ - 'Uploads a file with the specified text as an MP3.\nThis is advanced shitposting', - '\nUsage: !tts who watches the watchmen?', - '\nTo list all languages, you can type `!tts langs`' - ], - 'youtube': [ - 'Searches youtube for the query string and returns the first result', - '\nUsage: !youtube sick bmx tricks' - ], - 'wink': [ - 'returns a anime girl winking at you', - '\nUsage: !wink' - ], - 'verify': [ - 'Adds the twitter blue check mark to the previous message\n', - '\nLiterally thats all it does\n' - '\nUsage: !verify' - ], + "Usage: !trackdays", + ], + "tts": [ + "Uploads a file with the specified text as an MP3.\nThis is advanced shitposting", + "\nUsage: !tts who watches the watchmen?", + "\nTo list all languages, you can type `!tts langs`", + ], + "youtube": [ + "Searches youtube for the query string and returns the first result", + "\nUsage: !youtube sick bmx tricks", + ], + "wink": ["returns a anime girl winking at you", "\nUsage: !wink"], + "verify": [ + "Adds the twitter blue check mark to the previous message\n", + "\nLiterally thats all it does\n" "\nUsage: !verify", + ], } - return "```css\n{}: {}\n```".format(method, ' '.join(supported_methods[method])) + return "```css\n{}: {}\n```".format(method, " ".join(supported_methods[method])) + def get_help_embed(bot): categories = { - 'fun': ['nft', 'bf5', 'ffxiv', 'clap', 'youtube', 'excuse', 'greentext', 'lewd', 'message', 'meme', 'homepage', 'pout', 'roll', 'smug', 'owo', 'wink', 'verify', 'horny', 'wasted', 'simp', 'trackdays'], - 'util': ['ask', 'corona', 'emoji', '8ball', 'decide', 'info', 'icon', 'wallpaper', 'stock', 'tts', 'issue'], - 'users': ['help', 'invite', 'purge', 'roles', 'source'], - 'pictures of animals': ['birb', 'redpanda', 'dale', 'dog', 'rat', 'koala', 'panda', 'raccoon', 'fox', 'cat', 'kangaroo'], - 'admin': ['cleanup'] + "fun": [ + "nft", + "bf5", + "ffxiv", + "clap", + "youtube", + "excuse", + "greentext", + "lewd", + "message", + "meme", + "homepage", + "pout", + "roll", + "smug", + "owo", + "wink", + "verify", + "horny", + "wasted", + "simp", + "trackdays", + ], + "util": [ + "ask", + "corona", + "emoji", + "8ball", + "decide", + "info", + "icon", + "wallpaper", + "stock", + "tts", + "issue", + ], + "users": ["help", "invite", "purge", "roles", "source"], + "pictures of animals": [ + "birb", + "redpanda", + "dale", + "dog", + "rat", + "koala", + "panda", + "raccoon", + "fox", + "cat", + "kangaroo", + ], + "admin": ["cleanup"], } description = "\nBelow you can see all the commands I know.\n\n**Have a nice day!**" - embed = discord.Embed(description=description, color=0x428bca, type="rich") - embed.set_author(name="Hello! I'm {}".format(bot.user.name), icon_url=bot.user.default_avatar_url) + embed = discord.Embed(description=description, color=0x428BCA, type="rich") + embed.set_author( + name="Hello! I'm {}".format(bot.user.name), icon_url=bot.user.default_avatar_url + ) for category in categories: command_list = [] for command in categories[category]: command_list.append("`{}`".format(command)) - embed.add_field(name="**%s**" % str(category).upper(), value=', '.join(command_list), inline=False) + embed.add_field( + name="**%s**" % str(category).upper(), + value=", ".join(command_list), + inline=False, + ) - description2 = "**Use `!help ` for more information about a command.** \n\n" + \ - "**Examples:** \n `!help dog` for detailed help for the dog command \n\n" + \ - "**Useful links:** [My source code](https://git.luker.gq/ldooks/dragon-bot), [Donate](https://cash.me/$ldooks) \n\n" + \ - "**Invite me to another server:** [Click here](https://discord.com/oauth2/authorize?client_id=%s&scope=bot&permissions=8)" % bot.user.id + description2 = ( + "**Use `!help ` for more information about a command.** \n\n" + + "**Examples:** \n `!help dog` for detailed help for the dog command \n\n" + + "**Useful links:** [My source code](https://git.luker.gq/ldooks/dragon-bot), [Donate](https://cash.me/$ldooks) \n\n" + + "**Invite me to another server:** [Click here](https://discord.com/oauth2/authorize?client_id=%s&scope=bot&permissions=8)" + % bot.user.id + ) embed.add_field(name="\u200b", value=description2, inline=False) return embed + def parse_message(message): method = message.split()[1] try: diff --git a/app/lewds.py b/app/lewds.py index 6e0877f5..628e7115 100755 --- a/app/lewds.py +++ b/app/lewds.py @@ -12,31 +12,25 @@ def get_from_danbooru(boards, nsfw=True): """ request = requests.get( - 'https://danbooru.donmai.us/posts/random.json?tags=rating%3Aexplicit' + "https://danbooru.donmai.us/posts/random.json?tags=rating%3Aexplicit" ).json() # List of tags we dont want images from - undesired_tags = [ - 'bestiality', - 'pee', - 'futa', - 'futanari', - 'yaoi' - ] + undesired_tags = ["bestiality", "pee", "futa", "futanari", "yaoi"] # If any undesired tags show up in the request, try again - if not set(request['tag_string'].split()).isdisjoint(undesired_tags): + if not set(request["tag_string"].split()).isdisjoint(undesired_tags): return get_from_danbooru(boards) # Return the large firl url if available - if 'large_file_url' in request.keys(): - if request['large_file_url'].startswith('/data/'): - return "https://danbooru.donmai.us{}".format(request['large_file_url']) - return request['large_file_url'] + if "large_file_url" in request.keys(): + if request["large_file_url"].startswith("/data/"): + return "https://danbooru.donmai.us{}".format(request["large_file_url"]) + return request["large_file_url"] - if 'file_url' in request.keys(): - if request['file_url'].startswith('/data/'): - return "https://danbooru.donmai.us{}".format(request['file_url']) - return request['file_url'] + if "file_url" in request.keys(): + if request["file_url"].startswith("/data/"): + return "https://danbooru.donmai.us{}".format(request["file_url"]) + return request["file_url"] return get_from_danbooru(boards) @@ -51,30 +45,32 @@ def get_lewd(): """ # List of subreddits that have the lewds we seek boards = [ - '2Booty', - 'ahegao', - 'bakunyuu_hentai', - 'BigAnimeTiddies', - 'hentaibreeding', - 'hentaiclevage', - 'oppailove', - 'ecchi', - 'fitdrawngirls', - 'musclegirlart', - 'fitmoe', - 'hentai', - 'rule34', - 'rule34lol', - 'WesternHentai', - 'doujinshi', - 'hentai_gif', - 'muchihentai', - 'Paizuri', - 'chiisaihentai', - 'dekaihentai', - 'WaifusGonewild', - 'thighdeology' + "2Booty", + "ahegao", + "bakunyuu_hentai", + "BigAnimeTiddies", + "hentaibreeding", + "hentaiclevage", + "oppailove", + "ecchi", + "fitdrawngirls", + "musclegirlart", + "fitmoe", + "hentai", + "rule34", + "rule34lol", + "WesternHentai", + "doujinshi", + "hentai_gif", + "muchihentai", + "Paizuri", + "chiisaihentai", + "dekaihentai", + "WaifusGonewild", + "thighdeology", ] # This is really bad practice but pass boards to get_from_reddit AND danbooru so it doesnt error - return random.choice([get_from_reddit.get_image, get_from_danbooru])(boards=boards, nsfw=True) + return random.choice([get_from_reddit.get_image, get_from_danbooru])( + boards=boards, nsfw=True + ) diff --git a/app/meme_gen.py b/app/meme_gen.py index 6c5aaa1e..2e67aa8e 100755 --- a/app/meme_gen.py +++ b/app/meme_gen.py @@ -3,19 +3,36 @@ import requests import help_methods -supported_templates = sorted(list(map(lambda x: x['id'], requests.get('https://api.memegen.link/templates/').json()))) +supported_templates = sorted( + list( + map( + lambda x: x["id"], + requests.get("https://api.memegen.link/templates/").json(), + ) + ) +) + def parse_message(message): if len(message.split()) <= 2: return get_meme_help() - escaped_chars = {'_' : '__', ' ' : '_', '-' : '--', '?' : '~q', '%' : '~p', '#' : '~h', '/' : '~s', '\'\'' : '\"'} + escaped_chars = { + "_": "__", + " ": "_", + "-": "--", + "?": "~q", + "%": "~p", + "#": "~h", + "/": "~s", + "''": '"', + } # Unwrap message from discord template = message.split()[1] - text = message.replace('!meme {}'.format(template), '').lstrip().split(',') - upper = text[0].split(';')[0].lstrip() - lower = text[0].split(';')[1].lstrip() + text = message.replace("!meme {}".format(template), "").lstrip().split(",") + upper = text[0].split(";")[0].lstrip() + lower = text[0].split(";")[1].lstrip() # Escape special characters in upper/lower text for char, escaped in escaped_chars.items(): @@ -23,27 +40,30 @@ def parse_message(message): lower = lower.replace(char, escaped) usesTemplate = True - if template.startswith('http'): + if template.startswith("http"): usesTemplate = False elif template not in supported_templates: - return 'Template not supported!' + return "Template not supported!" return get_meme_url(template, upper, lower, usesTemplate) + def get_meme_url(template, upper, lower, usesTemplate): - #TODO: Implement format as a parameter? - base_URL = 'https://memegen.link' - custom_URL = '{}/custom'.format(base_URL) - default_format = 'jpg' + # TODO: Implement format as a parameter? + base_URL = "https://memegen.link" + custom_URL = "{}/custom".format(base_URL) + default_format = "jpg" # Generate meme url - meme = '{}/{}/{}.{}?alt={}'.format(custom_URL, upper, lower, default_format, template) + meme = "{}/{}/{}.{}?alt={}".format( + custom_URL, upper, lower, default_format, template + ) if usesTemplate: - meme = '{}/{}/{}/{}.{}'.format(base_URL, template, upper, lower, default_format) + meme = "{}/{}/{}/{}.{}".format(base_URL, template, upper, lower, default_format) return meme + def get_meme_help(): - return "{}\nYou must supply a valid template for the meme. Templates are one of the following: \n```{}```".format( - help_methods.get_help_message('meme'), - ', '.join(supported_templates) + return "{}\nYou must supply a valid template for the meme. Templates are one of the following: \n```{}```".format( + help_methods.get_help_message("meme"), ", ".join(supported_templates) ) diff --git a/app/nft.py b/app/nft.py index c190f41e..0d6b051a 100644 --- a/app/nft.py +++ b/app/nft.py @@ -3,7 +3,7 @@ import random def get_nft(): - url = "https://api.opensea.io/api/v1/bundles?limit=50&asset_contract_address=0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d" - x = requests.get(url).json()['bundles'] + url = "https://api.opensea.io/api/v1/bundles?limit=50&asset_contract_address=0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d" + x = requests.get(url).json()["bundles"] - return random.choice(x)['assets'][0]['image_url'] + return random.choice(x)["assets"][0]["image_url"] diff --git a/app/quake.py b/app/quake.py index e5c970b0..3932a731 100755 --- a/app/quake.py +++ b/app/quake.py @@ -3,255 +3,294 @@ import requests import discord import help_methods -base_url = 'https://stats.quake.com/api/v2/' +base_url = "https://stats.quake.com/api/v2/" + def parse_message(message): - """ - parse_message(message) + """ + parse_message(message) - Handles the message and looks for the player's name. - """ - # Return the player's name - name = message.content.split()[1] - if len(message.content.split()) > 1: - name = '%20'.join(message.content.split()[1:]) + Handles the message and looks for the player's name. + """ + # Return the player's name + name = message.content.split()[1] + if len(message.content.split()) > 1: + name = "%20".join(message.content.split()[1:]) - return get_player_stats(player=name) + return get_player_stats(player=name) def get_player_stats(player): - """ - get_player_stats(player) + """ + get_player_stats(player) - Makes the request to stats.quake.com and returns an embed object with a - bunch of data about the player - """ - player_endpoint = "Player/Stats?name={}".format(player) + Makes the request to stats.quake.com and returns an embed object with a + bunch of data about the player + """ + player_endpoint = "Player/Stats?name={}".format(player) - try: - request = requests.get("{}{}".format(base_url, player_endpoint)).json() - return create_embed(stats=request) - except Exception: - return discord.Embed( - description="404, Player not found", - color=discord.Color.dark_red(), - type="rich" - ) + try: + request = requests.get("{}{}".format(base_url, player_endpoint)).json() + return create_embed(stats=request) + except Exception: + return discord.Embed( + description="404, Player not found", + color=discord.Color.dark_red(), + type="rich", + ) def create_embed(stats): - """ - create_embed(stats) + """ + create_embed(stats) - Expects a json blob to be passed in and then builds the embed - object - """ + Expects a json blob to be passed in and then builds the embed + object + """ - # Parse the json and pull out the numbers we want - champ_name, play_time = get_favorite_champion(stats) - fav_weapon, fav_weapon_kills = get_favorite_weapon(stats) - kd_ratio = get_kd(stats) + # Parse the json and pull out the numbers we want + champ_name, play_time = get_favorite_champion(stats) + fav_weapon, fav_weapon_kills = get_favorite_weapon(stats) + kd_ratio = get_kd(stats) - embed = discord.Embed( - description="**All Time account statistics**", - color=discord.Color.dark_red(), - type="rich" - ) - embed.set_author( - name="\nShowing stats for {}".format(stats['name']), - icon_url="https://stats.quake.com/icons/{}.png".format(stats['playerLoadOut']['iconId']) - ) + embed = discord.Embed( + description="**All Time account statistics**", + color=discord.Color.dark_red(), + type="rich", + ) + embed.set_author( + name="\nShowing stats for {}".format(stats["name"]), + icon_url="https://stats.quake.com/icons/{}.png".format( + stats["playerLoadOut"]["iconId"] + ), + ) - embed.add_field(name="Current level:", value=stats['playerLevelState']['level']) - embed.add_field(name="Total XP:", value=stats['playerLevelState']['exp']) - embed.add_field(name="K/D:", value=kd_ratio) + embed.add_field(name="Current level:", value=stats["playerLevelState"]["level"]) + embed.add_field(name="Total XP:", value=stats["playerLevelState"]["exp"]) + embed.add_field(name="K/D:", value=kd_ratio) - embed.add_field(name="\u200b", value='\u200b', inline=False) + embed.add_field(name="\u200b", value="\u200b", inline=False) - embed.add_field(name="Favorite Champion:", value=champ_name) - embed.add_field(name="Total Playtime:", value="~{} hours".format(play_time)) + embed.add_field(name="Favorite Champion:", value=champ_name) + embed.add_field(name="Total Playtime:", value="~{} hours".format(play_time)) - embed.add_field(name="\u200b", value='\u200b', inline=False) + embed.add_field(name="\u200b", value="\u200b", inline=False) - embed.add_field(name="Favorite Weapon:", value=fav_weapon) - embed.add_field(name="Num of kills with it:", value=fav_weapon_kills) + embed.add_field(name="Favorite Weapon:", value=fav_weapon) + embed.add_field(name="Num of kills with it:", value=fav_weapon_kills) - embed.add_field(name="\u200b", value='\u200b', inline=False) + embed.add_field(name="\u200b", value="\u200b", inline=False) - # If they've played a ranked match, show the stats - if len(stats['playerRatings']['tdm']['history']): - match_blob = get_match_stats(stats, stats['name']) - embed.add_field(name="Last Ranked Game:", value=match_blob) + # If they've played a ranked match, show the stats + if len(stats["playerRatings"]["tdm"]["history"]): + match_blob = get_match_stats(stats, stats["name"]) + embed.add_field(name="Last Ranked Game:", value=match_blob) - embed.set_footer(text="Stats pulled from https://stats.quake.com", icon_url='https://stats.quake.com/icons/profile_icon_cbt_participant.png') + embed.set_footer( + text="Stats pulled from https://stats.quake.com", + icon_url="https://stats.quake.com/icons/profile_icon_cbt_participant.png", + ) - return embed + return embed def get_favorite_champion(blob): - """ - get_favorite_champion(blob) + """ + get_favorite_champion(blob) - figure out who the players favorite champion is - """ - play_times = {} - all_champions = blob['playerProfileStats']['champions'] + figure out who the players favorite champion is + """ + play_times = {} + all_champions = blob["playerProfileStats"]["champions"] - for champion in all_champions: - for game_mode in blob['playerProfileStats']['champions'][champion]['gameModes']: - if champion in play_times: - play_times[champion] += blob['playerProfileStats']['champions'][champion]['gameModes'][game_mode]['timePlayed'] - play_times[champion] += blob['playerProfileStats']['champions'][champion]['gameModes'][game_mode]['rankedTimePlayed'] - else: - play_times[champion] = blob['playerProfileStats']['champions'][champion]['gameModes'][game_mode]['timePlayed'] - play_times[champion] = blob['playerProfileStats']['champions'][champion]['gameModes'][game_mode]['rankedTimePlayed'] + for champion in all_champions: + for game_mode in blob["playerProfileStats"]["champions"][champion]["gameModes"]: + if champion in play_times: + play_times[champion] += blob["playerProfileStats"]["champions"][ + champion + ]["gameModes"][game_mode]["timePlayed"] + play_times[champion] += blob["playerProfileStats"]["champions"][ + champion + ]["gameModes"][game_mode]["rankedTimePlayed"] + else: + play_times[champion] = blob["playerProfileStats"]["champions"][ + champion + ]["gameModes"][game_mode]["timePlayed"] + play_times[champion] = blob["playerProfileStats"]["champions"][ + champion + ]["gameModes"][game_mode]["rankedTimePlayed"] - champion_play_time = max(play_times.values()) # maximum value - champion_name = [k for k, v in play_times.items() if v == champion_play_time][0] # getting all keys containing the `maximum` + champion_play_time = max(play_times.values()) # maximum value + champion_name = [k for k, v in play_times.items() if v == champion_play_time][ + 0 + ] # getting all keys containing the `maximum` - # Convert play_time from miliseconds to hours - champion_play_time = round(float(champion_play_time)/(1000*60*60), 2) - return(prettify(champion_name), champion_play_time) + # Convert play_time from miliseconds to hours + champion_play_time = round(float(champion_play_time) / (1000 * 60 * 60), 2) + return (prettify(champion_name), champion_play_time) def get_favorite_weapon(blob): - """ - get_favorite_weapon(blob) + """ + get_favorite_weapon(blob) - figure out what the players favorite weapon is - """ - weapon_stats = {} - all_champions = blob['playerProfileStats']['champions'] + figure out what the players favorite weapon is + """ + weapon_stats = {} + all_champions = blob["playerProfileStats"]["champions"] - for champion in all_champions: - for weapon in blob['playerProfileStats']['champions'][champion]['damageStatusList']: - if weapon in weapon_stats: - weapon_stats[weapon] += blob['playerProfileStats']['champions'][champion]['damageStatusList'][weapon]['kills'] - else: - weapon_stats[weapon] = blob['playerProfileStats']['champions'][champion]['damageStatusList'][weapon]['kills'] + for champion in all_champions: + for weapon in blob["playerProfileStats"]["champions"][champion][ + "damageStatusList" + ]: + if weapon in weapon_stats: + weapon_stats[weapon] += blob["playerProfileStats"]["champions"][ + champion + ]["damageStatusList"][weapon]["kills"] + else: + weapon_stats[weapon] = blob["playerProfileStats"]["champions"][ + champion + ]["damageStatusList"][weapon]["kills"] - total_kills = max(weapon_stats.values()) # maximum value - weapon_name = [k for k, v in weapon_stats.items() if v == total_kills][0] # getting all keys containing the `maximum` + total_kills = max(weapon_stats.values()) # maximum value + weapon_name = [k for k, v in weapon_stats.items() if v == total_kills][ + 0 + ] # getting all keys containing the `maximum` - return(prettify(weapon_name), total_kills) + return (prettify(weapon_name), total_kills) def get_kd(blob): - """ - get_kd(blob) + """ + get_kd(blob) - Parses json to find the player's k/d - """ - total_kills = 0 - total_deaths = 0 - all_champions = blob['playerProfileStats']['champions'] + Parses json to find the player's k/d + """ + total_kills = 0 + total_deaths = 0 + all_champions = blob["playerProfileStats"]["champions"] - for champion in all_champions: - for game_mode in blob['playerProfileStats']['champions'][champion]['gameModes']: - total_kills += blob['playerProfileStats']['champions'][champion]['gameModes'][game_mode]['kills'] - total_deaths += blob['playerProfileStats']['champions'][champion]['gameModes'][game_mode]['deaths'] + for champion in all_champions: + for game_mode in blob["playerProfileStats"]["champions"][champion]["gameModes"]: + total_kills += blob["playerProfileStats"]["champions"][champion][ + "gameModes" + ][game_mode]["kills"] + total_deaths += blob["playerProfileStats"]["champions"][champion][ + "gameModes" + ][game_mode]["deaths"] + + return round(float(total_kills / total_deaths), 2) - return round(float(total_kills/total_deaths), 2) - def get_match_stats(blob, target_player): - """ - get_match_stats(blob, target_player) + """ + get_match_stats(blob, target_player) - Takes the stats blob and a player name (so we know who's K/D we care about). - Attempts to figure out what the ranked game type was and then pulls stats from that game - """ - - # Figure out which ranked gametype they last played - game_type = 'tdm' if blob['playerRatings']['tdm']['lastUpdated'] < blob['playerRatings']['duel']['lastUpdated'] else 'duel' + Takes the stats blob and a player name (so we know who's K/D we care about). + Attempts to figure out what the ranked game type was and then pulls stats from that game + """ - most_recent_match_id = blob['playerRatings'][game_type]['history'][0]['sessionId'] - match_endpoint = "Player/Games?id={}".format(most_recent_match_id) - match_data = requests.get("{}{}".format(base_url, match_endpoint)).json() - fav_weapon = match_data['battleReportPersonalStatistics'][0]['bestWeapon'] - accuracy = match_data['battleReportPersonalStatistics'][0]['bestWeaponAccuracyPercent'] - score = '-'.join(str(x) for x in match_data['teamScores']) + # Figure out which ranked gametype they last played + game_type = ( + "tdm" + if blob["playerRatings"]["tdm"]["lastUpdated"] + < blob["playerRatings"]["duel"]["lastUpdated"] + else "duel" + ) - for team_mate in match_data['battleReportPersonalStatistics']: - if team_mate['nickname'].lower() == target_player.lower(): - earnedXp = team_mate['earnedXp'] - earnedFavor = team_mate['earnedFavor'] + most_recent_match_id = blob["playerRatings"][game_type]["history"][0]["sessionId"] + match_endpoint = "Player/Games?id={}".format(most_recent_match_id) + match_data = requests.get("{}{}".format(base_url, match_endpoint)).json() + fav_weapon = match_data["battleReportPersonalStatistics"][0]["bestWeapon"] + accuracy = match_data["battleReportPersonalStatistics"][0][ + "bestWeaponAccuracyPercent" + ] + score = "-".join(str(x) for x in match_data["teamScores"]) - kill_death_ratio = round(float(match_data['battleReportPersonalStatistics'][0]['kills']) / match_data['battleReportPersonalStatistics'][0]['deaths'], 2) - - return_blob = "Final score: {}\nK/D: {}\nFavorite Weapon: {} | {}% Accuracy\nXP Earned: {} | Favor Earned: {}".format( - score, - kill_death_ratio, - prettify(fav_weapon), - accuracy, - earnedXp, - earnedFavor, - ) + for team_mate in match_data["battleReportPersonalStatistics"]: + if team_mate["nickname"].lower() == target_player.lower(): + earnedXp = team_mate["earnedXp"] + earnedFavor = team_mate["earnedFavor"] - return return_blob + kill_death_ratio = round( + float(match_data["battleReportPersonalStatistics"][0]["kills"]) + / match_data["battleReportPersonalStatistics"][0]["deaths"], + 2, + ) + + return_blob = "Final score: {}\nK/D: {}\nFavorite Weapon: {} | {}% Accuracy\nXP Earned: {} | Favor Earned: {}".format( + score, + kill_death_ratio, + prettify(fav_weapon), + accuracy, + earnedXp, + earnedFavor, + ) + + return return_blob def prettify(name): - """ - prettify(name) + """ + prettify(name) - Takes in an items name and returns a cleaned up / readable version - """ + Takes in an items name and returns a cleaned up / readable version + """ - item_map = { - 'UNKNOWN_DAMAGE_TYPE' : 'Unknown Damage Type', - 'GAUNTLET' : 'Gauntlet', - 'MACHINEGUN' : 'Machinegun', - 'MACHINEGUN_GRADE1' : 'Heavy Machinegun', - 'SHOTGUN' : 'Basic Shotgun', - 'SHOTGUN_GRADE1' : 'Super Shotgun', - 'NAILGUN' : 'Nailgun', - 'NAILGUN_GRADE1' : 'Super Nailgun', - 'ROCKET_LAUNCHER' : 'Rocket Launcher', - 'LIGHTNING_GUN' : 'Lightning Gun', - 'RAILGUN' : 'Railgun', - 'LAGBOLT' : 'TriBolt', - 'ACID_DOMAIN' : 'Environmental Acid Death', - 'DAMAGE_DOMAIN' : 'Environmental Damage Death', - 'KILL_DOMAIN' : 'Environmental Kill Death', - 'DIRE_ORB' : 'Dire Orb', - 'DIRE_ORB_EXPLOSION' : 'Dire Orb Explosion', - 'DIRE_ORB_TELEFRAG' : 'Dire Orb Telefrag', - 'UNHOLY' : 'Galena\'s Totem', - 'TELEFRAG' : 'Telefrag', - 'FALL_DAMAGE' : 'Fall Damage', - 'PLASMA_TRAIL' : 'Slash\'s Plasma Trail', - 'PLASMA_TRAIL_EXPLOSION' : 'Slash\'s Plasma Trail Explosion', - 'MINING_LASER' : 'Mining Laser', - 'ABILITY_BERSERK' : 'Doom Slayer\'s Berserk Mode', - 'SWARM_GRENADE' : 'Keel\'s Swarm Grenade', - 'SB_DASH' : 'Scalbarer\'s Rush', - 'SB_STOMP' : 'Scalbarer\'s Stomp', - 'ACID_SPIT_DIRECT' : 'Acid Spit Direct', - 'VENDETTA_TELEFRAG' : 'Vendetta Telefrag', - 'ACID_DOT' : 'Sorlag\'s Acid DOT', - 'FLAME_DOT' : 'Flame DOT', - 'FLAME' : 'Flame', - 'ACID' : 'Acid', - 'DRONE_KAMIKAZE_EXPLOSION' : 'Drone Kamikaze Explosion', - 'RECON_DRONE' : 'Recon Drone', - 'RECON_DRONE_EXPLOSION' : 'Recon Drone Explosion', - 'ANARKI': 'Anarki', - 'ATHENA': 'Athena', - 'BJ_BLAZKOWICZ': 'BJ Blazkowicz', - 'CLUTCH': 'Clutch', - 'DEATH_KNIGHT': 'Death Knight', - 'DOOM_SLAYER': 'Doom Slayer', - 'EISEN': 'Eisen', - 'GALENA': 'Galena', - 'KEEL': 'Keel', - 'NYX': 'Nyx', - 'RANGER': 'Ranger', - 'SCALEBEARER': 'Scalebearer', - 'SLASH': 'Slash', - 'SORLAG': 'Sorlag', - 'STROGG': 'Strogg', - 'VISOR': 'Visor', - } + item_map = { + "UNKNOWN_DAMAGE_TYPE": "Unknown Damage Type", + "GAUNTLET": "Gauntlet", + "MACHINEGUN": "Machinegun", + "MACHINEGUN_GRADE1": "Heavy Machinegun", + "SHOTGUN": "Basic Shotgun", + "SHOTGUN_GRADE1": "Super Shotgun", + "NAILGUN": "Nailgun", + "NAILGUN_GRADE1": "Super Nailgun", + "ROCKET_LAUNCHER": "Rocket Launcher", + "LIGHTNING_GUN": "Lightning Gun", + "RAILGUN": "Railgun", + "LAGBOLT": "TriBolt", + "ACID_DOMAIN": "Environmental Acid Death", + "DAMAGE_DOMAIN": "Environmental Damage Death", + "KILL_DOMAIN": "Environmental Kill Death", + "DIRE_ORB": "Dire Orb", + "DIRE_ORB_EXPLOSION": "Dire Orb Explosion", + "DIRE_ORB_TELEFRAG": "Dire Orb Telefrag", + "UNHOLY": "Galena's Totem", + "TELEFRAG": "Telefrag", + "FALL_DAMAGE": "Fall Damage", + "PLASMA_TRAIL": "Slash's Plasma Trail", + "PLASMA_TRAIL_EXPLOSION": "Slash's Plasma Trail Explosion", + "MINING_LASER": "Mining Laser", + "ABILITY_BERSERK": "Doom Slayer's Berserk Mode", + "SWARM_GRENADE": "Keel's Swarm Grenade", + "SB_DASH": "Scalbarer's Rush", + "SB_STOMP": "Scalbarer's Stomp", + "ACID_SPIT_DIRECT": "Acid Spit Direct", + "VENDETTA_TELEFRAG": "Vendetta Telefrag", + "ACID_DOT": "Sorlag's Acid DOT", + "FLAME_DOT": "Flame DOT", + "FLAME": "Flame", + "ACID": "Acid", + "DRONE_KAMIKAZE_EXPLOSION": "Drone Kamikaze Explosion", + "RECON_DRONE": "Recon Drone", + "RECON_DRONE_EXPLOSION": "Recon Drone Explosion", + "ANARKI": "Anarki", + "ATHENA": "Athena", + "BJ_BLAZKOWICZ": "BJ Blazkowicz", + "CLUTCH": "Clutch", + "DEATH_KNIGHT": "Death Knight", + "DOOM_SLAYER": "Doom Slayer", + "EISEN": "Eisen", + "GALENA": "Galena", + "KEEL": "Keel", + "NYX": "Nyx", + "RANGER": "Ranger", + "SCALEBEARER": "Scalebearer", + "SLASH": "Slash", + "SORLAG": "Sorlag", + "STROGG": "Strogg", + "VISOR": "Visor", + } - return item_map[name] \ No newline at end of file + return item_map[name] diff --git a/app/questions.py b/app/questions.py index 026435e6..e1b6a952 100755 --- a/app/questions.py +++ b/app/questions.py @@ -3,6 +3,7 @@ import wolframalpha import help_methods + def answer_question(message): """ answer_question(question) @@ -12,8 +13,8 @@ def answer_question(message): """ if len(message.split()) > 1: - client = wolframalpha.Client('2LU2Y7-YJQTA7TL8E') - question = ' '.join(message.split()[1:]) + client = wolframalpha.Client("2LU2Y7-YJQTA7TL8E") + question = " ".join(message.split()[1:]) try: res = client.query(question) return next(res.results).text @@ -21,6 +22,6 @@ def answer_question(message): try: return wikipedia.summary(question, sentences=5) except Exception: - return "Sorry, I\'m unable to answer that" + return "Sorry, I'm unable to answer that" - return help_methods.get_help_message('message') + return help_methods.get_help_message("message") diff --git a/app/river_stats.py b/app/river_stats.py index f55c5386..6e48d621 100755 --- a/app/river_stats.py +++ b/app/river_stats.py @@ -5,37 +5,42 @@ import threading results = {} -def get_river_stats(river_id): - url = requests.get("https://waterdata.usgs.gov/usa/nwis/uv?" + river_id) - - soup = BeautifulSoup(url.content, "lxml") - river_name = ' '.join(soup.find('h2').text.split()[2:]) - table = soup.find('table', border=1, align='left') - title = table.find('caption').text.strip().split('--')[0].strip() - for rows in table.findAll('tr'): - flow_value = rows.findAll('td',{'class': 'highlight2'}) - results[river_name] = flow_value[0].text +def get_river_stats(river_id): + url = requests.get("https://waterdata.usgs.gov/usa/nwis/uv?" + river_id) + + soup = BeautifulSoup(url.content, "lxml") + river_name = " ".join(soup.find("h2").text.split()[2:]) + table = soup.find("table", border=1, align="left") + title = table.find("caption").text.strip().split("--")[0].strip() + + for rows in table.findAll("tr"): + flow_value = rows.findAll("td", {"class": "highlight2"}) + results[river_name] = flow_value[0].text def get_stats(): - river_ids = [ - '06752260', - '07091200', - '06719505', - ] - threads = [] - for river in river_ids: - t = threading.Thread(target=get_river_stats, args=(river,)) - threads.append(t) - t.start() + river_ids = [ + "06752260", + "07091200", + "06719505", + ] + threads = [] + for river in river_ids: + t = threading.Thread(target=get_river_stats, args=(river,)) + threads.append(t) + t.start() - for x in threads: - x.join() - - final_string = '' - embed = discord.Embed(description=":man_rowing_boat: Flows :man_rowing_boat:", color=0x428bca, type="rich") - embed.set_author(name="River stats") - for key, value in results.items(): - embed.add_field(name=key, value=value, inline=False) - return embed \ No newline at end of file + for x in threads: + x.join() + + final_string = "" + embed = discord.Embed( + description=":man_rowing_boat: Flows :man_rowing_boat:", + color=0x428BCA, + type="rich", + ) + embed.set_author(name="River stats") + for key, value in results.items(): + embed.add_field(name=key, value=value, inline=False) + return embed diff --git a/app/role_check.py b/app/role_check.py index 44505402..dd5cfb75 100755 --- a/app/role_check.py +++ b/app/role_check.py @@ -5,6 +5,7 @@ This module's purpose is to handle permissions for interacting with the bot. The end goal is to be able to lock certain actions down to certain roles """ + def check_permissions(user, roles_to_check): """ check_permissions(user) @@ -26,7 +27,7 @@ def is_admin(user): Returns true if the user contains the ADMIN role """ - return check_permissions(user, ['ADMIN']) + return check_permissions(user, ["ADMIN"]) def is_mod(user): @@ -35,7 +36,7 @@ def is_mod(user): Returns true if the user contains the Moderator role """ - return check_permissions(user, ['Moderator']) + return check_permissions(user, ["Moderator"]) def docker_permissions(user): diff --git a/app/set_avatar.py b/app/set_avatar.py index eef173e8..5645ffe4 100755 --- a/app/set_avatar.py +++ b/app/set_avatar.py @@ -3,15 +3,16 @@ import requests import core_utils import get_from_reddit + def change_bots_avatar(): image = None while not image: - image = get_from_reddit.get_image(boards='smuganimegirls') - extension = image.split('.')[-1] + image = get_from_reddit.get_image(boards="smuganimegirls") + extension = image.split(".")[-1] local_smug = "/tmp/smug.{}".format(extension) - if extension.lower() in ['png', 'jpg']: + if extension.lower() in ["png", "jpg"]: # save an image locally - return open(core_utils.download_image(image, local_smug), 'rb').read() + return open(core_utils.download_image(image, local_smug), "rb").read() else: image = None diff --git a/app/stock.py b/app/stock.py index 88af41be..9b74820b 100755 --- a/app/stock.py +++ b/app/stock.py @@ -2,48 +2,87 @@ import discord import os import requests + def parse_message(msg): if len(msg.split()) > 1: try: - res = '' + res = "" for s in msg.split()[1:]: res = get_stock(s) except: - res = '```Please input valid shares: !stock [share_name]```' + res = "```Please input valid shares: !stock [share_name]```" return res - return '```Please input at least one valid share: !stock [share_name]```' + return "```Please input at least one valid share: !stock [share_name]```" def get_stock(share_name): share_name = share_name.upper() # Fake headers to make yahoo happy - headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'} - request_string = "https://query1.finance.yahoo.com/v7/finance/quote?lang=en-US®ion=US&corsDomain=finance.yahoo.com&symbols=%s" % share_name - request = requests.get(request_string, headers=headers).json()['quoteResponse']['result'][0] + headers = { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" + } + request_string = ( + "https://query1.finance.yahoo.com/v7/finance/quote?lang=en-US®ion=US&corsDomain=finance.yahoo.com&symbols=%s" + % share_name + ) + request = requests.get(request_string, headers=headers).json()["quoteResponse"][ + "result" + ][0] - change_symbol = '+' + change_symbol = "+" embed_color = 2067276 - meme_url = 'https://i.ytimg.com/vi/if-2M3K1tqk/hqdefault.jpg' + meme_url = "https://i.ytimg.com/vi/if-2M3K1tqk/hqdefault.jpg" # If stock price has gone down since open, use red and a sad stonk meme - if float(request['bid']) < float(request['regularMarketOpen']): - change_symbol = '-' + if float(request["bid"]) < float(request["regularMarketOpen"]): + change_symbol = "-" embed_color = 15158332 - meme_url = 'https://i.ytimg.com/vi/E_XlA_IEzwM/hqdefault.jpg' + meme_url = "https://i.ytimg.com/vi/E_XlA_IEzwM/hqdefault.jpg" - embed = discord.Embed(description='-------', color=embed_color, type="rich") + embed = discord.Embed(description="-------", color=embed_color, type="rich") embed.set_thumbnail(url=meme_url) - embed.set_author(name=request['longName']) - embed.add_field(name='Current Price', value="$%s" % request['bid'], inline=False) - embed.add_field(name='Previous Close', value="$%s" % request['regularMarketPreviousClose'], inline=False) - embed.add_field(name='Opening price', value="$%s" % request['regularMarketOpen'], inline=False) - embed.add_field(name='Change', value="$%s" % request['regularMarketChange'], inline=False) - embed.add_field(name='Change percent', value="%s%%" % request['regularMarketChangePercent'], inline=False) - embed.add_field(name='Day Low', value="$%s" % request['regularMarketDayLow'], inline=False) - embed.add_field(name='Day High', value="$%s" % request['regularMarketDayHigh'], inline=False) - embed.add_field(name='Day\'s Range', value=request['regularMarketDayRange'], inline=False) - embed.add_field(name='Market Cap', value="{:,}".format(request['marketCap']), inline=False) - embed.add_field(name='Shares Outstanding', value="{:,}".format(request['sharesOutstanding']), inline=False) - embed.add_field(name='Link to stock price', value="https://finance.yahoo.com/quote/%s" % share_name, inline=False) - embed.set_footer(text="Pulled from https://finance.yahoo.com\nRemember, stocks can go up 100000%, but they can only go down 100%", icon_url='https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/emojidex/112/chart-with-downwards-trend_1f4c9.png') + embed.set_author(name=request["longName"]) + embed.add_field(name="Current Price", value="$%s" % request["bid"], inline=False) + embed.add_field( + name="Previous Close", + value="$%s" % request["regularMarketPreviousClose"], + inline=False, + ) + embed.add_field( + name="Opening price", value="$%s" % request["regularMarketOpen"], inline=False + ) + embed.add_field( + name="Change", value="$%s" % request["regularMarketChange"], inline=False + ) + embed.add_field( + name="Change percent", + value="%s%%" % request["regularMarketChangePercent"], + inline=False, + ) + embed.add_field( + name="Day Low", value="$%s" % request["regularMarketDayLow"], inline=False + ) + embed.add_field( + name="Day High", value="$%s" % request["regularMarketDayHigh"], inline=False + ) + embed.add_field( + name="Day's Range", value=request["regularMarketDayRange"], inline=False + ) + embed.add_field( + name="Market Cap", value="{:,}".format(request["marketCap"]), inline=False + ) + embed.add_field( + name="Shares Outstanding", + value="{:,}".format(request["sharesOutstanding"]), + inline=False, + ) + embed.add_field( + name="Link to stock price", + value="https://finance.yahoo.com/quote/%s" % share_name, + inline=False, + ) + embed.set_footer( + text="Pulled from https://finance.yahoo.com\nRemember, stocks can go up 100000%, but they can only go down 100%", + icon_url="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/emojidex/112/chart-with-downwards-trend_1f4c9.png", + ) return embed diff --git a/app/trackdays.py b/app/trackdays.py index e9d7496e..8b62de2a 100755 --- a/app/trackdays.py +++ b/app/trackdays.py @@ -3,68 +3,76 @@ import json import requests import xmltodict + def get_msreg(): - base_url = 'https://api.motorsportreg.com/rest/calendars/organization' - orgs = { - 'speeddistrict': '2E22740B-E8C9-9FB9-21406A496429A28B', - 'ongrid' : '06277C99-00C9-23EB-FD08FE5275BCC0C5', - 'speedsf' : '072A885E-AD68-6F64-E88C19E4D0D21DFB', - 'turn8' : 'F3469266-BEFF-E329-4FD6C4B189ACE2A8', - 'speedventures': 'DF7453ED-BF33-DC17-2C9BFD84C1F05E86', - 'nextlevel' : 'CC23AEA4-AAB1-D087-4A10818D229DAFD2', - # 'corsaclub' : 'CE6E69CF-BAEC-DBB6-303EE7D3EC69B8A3', - } - events = {} - for org_name, org_id in orgs.items(): - xml_blob = requests.get("%s/%s?exclude_cancelled=true&postalcode=95035&radius=500" % (base_url, org_id)).text - json_blob = json.loads(json.dumps(xmltodict.parse(xml_blob)['response']['events'])) + base_url = "https://api.motorsportreg.com/rest/calendars/organization" + orgs = { + "speeddistrict": "2E22740B-E8C9-9FB9-21406A496429A28B", + "ongrid": "06277C99-00C9-23EB-FD08FE5275BCC0C5", + "speedsf": "072A885E-AD68-6F64-E88C19E4D0D21DFB", + "turn8": "F3469266-BEFF-E329-4FD6C4B189ACE2A8", + "speedventures": "DF7453ED-BF33-DC17-2C9BFD84C1F05E86", + "nextlevel": "CC23AEA4-AAB1-D087-4A10818D229DAFD2", + "corsaclub": "CE6E69CF-BAEC-DBB6-303EE7D3EC69B8A3", + } + events = {} + for org_name, org_id in orgs.items(): + xml_blob = requests.get( + "%s/%s?exclude_cancelled=true&postalcode=94549&radius=500" + % (base_url, org_id) + ).text + json_blob = json.loads( + json.dumps(xmltodict.parse(xml_blob)["response"]["events"]) + ) - for event in json_blob['event']: - tracks_we_care_about = ["buttonwillow", "thunderhill"] - try: - if any(x in event['name'].lower() for x in tracks_we_care_about): - event_object = { - 'event_name': event['name'], - 'event_url': event['detailuri'].split('?utm')[0], - 'event_date': event['start'], - } - track = event['venue']['name'] - if track not in events: - events[track] = [] - events[track].append(event_object) - except TypeError: - pass - # sort track events by date - def date_to_datetime(input): - return datetime.strptime(input['event_date'], '%Y-%m-%d') - for races in events.values(): - sorted(races, key=date_to_datetime) + for event in json_blob["event"]: + tracks_we_care_about = ["buttonwillow", "thunderhill"] + try: + if any(x in event["name"].lower() for x in tracks_we_care_about): + event_object = { + "event_name": event["name"], + "event_url": event["detailuri"].split("?utm")[0], + "event_date": event["start"], + } + track = event["venue"]["name"] + if track not in events: + events[track] = [] + events[track].append(event_object) + except TypeError: + pass + # sort track events by date + def date_to_datetime(input): + return datetime.strptime(input["event_date"], "%Y-%m-%d") - return events + for races in events.values(): + sorted(races, key=date_to_datetime) + + return events def get_corsa_club(): - base_url = 'https://corsa.club' - events = {} - products_blob = requests.get(base_url + '/products.json').json()['products'] - for event in products_blob: - # Filter out hoodies and what not, only care about track days that list run-groups as the options - if any('Intermediate' in s for s in event['options'][0]['values']): - # pp.pprint(event) - event_object = { - 'event_name': event['title'], - 'event_url': base_url + '/products/' + event['handle'], - 'event_date': event['title'].split()[-1], - } - track = ' '.join(event['title'].split()[0:-1]) - try: - if track not in events: - events[track] = [] - events[track].append(event_object) - except TypeError: - pass + base_url = "https://corsa.club" + events = {} + products_blob = requests.get(base_url + "/products.json").json()["products"] + for event in products_blob: + # Filter out hoodies and what not, only care about track days that list run-groups as the options + if any("Intermediate" in s for s in event["options"][0]["values"]): + # pp.pprint(event) + event_object = { + "event_name": event["title"], + "event_url": base_url + "/products/" + event["handle"], + "event_date": event["title"].split()[-1], + } + track = " ".join(event["title"].split()[0:-1]) + try: + if track not in events: + events[track] = [] + events[track].append(event_object) + except TypeError: + pass + + return events - return events # if __name__ == '__main__': - # get_corsa_club() +# get_corsa_club() diff --git a/app/tts.py b/app/tts.py index ab5951ef..c549c0db 100755 --- a/app/tts.py +++ b/app/tts.py @@ -1,6 +1,7 @@ from gtts import gTTS, lang import tempfile + def text_to_speech(input): """ text_to_speech(input) @@ -10,27 +11,24 @@ def text_to_speech(input): robot """ file, file_path = tempfile.mkstemp() - message = ' '.join(input.split()[1:]) + message = " ".join(input.split()[1:]) - language = 'en' + language = "en" # check for another language denoted at the end of the message - if ';' in message: - print(message.split(';')) - language = message.split(';')[1].strip() - message = message.split(';')[0] + if ";" in message: + print(message.split(";")) + language = message.split(";")[1].strip() + message = message.split(";")[0] - gTTS( - text=message, - lang=language, - slow=False - ).save(file_path) + gTTS(text=message, lang=language, slow=False).save(file_path) return file_path + def get_all_langs(): """ get_all_langs() - + returns a dictionary with all supported languages """ blob = "" @@ -38,4 +36,3 @@ def get_all_langs(): blob += "{}: {}\n".format(key, value) return "```css\n{}```".format(blob) - diff --git a/app/wallpaper.py b/app/wallpaper.py index bec0c9e9..82686baf 100755 --- a/app/wallpaper.py +++ b/app/wallpaper.py @@ -3,6 +3,7 @@ from urllib.parse import urlparse import requests import urllib + def get_wall(message): """ get_wall(message) @@ -17,7 +18,7 @@ def get_wall(message): search_terms = message.split()[1:] # Turn search_terms into strings separated by commas - joined_terms = ','.join(search_terms) + joined_terms = ",".join(search_terms) # Add those comma separated strings onto the end of the URL variable url = unsplash_url + joined_terms @@ -31,11 +32,12 @@ def get_wall(message): response = requests.get(url).url - if 'photo-1446704477871-62a4972035cd' in response: + if "photo-1446704477871-62a4972035cd" in response: return "Could not find an image for those tags." else: return response + def fcking_homepage(): """ fcking_homepage() @@ -46,8 +48,8 @@ def fcking_homepage(): soup = BeautifulSoup(url.content) for pic in soup.find_all("p"): - if 'SWEET-ASS PICTURE' in ''.join(pic.findAll(text=True)): - link = pic.find_next_sibling('p') - if "http://" or "https://" in link.get('href', ''): - link = link.find('small').find_next('a', href=True)['href'] - return urllib.parse.unquote(link.split('=')[1].split('&')[0]) + if "SWEET-ASS PICTURE" in "".join(pic.findAll(text=True)): + link = pic.find_next_sibling("p") + if "http://" or "https://" in link.get("href", ""): + link = link.find("small").find_next("a", href=True)["href"] + return urllib.parse.unquote(link.split("=")[1].split("&")[0]) diff --git a/app/youtube.py b/app/youtube.py index 174246cc..468e2a27 100755 --- a/app/youtube.py +++ b/app/youtube.py @@ -1,9 +1,10 @@ import re from urllib import parse, request -def parse_message(message): - query_string = parse.urlencode({'search_query': message.split()[1:]}) - html_content = request.urlopen('http://www.youtube.com/results?' + query_string) - search_results = re.findall('\/watch\?v=(.{11})', html_content.read().decode()) - return 'https://www.youtube.com/watch?v=' + search_results[0] \ No newline at end of file +def parse_message(message): + query_string = parse.urlencode({"search_query": message.split()[1:]}) + html_content = request.urlopen("http://www.youtube.com/results?" + query_string) + search_results = re.findall("\/watch\?v=(.{11})", html_content.read().decode()) + + return "https://www.youtube.com/watch?v=" + search_results[0]