Example #1
0
 async def cog_before_invoke(self, ctx: discord.ext.commands.Context):
     ctx.player = Player.objects(dis_id=str(ctx.author.id)).first()
     if ctx.player is None:
         ctx.player = Player(dis_id=str(ctx.author.id),
                             name=ctx.author.name,
                             house=[i.name for i in ctx.author.roles if i.name in self.houses][0],
                             items=[]).save()
Example #2
0
def init_cleanup(ctx: discord.ext.commands.Context) -> None:
    if not hasattr(ctx, "cleanup"):
        ref = CleanupReference(ctx)
        ctx.cleanup = ref # type: ignore

        old_send = ctx.send
        async def send(*args: Any, **kwargs: Any) -> discord.Message:
            msg = await old_send(*args, **kwargs)
            ref.add(msg)
            return msg
        ctx.send = send # type: ignore
Example #3
0
    async def iv(self, ctx: discord.ext.commands.Context, ticker: str = None):
        """Displays ticker options IV [Barchart]

        Parameters
        -----------
        ticker: str
            ticker,
        """
        async with ctx.typing():
            await asyncio.sleep(0.2)

            await iv_command(ctx, ticker)
Example #4
0
async def role(ctx: discord.ext.commands.Context,
               name: str = None,
               color: discord.ext.commands.ColourConverter = None):
    print(f"{ctx.author}: {ctx.message.content}")
    role = get_highest_editable_role(ctx.author, ctx.me)
    if not color:
        if role:
            color = role.color
        else:
            # gets @everyone and the default color (#000000)
            color = ctx.author.top_role.color
    async with ctx.typing():
        # if this is not here it continues "typing" after done
        await asyncio.sleep(0.1)
        if name:
            if name in data["blacklisted_roles"]:
                await ctx.send(
                    "That name is not allowed! Please choose another one instead."
                )
                return
            if role:
                await role.edit(color=color, name=name, hoist=True)
            else:
                tmp_role: discord.Role = await ctx.guild.create_role(
                    color=color, name=name, hoist=True)
                await tmp_role.edit(position=data["insert_role_position"])
                await ctx.author.add_roles(tmp_role)
                if data["auto_role"]:
                    await ctx.author.add_roles(
                        ctx.guild.get_role(data["auto_role"]))

            embed = discord.Embed(
                title=
                f"Set {ctx.author.display_name}'s role to \"{name}\" with the color `{color}`"
            )
            embed.color = color
            await ctx.send(embed=embed)
        else:
            if role:
                embed = discord.Embed(
                    title=
                    f"Your role name is \"{role.name}\" and has the color `{role.color}`"
                )
                embed.color = role.color
                await ctx.send(embed=embed)
            else:
                await ctx.send(
                    "It looks like you need to set a role first. Try `!role \"role name\" #789abc`"
                )
Example #5
0
    async def unu(
        self,
        ctx: discord.ext.commands.Context,
        num: int = None,
    ):
        """Unusual Options

        Parameters
        -----------
        ticker: str
            ticker
        """
        async with ctx.typing():
            await asyncio.sleep(0.2)

            await unu_command(ctx, num)
Example #6
0
    async def automatic_get_jsons(
            self,
            ctx: discord.ext.commands.Context,
            last_message: Optional[discord.Message],
            channel: Optional[discord.TextChannel] = None,
            use_flashfreze: Optional[bool] = False):
        l.debug(
            f"pending fixes command invoked from {ctx.author.id} in channel {ctx.channel.id} - {ctx.message.jump_url}"
        )
        if not channel:
            channel = self.bot.get_channel(PENDING_FIXES_CHANNEL)
        async with ctx.typing():
            if last_message is not None:
                await ctx.send(
                    f"Getting all jsons in {channel.mention} not marked with a тЪая╕П  before <{last_message.jump_url}> and after the pin. "
                    f"Sit back and relax, this will take a while {COOL_CRAB}.")

                final_folder, start_date, end_date = await self.get_raw_json_messages_in_pending_fixes(
                    last_message, channel)
            else:
                await ctx.send(
                    f"Getting all jsons in {channel.mention} not marked with a тЪая╕П since the pin. "
                    f"Sit back and relax, this will take a while {COOL_CRAB}.")
                final_folder, start_date, end_date = await self.get_raw_json_messages_in_pending_fixes(
                    None, channel)

            archive = shutil.make_archive(
                f'pending_fixes {start_date} to {end_date}', 'zip',
                final_folder)
            l.debug(f"Sending fetched pending fixes")
            try:
                if not use_flashfreze:
                    await ctx.send(file=discord.File(archive))
                else:
                    await self.send_with_flashfreeze(ctx, archive)
            except HTTPException:
                await ctx.send(
                    "Resulting file too large, sending as to flashfreeze instead."
                )
                await self.send_with_flashfreeze(ctx, archive)

        shutil.rmtree(final_folder, True)
        os.remove(archive)
