Example #1
0
    async def on_slash_command_error(ctx: SlashContext, ex: Exception):
        def format_traceback(tback: list):
            return "".join(tback).replace("Aaron", "Secret")

        if isinstance(ex, discord.errors.NotFound):
            return log(f"Skipping a NotFound error", 1)
        elif isinstance(ex, (UserError, AssertionError)):
            embed = build_embed(
                title="Husker Bot User Error",
                description="An error occurred with user input",
                fields=[["Error Message", ex.message]],
            )
        elif isinstance(ex, CommandError):
            embed = build_embed(
                title="Husker Bot Command Error",
                description="An error occurred with command processing",
                fields=[["Error Message", ex.message]],
            )
        else:
            embed = build_embed(
                title="Husker Bot Command Error",
                description="An unknown error occurred",
                fields=[["Error Message", f"{ex.__class__}: {ex}"]],
            )

        await ctx.send(embed=embed)

        traceback_raw = traceback.format_exception(etype=type(ex),
                                                   value=ex,
                                                   tb=ex.__traceback__)

        tback = format_traceback(traceback_raw)
        cmd = ctx.command
        sub_cmd = ""
        if ctx.subcommand_name is not None:
            sub_cmd = ctx.subcommand_name

        inputs = []

        for key, value in ctx.data.items():
            inputs.append(f"{key} = {value}")

        message = (
            f"{ctx.author.mention} ({ctx.author.display_name}, {ctx.author_id}) received an unknown error!\n"
            f"\n"
            f"`/{cmd}{' ' + sub_cmd if sub_cmd is not None else ''} {inputs}`\n"
            f"\n"
            f"```\n{tback}\n```")

        try:
            gee = client.get_user(id=GEE_USER)
            await gee.send(content=message)
        except:
            await ctx.send(content=f"<@{GEE_USER}>\n{message}")
Example #2
0
async def send_welcome_message(who: discord.Member):
    chan_rules = client.get_channel(CHAN_RULES)

    embed = build_embed(
        title="Welcome to the server!",
        description="The official Husker football discord server",
        thumbnail=
        "https://cdn.discordapp.com/icons/440632686185414677/a_061e9e57e43a5803e1d399c55f1ad1a4.gif",
        fields=[
            [
                "Rules",
                f"Please be sure to check out {chan_rules.mention if chan_rules is not None else 'the rules channel'} to catch up on server rules.",
            ],
            [
                "Commands",
                f"View the list of commands with the `/commands` command. Note: commands only work while in the server.",
            ],
            [
                "Roles",
                "You can assign yourself come flair by using the `/roles` command.",
            ],
        ],
    )

    await who.send(embed=embed)
Example #3
0
async def send_tweet_alert(message: str):
    log(f"Receiving Twitter alert", 0)
    log(f"Twitter Alert: {message}", 1)
    chan_twitter: discord.TextChannel = client.get_channel(
        id=CHAN_TWITTERVERSE)

    embed = build_embed(fields=[["Twitter Stream Listener Alert", message]])
    await chan_twitter.send(embed=embed)
Example #4
0
    async def on_component(self, ctx: ComponentContext):
        try:  # Avoid listening to events that don't apply to the vote command
            if "Q:" not in ctx.origin_message.embeds[0].title:
                return
        except:
            return

        embed = ctx.origin_message.embeds[0]
        voters = embed.fields[2].value
        voter_name = ctx.author.mention

        key = embed.footer.text
        if key not in ctx.component_id:  # Avoid over writing other votes
            return

        if voter_name in voters:
            await ctx.send("You cannot vote more than once!", hidden=True)
            return

        query = embed.title.split(": ")[1]
        up_vote_count = int(embed.fields[0].value)
        up_vote_label = ctx.origin_message.components[0]["components"][0]["label"]
        down_vote_count = int(embed.fields[1].value)
        down_vote_label = ctx.origin_message.components[0]["components"][1]["label"]

        if voters == "_":
            voters = voter_name
        else:
            voters += f", {voter_name}"

        if ctx.component_id == f"{key}_a":
            try:
                up_vote_count += 1
            except KeyError:
                raise CommandError(f"Error modifying [{up_vote_label}]")
        elif ctx.component_id == f"{key}_b":
            try:
                down_vote_count += 1
            except KeyError:
                raise CommandError(f"Error modifying [{down_vote_label}]")

        embed = build_embed(
            title=f"Q: {query.capitalize()}",
            description="Times out after 60 seconds.",
            inline=False,
            fields=[
                [up_vote_label, str(up_vote_count)],
                [down_vote_label, str(down_vote_count)],
                ["Voters", voters],
            ],
            footer=key,
        )
        new_buttons = ctx.origin_message.components[0]["components"]

        await ctx.edit_origin(
            content="", embed=embed, components=[create_actionrow(*new_buttons)]
        )
