async def favorite_button(self, button, interaction): if interaction.user.id == self.ctx.author.id: await interaction.response.defer() if self.parent.code not in self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Favorites|*n*|fav']: if len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Favorites|*n*|fav"]) >= 25: await self.parent.am_channel.send( embed=Embed( color=0xff0000, description=localization[self.parent.language]['page_reader']['favorites_full'] ), delete_after=5) return self.stop() self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Favorites|*n*|fav'].append(self.parent.code) await self.parent.am_channel.send( embed=Embed( description=localization[self.parent.language]['page_reader']['added_to_favorites'].format(code=self.parent.code) ), delete_after=5) else: self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Favorites|*n*|fav'].remove(self.parent.code) await self.parent.am_channel.send( embed=Embed( description=localization[self.parent.language]['page_reader']['removed_from_favorites'].format(code=self.parent.code) ), delete_after=5) self.stop()
async def say_in(self, ctx: Context, dest: str = None): """Sets the destination for messages from `[p]say`""" if dest: try: self.say_dest: TextChannel = await GlobalTextChannelConverter( ).convert(ctx, dest) except BadArgument as error: em = Embed( title="Invalid Channel Identifier", description=f"**__{type(error).__name__}__**: {str(error)}", color=0xFF0000) await ctx.send(embed=em, delete_after=self.delete_after) else: em = Embed(title="Administration: Set `say` Destination", description=f"__Say destination set__\n" f"Guild: {self.say_dest.guild.name}\n" f"Channel: {self.say_dest.mention}\n" f"ID: {self.say_dest.id}", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after) else: self.say_dest = None em = Embed(title="Administration: Set `say` Destination", description=f"Say destination has been unset", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after)
async def _add(self, ctx: Context, *, role) -> None: """Configures a role as a selfrole""" r_ids = [i for i in self._selfroles.get(ctx.guild.id)] try: role = await RoleConverter().convert(ctx, role) except BadArgument: await ctx.send( embed=Embed(color=ctx.guild.me.colour, title="⚠ Selfroles Management", description=f"Could not recognize role.")) else: if role.id in r_ids: await ctx.send(embed=Embed( color=ctx.guild.me.colour, title="⚠ Selfroles Management", description= f"Role {role.mention} is already configured as a selfrole." )) else: self.config.sadd(f"{self.config}:{ctx.guild.id}", str(role.id)) self._selfroles[ctx.guild.id].append(role.id) await ctx.send(embed=Embed( color=ctx.guild.me.colour, title="Selfroles Management", description= f"Role {role.mention} has been added to selfroles."))
async def _rem(self, ctx: Context, *, role): """Removes a role from selfroles""" r_ids = [i for i in self._selfroles.get(ctx.guild.id)] try: role = await RoleConverter().convert(ctx, role) except BadArgument: await ctx.send( embed=Embed(color=ctx.guild.me.colour, title="⚠ Selfroles Management", description=f"Could not recognize role.")) else: if role.id in r_ids: self.config.srem(f"{self.config}:{ctx.guild.id}", role.id) self._selfroles[ctx.guild.id].remove(role.id) await ctx.send(embed=Embed( color=ctx.guild.me.colour, title="Selfroles Management", description= f"Role {role.mention} has been removed from selfroles.")) else: await ctx.send(embed=Embed( color=ctx.guild.me.colour, title="⚠ Selfroles Management", description= f"Role {role.mention} is not configured as a selfrole."))
async def guild(self, ctx: Context, *, prefix: str = None): """Change guild-specific prefix""" current_guild_prefix = self.config_bot.hget("prefix:guild", f"{ctx.guild.id}") if prefix: if current_guild_prefix == prefix: em = Embed( title="Administration: Guild-Specific Prefix", description=f"No changes to make.\n" f"Prefix for guild `{ctx.guild.name}` is currently set to `{prefix}`", color=self.color(ctx)) else: self.config_bot.hset("prefix:guild", f"{ctx.guild.id}", prefix) em = Embed( title="Administration: Guild-Specific Prefix", description= f"Prefix for guild `{ctx.guild.name}` set to `{prefix}`", color=self.color(ctx)) else: self.config_bot.hdel("prefix:guild", f"{ctx.guild.id}") em = Embed( title="Administration: Guild-Specific Prefix", description=f"Prefix for guild `{ctx.guild.name}` unset", color=self.color(ctx)) await ctx.send(embed=em, delete_after=self.delete_after)
async def selfroles(self, ctx: Context): """View all selfroles""" r_ids = self._selfroles.get(ctx.guild.id) if r_ids: roles = [] for role in ctx.guild.roles: if role.id in r_ids: roles.append(role.mention) roles = "\n".join(roles) await ctx.send(embed=Embed( color=ctx.guild.me.colour, title="Selfroles", description=f"The following roles are self-assignable:\n" f"{roles}" f"\n" f"\n" f"See `?help iam` for assigning selfroles.")) else: await ctx.send(embed=Embed( color=ctx.guild.me.colour, title="Selfroles", description="There are currently no assignable selfroles.\n" "Staff may configure selfroles with `?selfrole add`."))
async def invite(self, ctx): # This tells the user that the command they are trying to use isn't translated yet. user_language = { "lang": self.bot.user_data["UserData"][str( ctx.author.id)]["Settings"]["Language"] } if ctx.command.qualified_name not in localization[ user_language["lang"]]: class Continue(ui.View): def __init__(self): super().__init__(timeout=15) self.value = None @ui.button(label=localization[user_language["lang"]] ["language_not_available"]["button"], style=ButtonStyle.primary, emoji="▶️", custom_id="continue") async def continue_button(self, button, interaction): if interaction.user.id == ctx.author.id: user_language["lang"] = "eng" await self.message.delete() self.value = True self.stop() async def on_timeout(): await self.message.delete() self.stop() emb = Embed(description=localization[user_language["lang"]] ["language_not_available"]["description"]).set_footer( text=localization[user_language["lang"]] ["language_not_available"]["footer"]) view = Continue() view.message = await ctx.send(embed=emb, view=view) await view.wait() if not view.value: return user_language = user_language["lang"] app_info: AppInfo = await self.bot.application_info() permissions = Permissions() permissions.update(send_messages=True, embed_links=True, add_reactions=True, manage_messages=True, manage_roles=True, manage_channels=True, use_application_commands=True) emb = Embed( title=localization[user_language]["invite"]["title"], description=localization[user_language]["invite"]["description"]. format(url=oauth_url(app_info.id, permissions=permissions)), ).set_author(name=self.bot.user.name, icon_url=self.bot.user.avatar.url).set_footer( text=localization[user_language]["invite"]["footer"]) await ctx.send(embed=emb)
async def readlater_button(self, button, interaction): if interaction.user.id == self.ctx.author.id: await interaction.response.defer() if len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"]) >= 25: await self.ctx.send( embed=Embed( color=0xff0000, description=localization[self.parent.language]['results_browser']['buttons']['read_later_full'] ), delete_after=5) self.stop() return if str(self.parent.doujins[self.parent.index].id) not in self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"]: self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"].append(str(self.parent.doujins[self.parent.index].id)) await self.ctx.send( embed=Embed( description=localization[self.parent.language]['results_browser']['buttons']['add_to_read_later'].format(code=self.parent.doujins[self.parent.index].id) ), delete_after=5) else: self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"].remove(str(self.parent.doujins[self.parent.index].id)) await self.ctx.send( embed=Embed( description=localization[self.parent.language]['results_browser']['buttons']['remove_from_read_later'].format(code=self.parent.doujins[self.parent.index].id) ), delete_after=5) self.stop()
async def bookmark_button(self, button, interaction): if interaction.user.id == self.ctx.author.id: await interaction.response.defer() if not self.parent.on_bookmarked_page: if self.parent.current_page == 0: await self.parent.am_channel.send( embed=Embed( color=0xFF0000, description=localization[self.parent.language]['page_reader']['cannot_bookmark_first_page'] ), delete_after=5) return self.stop() if len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Bookmarks|*n*|bm"]) >= 25: await self.parent.am_channel.send( color=0xff0000, embed=Embed( description=localization[self.parent.language]['page_reader']['bookmarks_full'] ), delete_after=5) return self.stop() self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm'][self.parent.code] = self.parent.current_page self.parent.on_bookmarked_page = True else: if self.parent.code in self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm']: self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm'].pop(self.parent.code) self.parent.on_bookmarked_page = False self.stop()
async def err(self, ctx: Context, lines: int = 5): """Get stdout logs""" err = self.get_tail("error", lines) em = Embed(title="Administration: Tail", color=0x00FF00) em.add_field(name="Error", value=f"```diff\n{err}\n```", inline=False) for embed in em.split(): await ctx.send(embed=embed) await sleep(0.1)
async def iam(self, ctx: Context, *, role) -> None: """Add a self-assignable role If the `role` is configured as an assignable selfrole, you can use this command to assign the role to yourself. `[p]iam role` `[p]iam @role` `[p]iam role id` You can also use a country's short code. e.g. `[p]iam os`""" if role.lower() in ROLE_SHORTNAME.keys(): role = str(ROLE_SHORTNAME[role.lower()]) try: role = await RoleConverter().convert(ctx, role) except BadArgument: await ctx.send( embed=Embed(color=ctx.guild.me.colour, title="⚠ Selfroles", description=f"Could not recognize role.")) else: if role in ctx.author.roles: await ctx.send(embed=Embed( color=ctx.guild.me.colour, title="⚠ Selfroles", description="You already have this role assigned.")) elif role.id in self._selfroles.get(ctx.guild.id): for author_role in ctx.author.roles: if author_role.id in self._selfroles[ctx.guild.id]: await ctx.author.remove_roles( author_role, reason=ctx.message.content, atomic=True) await sleep(0.5) await ctx.author.add_roles(role, reason=ctx.message.content, atomic=True) await ctx.send(embed=Embed( color=role.colour, title="Role Assigned", description=f"Congratulations, {ctx.author.mention}!" f" You now have the **{role.mention}** " f"role.")) else: await ctx.send(embed=Embed( color=0xFF0000, title="⚠ Selfroles", description="That role is not self-assignable."))
async def on_message(self, msg: Message): if str(self.bot.user.id) in msg.content: ts = tz.localize(datetime.now()).strftime("%b. %d, %Y %I:%M %p") author = msg.author display_name = f' ({author.display_name})' if author.display_name != author.name else '' em = Embed(title=f"{msg.guild}: #{msg.channel} at {ts}", description=msg.content, color=author.colour) em.set_author( name=f"{author.name}#{author.discriminator}{display_name}", icon_url=author.avatar_url_as(format="png")) await self.notifchannel.send(msg.jump_url, embed=em)
async def legal(self, ctx): # This tells the user that the command they are trying to use isn't translated yet. user_language = { "lang": self.bot.user_data["UserData"][str( ctx.author.id)]["Settings"]["Language"] } if ctx.command.qualified_name not in localization[ user_language["lang"]]: class Continue(ui.View): def __init__(self): super().__init__(timeout=15) self.value = None @ui.button(label=localization[user_language["lang"]] ["language_not_available"]["button"], style=ButtonStyle.primary, emoji="▶️", custom_id="continue") async def continue_button(self, button, interaction): user_language["lang"] = "eng" await conf.delete() self.value = True self.stop() async def on_timeout(self): await conf.delete() self.stop() emb = Embed(description=localization[user_language["lang"]] ["language_not_available"]["description"]).set_footer( text=localization[user_language["lang"]] ["language_not_available"]["footer"]) view = Continue() conf = await ctx.send(embed=emb, view=view) await view.wait() if not view.value: return user_language = user_language["lang"] # Fetch document from one location channel = await self.bot.fetch_channel(815473015394926602) message = await channel.fetch_message(815473545307881522) await ctx.send( embed=Embed(title="<:info:818664266390700074> Legal Notice", description=message.content).set_author( name=self.bot.user.name, icon_url=self.bot.user.avatar.url).set_footer( text="Provided by MechHub"))
async def log_event(self, embed: Embed, guild: Guild, priority: bool = False, **kwargs) -> None: """Have to use this backwards-ass method because it throws http exceptions.""" guild_config = self.get_guild_config(guild) if priority: priority_modlog = int(guild_config.get("priority_modlog", 0)) dest = self.bot.get_channel(priority_modlog) else: default_modlog = int(guild_config.get("default_modlog", 0)) dest = self.bot.get_channel(default_modlog) if not dest: return try: for i, page in enumerate(embed.split()): if i: await sleep(0.1) await dest.send(embed=page, **kwargs) except HTTPException as error: await self.errorlog.send(error)
async def add_role(self, ctx: Context, role: Role): if self.config.sismember(f"allowed_roles:{ctx.guild.id}", role.id): em = Embed(title="Polls Administration", description= f"{role.mention} is already allowed to conduct polls.", color=Color.red()) await ctx.send(embed=em, delete_after=5) else: self.config.sadd(f"allowed_roles:{ctx.guild.id}", role.id) em = Embed( title="Polls Administration", description=f"{role.mention} is now allowed to conduct polls.", color=Color.green()) await ctx.send(embed=em, delete_after=5)
async def init(self, ctx: Context): """Get list of modules currently set as initial cogs""" modules = dict() failed = dict() for init_module in self.config_bot.lrange('initial_cogs', 0, -1): try: module = import_module(f"cogs.{init_module}") module_setup = getattr(module, "setup") modules[init_module] = module_setup.__doc__ except Exception as error: failed[ init_module] = error # TODO: Capture error details of failed cogs space = len(max(modules.keys(), key=lambda x: len(x))) fmt = "\n".join([ f"{module}{' ' * (space - len(module))} : {cog}" for module, cog in modules.items() ]) em = Embed( title="Administration: Initial Modules", description=f"Modules currently set to be loaded at startup\n" f"```py\n" f"{fmt}\n" f"```", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after)
async def pull(self, ctx: Context): """Updates bot repo from master""" em = Embed(title="Administration: Git Pull", description=self.gitpull(), color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after)
async def on_timeout(self): message_part = [] for ind, dj in enumerate(self.parent.doujins): tags = [tag.name for tag in dj.tags if tag.type == "tag"] if any([tag in restricted_tags for tag in tags]) and self.ctx.guild and not self.parent.lolicon_allowed: message_part.append(localization[self.parent.language]['search_doujins']['contains_restricted_tags']) else: message_part.append( f"__`{str(dj.id).ljust(7)}`__ | " f"{language_to_flag(dj.languages)} | " f"{shorten(dj.title.pretty, width=50, placeholder='...')}") self.parent.am_embed = Embed( title=self.parent.name, description=f"\n"+('\n'.join(message_part))) self.parent.am_embed.set_author( name="NHentai", url=f"https://nhentai.net/", icon_url="https://cdn.discordapp.com/emojis/845298862184726538.png?v=1") self.parent.am_embed.set_thumbnail(url=Embed.Empty) self.parent.am_embed.set_image(url=Embed.Empty) await self.parent.active_message.edit(embed=self.parent.am_embed, view=None) self.value = 1 self.stop()
async def on_member_remove(self, member: Member): if not self.awbw: return if member.guild.id != self.awbw.id: return em = Embed(description=LEAVE.format(member.display_name), color=member.guild.me.colour) await self.channel.send(embed=em)
async def remove(self, ctx: Context): """Removes status message""" activity = Activity(name=None) await self.bot.change_presence(activity=activity) em = Embed(title="Administration: Status Message Removed", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after)
async def invisible(self, ctx: Context): """Changes online status to Invisible""" await self.bot.change_presence(status=Status.invisible) em = Embed(title="Administration: Change Online Status", description="Status changed to `invisible`", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after)
async def dnd(self, ctx: Context): """Changes online status to Do Not Disturb""" await self.bot.change_presence(status=Status.dnd) em = Embed(title="Administration: Change Online Status", description="Status changed to `dnd`", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after)
async def _restart(self, ctx: Context): """Restarts the bot""" em = Embed(title="Administration: Restart", description=f"{ctx.author.mention} initiated bot restart.", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after) await self.bot.logout()
async def default(self, ctx: Context, prefix: str = None): """Show or change default prefix""" if prefix: self.config_bot.hset("prefix:config", "default_prefix", prefix) em = Embed(title="Administration: Default Prefix", description=f"Default prefix changed to `{prefix}`", color=self.color(ctx)) else: default_prefix = self.config_bot.hget("prefix:config", "default_prefix") em = Embed(title="Administration: Default Prefix", description= f"Default prefix currently set to `{default_prefix}`", color=self.color(ctx)) await ctx.send(embed=em, delete_after=self.delete_after)
async def watching(self, ctx: Context, *, status: str): """Changes status to `Watching (status)`""" activity = Activity(name=status, type=ActivityType.watching) await self.bot.change_presence(activity=activity) em = Embed(title="Administration: Status Message Set", description=f"Watching {status}", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after)
async def invite(self, ctx: Context): """Sends an OAuth bot invite URL""" em = Embed(title=f'OAuth URL for {self.bot.user.name}', description=f'[Click Here]' f'({oauth_url(self.bot.app_info.id)}) ' f'to invite {self.bot.user.name} to your guild.', color=self.color(ctx)) await ctx.send(embed=em)
async def legal(self, ctx): # Fetch document from one location channel = await self.bot.fetch_channel(815473015394926602) message = await channel.fetch_message(815473545307881522) await ctx.send( embed=Embed(title="<:info:818664266390700074> Legal Notice", description=message.content).set_author( name=self.bot.user.name, icon_url=self.bot.user.avatar_url).set_footer( text="Provided by MechHub Bot Factory"))
async def status_change(self): # activity = Activity( # type=ActivityType.playing, # name=f"COMMANDS ARE BEING REWRITTEN. Most will be unavailable.") # await self.bot.change_presence(activity=activity) # return time = datetime.utcnow().strftime("%H:%M") if self.bot.inactive >= 5: status = Status.idle else: status = Status.online activity = Activity(type=ActivityType.watching, name=f"{time}/UTC | /r | {len(self.bot.guilds)}") try: status_channel = await self.bot.fetch_channel(907036398048116758) status_message = await status_channel.fetch_message( 907036562427088976) except NotFound: await sleep(10) return # Unique timed check for NReader nhentai_ping = str() try: start = default_timer() nhentai_api = NHentai() await nhentai_api.search(query=f"\"small breasts\"") stop = default_timer() nhentai_ping = f"{round((stop-start)*1000)} miliseconds" self.is_available = True except Exception: nhentai_ping = "❌ Currently unaccessible" activity = Activity(type=ActivityType.playing, name=f"❌ Currently blocked from website.") self.is_available = False try: bot_ping = f"{round(self.bot.latency*1000)} miliseconds" except Exception: bot_ping = "Hmm, check back shortly..." await status_message.edit(embed=Embed( description=f"NHentai.net response time: {nhentai_ping}\n" f"Discord bot response time: {bot_ping}\n" f"Server count (affects response time when larger): {len(self.bot.guilds)}\n" ).set_footer(text="Updates approximately every 60 seconds.")) await self.bot.change_presence(status=status, activity=activity)
async def rem(self, ctx: Context, module: str): """Removes a module from initial modules""" # Get current list of initial cogs init_modules = self.config_bot.lrange("initial_cogs", 0, -1) if module in init_modules: self.config_bot.lrem("initial_cogs", 0, module) em = Embed( title="Administration: Initial Module Remove", description=f"Module `{module}` removed from initial modules", color=0x00FF00) await ctx.send(embed=em, delete_after=self.delete_after) else: em = Embed( title="Administration: Initial Module Remove Failed", description=f"Module `{module}` is not an initial module", color=0xFF0000) await ctx.send(embed=em, delete_after=self.delete_after)
async def restart_pull(self, ctx: Context): """Updates repo from origin master and restarts""" em = Embed( title="Administration: Git Pull and Restart", description= f"{ctx.author.mention} initiated bot code update and restart.\n{self.gitpull()}", color=0x00FF00) await ctx.send(embed=em) await self.bot.logout()