Example #7
0
 async def raw_react(cls, ctx: discord.ext.commands.Context, characters: str, member: discord.Member = None):
     """Adds provided emojis to the specified member's last non-command message in the form of reactions.
     If no member was specified, adds emojis to the last non-command message sent in the given channel.
     """
     if member is not None and member != ctx.author:
         async for message in ctx.history(limit=15):
             if message.author == member:
                 for reaction in characters:
                     try:
                         await message.add_reaction(reaction)
                     except discord.HTTPException:
                         pass
                 break
     else:
         messages = await ctx.history(limit=2).flatten()
         for reaction in characters:
             try:
                 await messages[1].add_reaction(reaction)
             except discord.HTTPException:
                 pass
Example #8
0
async def automod_add(ctx: discord.ext.commands.Context, kind: Literal["substring", "word", "regex"],
    patterns: discord.ext.commands.Greedy[Union[util.discord.CodeBlock, util.discord.Inline, str]]) -> None:
    """
        Add an automod pattern with one or more keywords.
        "substring" means the patterns will be matched anywhere in a message;
        "word" means the patterns have to match a separate word;
        "regex" means the patterns are case-insensitive regexes (use (?-i) to enable case sensitivity)
    """
    await ctx.message.delete()
    ctx.send = ctx.channel.send # type: ignore # Undoing the effect of cleanup
    if len(patterns) == 0:
        raise util.discord.InvocationError("Provide at least one pattern")
    keywords: List[str] = []
    for pattern in patterns:
        if isinstance(pattern, (util.discord.CodeBlock, util.discord.Inline)):
            pattern = pattern.text
        if kind == "regex":
            try:
                regex = re.compile(pattern)
            except Exception as exc:
                raise util.discord.UserError("Could not compile regex: {}".format(exc))
            if regex.search("") is not None:
                raise util.discord.UserError("Regex matches empty string, that's probably not good")
        else:
            if pattern == "":
                raise util.discord.UserError("The pattern is empty, that's probably not good")
        keywords.append(pattern)

    for i in range(conf.index):
        if conf[i, "keyword"] == keywords and conf[i, "type"] == kind and conf[i, "action"] == None:
            break
    else:
        i = conf.index
        conf.index += 1
        conf[i, "keyword"] = util.frozen_list.FrozenList(keywords)
        conf[i, "type"] = kind
        conf[i, "action"] = None
        await conf
    await ctx.send("Added as pattern **{}** with no action".format(i))
Example #9
0
    async def calls(self,
                    ctx: discord.ext.commands.Context,
                    ticker: str = None,
                    expiry: str = None):
        """Get call options for ticker and given expiration

        Parameters
        ----------
        ticker: str
            Stock ticker
        expiry: str
            accepts 0-9 or YYYY-MM-DD
            0 weeklies, 1+ for weeks out
            prompts reaction helper if empty
        """
        logger.info("!stocks.opt.calls %s %s", ticker, expiry)
        async with ctx.typing():
            await asyncio.sleep(0.2)

            func_cmd = calls_command

            await expiry_dates_reaction(ctx, ticker, expiry, func_cmd)
Example #10
0
    async def puts(
        self, ctx: discord.ext.commands.Context, ticker: str = None, expiry: str = None
    ):
        """Get put options for ticker and given expiration

        Parameters
        ----------
        ticker: str
            Stock ticker
        expiry: str
            accepts 0-9 or YYYY-MM-DD
            0 weeklies, 1+ for weeks out
            prompts reaction helper if empty
        """
        async with ctx.typing():
            await asyncio.sleep(0.2)

            if cfg.DEBUG:
                print(f"!stocks.opt.puts {ticker} {expiry}")

            func_cmd = puts_command

            await expiry_dates_reaction(ctx, ticker, expiry, func_cmd)
Example #11
0
    async def vol(
        self,
        ctx: discord.ext.commands.Context,
        ticker: str = None,
        expiry: str = None,
        min_sp: float = None,
        max_sp: float = None,
    ):
        """Display options volume for ticker and given expiration

        Parameters
        -----------
        ticker: str
            ticker
        strike: float
            strike
        expiry: str
            accepts 0-9 or YYYY-MM-DD
        min_sp: float
            min strike price
        max_sp:float
            max strike price

        Sends a message to the discord user with the expiry dates if empty.
        The user can then select a reaction to trigger the selected date.
        """
        logger.info("stocks.opt.vol %s %s %s %s", ticker, expiry, min_sp,
                    max_sp)
        async with ctx.typing():
            await asyncio.sleep(0.2)

            call_arg = (min_sp, max_sp)
            func_cmd = vol_command

            await expiry_dates_reaction(ctx, ticker, expiry, func_cmd,
                                        call_arg)