Example #5
0
    async def _urbandictionary(self, ctx: SlashContext, *, word: str):
        r = requests.get(f"http://www.urbandictionary.com/define.php?term={word}")
        soup = BeautifulSoup(r.content, features="html.parser")

        try:
            definitions = soup.find_all(name="div", attrs={"class": "def-panel"})
        except AttributeError:
            raise UserError(f"Unable to find [{word}] in the Urban Dictionary.")

        del r, soup

        if len(definitions) == 0:
            raise UserError(f"Unable to find [{word}] in the Urban Dictionary.")

        try:
            del definitions[1]  # Word of the day
        except IndexError:
            pass

        results = []
        for definition in definitions:
            results.append(
                self.Definition(
                    lookup_word=definition.contents[1].contents[0].text,
                    meaning=definition.contents[2].text,
                    example=definition.contents[3].text,
                    contributor=definition.contents[4].text,
                )
            )

        pages = []
        for index, result in enumerate(results):
            pages.append(
                build_embed(
                    title=f"Searched for: {result.lookup_word}",
                    description=f"Definition #{index + 1} from Urban Dictionary",
                    fields=[
                        ["Meaning", result.meaning],
                        ["Example", result.example],
                        ["Contributor", result.contributor],
                    ],
                )
            )

        await Paginator(
            bot=ctx.bot,
            ctx=ctx,
            pages=pages,
            useIndexButton=True,
            useSelect=False,
            firstStyle=ButtonStyle.gray,
            nextStyle=ButtonStyle.gray,
            prevStyle=ButtonStyle.gray,
            lastStyle=ButtonStyle.gray,
            indexStyle=ButtonStyle.gray,
        ).run()
Example #6
0
async def send_reminder(
    num_seconds,
    destination: typing.Union[discord.Member, discord.TextChannel],
    message: str,
    source: typing.Union[discord.Member, discord.TextChannel],
    alert_when,
    missed=False,
):
    log(
        f"Starting thread for [{pretty_time_delta(num_seconds)}] seconds. Send_When == [{alert_when}].",
        1,
    )

    if not missed:
        log(f"Destination: [{destination}]", 1)
        log(f"Message: [{message[:15] + '...'}]", 1)

        await asyncio.sleep(num_seconds)

        embed = build_embed(
            title="Bot Frost Reminder",
            inline=False,
            fields=[["Author", source.mention], [f"Reminder!", message]],
        )
    else:
        embed = build_embed(
            title="Missed Bot Frost Reminder",
            inline=False,
            fields=[
                ["Original Reminder Date Time", alert_when],
                ["Author", source],
                ["Message", message],
            ],
        )
    await destination.send(embed=embed)

    Process_MySQL(
        sqlUpdateTasks,
        values=(0, str(destination.id), message, alert_when, str(source)),
    )

    log(f"Thread completed successfully!", 0)
Example #7
0
async def on_ready():
    threshold = int(len(client.users) * client_percent)

    log(f"Bot Frost version 3.0", 0)
    log(f"Name: {client.user}", 1)
    log(f"ID: {client.user.id}", 1)
    log(f"Guild: {current_guild()}", 1)
    log(f"HOF/HOS Reaction Threshold: {threshold}", 1)
    log(f"The bot is ready!", 0)

    if "Windows" not in platform.platform():
        try:
            changelog_path = None

            if "Windows" in platform.platform():
                log(f"Windows changelog", 1)
                changelog_path = pathlib.PurePath(
                    f"{pathlib.Path(__file__).parent.resolve()}/changelog.md")
            elif "Linux" in platform.platform():
                log(f"Linux changelog", 0)
                changelog_path = pathlib.PurePosixPath(
                    f"{pathlib.Path(__file__).parent.resolve()}/changelog.md")

            changelog = open(changelog_path, "r")
            lines = changelog.readlines()
            lines_str = ""

            for line in lines:
                lines_str += f"* {str(line)}"
        except OSError:
            lines_str = "Error loading changelog."

        bot_spam = client.get_channel(CHAN_SCOTTS_BOTS)
        embed = build_embed(
            title="Husker Discord Bot",
            fields=[
                [
                    "Info",
                    f"I was restarted, but now I'm back! I'm now online as {client.user.mention}! Check out /commands.",
                ],
                ["HOF/HOS Reaction Threshold", f"{threshold}"],
                ["Changelog", lines_str],
                [
                    "More Changelog",
                    f"[View rest of commits](https://github.com/refekt/Bot-Frost/commits/master)",
                ],
            ],
        )
        await bot_spam.send(embed=embed)

        await change_my_status()
        await load_tasks()
Example #8
0
def ud_embed(embed_word, embed_meaning, embed_example, embed_contributor):
    return build_embed(
        title="Urban Dictionary Result",
        inline=False,
        footer=embed_contributor,
        fields=[
            [embed_word, embed_meaning],
            ["Example", embed_example],
            [
                "Link",
                f"https://www.urbandictionary.com/define.php?term={parse.quote(string=embed_word)}",
            ],
        ],
    )
