class RaidRegistration(commands.Cog): """ Cog that responsible for user registration. After registration user can use reaction. """ database = database_process.DatabaseManager() def __init__(self, bot): self.bot = bot @commands.command(name=command_names.function_command.reg, help=help_text.reg) async def reg(self, ctx: Context, name: str): """ Register game nickname in bot database. Attributes: ---------- name: str Game user nickname. """ # Checking correct input await check_input.validation(**locals()) try: self.database.user.reg_user(ctx.author.id, str(ctx.author), name) await ctx.message.add_reaction('✔') log_template.command_success(ctx) except database_process.UserExists: await ctx.author.send(messages.already_registered) await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.already_registered) @commands.command(name=command_names.function_command.rereg, help=help_text.rereg) async def rereg(self, ctx: Context, name: str): """ Re-register game nickname in bot database. Attributes: ---------- name: str Game user nickname. """ # Checking correct input await check_input.validation(**locals()) self.database.user.rereg_user(ctx.author.id, str(ctx.author), name) await ctx.message.add_reaction('✔') log_template.command_success(ctx)
class Admin(commands.Cog): """ Cog for controlling server, channels and messages. """ database = database_process.DatabaseManager() def __init__(self, bot): self.bot = bot @commands.command(name=command_names.function_command.remove_there, help=help_text.remove_there) @commands.guild_only() @commands.has_role('Капитан') async def remove_there(self, ctx: Context): """ Allow the raid creator use command for mass messages remove in current channel. """ guild = ctx.guild channel = ctx.channel self.database.settings.update_settings(guild.id, str(guild), channel.id, str(channel)) await ctx.message.add_reaction('✔') log_template.command_success(ctx) @commands.command(name=command_names.function_command.not_remove_there, help=help_text.not_remove_there) @commands.guild_only() @commands.has_permissions(administrator=True, manage_messages=True) async def not_remove_there(self, ctx: Context): """ Does not allow use command for mass messages remove in current channel. """ guild = ctx.guild channel = ctx.channel self.database.settings.not_delete_there(guild.id, channel.id) await ctx.message.add_reaction('✔') log_template.command_success(ctx) @commands.command(name=command_names.function_command.remove_msgs, help=help_text.remove_msgs) @commands.guild_only() @commands.has_role('Капитан') async def remove_msgs(self, ctx: Context, amount=100): """ Remove `amount` messages in current channel. Attributes ---------- amount: str Amount of messages to delete """ guild = ctx.guild channel = ctx.channel # In this channel can raid creator remove messages by bot? if not self.database.settings.can_delete_there(guild.id, channel.id): await ctx.message.add_reaction('❌') await ctx.author.send(messages.wrong_channel) log_template.command_fail(ctx, logger_msgs.wrong_channel) messages_to_remove = [] msg_count = 0 # Collect all messages in current channel that not older 14 days and not pinned async for msg in channel.history(limit=int(amount)): is_time_has_passed = datetime.now() - msg.created_at > timedelta( days=14) # Warning user if messages older than 14 days if not msg.pinned and is_time_has_passed: await ctx.author.send( messages.remove_msgs_fail_14.format(msg_count=msg_count, amount=amount)) break if not msg.pinned: messages_to_remove.append(msg) msg_count += 1 # Remove messages from channel await channel.delete_messages(messages_to_remove) log_template.command_success(ctx)
class Base(commands.Cog): """ Cog that responsible for basic bot commands. """ database = database_process.DatabaseManager() def __init__(self, bot): self.bot = bot self.bot.remove_command('help') # Remove command to create custom help @commands.command(name=command_names.function_command.test, help=help_text.test) async def test(self, ctx: Context): """ Command witch does nothing. For developer and debugging. """ await check_input.validation(**locals()) await ctx.message.add_reaction('❌') await ctx.message.add_reaction('✔') log_template.command_success(ctx) async def help_command(self, ctx: Context, command): """ Send command description as message in channel. Attributes ---------- command: str The name of command for getting the description """ # Get command obj from the name command = self.bot.get_command(command) if command: embed = discord.Embed( title=command.name, colour=discord.Colour.blue(), description=command.help, ) bot_as_user = self.bot.get_user(settings.BOT_ID) embed.set_author( name=str(bot_as_user), icon_url=bot_as_user.avatar_url, ) await ctx.send(embed=embed) await ctx.message.add_reaction('✔') log_template.command_success(ctx) else: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.command_not_found) @commands.command(name=command_names.function_command.send_logs, help=help_text.send_logs) @commands.is_owner() async def send_logs(self, ctx: Context): """ Command for admins and developers. Send the bot logs as msg to channel. """ path_to_logs = os.path.join('settings', 'logger', 'logs.log') if os.path.exists(path_to_logs): await ctx.send(file=discord.File(path_to_logs)) await ctx.message.add_reaction('✔') log_template.command_success(ctx) else: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.logs_not_found) @commands.command(name=command_names.function_command.help, help=help_text.help) async def help(self, ctx: Context, command=''): """ Custom help command. Attributes ---------- command: str The name of command for getting the description """ # If user enter name of command to get description if command: await self.help_command(ctx, command) return # Dict of emoji for control custom help HELP_EMODJI = ['🔼', '1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣'] pages = {} # Cogs witch should not be shown in help not_help_cogs = ['Base', 'Events'] # Get all available commands of the bot cogs_commands = {} for cog_name in self.bot.cogs: if cog_name not in not_help_cogs: cogs_commands[messages.cog_names[cog_name]] = self.bot.get_cog( cog_name).get_commands() main_embed = discord.Embed(title=messages.help_title, colour=discord.Colour.blue()) bot_as_user = self.bot.get_user(settings.BOT_ID) main_embed.set_author( name=str(bot_as_user), icon_url=bot_as_user.avatar_url, ) # Generate pages of cogs with description of all commands in cog section_help = messages.section_help.format(emoji=HELP_EMODJI[0]) for index, (cog_name, bot_commands) in enumerate(cogs_commands.items()): section_help += f"**{HELP_EMODJI[1:][index]} - {cog_name}**\n" page = f"**{cog_name}**:\n" for command in bot_commands: page += f"**`{settings.PREFIX}{command.name}` - {command.short_doc}**\n" embed_page = discord.Embed(title=messages.help_title, colour=discord.Colour.blue(), description=page) embed_page.set_author( name=str(bot_as_user), icon_url=bot_as_user.avatar_url, ) pages[HELP_EMODJI[1:][index]] = embed_page main_embed.add_field(name=messages.section_title, value=section_help, inline=False) main_embed.add_field(name=messages.author_title, value=messages.author_command_description, inline=False) main_embed.add_field(name=messages.additional_help_title, value=messages.additional_help, inline=False) main_embed.add_field(name=messages.help_reaction_title, value=messages.help_reaction, inline=False) # Set home page pages[HELP_EMODJI[0]] = main_embed help_msg = await ctx.send(embed=main_embed) log_template.command_success(ctx) # Add control emoji for message for emoji in HELP_EMODJI: await help_msg.add_reaction(emoji) def check(reaction, user): """ Only user who use command can use control emoji """ return (user == ctx.message.author and str(reaction.emoji) in HELP_EMODJI) while True: try: # Waiting for a click reaction from the user reaction, user = await self.bot.wait_for('reaction_add', timeout=600.0, check=check) except asyncio.TimeoutError: return log_template.user_answer(ctx, str(reaction)) # Switch page embed = pages.get(str(reaction)) if embed: await help_msg.edit(embed=embed) @commands.command(name=command_names.function_command.turn_off_bot, help=help_text.turn_off_bot) @commands.is_owner() async def turn_off_bot(self, ctx: Context): """ Disables the bot. Available only to the bot creator. """ log_template.command_success(ctx) await self.bot.logout() @commands.command(name=command_names.function_command.author_of_bot, help=help_text.author_of_bot) async def author_of_bot(self, ctx: Context): """ Send information about creator and bot as message in current channel. """ embed = discord.Embed(title=messages.author_title, colour=discord.Colour.blue(), description=messages.about_author) await ctx.send(embed=embed) log_template.command_success(ctx)
class RaidCreation(commands.Cog): """ Cog that responsible for creating and removing raids """ database = database_process.DatabaseManager() raid_list = raid_list.RaidList() def __init__(self, bot): self.bot = bot def captain_raids(self, captain_name: str) -> list or None: """ Return list of all captains Raid's or None. Attribute: ---------- captain_name: str Nickname of user that drove people Return: ---------- list or None if raids of captains not exist """ current_raids = [] for some_raid in self.raid_list: if some_raid.captain_name == captain_name: current_raids.append(some_raid) return current_raids def captain_raids_str(self, captain_name: str) -> str or None: """" Return list of all captains Raid's or None as text. Attribute: ---------- captain_name: str Nickname of user that drove people Return: ---------- str or None if raids of captains not exist """ current_raids = self.captain_raids(captain_name) if not current_raids: return msg = messages.yours_current_raids_start for captain_raid in current_raids: guild_name = str(self.bot.get_guild(captain_raid.guild_id)) channel_name = str(self.bot.get_channel(captain_raid.channel_id)) msg += ( f"**{guild_name}**/**{channel_name}**/" f"**{captain_raid.server}**/**{captain_raid.raid_time.time_leaving}**\n" ) return msg async def notify_about_leaving(self, current_raid: Raid): """ Send notification message to all users in raid after notification time. Attributes: ---------- current_raid: Raid raid to notification """ # Get secs left to notification secs_sleep = current_raid.raid_time.secs_to_notify() if not secs_sleep: return current_raid.raid_time.is_notified = True # Sleep before notification time sleep_task = asyncio.create_task(asyncio.sleep(secs_sleep)) current_raid.raid_time.notification_task = sleep_task await sleep_task users_list = self.database.user.get_users_id(list(current_raid.member_dict.keys())) amount = 0 # Send notification msg to users for member in users_list: if member: user = self.bot.get_user(member.get('discord_id')) await user.send(messages.member_notification) amount += 1 # Send notification message to the captain captain_id = self.database.user.user_post_by_name(current_raid.captain_name).get('discord_id') captain = self.bot.get_user(captain_id) await captain.send(messages.captain_notification) log_template.notify_success(current_raid.raid_time.time_leaving, amount + 1) @commands.command(name=command_names.function_command.remove_raid, help=help_text.remove_raid) @commands.guild_only() @commands.has_role('Капитан') async def remove_raid(self, ctx: Context, captain_name: str, time_leaving=''): """ Remove available raid Attributes: ---------- captain_name: str Name of the captain that created the raid. time_leaving: str or None Time when raid leaving. Required to fill if captain has more than one raid. """ # Checking correct inputs arguments await check_input.validation(**locals()) curr_raid = self.raid_list.find_raid(ctx.guild.id, ctx.channel.id, captain_name, time_leaving) if curr_raid: curr_raid.end_work() self.raid_list.remove(curr_raid) await ctx.message.add_reaction('✔') log_template.command_success(ctx) else: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.raid_not_found) @commands.command(name=command_names.function_command.collection, help=help_text.collection) @commands.guild_only() @commands.has_role('Капитан') async def collection(self, ctx: Context, captain_name: str, time_leaving=''): """ Send collection messaged to current channel and allowed users to get into the raid by adding reaction on collection message. Attributes: ---------- captain_name: str Name of the captain that created the raid. time_leaving: str or None Time when raid leaving. Required to fill if captain has more than one raid. """ # Checking correct inputs arguments await check_input.validation(**locals()) curr_raid = self.raid_list.find_raid( ctx.guild.id, ctx.channel.id, captain_name, time_leaving, ignore_channels=True ) # Does this captain have a raid with these parameters? if not curr_raid: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.raid_not_found) return # Its not deleted raid if curr_raid.is_deleted_raid: return # Stop async task if such exists for this raid if curr_raid.waiting_collection_task: curr_raid.waiting_collection_task.cancel() # Send message about collection collection_msg = await curr_raid.raid_msgs.send_coll_msg(ctx) await collection_msg.add_reaction('❤') log_template.command_success(ctx) # Remove the time that has already passed curr_raid.raid_time.validate_time() # Notify user if possible before leaving asyncio.ensure_future(self.notify_about_leaving(curr_raid)) raid_time = curr_raid.raid_time.time_to_display.copy() for index, time_display in enumerate(raid_time): curr_raid.save_raid() # Update text msg of start collection Raid await curr_raid.raid_msgs.update_coll_msg(self.bot) # Wait next time to display raid table secs_left = curr_raid.raid_time.secs_left_to_display() curr_raid.coll_sleep_task = asyncio.create_task(asyncio.sleep(secs_left)) await curr_raid.coll_sleep_task curr_raid.raid_time.time_passed() # Resend new message with raid table if not first time else just send table await curr_raid.raid_msgs.update_table_msg(self.bot, ctx) self.database.captain.update_captain(str(ctx.author), curr_raid) await ctx.send(messages.collection_end.format(server=curr_raid.server, captain_name=curr_raid.captain_name)) await self.remove_raid(ctx, captain_name, time_leaving) def check_captain_registration(self, user: discord.User, captain_name: str): """ Register captain in database if he is not registered yet Attributes: ---------- user: discord.User discord user that captain captain_name: str game nickname of user """ nickname = self.database.user.find_user(str(user)) if nickname == captain_name: return else: self.database.user.rereg_user(user.id, str(user), captain_name) async def check_raid_exists(self, ctx: Context, captain_name: str, time_leaving=''): """ Check raid exist by this captain. If raid exist ask captain. Attributes: ---------- captain_name: str Name of the captain that created the raid. time_leaving: str or None Time when raid leaving. Required to fill if captain has more than one raid. """ # Check captain exists captain_post = self.database.captain.find_captain_post(str(ctx.author)) if not captain_post: self.database.captain.create_captain(str(ctx.author)) # Check raid exists of this captain captain_raids = self.captain_raids(captain_name) if not captain_raids: return # If raid with this credentials absolutely matched for captain_raid in captain_raids: if captain_raid.raid_time.time_leaving == time_leaving: await ctx.author.send(messages.raid_exist_error) await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.raid_exist) raise commands.errors.UserInputError('Такой рейд уже существует.') active_raids = self.captain_raids_str(captain_name) message = await ctx.author.send(messages.raid_exist_warning + active_raids) await message.add_reaction('✔') await message.add_reaction('❌') def check(reaction, user): """Process answer only by author of command and correct reaction""" return user.id == ctx.message.author.id and (str(reaction.emoji) == '✔' or str(reaction.emoji) == '❌') # Wait answer of user try: reaction, user = await self.bot.wait_for('reaction_add', timeout=300.0, check=check) except asyncio.TimeoutError: log_template.command_fail(ctx, logger_msgs.user_not_response) raise commands.errors.UserInputError('Капитан не ответил на вопрос о создании рейда') else: emoji = str(reaction.emoji) log_template.user_answer(ctx, emoji) if emoji == '❌': raise commands.errors.UserInputError('Капитан отказался создавать новый рейд') @commands.command(name=command_names.function_command.captain, help=help_text.captain) @commands.guild_only() @commands.has_role('Капитан') async def captain(self, ctx: Context, captain_name: str, server: str, time_leaving: str, time_reservation_open='', reservation_count=0): """ Create raid. Start process of collection user into the new raid. Attributes: ---------- captain_name: str Nickname of user who drove people. server: str Game server where captain will carry. time_leaving: str Time when raid will sail. time_reservation_open: str or None Time when bot start collection people in raid. If None than start collection after one minute. reservation_count: int or 0 Amount of places which cannot be borrowed """ await check_input.validation(**locals()) await self.check_raid_exists(ctx, captain_name, time_leaving) self.check_captain_registration(ctx.author, captain_name) if not time_reservation_open: time_reservation_open = tools.now_time_plus_minute() new_raid = raid.Raid( captain_name, server, time_leaving, time_reservation_open, ctx.guild.id, ctx.channel.id, reservation_count ) self.raid_list.append(new_raid) await ctx.send(messages.raid_created.format(time_reservation_open=time_reservation_open)) await ctx.message.add_reaction('✔') log_template.command_success(ctx) # Wait time reservation open time_left_sec = tools.get_sec_left(time_reservation_open) sleep_task = asyncio.create_task(asyncio.sleep(time_left_sec)) new_raid.waiting_collection_task = sleep_task await sleep_task # Start raid collection collection_task = asyncio.create_task(self.collection(ctx, captain_name, time_leaving)) new_raid.collection_task = sleep_task await collection_task @commands.command(name=command_names.function_command.cap, help=help_text.cap) @commands.guild_only() @commands.has_role('Капитан') async def cap(self, ctx: Context): """ Short version of command captain. In this way user choose old parameters of raid by adding reaction. """ # Dict of controlling emoji NUMBER_REACTIONS = { '1️⃣': 1, '2️⃣': 2, '3️⃣': 3, 1: '1️⃣', 2: '2️⃣', 3: '3️⃣' } user = str(ctx.author) captain_post = self.database.captain.find_captain_post(user) # Get parameters of old raids if not captain_post: await ctx.message.add_reaction('❌') await ctx.author.send(messages.new_captain) log_template.command_fail(ctx, logger_msgs.captain_not_exist) return last_raids = captain_post.get('last_raids') raids_msg = messages.raid_create_choice_start.format(captain_name=captain_post['captain_name']) # Generate list of choices for index, last_raid in enumerate(last_raids): raids_msg += messages.raid_create_choice_server_time.format( index=index + 1, server=last_raid['server'], time_leaving=last_raid['time_leaving'] ) if last_raid.get('time_reservation_open'): raids_msg += messages.raid_create_choice_res_open.format( time_reservation_open=last_raid['time_reservation_open'] ) if last_raid.get('reservation_count') and not last_raid['reservation_count'] == 1: raids_msg += messages.raid_create_choice_count.format(reservtaion_count=last_raid['reservation_count']) raids_msg += '.\n' # Send list of choices and add controlling reactions msg = await ctx.send(raids_msg) for number in range(len(last_raids)): await msg.add_reaction(NUMBER_REACTIONS[number + 1]) def check(reaction, user): """Only get answer by author of command and correct reaction""" return ( user == ctx.message.author and ( str(reaction.emoji) == '1️⃣' or str(reaction.emoji) == '2️⃣' or str(reaction.emoji) == '3️⃣' ) ) try: # Wait for user answer reaction, user = await self.bot.wait_for('reaction_add', timeout=600.0, check=check) except asyncio.TimeoutError: log_template.command_fail(ctx, logger_msgs.user_not_response) await ctx.message.add_reaction('❌') else: emoji = str(reaction.emoji) log_template.user_answer(ctx, emoji) user_choice = NUMBER_REACTIONS[emoji] user_raid = last_raids[user_choice - 1] await self.check_raid_exists(ctx, captain_post.get('captain_name'), user_raid.get('time_leaving')) await self.captain( ctx, captain_post.get('captain_name'), user_raid.get('server'), user_raid.get('time_leaving'), user_raid.get('time_reservation_open'), user_raid.get('reservation_count'), )
class RaidOverview(commands.Cog): """ Cog of raid manager that responsible for raid overviewing. """ database = database_process.DatabaseManager() raid_list = raid_list.RaidList() def __init__(self, bot): self.bot = bot @commands.command(name=command_names.function_command.show_raids, help=help_text.show_raids) async def show_raids(self, ctx: Context, show_all=''): """ Send information about all active raid Attributes: ---------- show_all: str If not None show all active raids witch created by bot """ log_template.command_success(ctx) if not show_all: # Check raids exist if self.raid_list: await ctx.send(messages.no_active_raids) return # Generate information about active raids and send msg_of_raid = messages.active_raids_start for curr_raid in self.raid_list: if ctx.guild.id == curr_raid.guild_id: channel_name = str( self.bot.get_channel(curr_raid.channel_id)) msg_of_raid += messages.active_raid_all.format( channel_name=channel_name, captain_name=curr_raid.captain_name, server=curr_raid.server, time_leaving=curr_raid.raid_time.time_leaving, ) await ctx.send(msg_of_raid) else: # Check raids exist if self.raid_list: await ctx.send(messages.no_active_raids) return # Generate information about active raids and send msg_of_raid = messages.active_raids_start for curr_raid in self.raid_list: guild_name = str(self.bot.get_guild(curr_raid.guild_id)) channel_name = str(self.bot.get_channel(curr_raid.channel_id)) msg_of_raid += messages.active_raid_hide.format( guild_name=guild_name, channel_name=channel_name, captain_name=curr_raid.captain_name, time_leaving=curr_raid.raid_time.time_leaving, ) await ctx.send(msg_of_raid) @commands.command(name=command_names.function_command.show_text_raids, help=help_text.show_text_raids) @commands.guild_only() @commands.has_role('Капитан') async def show_text_raids(self, ctx: Context, captain_name: str, time_leaving=''): """ Send member list of raid as text Attributes: ---------- captain_name: str Name of the user that created the raid. time_leaving: str or None Time when raid leaving. Required to fill if captain has more than one raid. """ # Checking correct inputs arguments await check_input.validation(**locals()) curr_raid = self.raid_list.find_raid(ctx.guild.id, ctx.channel.id, captain_name, time_leaving, ignore_channels=True) if curr_raid: # If it's first display if not curr_raid.table: curr_raid.table_path() # Generate text member list text = curr_raid.table.create_text_table() title = text.split('\n')[0] embed = discord.Embed(title=title, colour=discord.Colour.blue(), description=text[len(title) + 1:]) await ctx.send(curr_raid.table.create_text_table()) await ctx.message.add_reaction('✔') log_template.command_success(ctx) else: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.raid_not_found) @commands.command(name=command_names.function_command.show, help=help_text.show) @commands.guild_only() @commands.has_role('Капитан') async def show(self, ctx: Context, captain_name: str, time_leaving=''): """ Send member list of raid as image Attributes: ---------- captain_name: str Name of the user that created the raid. time_leaving: str or None Time when raid leaving. Required to fill if captain has more than one raid. """ # Checking correct inputs arguments await check_input.validation(**locals()) curr_raid = self.raid_list.find_raid(ctx.guild.id, ctx.channel.id, captain_name, time_leaving, ignore_channels=True) if curr_raid: path = curr_raid.table_path() curr_raid.save_raid() await ctx.send(file=discord.File(path)) await ctx.message.add_reaction('✔') log_template.command_success(ctx) else: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.raid_not_found)
class Statistics(commands.Cog): """ Cog that provides all collected statistics. """ database = database_process.DatabaseManager() def __init__(self, bot): self.bot = bot @staticmethod def user_stat_msg(user, user_info: dict, captain_info: dict) -> discord.Embed: """ Return all information that bot knows about user to current channel as message. Attributes: ---------- user: discord.User User for getting information about him user_info: dict All user information collected by bot from database captain_info: dict All user information that drove people collected by bot Returns: -------- :discord.Embed All information about user as embed """ text_message = messages.no_data if user_info: # Choose a title whichever user drove or not people if captain_info and captain_info.get('raids_created'): text_message = messages.captain_title else: text_message = messages.member_title # Add the user game nickname text_message += (f"**{user_info.get('nickname')}**.\n") # Add information about whether the user joined raids or not if user_info.get('entries'): text_message += messages.raids_joined.format( entries=user_info.get('entries')) else: text_message += messages.no_raids_joined # Add information about whether the user drove people or not. if captain_info and captain_info.get('raids_created'): raids_created = captain_info.get('raids_created') drove_people = captain_info.get('drove_people') if raids_created < 5: text_message += messages.drove_raids_l5.format( raids_created=raids_created) else: text_message += messages.drove_raids_g5.format( raids_created=raids_created) if drove_people < 5: text_message += messages.drove_people_l5.format( drove_people=captain_info.get('drove_people')) else: text_message += messages.drove_people_g5.format( drove_people=captain_info.get('drove_people')) text_message += messages.last_time_drove.format( last_created=captain_info.get('last_created')) embed = discord.Embed(title=messages.statistics_user_title, colour=discord.Colour.blue(), description=text_message) # Add avatar if user: embed.set_author( name=str(user), icon_url=user.avatar_url, ) return embed @commands.command(name=command_names.function_command.user_statistics, help=help_text.user_statistics) async def user_statistics(self, ctx: Context, nickname=''): """ Send all information about the user collected by bot as message in current channel. Attributes: ---------- nickname: str information about specific user else about author of command """ user = None # Check specific user if nickname: # Try to find user in db user_info = self.database.user.find_user_post_by_name(nickname) # If user exist try to find captain activity in db if user_info: captain_info = self.database.captain.find_captain_post( user_info['discord_user']) user = self.bot.get_user(user_info['discord_id']) else: captain_info = None else: # If specific user not exist get current user user = ctx.author user_info = self.database.user.find_user_post(str(user)) captain_info = self.database.captain.find_captain_post(str(user)) embed = self.user_stat_msg(user, user_info, captain_info) await ctx.send(embed=embed) log_template.command_success(ctx) @commands.command(name=command_names.function_command.guild_statistics, help=help_text.guild_statistics) @commands.has_permissions(administrator=True, manage_messages=True) async def guild_statistics(self, ctx: Context): """ Send all information about the current server collected by bot as message in current channel. """ guild = ctx.guild user = ctx.author guild_info = self.database.settings.find_settings_post(guild.id) # Collect all information from db text_message = messages.no_data if guild_info and guild_info.get('can_remove_in_channels'): text_message = messages.can_remove_msgs_in for channel_id, channel in guild_info.get( 'can_remove_in_channels').items(): text_message += f" - **{channel}**\n" embed = discord.Embed(title=messages.statistics_guild_title, colour=discord.Colour.blue(), description=text_message) embed.set_author( name=str(guild), icon_url=user.guild.icon_url, ) await ctx.send(embed=embed) log_template.command_success(ctx)
class RaidJoining(commands.Cog): """ Cog that responsible for entering and exiting the raid. """ database = database_process.DatabaseManager() raid_list = raid_list.RaidList() def __init__(self, bot): self.bot = bot async def raid_reaction_add(self, collection_msg: discord.Message, emoji: discord.Emoji, user: discord.User): """ Getting user into raid by adding reaction. Attributes: ---------- collection_msg: discord.Message Collection message through which user can get into the raid. emoji: discord.Emoji Emoji that user added to get into raid. user: discord.User User that want to get into raid """ if str(emoji) != '❤' or user.id == settings.BOT_ID: return guild = collection_msg.guild channel = collection_msg.channel # Check registration nickname = self.database.user.find_user(str(user)) if not nickname: await user.send(messages.no_registration) log_template.reaction(guild, channel, user, emoji, logger_msgs.no_registration) return current_raid = self.raid_list.find_raid_by_coll_id(collection_msg.id) # Check user exists in raid if nickname in current_raid: await user.send(messages.already_in_raid) log_template.reaction(guild, channel, user, emoji, logger_msgs.already_in_raid) return if current_raid.is_full: log_template.reaction(guild, channel, user, emoji, logger_msgs.raid_is_full) await user.send(messages.raid_not_joined) return # If user already in same raid if not self.raid_list.is_correct_join( nickname, current_raid.raid_time.time_leaving): log_template.reaction(guild, channel, user, emoji, logger_msgs.already_in_same_raid) await user.send(messages.already_joined) return msg_success = messages.raid_joined.format( captain_name=current_raid.captain_name, server=current_raid.server, time_leaving=current_raid.raid_time.time_leaving, ) # Add user into raid current_raid += nickname self.database.user.user_joined_raid(str(user)) await user.send(msg_success) await current_raid.raid_msgs.update_coll_msg(self.bot) log_template.reaction( guild, channel, user, emoji, logger_msgs.raid_joining.format( captain_name=current_raid.captain_name)) async def raid_reaction_remove(self, collection_msg: discord.Message, emoji: discord.Emoji, user: discord.User): """ Allow user exit raid by removing reaction. Attributes: ---------- collection_msg: discord.Message Collection message through which user can get into the raid. emoji: discord.Emoji Emoji that user added to exit raid. user: discord.User User that want exit raid """ if str(emoji) != '❤' or user.id == settings.BOT_ID: return current_raid = self.raid_list.find_raid_by_coll_id(collection_msg.id) nickname = self.database.user.find_user(str(user)) if not nickname or nickname not in current_raid: return # Remove user from raid current_raid -= nickname self.database.user.user_leave_raid(str(user)) await user.send( messages.raid_leave.format(captain_name=current_raid.captain_name)) await current_raid.raid_msgs.update_coll_msg(self.bot) guild = collection_msg.guild channel = collection_msg.channel log_template.reaction( guild, channel, user, emoji, logger_msgs.raid_leaving.format( captain_name=current_raid.captain_name)) @commands.command(name=command_names.function_command.reserve, help=help_text.reserve) @commands.guild_only() @commands.has_role('Капитан') async def reserve(self, ctx: Context, name: str, captain_name='', time_leaving=''): """ Allow user join the raid by command Attributes: ---------- name: str Nickname of user that want join the raid. captain_name: str Nickname of user that created the raid. time_leaving: str Time when raid leaving. Required to fill if captain has more than one raid. """ # Checking correct input await check_input.validation(**locals()) if not captain_name and not time_leaving: available_raids = self.raid_list.find_raids_by_guild( name, ctx.guild.id) if not available_raids: log_template.command_fail(ctx, logger_msgs.no_available_raids) await ctx.message.add_reaction('❌') return # Get raid which has the least people smaller_raid = min(available_raids) # Add user into raid smaller_raid += name await smaller_raid.raid_msgs.update_coll_msg(self.bot) await ctx.message.add_reaction('✔') log_template.command_success(ctx) return curr_raid = self.raid_list.find_raid(ctx.guild.id, ctx.channel.id, captain_name, time_leaving) if not curr_raid: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.raid_not_found) return if curr_raid.is_full: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.raid_is_full) return if name in curr_raid: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.already_in_raid) return # if user already in the same raid if self.raid_list.is_correct_join(name, time_leaving): await ctx.author.send(messages.already_joined) await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.already_in_same_raid) return # Add user into the raid curr_raid += name await curr_raid.raid_msgs.update_coll_msg(self.bot) await ctx.message.add_reaction('✔') log_template.command_success(ctx) @commands.command(name=command_names.function_command.remove_res, help=help_text.remove_res) @commands.guild_only() @commands.has_role('Капитан') async def remove_res(self, ctx: commands.context.Context, name: str): """ Allow user exit the raid by command Attributes: ---------- name: str Nickname of user that want leave the raid. captain_name: str Nickname of user that created the raid. time_leaving: str Time when raid leaving. Required to fill if captain has more than one raid. """ # Checking correct inputs arguments await check_input.validation(**locals()) current_raid = self.raid_list.find_raid_by_nickname(name) if not current_raid: await ctx.message.add_reaction('❌') log_template.command_fail(ctx, logger_msgs.nope_in_raids) else: current_raid -= name await current_raid.raid_msgs.update_coll_msg(self.bot) await ctx.message.add_reaction('✔') log_template.command_success(ctx)