Example #12
0
    async def oi(
        self,
        ctx: discord.ext.commands.Context,
        ticker: str = None,
        expiry: str = None,
        min_sp: float = None,
        max_sp: float = None,
    ):
        """Display options open interest for ticker and given expiration [Max Pain]

        Parameters
        -----------
        ticker: str
            ticker
        strike: float
            strike
        expiry: str
            accepts 0-9 or YYYY-MM-DD
        min_sp: float
            min strike price
        max_sp:float
            max strike price

        Sends a message to the discord user with the expiry dates if empty.
        The user can then select a reaction to trigger the selected date.
        """
        async with ctx.typing():
            await asyncio.sleep(0.2)

            if cfg.DEBUG:
                print(f"!stocks.opt.oi {ticker} {expiry} {min_sp} {max_sp}")

            call_arg = (min_sp, max_sp)
            func_cmd = oi_command

            await expiry_dates_reaction(ctx, ticker, expiry, func_cmd, call_arg)
Example #13
0
    async def opt(
        self,
        ctx: discord.ext.commands.Context,
        ticker="",
        expiration="",
        strike="",
        put="",
    ):
        """Stocks Context - Shows Options Menu

        Run `!help OptionsCommands` to see the list of available commands.

        Returns
        -------
        Sends a message to the discord user with the commands from the stocks/options context.
        The user can then select a reaction to trigger a command.
        """
        logger.info("!stocks.opt %s %s %s %s", ticker, expiration, strike, put)
        async with ctx.typing():
            await asyncio.sleep(0.2)

            if TRADIER_TOKEN == "REPLACE_ME":  # nosec
                dates = yfinance_model.option_expirations(ticker)
            else:
                dates = tradier_model.option_expirations(ticker)

            index_dates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

            if not ticker:
                current = 0
                text = (
                    "```0️⃣ !stocks.opt.unu```\n"
                    "Provide a ticker and expiration date with this menu,\n"
                    "\ne.g.\n!stocks.opt TSLA 0-9\n!stocks.opt TSLA 2021-06-04"
                )

            if (ticker != "") and (expiration == ""):
                current = 1
                text = ("```0️⃣ !stocks.opt.unu\n"
                        f"1️⃣ !stocks.opt.exp {ticker}\n"
                        f"2️⃣ !stocks.opt.iv {ticker}\n```")

            if expiration:
                current = 2
                exp = int(expiration.replace("-", ""))
                if exp > 9 and (expiration
                                not in dates) and (exp not in index_dates):
                    call_arg = (strike, put)
                    func_cmd = opt_command
                    expiry = None
                    await expiry_dates_reaction(ctx, ticker, expiry, func_cmd,
                                                call_arg)
                    return
                if exp in index_dates:
                    expiration = dates[int(expiration)]

                hist = f"7️⃣ !stocks.opt.hist {ticker} (strike*) (c/p*) {expiration}\n\n* Required"
                if strike and put:
                    hist = f"7️⃣ !stocks.opt.hist {ticker} {strike} {put} {expiration}"
                    current = 3

                text = ("```0️⃣ !stocks.opt.unu\n"
                        f"1️⃣ !stocks.opt.exp {ticker}\n"
                        f"2️⃣ !stocks.opt.iv {ticker}\n"
                        f"3️⃣ !stocks.opt.calls {ticker} {expiration} \n"
                        f"4️⃣ !stocks.opt.puts {ticker} {expiration} \n"
                        f"5️⃣ !stocks.opt.oi {ticker} {expiration} \n"
                        f"6️⃣ !stocks.opt.vol {ticker} {expiration} \n"
                        f"{hist}```")

            if put == "p":
                put = bool(True)
            if put == "c":
                put = bool(False)

            title = "Stocks: Options Menu"
            embed = discord.Embed(title=title,
                                  description=text,
                                  colour=cfg.COLOR)
            embed.set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )
            msg = await ctx.send(embed=embed, delete_after=60.0)

            if current == 0:
                emoji_list = ["0️⃣"]
            if current == 1:
                emoji_list = ["0️⃣", "1️⃣", "2️⃣"]
            if current == 2:
                emoji_list = ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣"]
            if current == 3:
                emoji_list = [
                    "0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣"
                ]

            for emoji in emoji_list:
                await msg.add_reaction(emoji)

            def check(reaction, user):
                return user == ctx.message.author and str(
                    reaction.emoji) in emoji_list

            try:
                reaction, _ = await gst_bot.wait_for("reaction_add",
                                                     timeout=cfg.MENU_TIMEOUT,
                                                     check=check)
                if reaction.emoji == "0️⃣":
                    logger.info("Reaction selected: 0")
                    await unu_command(ctx)
                elif reaction.emoji == "1️⃣":
                    logger.info("Reaction selected: 1")
                    await expirations_command(ctx, ticker)
                elif reaction.emoji == "2️⃣":
                    logger.info("Reaction selected: 2")
                    await iv_command(ctx, ticker)
                elif reaction.emoji == "3️⃣":
                    logger.info("Reaction selected: 3")
                    await calls_command(ctx, ticker, expiration)
                elif reaction.emoji == "4️⃣":
                    logger.info("Reaction selected: 4")
                    await puts_command(ctx, ticker, expiration)
                elif reaction.emoji == "5️⃣":
                    logger.info("Reaction selected: 5")
                    await oi_command(ctx, ticker, expiration)
                elif reaction.emoji == "6️⃣":
                    logger.info("Reaction selected: 6")
                    await vol_command(ctx, ticker, expiration)
                elif reaction.emoji == "7️⃣":
                    logger.info("Reaction selected: 7")
                    strike = float(strike)
                    await hist_command(ctx, ticker, expiration, strike, put)

                for emoji in emoji_list:
                    await msg.remove_reaction(emoji, ctx.bot.user)

            except asyncio.TimeoutError:
                for emoji in emoji_list:
                    await msg.remove_reaction(emoji, ctx.bot.user)
                if cfg.DEBUG:
                    embed = discord.Embed(
                        description="Error timeout - you snooze you lose! 😋",
                        colour=cfg.COLOR,
                        title="TIMEOUT Stocks: Options Menu",
                    ).set_author(
                        name=cfg.AUTHOR_NAME,
                        icon_url=cfg.AUTHOR_ICON_URL,
                    )
                    await ctx.send(embed=embed, delete_after=30.0)