Example #9
0
    async def _vote(
        self,
        ctx: SlashContext,
        query: str,
        option_a: str = "UP VOTE",
        option_b: str = "DOWN VOTE",
    ):
        if (option_a is not None and option_b is None) or (
            option_b is not None and option_a is None
        ):
            raise UserError("You must provide both options!")

        option_a = str(option_a).upper()
        option_b = str(option_b).upper()

        but_a = ButtonStyle.green
        but_b = ButtonStyle.red

        key = set_component_key()
        buttons_voting = []

        query = query.capitalize()
        if not query.endswith("?"):
            query += "?"

        if option_a != "UP VOTE" and option_b != "DOWN VOTE":  # Non-standard vote
            but_a = but_b = ButtonStyle.gray

        buttons_voting.append(
            create_button(custom_id=f"{key}_a", label=option_a, style=but_a)
        )
        buttons_voting.append(
            create_button(custom_id=f"{key}_b", label=option_b, style=but_b)
        )

        embed = build_embed(
            title=f"Q: {query}",
            inline=False,
            fields=[
                [buttons_voting[-2]["label"], "0"],
                [buttons_voting[-1]["label"], "0"],
                ["Voters", "_"],
            ],
            footer=key,
        )

        await ctx.send(
            content="", embed=embed, components=[create_actionrow(*buttons_voting)]
        )
Example #10
0
    async def _teamstats(self, ctx: SlashContext, team_name: str):
        await ctx.defer()

        team = TeamStatsWinsipediaTeam(team_name=team_name)

        embed = build_embed(
            title=f"{team_name.title()} Historical Stats",
            fields=[
                [
                    "All Time Record",
                    f"{team.all_time_record} ({team.all_time_record_rank})",
                ],
                [
                    "All Time Wins",
                    f"{team.all_time_wins} ({team.all_time_wins_rank})"
                ],
                ["Bowl Games", f"{team.bowl_games} ({team.bowl_games_rank})"],
                [
                    "Bowl Record",
                    f"{team.bowl_record} ({team.bowl_record_rank})"
                ],
                [
                    "Championships",
                    f"{team.championships} ({team.championships_rank})"
                ],
                [
                    "Conference Championships",
                    f"{team.conf_championships} ({team.conf_championships_rank})",
                ],
                [
                    "Consensus All American",
                    f"{team.conf_championships} ({team.conf_championships_rank})",
                ],
                [
                    "Heisman Winners",
                    f"{team.heisman_winners} ({team.heisman_winners_rank})",
                ],
                [
                    "NFL Draft Picks",
                    f"{team.nfl_draft_picks} ({team.nfl_draft_picks_rank})",
                ],
                [
                    "Weeks in AP Poll",
                    f"{team.week_in_ap_poll} ({team.week_in_ap_poll_rank})",
                ],
            ],
            inline=False,
        )
        await ctx.send(embed=embed)
Example #11
0
    async def _crootbot(self, ctx: SlashContext, year: int, search_name: str):
        print(f"[{datetime.datetime.now().astimezone(tz=TZ)}] ### Crootbot")

        if len(search_name) == 0:
            raise UserError("A player's first and/or last search_name is required.")

        if len(str(year)) == 2:
            year += 2000
        elif len(str(year)) == 1 or len(str(year)) == 3:
            raise UserError("The search year must be two or four digits long.")

        if year > datetime.datetime.now().year + 5:
            raise UserError(
                "The search year must be within five years of the current class."
            )

        if year < 1869:
            raise UserError(
                "The search year must be after the first season of college football--1869."
            )

        await ctx.defer()  # Similar to sending a message with a loading screen to edit later on

        log(f"Searching for [{year} {search_name.capitalize()}]", 1)

        global croot_search
        croot_search = FootballRecruit(year, search_name)

        log(f"Found [{len(croot_search)}] results", 1)

        if len(croot_search) == 1:
            return await final_send_embed_fap_loop(
                ctx=ctx, target_recruit=croot_search[0], bot=self.bot
            )

        result_info = search_result_info(croot_search)
        action_row = create_actionrow(*search_buttons)

        embed = build_embed(
            title=f"Search Results for [{year} {search_name.capitalize()}]",
            fields=[["Search Results", result_info]],
        )

        await ctx.send(embed=embed, components=[action_row])

        log(f"Sent search results for [{year} {search_name.capitalize()}]", 1)
Example #12
0
    async def _possumdroppings(self, ctx: SlashContext, message: str):
        await ctx.defer()

        if not ctx.channel_id == CHAN_POSSUMS:
            raise UserError(
                f"You can only use this command in [{ctx.guild.get_channel(CHAN_POSSUMS).mention}]"
            )

        await ctx.send("Thinking...", delete_after=0)

        embed = build_embed(
            title="Possum Droppings",
            inline=False,
            thumbnail="https://cdn.discordapp.com/attachments/593984711706279937/875162041818693632/unknown.jpeg",
            footer="Created by a possum",
            fields=[["Droppings", message]],
        )
        await ctx.send(embed=embed)
