async def todo_add(self, ctx: context.Context, *, content: commands.clean_content) -> None: """ Creates a todo. `content`: The content of your todo. Can not be more than 180 characters. """ content = str(content) if len(content) > 180: raise exceptions.ArgumentError( 'Your todo can not be more than 180 characters long.') todo_count = await self.bot.db.fetchrow( 'SELECT count(*) as c FROM todos WHERE owner_id = $1', ctx.author.id) if todo_count['c'] > 100: raise exceptions.GeneralError( f'You have too many todos, try removing some of them before adding more.' ) query = 'INSERT INTO todos (owner_id, time_added, todo, link) VALUES ($1, $2, $3, $4)' await self.bot.db.execute(query, ctx.author.id, pendulum.now(tz='UTC'), content, ctx.message.jump_url) await ctx.send('Your todo was created.')
async def role(self, ctx: context.Context, *, role: discord.Role = None) -> None: """ Displays information about a role. `role`: The role to display information of. Can be its @Mention, ID or Name. """ if not role: if not ctx.guild: raise exceptions.GeneralError( 'You must be in a guild to use this command without passing the `role` argument.' ) role = ctx.author.top_role embed = discord.Embed(colour=ctx.colour, title=f'Information about the role `{role}`') embed.set_footer(text=f'ID: {role.id}') embed.description = f'`Name:` {role.name}\n' \ f'`Hoisted:` {role.hoist}\n' \ f'`Position (from bottom):` {role.position}\n' \ f'`Managed:` {role.managed}\n' \ f'`Mentionable:` {role.mentionable}\n' \ f'`Colour:` {str(role.colour).upper()}\n' \ f'`Created at:` {self.bot.utils.format_datetime(datetime=role.created_at)}\n' \ f'`Members with this role:` {len(role.members)}' await ctx.send(embed=embed)
async def todo_clear(self, ctx: context.Context) -> None: """ Clears your todo list. """ todos = await self.bot.db.fetch( 'SELECT * FROM todos WHERE owner_id = $1 ORDER BY time_added', ctx.author.id) if not todos: raise exceptions.GeneralError('You don not have any todos.') await self.bot.db.execute( 'DELETE FROM todos WHERE owner_id = $1 RETURNING *', ctx.author.id) await ctx.send(f'Cleared your todo list of `{len(todos)}` todo(s).')
async def todo_delete(self, ctx: context.Context, *, todo_ids: str) -> None: """ Deletes a todo. `todo_ids`: The ids of the todos to delete. You can provide a list of ids and they will all be deleted. """ todos = await self.bot.db.fetch( 'SELECT * FROM todos WHERE owner_id = $1 ORDER BY time_added', ctx.author.id) if not todos: raise exceptions.GeneralError(f'You do not have any todos.') todos = {index + 1: todo for index, todo in enumerate(todos)} todos_to_remove = [] for todo_id in todo_ids.split(' '): try: todo_id = int(todo_id) except ValueError: raise exceptions.ArgumentError( f'`{todo_id}` is not a valid todo id.') if todo_id not in todos.keys(): raise exceptions.ArgumentError( f'You do not have a todo with the id `{todo_id}`.') if todo_id in todos_to_remove: raise exceptions.ArgumentError( f'You provided the todo id `{todo_id}` more than once.') todos_to_remove.append(todo_id) query = 'DELETE FROM todos WHERE owner_id = $1 and time_added = $2' entries = [(todos[todo_id]['owner_id'], todos[todo_id]['time_added']) for todo_id in todos_to_remove] await self.bot.db.executemany(query, entries) embed = discord.Embed( colour=ctx.colour, description=f'**Deleted** `{len(todos_to_remove)}` **todo(s):**') embed.add_field( name='Contents:', value='\n'.join([ f'[`{todo_id}`]({todos[todo_id]["link"]}) {todos[todo_id]["todo"]}' for todo_id in todos_to_remove ])) await ctx.send(embed=embed)
async def reminders_list(self, ctx: context.Context) -> None: """ Displays a list of your reminders. """ reminders = [reminder for reminder in ctx.user_config.reminders if not reminder.done] if not reminders: raise exceptions.GeneralError('You do not have any active reminders.') embed = discord.Embed(colour=ctx.colour, description=f'**Reminders for** `{ctx.author}:`\n\n') for reminder in sorted(reminders, key=lambda reminder: reminder.datetime): embed.description += f'`{reminder.id}`: **In {self.bot.utils.format_difference(datetime=reminder.datetime, suppress=[])}**\n' \ f'`When:` {self.bot.utils.format_datetime(datetime=reminder.datetime, seconds=True)}\n' \ f'`Content:` {reminder.content[:100]}\n\n' await ctx.send(embed=embed)
async def todo_edit(self, ctx: context.Context, todo_id: str, *, content: commands.clean_content) -> None: """ Edits the todo with the given id. `todo_id`: The id of the todo to edit. `content`: The content of the new todo. """ todos = await self.bot.db.fetch( 'SELECT * FROM todos WHERE owner_id = $1 ORDER BY time_added', ctx.author.id) if not todos: raise exceptions.GeneralError('You do not have any todos.') content = str(content) if len(content) > 180: raise exceptions.ArgumentError( 'Your todo can not be more than 180 characters long.') todos = {index + 1: todo for index, todo in enumerate(todos)} try: todo_id = int(todo_id) except ValueError: raise exceptions.ArgumentError( f'`{todo_id}` is not a valid todo id.') if todo_id not in todos.keys(): raise exceptions.ArgumentError( f'You do not have a todo with the id `{todo_id}`.') todo = todos[todo_id] query = 'UPDATE todos SET todo = $1, link = $2 WHERE owner_id = $3 and time_added = $4' await self.bot.db.execute(query, content, ctx.message.jump_url, todo['owner_id'], todo['time_added']) embed = discord.Embed(colour=ctx.colour, description=f'**Updated your todo:**') embed.add_field(name='Old content:', value=todo['todo'], inline=False) embed.add_field(name='New content:', value=content, inline=False) await ctx.send(embed=embed)
async def todo(self, ctx: context.Context, content: str = None) -> None: """ Display a list of your todos. """ if content is not None: await ctx.invoke(self.todo_add, content=content) return todos = await self.bot.db.fetch( 'SELECT * FROM todos WHERE owner_id = $1 ORDER BY time_added', ctx.author.id) if not todos: raise exceptions.GeneralError('You do not have any todos.') entries = [ f'[`{index + 1}`]({todo["link"]}) {todo["todo"]}' for index, todo in enumerate(todos) ] await ctx.paginate_embed(entries=entries, per_page=10, header=f'**{ctx.author}\'s todo list:**\n\n')