예제 #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}")
예제 #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)
예제 #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)
예제 #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)]
        )
예제 #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()
예제 #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)
예제 #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()
예제 #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)}",
            ],
        ],
    )
예제 #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)]
        )
예제 #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)
예제 #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)
예제 #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)
예제 #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)
예제 #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)
예제 #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)
예제 #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)
예제 #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)
예제 #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)
예제 #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)
예제 #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])
예제 #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)
예제 #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()
예제 #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)