async def buy(self, ctx, ticker: str = 'MSFT', amount='1'): wallet, bank = await self.get_stats(self, ctx.author.id) ticker = ticker.upper() async with self.bot.session.get( f'https://ws-api.iextrading.com/1.0/tops/last?symbols={ticker}' ) as resp: data: list = await resp.json() if not data: return await ctx.send('Yeah so thats not a valid stock lmao') stock: dict = data[0] price: int = math.floor(stock["price"]) humanized_price: str = humanize.intcomma(price) match = re.search(r'^[0-9]*$', str(amount)) if match: amount = int(match[0]) else: match = re.search(r'^[a-zA-Z]*$', amount) if match and match[0] == 'max': amount = math.floor(wallet / price) if amount == 0: return await ctx.send( 'You don\'t have enough money to buy a share.') else: amount = 1 total: int = amount * price humanized_total: str = humanize.intcomma(total) share: str = plural("share(s)", amount) answer, message = await ctx.confirm( f'Confirm to buy **{amount}** {share} of **{ticker}** at **${humanized_price}**' f' per share for a total of **${humanized_total}**.') if answer: if total > wallet: return await message.edit( content= f'You need **${total - wallet}** more in order to purchase this stock.' ) values = (ctx.author.id, ticker, amount) await ctx.bot.db.execute( "INSERT INTO stocks(user_id, ticker, amount) VALUES($1, $2, $3) ON CONFLICT (user_id, ticker) DO UPDATE SET amount = stocks.amount + $3", *values) await self.bot.db.execute( "UPDATE economy SET wallet = $1 WHERE userid = $2", wallet - total, ctx.author.id) await message.edit( content= f'Purchased **{amount}** {share} of **{ticker}** for **${humanized_total}**.' ) if not answer: await message.edit(content='Cancelled the transaction.')
async def sell(self, ctx, ticker: str = 'MSFT', amount='1'): wallet, bank = await self.get_stats(self, ctx.author.id) ticker = ticker.upper() async with self.bot.session.get( f'https://ws-api.iextrading.com/1.0/tops/last?symbols={ticker}' ) as resp: data: list = await resp.json() if not data: return await ctx.send('Yeah so thats not a valid stock lmao') stock: dict = data[0] price: int = math.floor(stock["price"]) humanized_price: str = humanize.intcomma(price) match = re.search(r'^[0-9]*$', str(amount)) if match: amount = int(match[0]) else: match = re.search(r'^[a-zA-Z]*$', amount) if match and match[0] == 'max': amount = await ctx.bot.db.fetchval( "SELECT amount FROM stocks WHERE user_id = $1 AND ticker = $2", ctx.author.id, ticker) else: amount = 1 total: int = amount * price humanized_total: str = humanize.intcomma(total) share: str = plural("share(s)", amount) answer, message = await ctx.confirm( f'Confirm to sell **{amount}** {share} of **{ticker}** at **${humanized_price}**' f' per share for a total of **${humanized_total}**.') if answer: try: query = await ctx.bot.db.execute( "UPDATE stocks SET amount = stocks.amount - $3 WHERE user_id = $1 AND ticker = $2", ctx.author.id, ticker, amount) if query == 'UPDATE 0': return await message.edit(content="You don't any stock.") await ctx.bot.db.execute('DELETE FROM stocks WHERE amount = 0') await self.bot.db.execute( "UPDATE economy SET wallet = $1 WHERE userid = $2", wallet + total, ctx.author.id) return await message.edit( content= f'Sold **{amount}** {share} of **{ticker}** for **${humanized_total}**.' ) except CheckViolationError: return await message.edit("You don't have that much stock") else: await message.edit(content='Cancelled the transaction.')
class Help(commands.MinimalHelpCommand): def get_command_signature(self, command, ctx=None): """Method to return a commands name and signature""" sig = command.usage or command.signature if not sig and not command.parent: return f'`{self.clean_prefix}{command.name}`' if not command.parent: return f'`{self.clean_prefix}{command.name}` `{sig}`' if not sig: return f'`{self.clean_prefix}{command.parent}` `{command.name}`' else: return f'`{self.clean_prefix}{command.parent}` `{command.name}` `{sig}`' async def send_error_message(self, error): ctx = self.context destination = self.get_destination() embed = discord.Embed(description=error, color=ctx.bot.embed_color, timestamp=ctx.message.created_at).set_footer( text=f"Requested by {ctx.author}", icon_url=ctx.author.avatar_url) await destination.send(embed=embed) def get_opening_note(self): return "`<arg>` means the argument is required\n`[arg]` means the argument is optional" def add_bot_commands_formatting(self, commands, heading): if commands: joined = '`,\u2002`'.join(c.name for c in commands) emoji_dict = { 'economy': "💵", 'fun': "<:hahayes:739613910180692020>", 'polaroid': "📸", 'prefixes': "<:shrug:747680403778699304>", 'useful': "<:bruhkitty:739613862302711840>", 'utilities': "⚙️", "music": "<:bruhkitty:739613862302711840>" } self.paginator.add_line( f'{emoji_dict[heading.lower()]} **{heading}**') self.paginator.add_line(f'> `{joined}`') # self.paginator.add_line() def get_ending_note(self): command_name = self.invoked_with return ( "Type `{0}{1} [command]` for more info on a command.\n" "You can also type `{0}{1} [category]` for more info on a category." .format(self.clean_prefix, command_name)) async def send_pages(self): ctx = self.context destination = self.get_destination() for page in self.paginator.pages: embed = discord.Embed(description=page, color=0x9c5cb4, timestamp=ctx.message.created_at).set_footer( text=f"Requested by {ctx.author}", icon_url=ctx.author.avatar_url) await destination.send(embed=embed) def add_subcommand_formatting(self, command): fmt = '{0} \N{EN DASH} {1}' if command.short_doc else '{0} \N{EN DASH} This command is not documented' self.paginator.add_line( fmt.format(self.get_command_signature(command), command.short_doc)) async def on_help_command_error(self, ctx, error): if isinstance(error, commands.BadArgument): embed = discord.Embed(title="Error", description=str(error)) await ctx.send(embed=embed) if isinstance(error, commands.CommandNotFound): embed = discord.Embed(title="Error", description=str(error)) await ctx.send(embed=embed) else: raise error async def send_bot_help(self, mapping): ctx = self.context bot = ctx.bot if bot.description: self.paginator.add_line(bot.description, empty=True) no_category = '\u200b{0.no_category}'.format(self) def get_category(command, *, no_category=no_category): cog = command.cog return cog.qualified_name if cog is not None else no_category filtered = await self.filter_commands(bot.commands, sort=True, key=get_category) to_iterate = itertools.groupby(filtered, key=get_category) for category, commands in to_iterate: commands = sorted( commands, key=lambda c: c.name ) if self.sort_commands else list(f'**{commands}**') self.add_bot_commands_formatting(commands, category) self.paginator.add_line() self.paginator.add_line(self.get_ending_note()) await self.send_pages() @staticmethod def get_help(command, brief=True): real_help = command.help or "This command is not documented." return real_help if not brief else command.short_doc or real_help async def send_cog_help(self, cog): bot = self.context.bot if bot.description: self.paginator.add_line(bot.description) note = self.get_opening_note() if note: self.paginator.add_line(note, empty=True) filtered = await self.filter_commands(cog.get_commands(), sort=self.sort_commands) if filtered: self.paginator.add_line( '**%s %s**' % (cog.qualified_name, self.commands_heading)) if cog.description: self.paginator.add_line(cog.description, empty=True) for command in filtered: self.add_subcommand_formatting(command) await self.send_pages() def get_command_help(self, command): ctx = self.context embed = discord.Embed( title=self.get_command_signature(command), description=f'```{self.get_help(command, brief=False)}```', color=0x9c5cb4, timestamp=ctx.message.created_at).set_footer( text=f"Requested by {ctx.author}", icon_url=ctx.author.avatar_url) if alias := command.aliases: embed.add_field(name="Aliases", value=f"```{', '.join(alias)}```", inline=False) if isinstance(command, commands.Group): subcommand = command.commands value = "\n".join( f'{self.get_command_signature(c)} \N{EN DASH} {c.short_doc}' for c in subcommand) if len(value) > 1024: value = "\n".join(f'{self.get_command_signature(c)}' for c in subcommand) embed.add_field(name=plural("Subcommand(s)", len(subcommand)), value=value) return embed
class Help(commands.MinimalHelpCommand): def get_command_signature(self, command, ctx=None): """Method to return a commands name and signature""" if not ctx: if not command.signature and not command.parent: return f'`{self.clean_prefix}{command.name}`' if command.signature and not command.parent: return f'`{self.clean_prefix}{command.name}` `{command.signature}`' if not command.signature and command.parent: return f'`{self.clean_prefix}{command.parent}` `{command.name}`' else: return f'`{self.clean_prefix}{command.parent}` `{command.name}` `{command.signature}`' else: def get_invoke_with(): msg = ctx.message.content escape = "\\" prefixmax = re.match(f'{escape}{escape.join(ctx.prefix)}', msg).regs[0][1] return msg[prefixmax:msg.rindex(ctx.invoked_with)] if not command.signature and not command.parent: return f'{ctx.prefix}{ctx.invoked_with}' if command.signature and not command.parent: return f'{ctx.prefix}{ctx.invoked_with} {command.signature}' if not command.signature and command.parent: return f'{ctx.prefix}{get_invoke_with()}{ctx.invoked_with}' else: return f'{ctx.prefix}{get_invoke_with()}{ctx.invoked_with} {command.signature}' async def send_error_message(self, error): ctx = self.context destination = self.get_destination() embed = discord.Embed(description=error, color=0x9c5cb4, timestamp=ctx.message.created_at).set_footer( text=f"Requested by {ctx.author}", icon_url=ctx.author.avatar_url) await destination.send(embed=embed) def command_not_found(self, string): return 'No command called "{}" found.'.format(string) def get_opening_note(self): return "`<arg>` means the argument is required\n`[arg]` means the argument is optional" def add_bot_commands_formatting(self, commands, heading): if commands: joined = '`\u2002•\u2002`'.join(c.name for c in commands) self.paginator.add_line('**%s commands:**' % heading) self.paginator.add_line(f'`{joined}`') self.paginator.add_line() def get_ending_note(self): command_name = self.invoked_with return ( "Type {0}{1} [command] for more info on a command.\n" "You can also type {0}{1} [category] for more info on a category.". format(self.clean_prefix, command_name)) async def send_pages(self): ctx = self.context destination = self.get_destination() for page in self.paginator.pages: emby = discord.Embed(description=page, color=0x9c5cb4, timestamp=ctx.message.created_at).set_footer( text=f"Requested by {ctx.author}", icon_url=ctx.author.avatar_url) await destination.send(embed=emby) def add_subcommand_formatting(self, command): fmt = '{0} \N{EN DASH} {1}' if command.short_doc else '{0} \N{EN DASH} This command is not documented' self.paginator.add_line( fmt.format(self.get_command_signature(command), command.short_doc)) async def on_help_command_error(self, ctx, error): if isinstance(error, commands.BadArgument): embed = discord.Embed(title="Error", description=str(error)) await ctx.send(embed=embed) if isinstance(error, commands.CommandNotFound): embed = discord.Embed(title="Error", description=str(error)) await ctx.send(embed=embed) else: raise error async def send_bot_help(self, mapping): ctx = self.context bot = ctx.bot if bot.description: self.paginator.add_line(bot.description, empty=False) no_category = '\u200b{0.no_category}'.format(self) def get_category(command, *, no_category=no_category): cog = command.cog return cog.qualified_name if cog is not None else no_category filtered = await self.filter_commands(bot.commands, sort=True, key=get_category) to_iterate = itertools.groupby(filtered, key=get_category) for category, commands in to_iterate: commands = sorted( commands, key=lambda c: c.name ) if self.sort_commands else list(f'**{commands}**') self.add_bot_commands_formatting(commands, category) async with aiohttp.ClientSession() as cs: async with cs.get( 'https://api.github.com/repos/ppotatoo/pdbot/commits/master' ) as f: resp = await f.json() if resp["commit"]["message"].capitalize().startswith('Minor'): pass else: self.paginator.add_line('**Latest Github Commit:**') self.paginator.add_line(resp["commit"]["message"].capitalize()) # self.paginator.add_line('you can also choose to write it yourself') self.paginator.add_line() self.paginator.add_line(self.get_ending_note()) await self.send_pages() def get_help(self, command, brief=True): real_help = command.help or "This command is not documented." return real_help if not brief else command.short_doc or real_help async def send_cog_help(self, cog): bot = self.context.bot if bot.description: self.paginator.add_line(bot.description) note = self.get_opening_note() if note: self.paginator.add_line(note, empty=True) filtered = await self.filter_commands(cog.get_commands(), sort=self.sort_commands) if filtered: self.paginator.add_line( '**%s %s**' % (cog.qualified_name, self.commands_heading)) if cog.description: self.paginator.add_line(cog.description, empty=True) for command in filtered: self.add_subcommand_formatting(command) await self.send_pages() def get_command_help(self, command): ctx = self.context embed = discord.Embed( title=self.get_command_signature(command), description=f'```{self.get_help(command, brief=False)}```', color=0x9c5cb4, timestamp=ctx.message.created_at).set_footer( text=f"Requested by {ctx.author}", icon_url=ctx.author.avatar_url) if alias := command.aliases: embed.add_field(name="Aliases", value=f"```{', '.join(alias)}```", inline=False) if isinstance(command, commands.Group): subcommand = command.commands value = "\n".join( f'{self.get_command_signature(c)} \N{EN DASH} {c.short_doc}' for c in subcommand) if len(value) > 1024: value = "\n".join(f'{self.get_command_signature(c)}' for c in subcommand) embed.add_field(name=plural("Subcommand(s)", len(subcommand)), value=value) return embed
async def buy(self, ctx, ticker: str = 'MSFT', amount='1'): """Buys a stock You can view a list of all stocks at https://stockanalysis.com/stocks/ """ wallet, _ = await get_stats(ctx, ctx.author.id) ticker = ticker.upper() async with self.bot.session.get( f'{FINNHUB_URL}/quote?symbol={ticker}&token={self.finnhub}' ) as data: stock = await data.json() if stock["c"] == 0: return await ctx.send('Invalid stock provided.') price: int = round(stock["c"]) humanized_price: str = humanize.intcomma(price) if amount == 'max': amount = math.floor(wallet / price) if amount == 0: return await ctx.send( f'You don\'t have enough money to buy a share of {ticker}. ' f'You need **${humanize.intcomma(price - wallet)}** more in order to purchase a share of {ticker}.' ) try: if int(amount): amount = int(amount) except ValueError: return await ctx.send("Invalid amount provided.") total: int = amount * price humanized_total: str = humanize.intcomma(total) share: str = plural("share(s)", amount) if total > wallet: return await ctx.send( f'You need **${humanize.intcomma(total - wallet)}** more in order to purchase' f' **{amount}** {share} of **{ticker}**') answer, message = await ctx.confirm( f'Confirm to buy **{amount}** {share} of **{ticker}** at **${humanized_price}**' f' per share for a total of **${humanized_total}**.') if answer: stock_sql = ( "INSERT INTO stocks(user_id, ticker, amount) VALUES($1, $2, $3) " "ON CONFLICT (user_id, ticker) " "DO UPDATE SET amount = stocks.amount + $3") stock_values = (ctx.author.id, ticker, amount) eco_sql = ("UPDATE economy " "SET wallet = $1 " "WHERE user_id = $2") eco_values = (wallet - total, ctx.author.id) await self.bot.db.execute(stock_sql, *stock_values) await self.bot.db.execute(eco_sql, *eco_values) await message.edit( content= f'Purchased **{amount}** {share} of **{ticker}** for **${humanized_total}**.' ) if not answer: await message.edit(content='Cancelled the transaction.')
async def sell(self, ctx, ticker: str = 'MSFT', amount='1'): ticker = ticker.upper() sql = ("SELECT amount FROM stocks WHERE user_id = $1 AND ticker = $2") check = await ctx.bot.db.fetchval(sql, ctx.author.id, ticker) if not check: return await ctx.send(f'You don\'t have any shares of **{ticker}**' ) try: if amount != 'max' and int(amount) > check: return await ctx.send( f"You only have {check} {plural('share(s)', check)} of {ticker}" ) except ValueError: return await ctx.send("Invalid amount provided.") if amount == 'max': amount = check amount = int(amount) async with self.bot.session.get( f'{FINNHUB_URL}/quote?symbol={ticker}&token={self.finnhub}' ) as r: data: dict = await r.json() if data["c"] == 0: return await ctx.send('Invalid stock provided.') stock: dict = data price: int = round(stock["c"]) total: int = amount * price humanized_price: str = humanize.intcomma(price) humanized_total: str = humanize.intcomma(total) share: str = plural("share(s)", amount) answer, message = await ctx.confirm( f'Confirm to sell **{amount}** {share} of **{ticker}** at **${humanized_price}**' f' per share for a total of **${humanized_total}**.') if answer: stock_sql = ("UPDATE stocks " "SET amount = stocks.amount - $3 " "WHERE user_id = $1 AND ticker = $2") stock_values = (ctx.author.id, ticker, amount) wallet, _ = await get_stats(ctx, ctx.author.id) eco_values = (wallet + total, ctx.author.id) await self.bot.db.execute( "UPDATE economy SET wallet = $1 WHERE user_id = $2", *eco_values) await self.bot.db.execute(stock_sql, *stock_values) await message.edit( content= f'Sold **{amount}** {share} of **{ticker}** for **${humanized_total}**.' ) else: await message.edit(content='Cancelled the transaction.')