async def fetch(self, ctx, invite): try: f = await self.bot.fetch_invite(invite, with_counts=True) except (discord.HTTPException, discord.NotFound): await ctx.send(loc.get(ctx, mn, "fetch_error")) return if invite is None: await ctx.send(loc.get(ctx, mn, "fetch_error")) return embed = discord.Embed(color=discord.Color.teal(), title=f.guild.name) if f.guild.description: embed = discord.Embed(color=discord.Color.teal(), title=f.guild.name, description=f.guild.description) if f.guild.icon_url: embed.set_thumbnail(url=f.guild.icon_url) if f.inviter: inviter = loc.get(ctx, mn, "user").format(f.inviter.name, f.inviter.discriminator) embed.set_footer(text=loc.get(ctx, mn, "inv_f").format(f.inviter.id, f.guild.id)) else: inviter = loc.get(ctx, mn, "empty") embed.set_footer(text=loc.get(ctx, mn, "inv_f_no_user").format(f.guild.id)) embed.add_field(name=loc.get(ctx, mn, "inv_details"), value=loc.get(ctx, mn, "inv_details_v").format( f.code, inviter, f.url )) embed.add_field(name=loc.get(ctx, mn, "inv_guild"), value=loc.get(ctx, mn, "inv_guild_v").format( f.approximate_presence_count, f.approximate_member_count, f.channel.name or loc.get(ctx, mn, "empty") )) await ctx.send(embed=embed)
async def idban(self, ctx, user: int, *, reason=None): try: member = ctx.guild.get_member(user) except discord.NotFound: member = None if member: await ctx.send( loc.get(ctx, mn, "idban_is_member").format(member.name, ctx.prefix, member.id)) return if reason: reason = loc.get(ctx, mn, "ban_reason").format(ctx.author.name, reason) else: reason = loc.get(ctx, mn, "ban_reason_empty").format(ctx.author.name) try: await self.bot.http.ban(user, ctx.guild.id, reason=reason) except (discord.Forbidden, discord.errors.HTTPException): await ctx.send(loc.get(ctx, mn, "user_notfound")) else: for x in await ctx.guild.bans(): if x.user.id == user: member = x.user await ctx.send( loc.get(ctx, mn, "ban_success").format(member.name, reason))
async def list_servers(self, ctx): servers = [] for s in self.bot.guilds: servers.append([f"`{s.id}`", loc.get(ctx, mn, "config_servers_desc").format(s.name, s.owner_id)]) for x in tools.paginate_text(servers, first=loc.get(ctx, mn, "config_servers").format(len(self.bot.guilds)), mid_sep="\n", line_sep="\n\n"): await ctx.send(x)
async def reload(self, ctx, ext): try: self.bot.reload_extension(ext) await ctx.send(loc.get(ctx, mn, "ext_reloaded").format(ext)) except commands.ExtensionNotFound: await ctx.send(loc.get(ctx, mn, "ext_notfound").format(ext)) except commands.ExtensionNotLoaded: await ctx.send(loc.get(ctx, mn, "ext_notloaded").format(ext))
async def shutdown(self, ctx, opt="normal"): db.delete_table("temp") print(loc.get(ctx, mn, "shutdown")) await ctx.send(loc.get(ctx, mn, "shutdown")) await self.bot.change_presence(status=tools.get_status("offline")) if "kill" in opt: exit(-1) else: await self.bot.close()
def _format_illustration(ctx, ilu): r18 = True if ilu["x_restrict"] >= 1 else False if r18: ilu_string = loc.get(ctx, mn, "tag_fs") else: ilu_string = loc.get(ctx, mn, "tag_fs_nsfw") ilu_name = ilu["title"][:30] ilu_author = ilu["user"]["name"][:20] ilu_pages = len(ilu["meta_pages"]) if ilu["meta_pages"] else 1 return ilu_string.format(ilu_name, ilu_author, ilu_pages)
async def unload(self, ctx, ext, store=None): try: self.bot.unload_extension(ext) await ctx.send(loc.get(ctx, mn, "ext_unloaded").format(ext)) except commands.ExtensionNotLoaded: await ctx.send(loc.get(ctx, mn, "ext_notloaded").format(ext)) finally: if ext in config["loadPlugins"] and store == "-config": config["loadPlugins"].remove(ext) dataIO.save_json("data/config.json", config)
def _paginate(ctx, commands, embeds_input=None): pages = [] cmds = commands.copy() for command in commands: if command.hidden is True: cmds.remove(command) for x in cmds: pages.append([x.name, loc.get(ctx, dn, x.brief or "help_undef")]) main = discord.Embed(title=cmds[0].cog.qualified_name, color=discord.Color.teal(), description=loc.get(ctx, dn, cmds[0].cog.qualified_name.lower())) return tools.paginate(pages, discord.Embed(color=discord.Color.teal()), main, False, embeds=embeds_input)
async def load(self, ctx, ext, store=None): try: self.bot.load_extension(ext) await ctx.send(loc.get(ctx, mn, "ext_loaded").format(ext)) except commands.ExtensionNotFound: await ctx.send(loc.get(ctx, mn, "ext_notfound").format(ext)) except commands.ExtensionAlreadyLoaded: await ctx.send(loc.get(ctx, mn, "ext_alreadyloaded").format(ext)) finally: if ext not in config["loadPlugins"] and store == "-config": config["loadPlugins"].append(ext) dataIO.save_json("data/config.json", config)
async def list_shards(self, ctx): sds = self.bot.shards pages = [] first = discord.Embed(title=loc.get(ctx, mn, "config_shard").format(len(self.bot.shards)), color=discord.Color.teal()) for s in sds: pages.append([loc.get(ctx, mn, "config_shard_n").format(sds[s].id), loc.get(ctx, mn, "config_shard_v").format(int(sds[s].latency*1000), loc.get(ctx, mn, str(not sds[s].is_closed())), loc.get(ctx, mn, str(sds[s].is_ws_ratelimited())))]) for e in tools.paginate(pages, discord.Embed(color=discord.Color.teal()), first, True): await ctx.send(embed=e)
async def summary(bot, ctx): cl = "" cogs = sorted(bot.cogs) for cog in cogs: cl = cl + f"`{cog}` {loc.get(ctx, dn, cog.lower())}\n" embed = discord.Embed(title=loc.get(ctx, mn, "help_title"), description=loc.get(ctx, mn, "about_bot").format(db.read("settings", 0, "name")), color=discord.Color.teal()) embed.add_field(name=loc.get(ctx, mn, "help_title"), value=loc.get(ctx, mn, "help_how").format(prefix), inline=False) embed.add_field(name=loc.get(ctx, mn, "modules_all"), value=cl[:-1], inline=False) await ctx.send(embed=embed)
async def get_server(self, ctx, sid: int, action=None): g = self.bot.get_guild(sid) if not g: await ctx.send(loc.get(ctx, mn, "server_notfound")) elif not action: await ctx.send(loc.get(ctx, mn, "config_server_info").format(g.name, g.id, g.shard_id, loc.get(ctx, mn, str(not g.unavailable)))) elif action == "leave": await g.leave() await ctx.send(loc.get(ctx, mn, "config_server_left").format(g.name)) else: await help.send_cmd_help(ctx, error=True)
async def lang(self, ctx, lang=None): if lang: if lang in locales: db.write("serversettings", ctx.guild.id, "locale", lang) await ctx.send(loc.get(ctx, mn, "lang_changed").format(locales[lang])) else: await ctx.send(loc.get(ctx, mn, "lang_not_found")) else: lc = [] for x in locales: lc.append("`" + x + "` " + locales[x]) await ctx.send(loc.get(ctx, mn, "lang_list").format("\n".join(lc)))
async def set_status(self, ctx, status=None): if status not in ["online", "idle", "dnd", "offline"]: await help.send_cmd_help(ctx, error=True) return db.write("settings", 0, "status", status) await self.bot.change_presence(status=tools.get_status(status)) await ctx.send(loc.get(ctx, mn, "config_status_set"))
async def send_cmd_help(ctx, cmd=None, error=False): cmd = cmd or ctx.command desc = loc.get(ctx, mn, "help_undef") if cmd.brief: desc = loc.get(ctx, dn, cmd.brief) embed = discord.Embed(title=cmd.name, description=desc, color=discord.Color.teal()) if error: embed = discord.Embed(title=cmd.name, description=desc, color=discord.Color.red()) embed.set_footer(text=loc.get(ctx, mn, "arg_error")) if cmd.help: embed.add_field(name=loc.get(ctx, mn, "help_title"), value=loc.get(ctx, dn, cmd.help).format(prefix)) embed.set_author(name=cmd.cog_name) await ctx.send(embed=embed) if isinstance(cmd, discord_commands.Group): embeds = _paginate(ctx, list(cmd.commands)) for to_send in embeds: await ctx.send(embed=to_send)
async def set_invite(self, ctx, link: str = None): if not link: await ctx.send(loc.get(ctx, mn, "config_invite").format(db.read("settings", 0, "invite") or inv_d + str(ctx.me.id))) return if link == "default": db.delete("settings", 0, "invite") elif link == "off": db.write("settings", 0, "invite", "off") await ctx.send(loc.get(ctx, mn, "config_invite_disabled")) return else: if not link.startswith("https://"): await ctx.send(loc.get(ctx, mn, "config_invite_invalid")) return db.write("settings", 0, "invite", link) await ctx.send(loc.get(ctx, mn, "config_invite_set").format(db.read("settings", 0, "invite") or inv_d + str(ctx.me.id)))
async def purge(self, ctx, nb: int, user: discord.User = None): if not nb >= 1: await help.send_cmd_help(ctx, error=True) return await ctx.message.delete() if user: def chk(m): return m.author == user deleted = await ctx.channel.purge(limit=nb, check=chk, bulk=True) else: deleted = await ctx.channel.purge(limit=nb, bulk=True) if len(deleted) > 0: await ctx.send( loc.get(ctx, mn, "purge_success").format(len(deleted))) else: await ctx.send(loc.get(ctx, mn, "purge_null"))
async def unban(self, ctx, *, user): for x in await ctx.guild.bans(): if x.user.name == user: await ctx.guild.unban(x.user) await ctx.send( loc.get(ctx, mn, "unban_success").format(x.user.name)) return for x in await ctx.guild.bans(): try: user = int(user) except ValueError: await ctx.send(loc.get(ctx, mn, "user_notfound")) return if x.user.id == user: await ctx.guild.unban(x.user) await ctx.send( loc.get(ctx, mn, "unban_success").format(x.user.name)) return await ctx.send(loc.get(ctx, mn, "user_notfound"))
async def set_presence(self, ctx, p_type, *, p_val=None): if p_type not in ["none", "game", "listen", "watch", "compete", "stream"] or not p_val and p_type != "none": await help.send_cmd_help(ctx, error=True) return if p_type == "none": db.write("settings", 0, "presence_type", "none") db.write("settings", 0, "presence_value", "none") else: db.write("settings", 0, "presence_type", p_type) db.write("settings", 0, "presence_value", p_val) await self.bot.change_presence(activity=tools.get_presence(p_type, p_val)) await ctx.send(loc.get(ctx, mn, "config_presence_set"))
async def on_command_error(ctx, error): if isinstance(error, commands.NoPrivateMessage): await ctx.send(loc.load(dl, mn, "err_pm")) elif isinstance(error, commands.PrivateMessageOnly): await ctx.send(loc.get(ctx, mn, "err_pm_only")) elif isinstance(error, commands.DisabledCommand): await ctx.send(loc.get(ctx, mn, "err_disabled")) elif isinstance(error, commands.NSFWChannelRequired): await ctx.send(loc.load(dl, mn, "err_nsfw")) elif isinstance(error, commands.CommandOnCooldown): await ctx.send(loc.get(ctx, mn, "err_cd").format(error.retry_after)) elif isinstance(error, commands.MissingRequiredArgument): await help.send_cmd_help(ctx, error=True) elif isinstance(error, commands.BadArgument): await help.send_cmd_help(ctx, error=True) elif isinstance(error, commands.CommandInvokeError): if isinstance(error.original, discord.Forbidden): await ctx.send(loc.get(ctx, mn, "err_missing_perm")) else: await ctx.send(loc.get(ctx, mn, "err_exec").format(error)) elif isinstance(error, commands.CommandNotFound): pass elif isinstance(error, commands.CheckFailure): pass else: print(f"Uncaught exception {error}") dataIO.save_json("error.json", [error]) await ctx.send(loc.get(ctx, mn, "err_uncaught"))
async def info(self, ctx): owner = self.bot.get_user(config["owner"]) if owner is None: owner = loc.get(ctx, mn, "info_unknown") ping = int(self.bot.latency * 1000) embed = discord.Embed(title=loc.get(ctx, mn, "info_about"), color=discord.Color.teal()) bot = self.bot.user start_at = datetime.strptime(db.read("temp", 1, "start_time"), "%Y-%m-%d %H:%M:%S") diff = datetime.now() - start_at h, r = divmod(int(diff.total_seconds()), 3600) m, s = divmod(r, 60) d, h = divmod(h, 24) up = f"{d}:{h}:{m}:{s}" embed.set_author(name=bot.name, icon_url=str(bot.avatar_url)) embed.add_field(name=loc.get(ctx, mn, "info_bot_title"), value=loc.get(ctx, mn, "info_bot").format(owner, len(self.bot.users), len(self.bot.guilds), db.read("settings", 0, "prefix"), len(self.bot.cogs)), inline=True) embed.add_field(name=loc.get(ctx, mn, "info_other_title"), value=loc.get(ctx, mn, "info_other").format(ping, self.bot.user.id, len(self.bot.cached_messages), discord.__version__, up), inline=True) embed.set_footer(text=db.read("settings", 0, "name")) await ctx.send(embed=embed)
async def _help(self, ctx, query=None): if query: if query.lower() == "all": await help.send_help(self.bot, ctx) return for cog in self.bot.cogs: if query.lower() == cog.lower(): await help.send_plugin_help(ctx, self.bot.cogs[cog]) return if any(c.name == query.lower() for c in self.bot.commands): await help.send_cmd_help(ctx, self.bot.get_command(query.lower())) return await ctx.send(loc.get(ctx, mn, "help_not_found")) else: await help.summary(self.bot, ctx)
async def _send_illustration(self, ctx, ilu, send_error=True): if ilu["x_restrict"] >= 1: if not p_conf["allow_nsfw"]: if send_error: await ctx.send(loc.get(ctx, mn, "tag_no_nsfw")) return if not ctx.channel.is_nsfw(): if send_error: await ctx.send(loc.get(ctx, mn, "tag_is_nsfw")) return embed = discord.Embed(title=ilu["title"][:256], description=ilu["caption"][:2048], url=art_url.format(ilu["id"]), color=discord.Color.teal()) embed.set_author(name=ilu["user"]["name"][:256], url=user_url.format(ilu["user"]["id"]), icon_url=self._cache_get( ilu["user"]["profile_image_urls"]["medium"])) tags = ", ".join( [x["translated_name"] or x["name"] for x in ilu["tags"]]) embed.add_field(name=loc.get(ctx, mn, "tag_e_tags"), value=tags[:1024]) self._preload_cache(ilu) if ilu["meta_pages"]: y = 1 embed.set_image(url=self._cache_get(ilu["meta_pages"][0] ["image_urls"]["original"])) embed.set_footer(text=loc.get(ctx, mn, "tag_e_id_page").format( ilu["id"], y, len(ilu["meta_pages"]))) to_send = [embed] y += 1 for x in ilu["meta_pages"][1:]: part_embed = discord.Embed(color=discord.Color.teal()) part_embed.set_image( url=self._cache_get(x["image_urls"]["original"])) part_embed.set_footer( text=loc.get(ctx, mn, "tag_e_id_page").format( ilu["id"], y, len(ilu["meta_pages"]))) to_send.append(part_embed) y += 1 for x in to_send: await ctx.send(embed=x) else: embed.set_image(url=self._cache_get(ilu["meta_single_page"] ["original_image_url"])) embed.set_footer( text=loc.get(ctx, mn, "tag_e_id").format(ilu["id"])) await ctx.send(embed=embed)
async def kick(self, ctx, user: discord.User, *, reason=None): if user == ctx.me or user == ctx.author or user == ctx.guild.owner: await ctx.send(loc.get(ctx, mn, "target_error")) return if reason: reason = loc.get(ctx, mn, "kick_reason").format(ctx.author.name, reason) else: reason = loc.get(ctx, mn, "kick_reason_empty").format(ctx.author.name) member = ctx.guild.get_member(user.id) if member is None: await ctx.send(loc.get(ctx, mn, "user_notfound")) return try: await member.send( loc.get(ctx, mn, "kick_dm").format(ctx.guild.name, reason)) except (discord.Forbidden, discord.errors.HTTPException): await ctx.send(loc.get(ctx, mn, "dm_error")) await member.kick(reason=reason) await ctx.send( loc.get(ctx, mn, "kick_success").format(member.name, reason))
def _embed_illustrations(self, ctx, term, r, cp): strings = [] y = 1 for x in r["list"]: strings.append(f"{y}. " + self._format_illustration(ctx, x)) y += 1 embed = discord.Embed(color=discord.Color.teal(), name=term, description=loc.get(ctx, mn, "tag_e_desc")) embed.set_author(icon_url=icon_url, name=loc.get(ctx, mn, "tag_e_sr")) embed.set_footer(text=loc.get(ctx, mn, "tag_e_page").format(cp)) if strings[15:]: embed.add_field(name=loc.get(ctx, mn, "tag_e_works1"), value="\n".join(strings[:15])) embed.add_field(name=loc.get(ctx, mn, "tag_e_works2"), value="\n".join(strings[15:])) else: embed.add_field(name=loc.get(ctx, mn, "tag_e_works"), value="\n".join(strings[:15])) return embed
async def g_userinfo(self, ctx, user: int): try: u = await self.bot.fetch_user(user) except discord.NotFound: await ctx.send(loc.get(ctx, mn, "user_notfound")) return delta_c = datetime.now() - u.created_at embed = discord.Embed(color=discord.Color.teal(), title=u.name) embed.set_footer(text=loc.get(ctx, mn, "usr_reduced_info").format(u.id)) embed.set_thumbnail(url=u.avatar_url) embed.add_field(name=loc.get(ctx, mn, "general"), value=loc.get(ctx, mn, "usr_general_id").format( u.name, u.discriminator, u.avatar_url )) embed.add_field(name=loc.get(ctx, mn, "history"), value=loc.get(ctx, mn, "usr_history_id").format( u.created_at.strftime(loc.get(ctx, "region", "date")), int(delta_c.days) )) embed.add_field(name=loc.get(ctx, mn, "misc"), value=loc.get(ctx, mn, "usr_misc_id").format( loc.get(ctx, mn, str(u.system)), ", ".join([loc.get(ctx, mn, "flags")[p[0]] for p in u.public_flags if p[1] is True]) or loc.get(ctx, mn, "empty") )) await ctx.send(embed=embed)
async def tags(self, ctx, *, term: str): term = term[:32] page = 1 offset = 0 np = False def check(m): return m.author == ctx.author and m.channel == ctx.channel while True: await ctx.trigger_typing() r = self._search_illustrations(term, offset) if not r["list"]: await ctx.send(loc.get(ctx, mn, "tag_search_empty")) return ilu_embed = self._embed_illustrations(ctx, term, r, page) list_msg = await ctx.send(embed=ilu_embed) while True: try: msg = await self.bot.wait_for('message', check=check, timeout=30.0) except asyncio.TimeoutError: await ctx.send(loc.get(ctx, mn, "tag_timeout")) break if msg.content.strip().lower() == "next": if r["next"]: await msg.delete() np = True break else: await ctx.send(loc.get(ctx, mn, "tag_no_next_page")) elif msg.content.strip().lower() == "all": send_msg = await ctx.send(loc.get(ctx, mn, "tag_sending")) for x in r["list"]: await ctx.trigger_typing() await self._send_illustration(ctx, x, False) await send_msg.delete() elif msg.content.strip().lower() == "quit": await ctx.send(loc.get(ctx, mn, "tag_quit")) break else: try: select = int(msg.content.strip()) - 1 if select in range(0, len(r["list"])): send_msg = await ctx.send( loc.get(ctx, mn, "tag_sending")) await ctx.trigger_typing() await self._send_illustration( ctx, r["list"][select]) await send_msg.delete() else: await ctx.send(loc.get(ctx, mn, "tag_choice_err")) return except ValueError: await ctx.send(loc.get(ctx, mn, "tag_choice_err")) return if np: np = False await list_msg.delete() page += 1 offset = r["next"] else: return
async def serverinfo(self, ctx): g = ctx.guild online = len([m.status for m in g.members if m.status != discord.Status.offline]) delta = datetime.now() - g.created_at embed = discord.Embed(color=discord.Color.teal(), title=g.name) if g.description: embed = discord.Embed(color=discord.Color.teal(), title=g.name, description=g.description) embed.set_footer(text=loc.get(ctx, mn, "id").format(g.id)) if g.icon_url: embed.set_thumbnail(url=g.icon_url) embed.add_field(name=loc.get(ctx, mn, "general"), value=loc.get(ctx, mn, "srv_general").format( g.owner, online, g.member_count, g.premium_subscription_count, len(g.emojis), g.emoji_limit, len(g.roles), g.icon_url )) embed.add_field(name=loc.get(ctx, mn, "channel"), value=loc.get(ctx, mn, "srv_channel").format( len(g.text_channels), len(g.voice_channels), len(g.categories), str(g.region) )) embed.add_field(name=loc.get(ctx, mn, "history"), value=loc.get(ctx, mn, "srv_history").format( g.created_at.strftime(loc.get(ctx, "region", "date")), int(delta.days) )) embed.add_field(name=loc.get(ctx, mn, "misc"), value=loc.get(ctx, mn, "srv_misc").format( int(g.filesize_limit/1024/1024), int(g.bitrate_limit/1000), loc.get(ctx, mn, "ct_filter")[str(g.explicit_content_filter)], loc.get(ctx, mn, "vr_level")[str(g.verification_level)] )) await ctx.send(embed=embed)
async def userinfo(self, ctx, user: discord.User = None): if not user: u = ctx.author else: u = ctx.guild.get_member(user.id) if u is None: await ctx.send(loc.get(ctx, mn, "user_notfound")) return roles = u.roles roles.remove(ctx.guild.default_role) delta_c = datetime.now() - u.created_at delta_j = datetime.now() - u.joined_at embed = discord.Embed(color=u.color, title=u.name) embed.set_footer(text=loc.get(ctx, mn, "id").format(u.id)) embed.set_thumbnail(url=u.avatar_url) embed.add_field(name=loc.get(ctx, mn, "general"), value=loc.get(ctx, mn, "usr_general").format( u.name, u.discriminator, u.display_name, loc.get(ctx, mn, "status")[u.raw_status], u.avatar_url )) embed.add_field(name=loc.get(ctx, mn, "roles"), value=loc.get(ctx, mn, "usr_roles").format( len(roles), ", ".join([r.mention for r in roles]) or loc.get(ctx, mn, "empty") )) embed.add_field(name=loc.get(ctx, mn, "history"), value=loc.get(ctx, mn, "usr_history").format( u.created_at.strftime(loc.get(ctx, "region", "date")), int(delta_c.days), u.joined_at.strftime(loc.get(ctx, "region", "date")), int(delta_j.days) )) embed.add_field(name=loc.get(ctx, mn, "misc"), value=loc.get(ctx, mn, "usr_misc").format( ", ".join([loc.get(ctx, mn, "flags")[p[0]] for p in u.public_flags if p[1] is True]) or loc.get(ctx, mn, "empty") )) await ctx.send(embed=embed)
async def invite(self, ctx): inv = db.read("settings", 0, "invite") or inv_d + str(ctx.me.id) if inv == "off": await ctx.send(loc.get(ctx, mn, "invite_disabled")) else: await ctx.send(loc.get(ctx, mn, "invite").format(inv))