Example #14
0
    async def hist(
        self,
        ctx: discord.ext.commands.Context,
        ticker: str = None,
        strike: float = None,
        put="",
        expiry: str = None,
    ):
        """Display chart of given option historical price [Tradier]

        Parameters
        -----------
        ticker: str
            ticker
        strike: float
            strike
        put: bool
            c for call
            p for put
        expiry: str
            accepts 0-9 or YYYY-MM-DD

        Sends a message to the discord user with the expiry dates if empty.
        The user can then select a reaction to trigger the selected date.
        """
        logger.info("!stocks.opt.hist %s %s %s %s", ticker, strike, put,
                    expiry)
        async with ctx.typing():
            await asyncio.sleep(0.2)
            try:
                error = ""
                if TRADIER_TOKEN == "REPLACE_ME":  # nosec
                    raise Exception("Tradier Token is required")

                if expiry in ("c", "p"):
                    raise Exception(
                        'Invalid format.\n\nUse:\n```bash\n"!stocks.opt.hist {ticker} {strike} {c/p}"```'
                        '```bash\n"!stocks.opt {ticker} {expiration} {strike} {c/p}"```'
                    )

                if strike is None or put == "":
                    raise Exception(
                        'A strike and c/p is required\n```bash\n"!stocks.opt.hist {ticker} {strike} {c/p}"```'
                    )

                if put == "p":
                    put = bool(True)
                if put == "c":
                    put = bool(False)

                call_arg = (
                    strike,
                    put,
                )
                func_cmd = hist_command

                await expiry_dates_reaction(ctx, ticker, expiry, func_cmd,
                                            call_arg)
            except TypeError:
                error = (
                    'Invalid format.\n\nUse:\n```bash\n"!stocks.opt.hist {ticker} {strike} {c/p}"```'
                    '```bash\n"!stocks.opt {ticker} {expiration} {strike} {c/p}"```'
                )
            except Exception as e:
                error = str(e)
            finally:
                if error:
                    logger.error(error)
                    embed = discord.Embed(
                        title="ERROR Options: History",
                        colour=cfg.COLOR,
                        description=error,
                    )
                    embed.set_author(
                        name=cfg.AUTHOR_NAME,
                        icon_url=cfg.AUTHOR_ICON_URL,
                    )

                    await ctx.send(embed=embed, delete_after=30.0)