Example #13
0
    async def _compare(self, ctx: SlashContext, comparison_team: str,
                       comparison_against: str):
        await ctx.defer()

        comparison_team = comparison_team.replace(" ", "-")
        comparison_against = comparison_against.replace(" ", "-")

        comparison = CompareWinsipedia(compare=comparison_team,
                                       against=comparison_against)
        embed = build_embed(
            title=
            f"Historical records for [{comparison_team.title()}] vs. [{comparison_against.title()}]",
            inline=False,
            fields=[
                [
                    "Links",
                    f"[All Games ]({comparison.full_games_url}) | "
                    f"[{comparison_team.title()}'s Games]({'http://www.winsipedia.com/' + comparison_team.lower()}) |     "
                    f"[{comparison_against.title()}'s Games]({'http://www.winsipedia.com/' + comparison_against.lower()})",
                ],
                [
                    f"{comparison_team.title()}'s Recoard vs. {comparison_against.title()}",
                    comparison.all_time_record,
                ],
                [
                    f"{comparison_team.title()}'s Largest MOV",
                    f"{comparison.compare.largest_mov} ({comparison.compare.largest_mov_date})",
                ],
                [
                    f"{comparison_team.title()}'s Longest Win Streak",
                    f"{comparison.compare.longest_win_streak} ({comparison.compare.largest_win_streak_date})",
                ],
                [
                    f"{comparison_against.title()}'s Largest MOV",
                    f"{comparison.against.largest_mov} ({comparison.against.largest_mov_date})",
                ],
                [
                    f"{comparison_against.title()}'s Longest Win Streak",
                    f"{comparison.against.longest_win_streak} ({comparison.against.largest_win_streak_date})",
                ],
            ],
        )
        await ctx.send(embed=embed)
Example #14
0
    async def _eightball(self, ctx: SlashContext, question: str):
        eight_ball = [
            "As I see it, yes.",
            "Ask again later.",
            "Better not tell you now.",
            "Cannot predict now.",
            "Coach V's cigar would like this!",
            "Concentrate and ask again.",
            "Definitely yes!",
            "Donโ€™t count on it...",
            "Frosty!",
            "F**k Iowa!",
            "It is certain.",
            "It is decidedly so.",
            "Most likely...",
            "My reply is no.",
            "My sources say no.",
            "Outlook not so good and reply hazy",
            "Scott Frost approves!",
            "These are the affirmative answers.",
            "Try again...",
            "Without a doubt.",
            "Yes โ€“ definitely!",
            "You may rely on it.",
        ]

        random.shuffle(eight_ball)

        embed = build_embed(
            title="BotFrost Magic 8-Ball :8ball: says...",
            description="These are all 100% accurate. No exceptions! Unless an answer says anyone other than Nebraska is good.",
            inline=False,
            fields=[
                ["Question", question.capitalize()],
                ["Response", random.choice(eight_ball)],
            ],
            thumbnail="https://i.imgur.com/L5Gpu0z.png",
        )

        await ctx.send(embed=embed)
Example #15
0
    async def _lines(
        self,
        ctx: SlashContext,
        week: int = None,
        team_name: str = "Nebraska",
        year: int = datetime.now().year,
    ):
        log(f"Gathering info for lines", 0)
        games, stats = HuskerSchedule(sport="football", year=year)
        del stats

        lines = None

        if week is None:
            week = get_current_week(year=year, team=team_name)

        week += 1  # account for week 0

        log(f"Current week: {week}", 1)

        icon = None
        for game in games:
            if game.week == week:
                lines = get_consensus_line(team_name=team_name,
                                           year=year,
                                           week=week - 1)
                icon = game.icon
                break

        if lines is None:
            lines = "TBD"

        embed = build_embed(
            title=f"Betting lines for [{team_name.title()}]",
            fields=[["Year", year], ["Week", week - 1], ["Lines", lines]],
            thumbnail=icon,
        )
        await ctx.send(embed=embed)
        log(f"Lines completed", 0)
Example #16
0
    async def _police(self, ctx: SlashContext, arestee: discord.Member):
        message = (
            f"**"
            f"๐Ÿšจ NANI ๐Ÿšจ\n"
            f"..๐Ÿšจ THE ๐Ÿšจ\n"
            f"...๐Ÿšจ F**K ๐Ÿšจ\n"
            f"....๐Ÿšจ DID ๐Ÿšจ\n"
            f".....๐Ÿšจ YOU ๐Ÿšจ\n"
            f"....๐Ÿšจ JUST ๐Ÿšจ\n"
            f"...๐Ÿšจ SAY ๐Ÿšจ\n"
            f"..๐Ÿšจ {arestee.mention} ๐Ÿšจ\n"
            f"๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ ๐Ÿ”ซ๐Ÿš“๐Ÿ”ซ๐Ÿš“๐Ÿ”ซ๐Ÿš“\n"
            f"\n"
            f"๐Ÿ‘ฎโ€๐Ÿ“ข Information โ„น provided in the VIP ๐Ÿ‘‘ Room ๐Ÿ† is intended for Husker247 ๐ŸŒฝ๐ŸŽˆ members only โ€ผ๐Ÿ”ซ. Please do not copy โœ and paste ๐Ÿ–จ or summarize this content elsewhereโ€ผ Please try to keep all replies in this thread ๐Ÿงต for Husker247 members only! ๐Ÿšซ โ›” ๐Ÿ‘Ž "
            f"๐Ÿ™…โ€โ™€๏ธThanks for your cooperation. ๐Ÿ˜๐Ÿคฉ๐Ÿ˜˜"
            f"**"
        )

        embed = build_embed(
            title="Wee woo wee woo!", inline=False, fields=[["Halt!", message]]
        )
        await ctx.send(embed=embed)
