async def delete_menu(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: """ Deletes the whole Selection Role menu, including the original message. """ await interaction.response.defer() member = interaction.user view = ConfirmButton(member) self.stop() msg = await interaction.channel.send( f"**Are you sure you want to delete this menu, {member.mention}?**", view=view) # Wait for the View to stop listening for input... await view.wait() if view.value is None: await interaction.channel.send(f"**Timeout, {member.mention}!**", delete_after=5) elif view.value: await self.db.delete_selection_menu_by_message_id( self.message.id, self.message.guild.id) await self.message.delete() await interaction.channel.send( f"**Menu successfully deleted, {member.mention}!**", delete_after=5) else: await interaction.channel.send( f"**Not deleting it then, {member.mention}!**", delete_after=5) try: await msg.delete() except: pass
async def _giveaway_delete_callback(self, ctx, message_id: int) -> None: """ Deletes an existing giveaway. :param message_id: The ID of the giveaway message. """ member = ctx.author if not message_id: return await ctx.respond( f"**Please, inform a message ID, {member.mention}!**", ephemeral=True) giveaway = await self.get_giveaway(message_id) if not giveaway: return await ctx.respond( f"**The specified giveaway message doesn't exist, {member.mention}!**", ephemeral=True) if giveaway[7] != member.id and not await utils.is_allowed( [mod_role_id]).predicate(ctx): return await ctx.send( f"**You cannot delete someone else's giveaway, {member.mention}!**" ) confirm_view = ConfirmButton(member, timeout=60) embed = discord.Embed( description= f"**Are you sure you wanna delete the giveaway with ID `{giveaway[0]}`, {member.mention}?**", color=member.color) await ctx.respond(embed=embed, view=confirm_view, ephemeral=True) await confirm_view.wait() if confirm_view.value is None: return await ctx.respond( f"**{member.mention}, you took too long to answer...**", ephemeral=True) if not confirm_view.value: return await ctx.respond( f"**Not doing it then, {member.mention}!**", ephemeral=True) await self.delete_giveaway(giveaway[0]) await ctx.respond( f"**Successfully deleted the giveaway with ID: `{giveaway[0]}`, {member.mention}!**", ephemeral=True) try: channel = discord.utils.get(ctx.guild.text_channels, id=giveaway[1]) message = await channel.fetch_message(giveaway[0]) await message.delete() except: pass
async def modrep(self, ctx): """ (STAFF) Shows all the moderators and their statuses in an embedded message. """ mod_activities = await self.get_mod_activities() member: discord.Member = ctx.author embed = discord.Embed(title="This Week's Report", description="Moderators' activity statuses.", url='https://discordapp.com', color=discord.Color.dark_green(), timestamp=ctx.message.created_at) embed.set_footer(text='Activity Report', icon_url=self.client.user.display_avatar) embed.set_thumbnail(url=ctx.guild.icon.url) embed.set_author(name=ctx.guild.name) for mod in mod_activities: m, s = divmod(mod[1], 60) h, m = divmod(m, 60) user = discord.utils.get(ctx.guild.members, id=mod[0]) embed.add_field( name=f'👤__**{user}**__', value= f"**- Voice Chat Activity:**\n{h:d} hours, {m:02d} minutes and {s:02d} seconds\n**- Text Chat Activity:**\n{mod[3]} messages", inline=False) confirm_view: discord.ui.View = ConfirmButton(member, timeout=60) await ctx.send(embed=embed) msg = await ctx.send("**Do you want to reset the data?**", view=confirm_view) await confirm_view.wait() await utils.disable_buttons(confirm_view) await msg.edit(view=confirm_view) if confirm_view.value is None: await ctx.send(f"**Timeout, not deleting it, {member.mention}!**", delete_after=3) elif confirm_view.value: await self.delete_mod_activity() await ctx.send(f"**Mod Activity data reset, {member.mention}!**", delete_after=3) else: await ctx.send(f"**Not deleting it then, {member.mention}!**", delete_after=3) await msg.delete()
async def start_menu(self, ctx, message_id: int = None) -> None: """ Creates a Button Role-Selection Menu. :param message_id: The ID of the message which is gonna be the menu. """ await ctx.message.delete() member = ctx.author if not message_id: return await ctx.send(f"**Please, inform a `message ID`, {member.mention}!**", delete_after=5) msg = await ctx.channel.fetch_message(message_id) if not msg: return await ctx.send(f"**Message not found, {member.mention}!**", delete_after=5) view = discord.ui.View(timeout=None) while True: button_configs = await self.ask_button_questions(ctx, msg) if not button_configs: break view.add_item(RoleButton(**button_configs)) try: await self.db.insert_menu_button(msg.id, msg.channel.id, msg.guild.id, *button_configs.values()) except Exception as e: print(e) await ctx.send(f"**I couldn't add your button to the database, {member.mention}!**", delete_after=5) else: await msg.edit(view=view) await msg.edit(view=view) confirm_view = ConfirmButton(member) embed = discord.Embed(description=f"**Wanna add more buttons into your menu, {member.mention}?**", color=member.color) confirm_msg = await ctx.channel.send(embed=embed, view=confirm_view) await confirm_view.wait() await confirm_msg.delete() if confirm_view.value is None or not confirm_view.value: break self.client.add_view(view=view, message_id=msg.id) await ctx.send(f"**Menu successfully completed, {member.mention}!**", delete_after=5)
async def add_button(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: await interaction.response.defer() member = interaction.user view_menu = discord.ui.View.from_message(self.message, timeout=None) ctx = await self.client.get_context(interaction.message) ctx.author = member cog = self.client.get_cog('RoleSelection') # print('\n'.join([f"button: {btn.label} custom id {btn.custom_id}" for btn in view.children])) self.stop() while True: button_configs = await cog.ask_button_questions(ctx, self.message) if not button_configs: break view_menu.add_item(RoleButton(**button_configs)) for child in view_menu.children: child.callback = partial(button_callback, child) try: await self.db.insert_menu_button(self.message.id, self.message.channel.id, self.message.guild.id, *button_configs.values()) except Exception as e: print(e) await interaction.channel.send(f"**I couldn't add your button to the database, {member.mention}!**", delete_after=5) else: await self.message.edit(view=view_menu) self.client.add_view(view=view_menu) # Maybe delete this line later view = ConfirmButton(member) embed = discord.Embed(description=f"**Wanna add more buttons into your menu, {member.mention}?**", color=member.color) msg = await interaction.channel.send(embed=embed, view=view) await view.wait() await msg.delete() if view.value is None or not view.value: break await self.message.channel.send("**Menu updated!**", delete_after=5)
async def add_button(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: """ Adds a button to an existing drop-down menu. """ await interaction.response.defer() member = interaction.user view_menu = discord.ui.View.from_message(self.message, timeout=None) ctx = await self.client.get_context(interaction.message) ctx.author = member cog = self.client.get_cog('RoleSelection') selects = await self.db.get_selection_menus_by_message_id_and_placeholder( self.message.id) initial_view = BasicUserCheckView(member, 180) # Creates button options for selecting the drop-down in which to add new select options for i, select in enumerate(selects): initial_view.add_item( ValueButton(style=discord.ButtonStyle.blurple, label=f"{i} - {select[6]}", custom_id=f"select_select_{i}_id")) # Prompts user the select to use initial_msg = await ctx.send("Select a select", view=initial_view) await initial_view.wait() if initial_view.value is None: return await initial_msg.delete() for child in view_menu.children: child.callback = partial(RoleSelect.callback, child) placeholder = view_menu.children[initial_view.value].placeholder self.stop() # Loops creation of select options while True: select_configs = await cog.ask_select_questions(ctx, self.message) if not select_configs: break view_menu.children[initial_view.value].options.append( discord.SelectOption(**select_configs)) try: await self.db.insert_menu_select(self.message.id, self.message.channel.id, self.message.guild.id, *select_configs.values(), placeholder) except Exception as e: print(e) await interaction.channel.send( f"**I couldn't add your button to the database, {member.mention}!**", delete_after=5) else: await self.message.edit(view=view_menu) self.client.add_view(view=view_menu) view = ConfirmButton(member) embed = discord.Embed( description= f"**Wanna add more options into your select menu, {member.mention}?**", color=member.color) msg = await interaction.channel.send(embed=embed, view=view) await view.wait() await msg.delete() if view.value is None or not view.value: break await self.message.channel.send("**Menu updated!**", delete_after=5)
async def delete_select_dropdopwn_menu( self, button: discord.ui.Button, interaction: discord.Interaction) -> None: """ Deletes a specific select drop-down from the Role Selection menu. """ await interaction.response.defer() member = interaction.user ctx = await self.client.get_context(interaction.message) ctx.author = member view_menu = discord.ui.View.from_message(self.message, timeout=None) selects = await self.db.get_selection_menus_by_message_id_and_placeholder( self.message.id) initial_view = BasicUserCheckView(member, 180) for i, select in enumerate(selects): initial_view.add_item( ValueButton(style=discord.ButtonStyle.blurple, label=f"{i} - {select[6]}", custom_id=f"select_select_{i}_id")) initial_msg = await ctx.send("Which select do you wanna delete?", view=initial_view) await initial_view.wait() if initial_view.value is None: return await initial_msg.delete() view = ConfirmButton(member) self.stop() msg = await interaction.channel.send( f"**Are you sure you want to delete the `{initial_view.value}#` select, {member.mention}?**", view=view) # Wait for the View to stop listening for input... await view.wait() await msg.delete() if view.value is None: await interaction.channel.send(f"**Timeout, {member.mention}!**", delete_after=5) elif view.value: try: placeholder = view_menu.children[ initial_view.value].placeholder view_menu.children.pop(initial_view.value) for child in view_menu.children: child.callback = partial(RoleSelect.callback, child) await self.db.delete_selection_menu_by_message_id_and_placeholder( self.message.id, self.message.guild.id, placeholder) await self.message.edit(view=view_menu) self.client.add_view(view=view_menu, message_id=self.message.id) await interaction.channel.send( f"**Select `{initial_view.value}#` successfully deleted, {member.mention}!**", delete_after=5) except Exception as e: print(e) await interaction.channel.send( f"**For some reason I couldn't delete this select, {member.mention}!**" ) else: await interaction.channel.send( f"**Not deleting it then, {member.mention}!**", delete_after=5)
async def delete_select_option(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: """ Deletes a specific item/option from a specific select drop-down. """ await interaction.response.defer() self.stop() member = interaction.user ctx = await self.client.get_context(interaction.message) ctx.author = member view_menu = discord.ui.View.from_message(self.message, timeout=None) selects = await self.db.get_selection_menus_by_message_id_and_placeholder( self.message.id) initial_view = BasicUserCheckView(member, 180) # Makes a view with the select options for i, select in enumerate(selects): initial_view.add_item( ValueButton(style=discord.ButtonStyle.blurple, label=f"{i} - {select[6]}", custom_id=f"select_select_{i}_id")) initial_msg = await ctx.send("Select a select", view=initial_view) await initial_view.wait() if initial_view.value is None: return await initial_msg.delete() chosen_select = view_menu.children[initial_view.value] options = view_menu.children[initial_view.value].options options_text: List[str] = [ f"`{i+1}`: ({child.emoji}) {child.label} <@&{int(child.value)}>" for i, child in enumerate(options) ] if not options_text: return await interaction.channel.send( f"**You have no options in this menu yet, {member.mention}!**", delete_after=3) embed = discord.Embed( title="__Available Select Options in this Menu__", description='\n'.join(options_text), color=member.color, timestamp=self.message.created_at) embed.set_footer(text=f"Menu: {self.message.id}") # Asks user the option to delete del_btn_msg = await interaction.channel.send( f"**What select option do you want to delete, {member.mention}?**", embed=embed) number = await prompt_number(self.client, interaction.channel, member, limit=len(options)) if not number: return await del_btn_msg.delete() view = ConfirmButton(member) chosen_option = options[number - 1] embed = discord.Embed( description= f"""**Are you sure you want to delete the button with label `{chosen_option.label}`, with the <@&{chosen_option.value}> role attached to it, {member.mention}?**""" ) msg = await interaction.channel.send(embed=embed, view=view) # Wait for the View to stop listening for input... await view.wait() if view.value is None: await interaction.channel.send(f"**Timeout, {member.mention}!**", delete_after=5) elif view.value: chosen_select.options.remove(chosen_option) if not chosen_select.options: view_menu.children.pop(initial_view.value) for child in view_menu.children: child.callback = partial(RoleSelect.callback, child) try: await self.db.delete_menu_select(self.message.id, self.message.channel.id, self.message.guild.id, chosen_option.value) except Exception as e: await interaction.channel.send( f"**I couldn't remove your button from the database, {member.mention}!**", delete_after=5) else: await self.message.edit(view=view_menu) self.client.add_view(view=view_menu, message_id=self.message.id) await interaction.channel.send( f"**Menu successfully deleted, {member.mention}!**", delete_after=5) else: await interaction.channel.send( f"**Not deleting it then, {member.mention}!**", delete_after=5) await msg.delete()
async def honeymoon(self, ctx) -> None: """ Celebrates a honey moon with your partner. Benefits: It heals the couple, protects and resets all skills cooldowns and change class cooldown. """ member = ctx.author SlothClass = self.client.get_cog('SlothClass') member_marriage = await SlothClass.get_user_marriage(member.id) if not member_marriage['partner']: self.client.get_command('honeymoon').reset_cooldown(ctx) return await ctx.send( f"**You don't have a partner, you can't have a honeymoon by yourself, {member.mention}!** 😔" ) if member_marriage['honeymoon']: self.client.get_command('honeymoon').reset_cooldown(ctx) return await ctx.send( f"**You already had a honeymoon, what are you doing, {member.mention}?**" ) partner = discord.utils.get(ctx.guild.members, id=member_marriage['partner']) if not partner: self.client.get_command('honeymoon').reset_cooldown(ctx) return await ctx.send( f"**It looks like your partner has left the server, {member.mention}. RIP!" ) embed = discord.Embed( title="__Honeymoon Setup__", description= f"{member.mention}, select where in the world you wanna have your honeymoon with {partner.mention}.", color=discord.Color.gold(), timestamp=ctx.message.created_at, url= "https://travel.usnews.com/rankings/best-honeymoon-destinations/") embed.set_thumbnail( url= 'https://i.pinimg.com/originals/87/35/53/873553eeb255e47b1b4b440e4302e17f.gif' ) embed.set_author(name=partner, icon_url=partner.display_avatar, url=partner.display_avatar) embed.set_footer(text=f"Requested by {member}", icon_url=member.display_avatar) # Honeymoon setup view view = HoneymoonView(member=member, target=member, timeout=300) await ctx.send(content=f"{member.mention}, {partner.mention}", embed=embed, view=view) await view.wait() if not view.value: return await utils.disable_buttons(view) # Check user currency user_currency = await SlothClass.get_user_currency(member.id) if user_currency[1] < 1500: return await ctx.send( f"**You don't have `1500łł` to have a honeymoon, {member.mention}!**" ) # Confirmation view confirm_embed = discord.Embed( title="__Confirmation Prompt__", description= f"Are you sure you wanna spend `1500łł` for having your honeymoon with {partner.mention}, {member.mention}?", color=discord.Color.orange(), timestamp=ctx.message.created_at) confirmation_view = ConfirmButton(member, 60) msg = await ctx.send(embed=confirm_embed, view=confirmation_view) await confirmation_view.wait() if confirmation_view.value is None: embed.description = "Timeout" embed.color = discord.Color.red() elif not confirmation_view.value: embed.description = "Canceled!" embed.color = discord.Color.red() else: embed.description = "Confirmed!" embed.color = discord.Color.green() # Disable buttons and updates the confirmation_view await utils.disable_buttons(confirmation_view) await msg.edit(embed=embed, view=confirmation_view) if not confirmation_view.value: return member_marriage = await SlothClass.get_user_marriage(member.id) if member_marriage['honeymoon']: return await ctx.send( f"**You already had your honeymoon, {member.mention}!**") await self.client.get_cog('SlothCurrency').update_user_money( member.id, -1500) # Updates user money await SlothClass.update_marriage_content(member.id) place, activity = view.place, view.activity final_embed = view.embed final_embed.clear_fields() final_embed.title = "__Honeymoon Time!__" final_embed.description = f""" {member.mention} and {partner.mention} went to `{place['value']}` for their honeymoon! 🍯🌛 And arriving there, they will `{activity['name']}`. 🎉 """ current_ts = await utils.get_timestamp() try: # Reset effects member_fx = await SlothClass.get_user_effects(member) partner_fx = await SlothClass.get_user_effects(partner) await SlothClass.remove_debuffs(member=member, debuffs=member_fx) await SlothClass.remove_debuffs(member=partner, debuffs=partner_fx) # Resets skills cooldown await SlothClass.update_user_skills_ts(member.id) await SlothClass.update_user_skills_ts(partner.id) # Resets Change-Sloth-Class cooldown ten_days = current_ts - 864000 await SlothClass.update_change_class_ts(member.id, ten_days) await SlothClass.update_change_class_ts(partner.id, ten_days) # Protects / Reinforces if 'protected' not in partner_fx: await SlothClass.insert_skill_action( user_id=member.id, skill_type="divine_protection", skill_timestamp=current_ts, target_id=partner.id) else: await SlothClass.reinforce_shield(partner.id) if 'protected' not in member_fx: await SlothClass.insert_skill_action( user_id=partner.id, skill_type="divine_protection", skill_timestamp=current_ts, target_id=member.id) else: await SlothClass.reinforce_shield(member.id) except Exception as e: print('Honeymoon error', e) await ctx.send(content=f"{member.mention}, {partner.mention}", embed=final_embed)
async def rip_off(self, ctx, target: discord.Member = None) -> None: """ Will rip off an item of your choice of your target. :param target: The target member. * Cooldown: 2 days. * Price: Half of the price of your target's ripped-off item Ps: - The menu containing the target's items will appear when using this command on them. - You will only see up to 25 items of your target, the first 25 items. - If an item is ripped-off, it's removed permanently from the member's inventory. """ attacker = ctx.author if ctx.channel.id != self.bots_txt.id: return await ctx.send( f"**You can only use this skill in {self.bots_txt.mention}, {attacker.mention}!**" ) attacker_fx = await self.get_user_effects(attacker) if 'knocked_out' in attacker_fx: return await ctx.send( f"**You can't use this skills because you are knocked-out, {attacker.mention}!**" ) if not target: return await ctx.send( f"**Please, inform a target, {attacker.mention}!**") if attacker.id == target.id: return await ctx.send( f"**{attacker.mention}, you cannot do it on yourself!**") if target.bot: return await ctx.send( f"**{attacker.mention}, you cannot do it on a bot!**") target_sloth_profile = await self.get_sloth_profile(target.id) if not target_sloth_profile: return await ctx.send( f"**You cannot do it on someone who doesn't have an account, {attacker.mention}!**" ) if target_sloth_profile[1] == 'default': return await ctx.send( f"**You cannot do it on someone who has a `default` Sloth class, {attacker.mention}!**" ) target_fx = await self.get_user_effects(target) if 'protected' in target_fx: return await ctx.send( f"**You cannot attack {target.mention} because they are protected, {attacker.mention}!**" ) SlothCurrency = self.client.get_cog('SlothCurrency') target_items = await SlothCurrency.get_user_registered_items(target.id) if not target_items: return await ctx.send( f"**{target.mention} doesn't have any items to rip off, {attacker.mention}!**" ) view = BasicUserCheckView(attacker) view.add_item(WarriorUserItemSelect(target_items[:25])) await ctx.send(f"**{target.display_name}**'s items:", view=view) await view.wait() if not hasattr(view, 'selected_item'): return await ctx.send(f"**Timeout, {attacker.mention}!**") item = view.selected_item cost = int(item[6] / 2) confirm_view = ConfirmButton(attacker, timeout=60) await ctx.send(embed=discord.Embed( title="__Confirm__", description= f"**Do you really wanna rip off {target.mention}'s `{item[4]}` item for the cost of `{cost}Å‚Å‚`, {attacker.mention}?**", color=discord.Color.green()), view=confirm_view) await confirm_view.wait() if confirm_view.value is None or not confirm_view.value: return await ctx.send(f"**Not doing it, then!**") _, exists = await Player.skill_on_cooldown( skill=Skill.THREE, seconds=172800).predicate(ctx) attacker_currency = await self.get_user_currency(attacker.id) if attacker_currency[1] < cost: return await ctx.send( f"**You don't have {item[6]}Å‚Å‚ to rip off the {item[4]} item, {attacker.mention}!**" ) await self.client.get_cog('SlothCurrency').update_user_money( attacker.id, -cost) try: current_timestamp = await utils.get_timestamp() # Don't need to store it, since it is forever if exists: await self.update_user_skill_ts(attacker.id, Skill.THREE, current_timestamp) else: await self.insert_user_skill_cooldown(attacker.id, Skill.THREE, current_timestamp) # Updates user's skills used counter await self.update_user_skills_used(user_id=attacker.id) await SlothCurrency.remove_user_item(target.id, item[4]) except Exception as e: print(e) return await ctx.send( f"**Something went wrong and your `Rip Off` skill failed, {attacker.mention}!**" ) else: rip_off_embed = await self.get_rip_off_embed( channel=ctx.channel, perpetrator_id=attacker.id, target_id=target.id, item=item) await ctx.send(embed=rip_off_embed)
async def delete_button(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: await interaction.response.defer() self.stop() member = interaction.user view_menu = discord.ui.View.from_message(self.message, timeout=60) buttons_text = [f"`{i+1}`: ({child.emoji}) {child.label} <@&{child.custom_id}>" for i, child in enumerate(view_menu.children)] if not buttons_text: return await interaction.channel.send(f"**You have no buttons in this menu yet, {member.mention}!**", delete_after=3) embed = discord.Embed( title="__Available Buttons in this Menu__", description='\n'.join(buttons_text), color=member.color, timestamp=self.message.created_at ) embed.set_footer(text=f"Menu: {self.message.id}") await interaction.channel.send(f"**What button you want to delete, {member.mention}?**", embed=embed) number = await prompt_number(self.client, interaction.channel, member, limit=len(view_menu.children)) if not number: return view = ConfirmButton(member) chosen_button = view_menu.children[number-1] embed = discord.Embed( description=f"""**Are you sure you want to delete the button with label `{chosen_button.label}`, with the <@&{chosen_button.custom_id}> role attached to it, {member.mention}?**""" ) msg = await interaction.channel.send(embed=embed, view=view) # Wait for the View to stop listening for input... await view.wait() if view.value is None: await interaction.channel.send(f"**Timeout, {member.mention}!**", delete_after=5) elif view.value: view_menu.children = [ child for child in view_menu.children if child != chosen_button ] for child in view_menu.children: child.callback = partial(button_callback, child) try: await self.db.delete_menu_button( self.message.id, self.message.channel.id, self.message.guild.id, chosen_button.custom_id) except Exception as e: await interaction.channel.send(f"**I couldn't remove your button from the database, {member.mention}!**", delete_after=5) else: await self.message.edit(view=view_menu) await self.client.add_view(view=view_menu, message_id=self.message.id) await interaction.channel.send(f"**Menu successfully deleted, {member.mention}!**", delete_after=5) else: await interaction.channel.send(f"**Not deleting it then, {member.mention}!**", delete_after=5) await msg.delete()
async def _add(self, ctx, message_id: int = None) -> None: """ Subcommand for adding drop-downs to a message. """ await ctx.message.delete() member = ctx.author if not message_id: return await ctx.send( f"**Please, inform a `message ID`, {member.mention}!**", delete_after=5) msg = await ctx.channel.fetch_message(message_id) if msg is None: return await ctx.send(f"**Message not found, {member.mention}!**", delete_after=5) embed = discord.Embed( description="**What is the default placeholder for the select?**", color=member.color, timestamp=ctx.message.created_at) # Question 1 - Label: initial_msg = await ctx.send(embed=embed) placeholder = await prompt_message_guild(self.client, member=member, channel=ctx.channel, limit=100) await initial_msg.delete() view = discord.ui.View.from_message(msg, timeout=None) for child in view.children: child.callback = partial(RoleSelect.callback, child) select = RoleSelect(placeholder=placeholder, custom_id=placeholder.lower().replace(' ', '_'), options=[]) view.add_item(select) while True: select_configs = await self.ask_select_questions(ctx, msg) if not select_configs: break view.children[-1].options.append( discord.SelectOption(**select_configs)) try: await self.db.insert_menu_select(msg.id, msg.channel.id, msg.guild.id, *select_configs.values(), placeholder) except Exception as e: print(e) await ctx.send( f"**I couldn't add your button to the database, {member.mention}!**", delete_after=5) await msg.edit(view=view) confirm_view = ConfirmButton(member) embed = discord.Embed( description= f"**Wanna add more options into your select menu, {member.mention}?**", color=member.color) confirm_msg = await ctx.channel.send(embed=embed, view=confirm_view) await confirm_view.wait() await confirm_msg.delete() if confirm_view.value is None or not confirm_view.value: break self.client.add_view(view=view, message_id=msg.id) await ctx.send(f"**Menu successfully completed, {member.mention}!**", delete_after=5)
async def _giveaway_end_callback(self, ctx, message_id: int = None) -> None: """ Force-ends an on-going giveaway. :param message_id: The ID of the giveaway message. """ member = ctx.author if not message_id: return await ctx.respond( f"**Please, inform a message ID, {member.mention}!**", ephemeral=True) giveaway = await self.get_giveaway(message_id) if not giveaway: return await ctx.respond( f"**The specified giveaway message doesn't exist, {member.mention}!**", ephemeral=True) if giveaway[5]: return await ctx.respond( f"**This giveaway has been ended already, consider using rerolling or deleting it, {member.mention}!**", ephemeral=True) confirm_view = ConfirmButton(member, timeout=60) embed = discord.Embed( description= f"**Are you sure you want to end the giveaway with ID: `{giveaway[0]}`, {member.mention}?**", color=member.color) await ctx.respond(embed=embed, view=confirm_view, ephemeral=True) await confirm_view.wait() if confirm_view.value is None: return await ctx.respond( f"**{member.mention}, you took too long to answer...**", ephemeral=True) if not confirm_view.value: return await ctx.respond( f"**Not doing it then, {member.mention}!**", ephemeral=True) # Gets the channel and message channel = message = None try: channel = await self.client.fetch_channel(giveaway[1]) except discord.errors.NotFound: await self.delete_giveaway(giveaway[0]) return await ctx.respond( f"**Channel of the given giveaway doesn't exist anymore, {member.mention}!**", ephemeral=True) try: message = await channel.fetch_message(giveaway[0]) except discord.errors.NotFound: await self.delete_giveaway(giveaway[0]) return await ctx.respond( f"**Message of the given giveaway doesn't exist anymore, {member.mention}!**", ephemeral=True) try: entries = await self.get_giveaway_entries(giveaway[0]) winners = await self.get_winners(giveaway, entries) # Edits the embed embed = message.embeds[0] embed.title += ' (Ended)' embed.color = discord.Color.red() view = discord.ui.View.from_message(message) await utils.disable_buttons(view) await message.edit(embed=embed, view=view) # Sends last message await message.reply( f"**Giveaway is over, we had a total of `{len(entries)}` people participating, and the `{giveaway[3]}` winners are: {winners}!**" ) # Notifies the giveaway's termination await self.update_giveaway(giveaway[0]) current_ts: int = await utils.get_timestamp() await self.update_giveaway_deadline(giveaway[0], current_ts) except Exception as e: print('Error at force-ending giveaway: ', e) await ctx.respond( f"**Something went wrong with it, please contact an admin, {member.mention}!**", ephemeral=True)