Example #17
0
    async def _fap_predict(self, ctx: SlashContext, year: int, search_name: str):
        if len(str(year)) == 2:
            year += 2000

        if year > datetime.datetime.now().year + 5:
            raise UserError(
                "The search year must be within five years of the current class."
            )

        if year < 1869:
            raise UserError(
                "The search year must be after the first season of college football--1869."
            )

        await ctx.defer(hidden=True)

        global fap_search
        fap_search = FootballRecruit(year, search_name)

        if type(fap_search) == commands.UserInputError:
            return await ctx.send(content=fap_search, hidden=True)

        async def send_fap_convo(target_recruit):
            await initiate_fap(
                ctx=ctx, user=ctx.author, recruit=target_recruit, client=ctx.bot
            )

        if len(fap_search) == 1:
            return await send_fap_convo(fap_search[0])

        result_info = search_result_info(fap_search)
        action_row = create_actionrow(*search_buttons)

        embed = build_embed(
            title=f"Search Results for [{year} {search_name.capitalize()}]",
            fields=[["Search Results", result_info]],
        )

        await ctx.send(embed=embed, components=[action_row], hidden=True)
Example #18
0
    async def _remindme(
        self,
        ctx: SlashContext,
        remind_when: str,
        message: str,
        who: discord.member = None,
        channel: discord.TextChannel = None,
    ):
        if who and channel:
            raise UserError(
                "You cannot input both a member and channel to remind.")
        elif who and not ctx.author == who:
            raise UserError(
                "You cannot set reminders for anyone other than yourself!")
        elif channel in CHAN_BANNED:
            raise ValueError(
                f"Setting reminders in {channel.mention} is banned!")

        await ctx.defer()

        today = datetime.today()

        def convert_dt_value(dt_item: str, from_when: str):

            if dt_item in from_when:
                raw = from_when.split(dt_item)[0]
                if raw.isnumeric():
                    return int(raw)
                else:
                    try:
                        findall = re.findall(r"\D", raw)[-1]
                        return int(raw[raw.find(findall) + 1:])
                    except:
                        return 0
            else:
                return 0

        days = convert_dt_value(DateTimeStrings.day, remind_when)
        hours = convert_dt_value(DateTimeStrings.hour, remind_when)
        minutes = convert_dt_value(DateTimeStrings.minute, remind_when)
        seconds = convert_dt_value(DateTimeStrings.seconds, remind_when)

        time_diff = timedelta(days=days,
                              hours=hours,
                              minutes=minutes,
                              seconds=seconds)

        min_timer_allowed = 5  # 60 * 5

        if time_diff.total_seconds() < min_timer_allowed:
            raise UserError(
                f"The num_seconds entered is too short! The minimum allowed timer is {min_timer_allowed} seconds."
            )

        try:
            raw_when = today + time_diff
        except ValueError:
            raise UserError("The num_seconds entered is too large!")

        duration = raw_when - today
        send_when = today + duration
        mysql_author = f"{ctx.author.name}#{ctx.author.discriminator}"
        is_open = 1

        if who:
            destination = who
        elif channel:
            destination = channel
        else:
            destination = ctx.channel

        try:
            Process_MySQL(
                sqlRecordTasks,
                values=(
                    str(destination.id),
                    message,
                    str(send_when),
                    is_open,
                    mysql_author,
                ),
            )
            destination = ctx.channel
        except:
            raise CommandError("Error submitting MySQL")

        nest_asyncio.apply()
        asyncio.create_task(
            send_reminder(
                num_seconds=duration.total_seconds(),
                destination=destination,
                message=message,
                source=ctx.author,
                alert_when=str(send_when),
            ))

        embed = build_embed(
            title="Bot Frost Reminders",
            description=
            f"Setting a timer for [{destination.mention}] in [{pretty_time_delta(duration.total_seconds())}]. The timer will go off at [{send_when.strftime('%x %X')}].",
            inline=False,
            fields=[["Author", ctx.author.mention], ["Message", message]],
        )
        await ctx.send(embed=embed)
Example #19
0
async def hall_of_fame_messages(reactions: list):
    multiple_threshold = False
    for reaction in reactions:
        if (
                multiple_threshold
        ):  # Rare instance where a message has multiple reactions that break the threshold
            break

        if reaction.message.channel.id in (
                CHAN_HOF_PROD,
                CHAN_SHAME,
        ):  # Stay out of HOF and HOS
            continue

        slowpoke_emoji = "<:slowpoke:758361250048245770>"
        server_member_count = len(client.users)
        reaction_threshold = int(client_percent * server_member_count)
        hos_channel = hof_channel = None

        if reaction.count >= reaction_threshold:
            multiple_threshold = True
            log(
                f"Reaction threshold broken with [{reaction.count}] [{reaction.emoji}] in [{reaction.message.channel}] reactions",
                0,
            )
            if str(reaction.emoji) == slowpoke_emoji:
                hof = False
                hos_channel = client.get_channel(id=CHAN_SHAME)
                raw_message_history = await hos_channel.history(limit=5000
                                                                ).flatten()
            else:
                hof = True
                hof_channel = client.get_channel(id=CHAN_HOF_PROD)
                raw_message_history = await hof_channel.history(limit=5000
                                                                ).flatten()

            duplicate = False
            for raw_message in raw_message_history:
                if len(raw_message.embeds) > 0:
                    if str(reaction.message.id
                           ) in raw_message.embeds[0].footer.text:
                        duplicate = True
                        break
            del raw_message_history

            if not duplicate:
                slowking_path = None

                if not hof:
                    embed_title = f"{slowpoke_emoji * 3} Hall of Shame Message {slowpoke_emoji * 3}"
                    embed_description = (
                        "Messages so shameful they had to be memorialized forever!"
                    )
                    channel = hos_channel

                    avatar_url = (str(
                        reaction.message.author.avatar_url).split("?")
                                  [0].replace("webp", "png"))
                    make_slowking(avatar_url)
                    slowking_path = f"{pathlib.Path(__file__).parent.resolve()}\\resources\\images\\new_slowking.png"
                    slowking_path = upload_picture(slowking_path)
                else:
                    embed_title = f"{'๐Ÿ†' * 3} Hall of Fame Message {'๐Ÿ†' * 3}"
                    embed_description = (
                        "Messages so amazing they had to be memorialized forever!"
                    )
                    channel = hof_channel

                embed = build_embed(
                    title=embed_title,
                    description=embed_description,
                    thumbnail=slowking_path if not None else None,
                    fields=[
                        ["Author", reaction.message.author.mention],
                        ["Message", reaction.message.content],
                        [
                            "Message Link",
                            f"[Click to view message]({reaction.message.jump_url})",
                        ],
                    ],
                    footer=
                    f"Message ID: {reaction.message.id} | Hall of Shame message created at {reaction.message.created_at.strftime('%B %d, %Y at %H:%M%p')}",
                )
                await channel.send(embed=embed)
                log(f"Processed HOF/HOS message.", 0)
Example #20
0
async def send_tweet(tweet):
    if tweet.author.id_str not in [
            member["id_str"] for member in list_members
    ]:
        return

    direct_url = (
        f"https://twitter.com/{tweet.author.screen_name}/status/{tweet.id_str}/"
    )

    if hasattr(tweet, "extended_tweet"):
        fields = [["Message", tweet.extended_tweet["full_text"]]]
    else:
        fields = [["Message", tweet.text]]

    embed = build_embed(
        url="https://twitter.com/i/lists/1307680291285278720",
        fields=fields,
        footer=f"Tweet sent {tweet.created_at.strftime(DT_TWEET_FORMAT)}",
    )

    embed.set_author(
        name=
        f"{tweet.author.name} (@{tweet.author.screen_name}) via {tweet.source}",
        icon_url=tweet.author.profile_image_url_https,
    )

    if hasattr(tweet, "extended_entities"):
        try:
            for index, media in enumerate(tweet.extended_entities["media"]):
                if index == 0:
                    embed.set_image(url=tweet.extended_entities["media"][index]
                                    ["media_url"])
                embed.add_field(
                    name=f"Media #{index + 1}",
                    value=f"[Link #{index + 1}]({media['media_url']})",
                    inline=False,
                )
        except:
            pass

    log(f"Sending tweeit from @{tweet.author.screen_name}", 1)
    chan_twitter: discord.TextChannel = client.get_channel(
        id=CHAN_TWITTERVERSE)

    buttons = [
        create_button(
            style=ButtonStyle.gray,
            custom_id=f"{set_component_key()}_send_to_general",
            label="Send to General",
        ),
        create_button(
            style=ButtonStyle.gray,
            custom_id=f"{set_component_key()}_send_to_recruiting",
            label="Send to Recruiting",
        ),
        create_button(style=ButtonStyle.URL,
                      label="Open Tweet",
                      url=direct_url),
    ]
    actionrow = create_actionrow(*buttons)
    # noinspection PyArgumentList
    await chan_twitter.send(embed=embed, components=[actionrow])
Example #21
0
    async def _weather(
        self, ctx: SlashContext, city: str, state: str, country: str = "US"
    ):
        def shift_utc_tz(dt, shift):
            return dt + timedelta(seconds=shift)

        if not len(state) == 2:
            raise UserError("State input must be the two-digit state code.")

        found = False
        for item in US_STATES:
            if item.get("Code") == state.upper():
                found = True
                break
        if not found:
            raise UserError(
                f"Unable to find the state {state.upper()}. Please try again!"
            )

        weather_url = f"https://api.openweathermap.org/data/2.5/weather?appid={WEATHER_API_KEY}&units=imperial&lang=en&q={city},{state},{country}"
        response = requests.get(weather_url, headers=HEADERS)
        j = json.loads(response.content)

        weather = WeatherResponse(j)
        if weather.cod == "404":
            raise UserError(
                f"Unable to find {city.title()}, {state.upper()}. Try again!"
            )

        temp_str = (
            f"Temperature: {weather.main.temp}โ„‰\n"
            f"Feels Like: {weather.main.feels_like}โ„‰\n"
            f"Humidity: {weather.main.humidity}%\n"
            f"Max: {weather.main.temp_max}โ„‰\n"
            f"Min: {weather.main.temp_min}โ„‰"
        )

        if len(weather.wind) == 2:
            wind_str = (
                f"Speed: {weather.wind.speed} MPH\n" f"Direction: {weather.wind.deg} ยฐ"
            )
        elif len(weather.wind) == 3:
            wind_str = (
                f"Speed: {weather.wind.speed} MPH\n"
                f"Gusts: {weather.wind.gust} MPH\n"
                f"Direction: {weather.wind.deg} ยฐ"
            )
        else:
            wind_str = f"Speed: {weather.wind.speed} MPH"

        hourly_url = f"https://api.openweathermap.org/data/2.5/onecall?lat={weather.coord.lat}&lon={weather.coord.lon}&appid={WEATHER_API_KEY}&units=imperial"
        response = requests.get(hourly_url, headers=HEADERS)
        j = json.loads(response.content)
        hours = []
        for index, item in enumerate(j["hourly"]):
            hours.append(WeatherHour(item))
            if index == 3:
                break

        hour_temp_str = ""
        hour_wind_str = ""
        for index, hour in enumerate(hours):
            if index < len(hours) - 1:
                hour_temp_str += f"{hour.temp}โ„‰ ยป "
                hour_wind_str += f"{hour.wind_speed} MPH ยป "
            else:
                hour_temp_str += f"{hour.temp}โ„‰"
                hour_wind_str += f"{hour.wind_speed} MPH"

        sunrise = shift_utc_tz(weather.sys.sunrise, weather.timezone)
        sunset = shift_utc_tz(weather.sys.sunset, weather.timezone)

        sun_str = (
            f"Sunrise: {sunrise.astimezone(tz=TZ).strftime(DT_OPENWEATHER_UTC)}\n"
            f"Sunset: {sunset.astimezone(tz=TZ).strftime(DT_OPENWEATHER_UTC)}"
        )

        embed = build_embed(
            title=f"Weather conditions for {city.title()}, {state.upper()}",
            description=f"It is currently {weather.weather[0].main} with {weather.weather[0].description}. {city.title()}, {state.upper()} is located at {weather.coord.lat}, {weather.coord.lon}.",
            fields=[
                ["Temperature", temp_str],
                ["Clouds", f"Coverage: {weather.clouds.all}%"],
                ["Wind", wind_str],
                ["Temp Next 4 Hours", hour_temp_str],
                ["Wind Next 4 Hours", hour_wind_str],
                ["Sun", sun_str],
            ],
            inline=False,
            thumbnail=f"https://openweathermap.org/img/wn/{weather.weather[0].icon}@4x.png",
        )

        await ctx.send(embed=embed)
Example #22
0
    async def _seasonstats(
        self,
        ctx: SlashContext,
        team_name: str = "Nebraska",
        year: int = datetime.now().year,
    ):
        cfb_api = StatsApi(ApiClient(cfbd_config))

        try:
            api_response = cfb_api.get_team_season_stats_with_http_info(
                year=year, team=team_name)
        except ApiException:
            return None

        season_stats = {}
        for stat in api_response[0]:
            season_stats[stat.stat_name] = stat.stat_value

        pages = [
            # Offense
            build_embed(fields=[
                [
                    "Offense",
                    f"**Total Yards**: {season_stats.get('totalYards', 0):,}\n"
                    f"---\n"
                    f"**Rushing Attempts**: {season_stats.get('rushingAttempts', 0):,}\n"
                    f"**Rushing Yards**: {season_stats.get('rushingYards', 0):,}\n"
                    f"**Rushing TDs**: {season_stats.get('rushingTDs', 0)}\n"
                    f"---\n"
                    f"**Pass Attempts**: {season_stats.get('passAttempts', 0):,}\n"
                    f"**Pass Completions**: {season_stats.get('passCompletions', 0):,}\n"
                    f"**Passing Yards**: {season_stats.get('netPassingYards', 0):,}\n"
                    f"**Passing TDs**: {season_stats.get('passingTDs', 0)}\n"
                    f"---\n"
                    f"**First Downs**: {season_stats.get('firstDowns', 0):,}\n"
                    f"**Third Downs**: {season_stats.get('thirdDowns', 0):,}\n"
                    f"**Third Down Conversions**: {season_stats.get('thirdDownConversions', 0):,}\n"
                    f"**Fourth Downs**: {season_stats.get('fourthDowns', 0)}\n"
                    f"**Fourth Down Conversions**: {season_stats.get('fourthDownConversions', 0)}\n"
                    f"---\n"
                    f"**Interceptions Thrown**: {season_stats.get('interceptions', 0)}\n"
                    f"---\n"
                    f"**Time of Possession**: {pretty_time_delta(season_stats.get('possessionTime', 0))}\n",
                ],
            ], ),
            # Defense
            build_embed(fields=[
                [
                    "Defense",
                    f"**Tackles for Loss**: {season_stats.get('tacklesForLoss', 0)}\n"
                    f"**Sacks**: {season_stats.get('sacks', 0)}\n"
                    f"**Passes Intercepted**: {season_stats.get('passesIntercepted', 0)}\n"
                    f"**Interception Yards**: {season_stats.get('interceptionYards', 0)}\n"
                    f"**Interception TDs**: {season_stats.get('interceptionTDs', 0)}\n",
                ],
            ], ),
            # Special Teams
            build_embed(fields=[
                [
                    "Special Teams",
                    f"**Kick Returns**: {season_stats.get('kickReturns', 0)}\n"
                    f"**Kick Return Yards**: {season_stats.get('kickReturnYards', 0):,}\n"
                    f"**Kick Return TDs**: {season_stats.get('kickReturnTDs', 0)}\n"
                    f"---\n"
                    f"**Punt Returns**: {season_stats.get('puntReturns', 0)}\n"
                    f"**Punt Return Yards**: {season_stats.get('puntReturnYards', 0):,}\n"
                    f"**Punt Return TDs**: {season_stats.get('puntReturnTDs', 0)}\n",
                ],
            ], ),
            # Penalties
            build_embed(fields=[
                [
                    "Penalties",
                    f"**Penalties**: {season_stats.get('penalties', 0)}\n"
                    f"**Penalty Yards**: {season_stats.get('penaltyYards', 0):,}\n",
                ],
            ], ),
            # Fumbles and Turnovers
            build_embed(fields=[
                [
                    "Fumbles and Turnovers",
                    f"**Fumbles Lost**: {season_stats.get('fumblesLost', 0)}\n"
                    f"**Fumbles Recovered**: {season_stats.get('fumblesRecovered', 0)}\n"
                    f"**Turnovers**: {season_stats.get('turnovers', 0)}\n",
                ],
            ], ),
        ]

        content = [
            f"{team_name.title()}'s {year} Offensive Stats",
            f"{team_name.title()}'s {year} Defensive Stats",
            f"{team_name.title()}'s {year} Special Teams Stats",
            f"{team_name.title()}'s {year} Penalties Stats",
            f"{team_name.title()}'s {year} Fumble and Turnover Stats",
        ]

        await Paginator(
            bot=ctx.bot,
            ctx=ctx,
            pages=pages,
            content=content,
            useIndexButton=True,
            useSelect=False,
            firstStyle=ButtonStyle.gray,
            nextStyle=ButtonStyle.gray,
            prevStyle=ButtonStyle.gray,
            lastStyle=ButtonStyle.gray,
            indexStyle=ButtonStyle.gray,
        ).run()
Example #23
0
    async def predict(self, ctx, year: int, *name):
        """Put in a FAP prediction for a recruit."""
        from utilities.embed import build_embed

        if len(name) == 0:
            raise discord.ext.commands.UserInputError(
                "A player's first and/or last name is required."
            )

        if len(str(year)) == 2:
            year += 2000

        if year > datetime.datetime.now().year + 5:
            raise discord.ext.commands.UserInputError(
                "The search year must be within five years of the current class."
            )

        if year < 1869:
            raise discord.ext.commands.UserInputError(
                "The search year must be after the first season of college football--1869."
            )

        edit_msg = await ctx.send("Loading...")
        search = FootballRecruit(year, name)

        if type(search) == commands.UserInputError:
            await edit_msg.edit(content=search)
            return

        async def send_fap_convo(target_recruit):
            await initiate_fap(ctx.message.author, target_recruit, self.bot)

        if len(search) == 1:
            await edit_msg.delete()
            await send_fap_convo(search[0])
            return

        result_info = ""
        search_reactions = {
            "1๏ธโƒฃ": 0,
            "2๏ธโƒฃ": 1,
            "3๏ธโƒฃ": 2,
            "4๏ธโƒฃ": 3,
            "5๏ธโƒฃ": 4,
            "6๏ธโƒฃ": 5,
            "7๏ธโƒฃ": 6,
            "8๏ธโƒฃ": 7,
            "9๏ธโƒฃ": 8,
            "๐Ÿ”Ÿ": 9,
        }

        index = 0

        for index, result in enumerate(search):
            if index < 10:
                result_info += f"{list(search_reactions.keys())[index]}: {result.year} - {'โญ' * result.rating_stars}{' - ' + result.position if result.rating_stars > 0 else result.position} - {result.name}\n"

        embed = build_embed(
            title=f"Search Results for [{year} {[n for n in name]}]",
            fields=[["Search Results", result_info]],
        )

        await edit_msg.edit(content="", embed=embed)

        for reaction in list(search_reactions.keys())[0 : index + 1]:
            await edit_msg.add_reaction(reaction)

        def checking_reaction(reaction, user):
            if not user.bot:
                return (reaction.emoji in search_reactions) and (
                    user == ctx.message.author
                )

        search_result_player = None

        try:
            reaction, user = await self.bot.wait_for(
                "reaction_add", check=checking_reaction
            )
        except asyncio.TimeoutError:
            pass
        else:
            search_result_player = search[search_reactions[reaction.emoji]]

        try:
            await edit_msg.delete()
        except discord.HTTPException:
            log(f"Deleting the message failed.", 1)
        except discord.ClientException:
            log(f"Unable to delete message due to lack of permissions.", 1)

        await send_fap_convo(search_result_player)