async def team_mischief(self, ctx): if ctx.guild and not Utils.can_mod_official(ctx): return embed = discord.Embed( timestamp=ctx.message.created_at, color=0xFFBD1C, title="Mischief!") guild = Utils.get_home_guild() for role_name, role_id in self.role_map.items(): this_role: discord.role = guild.get_role(role_id) if this_role is None: continue member_count = self.role_counts[str(role_id)] embed.add_field(name=this_role.name, value=str(member_count), inline=True) if len(embed.fields) == 25: await ctx.send(embed=embed, allowed_mentions=AllowedMentions.none()) embed = discord.Embed( timestamp=ctx.message.created_at, color=0xFFBD1C, title="mischief continued...") await ctx.send(embed=embed, allowed_mentions=AllowedMentions.none())
async def do_power_kick(self, ctx, protected_members): the_saved = [] for member in ctx.guild.members: if member not in protected_members and \ not member.bot and \ not member.guild_permissions.ban_members and \ not member.guild_permissions.manage_channels: await ctx.send(f"kicking {Utils.get_member_log_name(member)}", allowed_mentions=AllowedMentions.none()) try: await ctx.guild.kick(member) except Forbidden: await ctx.send( f"I'm not allowed to kick {Utils.get_member_log_name(member)} (forbidden)", allowed_mentions=AllowedMentions.none()) except HTTPException: await ctx.send( f"I failed to kick {Utils.get_member_log_name(member)} (http exception)", allowed_mentions=AllowedMentions.none()) else: the_saved.append(Utils.get_member_log_name(member)) # list count of members who will remain the_saved_description = '\n'.join(the_saved) the_saved_description = Utils.paginate(the_saved_description) await ctx.send("`These members were not kicked:`") for page in the_saved_description: await ctx.send(page, allowed_mentions=AllowedMentions.none()) # TODO: ping on task completion? del self.power_task[ctx.guild.id]
async def search_user(self, ctx, args=None): if not args: return await ctx.reply('ユーザーIDを指定してください', allowed_mentions=AllowedMentions.none()) fetched_user = await self.bot.fetch_user(int(args)) if not fetched_user: return await ctx.reply('ユーザーが見つかりませんでした', allowed_mentions=AllowedMentions.none()) user_info = { 'user_id': fetched_user.id, 'user_name': fetched_user.display_name, 'user_avatar': fetched_user.avatar_url, 'user_created_at': fetched_user.created_at, 'user_guilds': fetched_user.mutual_guilds } created_at_jst = user_info["user_created_at"].astimezone( timezone("Asia/Tokyo")).strftime("%Y/%m/%d %H:%M:%S") info_msg = Embed() info_msg.set_author(name=f'{fetched_user}') info_msg.set_thumbnail(url=user_info['user_avatar']) info_msg.add_field(name='ユーザーID', value=f'{user_info["user_id"]}', inline=False) info_msg.add_field(name='ユーザー名', value=f'{user_info["user_name"]}', inline=False) info_msg.add_field(name='アカウント作成日時', value=f'{created_at_jst}') info_msg.add_field(name='共通サーバー数', value=f'{user_info["user_guilds"]}') return await ctx.reply(embed=info_msg, allowed_mentions=AllowedMentions.none())
async def owo(self, ctx: commands.Context): """ Small. """ async for msg in ctx.history(limit=1, before=ctx.message): await ctx.message.delete() owomsg = owo.owoify(msg.content) if len(msg.embeds) > 0: embeds = msg.embeds for embed in embeds: if embed.title: embed.title = owo.owoify(embed.title) if embed.description: embed.description = owo.owoify(embed.description) if embed.footer: embed.set_footer(text=owo.owoify(embed.footer.text), icon_url=embed.footer.icon_url) if embed.author: embed.set_author(name=owo.owoify(embed.author.name), icon_url=embed.footer.icon_url) for f in range(len(embed.fields)): embed.set_field_at( f, name=owo.owoify(embed.fields[f].name), value=owo.owoify(embed.fields[f].value)) await ctx.send(owomsg, embed=embeds[0], allowed_mentions=AllowedMentions.none()) if len(embeds) > 1: for e in embeds[1:]: await ctx.send(embed=e, allowed_mentions=AllowedMentions.none()) elif owomsg != msg.content: await ctx.send(owomsg, allowed_mentions=AllowedMentions.none())
async def search_server(self, ctx, args=None): if not args: return await ctx.reply('サーバーIDを指定してください', allowed_mentions=AllowedMentions.none()) fetched_guild = self.bot.get_guild(int(args)) if not fetched_guild: return await ctx.reply('ユーザーが見つかりませんでした', allowed_mentions=AllowedMentions.none()) guild = fetched_guild server_name = guild.name server_id = guild.id server_icon = guild.icon_url server_owner = guild.owner server_created = guild.created_at server_region = guild.region server_all_ch_count = len(guild.channels) server_t_ch_count = len(guild.text_channels) server_v_ch_count = len(guild.voice_channels) server_c_ch_count = len(guild.categories) server_all_member_count = len(guild.members) server_m_count = len([m for m in guild.members if not m.bot]) server_b_count = len([b for b in guild.members if b.bot]) server_ban_m_count = len(await guild.bans()) server_e_count = len([e for e in guild.emojis if not e.animated]) server_ani_e_count = len([ae for ae in guild.emojis if ae.animated]) server_e_limit = guild.emoji_limit embed = Embed(title=server_name, description=f'ID: `{server_id}`') embed.add_field(name='オーナー', value=f'{server_owner} ({server_owner.id})', inline=False) embed.add_field( name='作成日時', value= f'{server_created.astimezone(timezone("Asia/Tokyo")).strftime("%Y/%m/%d %H:%M:%S")}' ) embed.add_field(name='地域', value=server_region) embed.add_field( name=f'チャンネル - {server_all_ch_count}/500', value= f'```diff\n+ カテゴリーチャンネル: {server_c_ch_count}\n+ テキストチャンネル: {server_t_ch_count}' f'\n+ ボイスチャンネル: {server_v_ch_count}\n```', inline=False) embed.add_field( name=f'メンバー - {server_all_member_count}', value=f'```diff\n+ メンバー: {server_m_count}\n+ BOT: {server_b_count}' f'\n+ Banされた人数: {server_ban_m_count}\n```', inline=False) embed.add_field( name=f'絵文字', value=f'```diff\n+ 通常: {server_e_count}/{server_e_limit}' f'\n+ アニメーション: {server_ani_e_count}/{server_e_limit}\n```', inline=False) embed.set_thumbnail(url=server_icon) await ctx.send(embed=embed)
async def _eval(self, ctx, *, body: str): """Evaluates a code""" env = { 'bot': self.bot, 'ctx': ctx, 'channel': ctx.channel, 'author': ctx.author, 'guild': ctx.guild, 'message': ctx.message, '_': self._last_result } env.update(globals()) body = cogs.cleanup_code(body) stdout = io.StringIO() to_compile = f'async def func():\n{textwrap.indent(body, " ")}' try: exec(to_compile, env) except Exception as e: e_msg1 = Embed( title='Error', description=f'```py\n{e.__class__.__name__}: {e}\n```') return await ctx.reply(embed=e_msg1, allowed_mentions=AllowedMentions.none()) func = env['func'] try: with redirect_stdout(stdout): ret = await func() except Exception as e: value = stdout.getvalue() e_msg2 = Embed( title='Error', description=f'```py\n{value}{traceback.format_exc()}\n```') await ctx.reply(embed=e_msg2, allowed_mentions=AllowedMentions.none()) else: value = stdout.getvalue() try: await ctx.message.add_reaction('\u2705') except: pass if ret is None: if value: s_msg1 = Embed(title='Success', description=f'```py\n{value}\n```') await ctx.reply(embed=s_msg1, allowed_mentions=AllowedMentions.none()) else: self._last_result = ret s_msg2 = Embed(title='Success', description=f'```py\n{value}{ret}\n```') await ctx.reply(embed=s_msg2, allowed_mentions=AllowedMentions.none())
def send_message( self, token: str, interaction_id: int, *, type: int, initial_response: bool, content: str = None, embed: discord.Embed = None, embeds: List[discord.Embed] = [], tts: bool = False, allowed_mentions: discord.AllowedMentions = None, flags: int = None, ): payload = {"type": type} if embed is not None: embeds = [embed] if allowed_mentions is None: allowed_mentions = self.bot.allowed_mentions data = {} if content: data["content"] = content if tts: data["tts"] = True if embeds: data["embeds"] = [e.to_dict() for e in embeds] if allowed_mentions: data["allowed_mentions"] = allowed_mentions.to_dict() if flags: data["flags"] = flags if embeds: data["embeds"] = [e.to_dict() for e in embeds] if flags: data["flags"] = flags if data: data["allowed_mentions"] = allowed_mentions.to_dict() payload["data"] = data if initial_response: url = "/interactions/{interaction_id}/{token}/callback" send_data = payload else: url = "/webhooks/{application_id}/{token}" send_data = data route = Route( "POST", url, interaction_id=interaction_id, token=token, application_id=self.application_id, ) log.debug( f"sending response, initial = {initial_response}: {send_data}") return self.request(route, json=send_data)
async def send(self, send_type: int = 4, content: str = "", embeds: typing.List[discord.Embed] = None, tts: bool = False, allowed_mentions: discord.AllowedMentions = None, hidden: bool = False): """ Sends response of the slash command. .. note:: Param ``hidden`` ONLY works without embeds. :param send_type: Type of the response. Refer Discord API DOCS for more info about types. Default ``4``. :type send_type: int :param content: Content of the response. Can be ``None``. :type content: str :param embeds: Embeds of the response. Maximum 10, can be empty. :type embeds: List[discord.Embed] :param tts: Whether to speak message using tts. Default ``False``. :type tts: bool :param allowed_mentions: AllowedMentions of the message. :type allowed_mentions: discord.AllowedMentions :param hidden: Whether the message is hidden, which means message content will only be seen to the author. :return: ``None`` """ if embeds and len(embeds) > 10: raise error.IncorrectFormat("Embed must be 10 or fewer.") base = { "type": send_type, "data": { "tts": tts, "content": content, "embeds": [x.to_dict() for x in embeds] if embeds else [], "allowed_mentions": allowed_mentions.to_dict() if allowed_mentions else self._discord.allowed_mentions.to_dict() if self._discord.allowed_mentions else {} } } if not self.sent else { "content": content, "tts": tts, "embeds": [x.to_dict() for x in embeds] if embeds else [], "allowed_mentions": allowed_mentions.to_dict() if allowed_mentions else self._discord.allowed_mentions.to_dict() if self._discord.allowed_mentions else {} } if hidden: if self.sent: base["flags"] = 64 else: base["data"]["flags"] = 64 initial = True if not self.sent else False resp = await self._http.post(base, self._discord.user.id, self.interaction_id, self.__token, initial) self.sent = True return resp
async def leave(self, ctx, args=None): if args is None: return await ctx.reply('サーバーIDを指定してください', allowed_mentions=AllowedMentions.none()) i_get_guild = self.bot.get_guild(int(args)) if i_get_guild is None: return await ctx.reply('サーバーが見つかりませんでした', allowed_mentions=AllowedMentions.none()) await i_get_guild.leave() return await ctx.reply('サーバーから退出しました', allowed_mentions=AllowedMentions.none())
async def log_task(guild_id, target): to_send = "" todo = None # keep pumping until we run out of messages while not LOG_QUEUE[target].empty(): try: channel = BOT.get_channel(int(target)) # channel no longer exists, abort and re-validate config to remove the invalid entry if channel is None: del LOG_QUEUE[target] Configuration.validate_config(guild_id) return # pull message from queue todo = LOG_QUEUE[target].get(block=False) if (len(to_send) + len(todo.message) if todo.message is not None else 0) < 2000: to_send = f'{to_send}\n{todo.message if todo.message is not None else ""}' else: # too large, send it out await channel.send(to_send, allowed_mentions=AllowedMentions( everyone=False, users=False, roles=False)) to_send = todo.message if todo.embed is not None or todo.file is not None or LOG_QUEUE[ target].empty(): await channel.send(to_send, embed=todo.embed, file=todo.file, allowed_mentions=AllowedMentions( everyone=False, users=False, roles=False)) to_send = "" except discord.Forbidden: # someone screwed up their permissions, not my problem, will show an error in the dashboard del LOG_QUEUE[target] return except CancelledError: return # bot is terminating except Exception as e: del LOG_QUEUE[target] await TheRealGearBot.handle_exception("LOG PUMP", BOT, e, cid=target, todo=todo, to_send=to_send) return del LOG_QUEUE[target]
async def send_button_msg( self, channel: TextChannel, content: str = "", *, tts: bool = False, embed: Embed = None, allowed_mentions: AllowedMentions = None, buttons: List[Button] = None, **options, ) -> Message: state = self.bot._get_state() if embed: embed = embed.to_dict() if allowed_mentions: if state.allowed_mentions: allowed_mentions = state.allowed_mentions.merge(allowed_mentions).to_dict() else: allowed_mentions = allowed_mentions.to_dict() else: allowed_mentions = state.allowed_mentions and state.allowed_mentions.to_dict() data = { "content": content, **self._get_buttons_json(buttons), **options, "embed": embed, "allowed_mentions": allowed_mentions, "tts": tts, } data = await self.bot.http.request( Route("POST", f"/channels/{channel.id}/messages"), json=data ) return Message(state=state, channel=channel, data=data)
async def listall(self, ctx: commands.Context): """ (Restricted to moderators) List all reminders. """ if len(self._reminders.all()) == 0: await ctx.reply("There are no reminders.", delete_after=10, mention_author=False) return out = "" for reminder in sorted(self._reminders.all(), key=remsort(datetime.datetime.utcnow())): then = datetime.datetime.strptime(reminder["datetime"], TIME_FORMAT) msg = remshort(reminder) out += fmt_list_item( f"{fmt_code(str(reminder.doc_id).rjust(3))} - " + f"{fmt_code(reminder['datetime'])}, " + f"{readable_delta(datetime.datetime.utcnow() - then)} " + f"(<@{reminder['meta']['member']}>):\n" f" {msg}") await ctx.reply(out, allowed_mentions=AllowedMentions.none(), mention_author=False)
def send_to_discord_channels(self, channel_ids: set[Union[str, int]], content: str) -> None: """ Send a message to a set of channel_ids on discord provided. :param: channel_ids: the ids of the channels the message should be sent to. :param: content: the content of the message to send to the discord channels """ if not self.is_discord_logged_in(): return # if we were not provided any channel_ids, do nothing. if not channel_ids or len(channel_ids) == 0: return # send the message in its own thread to avoid blocking of the server for channel_id in channel_ids: channel = self.discord.get_channel(channel_id) if channel is None: continue asyncio.run_coroutine_threadsafe(channel.send( content, allowed_mentions=AllowedMentions(everyone=False, users=True, roles=True)), loop=self.discord.loop)
def edit_message( self, token: str, message_id: int, *, content: str = None, embed: discord.Embed = None, embeds: List[discord.Embed] = None, allowed_mentions: discord.AllowedMentions = None, ): route = Route( "PATCH", "/webhooks/{application_id}/{token}/messages/{message_id}", application_id=self.application_id, token=token, message_id=message_id, ) if embed is not None: embeds = [embed] if allowed_mentions is None: allowed_mentions = self.bot.allowed_mentions payload = {} if content: payload["content"] = content if embeds: payload["embeds"] = [e.to_dict() for e in embeds] payload["allowed_mentions"] = allowed_mentions.to_dict() return self.request(route, json=payload)
async def send_to(self, dest, content=None, files=None, embed=None, allowed_mentions=AllowedMentions(everyone=False, roles=False), send_as_slash_command=True, hidden=False, reference=None, mention_author=None, fail_on_dm=None, view=None): msg = None if fail_on_dm and isinstance(dest, (DMChannel, User, Member)): return None if isinstance(dest, Webhook): msg = await dest.send(content, username=self.bot_name, avatar_url=self.bot_avatar, embed=embed, files=files, wait=True, allowed_mentions=allowed_mentions, view=view or ui.View()) elif self.slash_command and send_as_slash_command: kwargs = {"content": content, "ephemeral": hidden} if embed: kwargs["embeds"] = [embed] if view: kwargs["view"] = view if self.sent_first_slash_command: msg = InteractionWebhook(await self.slash_command[1].send(**kwargs), True) # webhook else: await self.slash_command[0].send_message(**kwargs) # no return msg = InteractionWebhook(self.slash_command[2], False) if not self.first_slash_command: self.first_slash_command = msg if not self.sent_first_slash_command: self.sent_first_slash_command = True else: msg = await dest.send(content, embed=embed, files=files, allowed_mentions=allowed_mentions, reference=reference, mention_author=mention_author, view=view) self.bot_responses.append(msg.id) return msg
async def echo(self, ctx, *, text: str): '''Echo a message.\n **Example:```yml\n♤echo ECHO!\n♤say hello!```** ''' await ctx.message.delete() await ctx.send(text, allowed_mentions=AllowedMentions.none())
async def send(self, ctx, filter=None, delete=False): reference = ctx.message.reference if reference: message = await ctx.fetch_message(id=reference.message_id) text = message.content else: text = ctx.message.content prefix = fn.getprefix(self.bot, ctx.message) command = ctx.command.name if not text.lower().startswith(prefix + command): for alias in ctx.command.aliases: if text.lower().startswith(prefix + alias): command = alias break text = text[len(prefix) + len(command) + 1:] if text: if filter: text = sanitise_text(text) text = filter(text) try: await ctx.send(text, allowed_mentions=AllowedMentions.none()) except: text = "Text is too long to send" if filter: text = filter(text) await ctx.send(text) else: text = "You didn't include or reference any text to say!" if filter: text = filter(text) await ctx.reply(text)
async def edit_button_msg( self, message: Message, content: str = "", *, tts: bool = False, embed: Embed = None, allowed_mentions: AllowedMentions = None, buttons: List[Button] = None, **options, ): state = self.bot._get_state() if embed: embed = embed.to_dict() if allowed_mentions: if state.allowed_mentions: allowed_mentions = state.allowed_mentions.merge(allowed_mentions).to_dict() else: allowed_mentions = allowed_mentions.to_dict() else: allowed_mentions = state.allowed_mentions and state.allowed_mentions.to_dict() data = { "content": content, **self._get_buttons_json(buttons), **options, "embed": embed, "allowed_mentions": allowed_mentions, "tts": tts, } await self.bot.http.request( Route("PATCH", f"/channels/{message.channel.id}/messages/{message.id}"), json=data )
async def event_check(self): print("checking for event") now = datetime.datetime.now(tz=timezone('UTC')) soon = now + datetime.timedelta(minutes=15) events_soon = [event for event in self.events if event["start"] > now and event["start"] < soon and not(event["id"] in self.already_notified)] for event in events_soon: self.already_notified.append(event["id"]) description = event['description'].replace( " ", " ").replace("<br />", "\n").replace( "<br>", "\n").replace("<ul>","").replace( "<li>","- ").replace("</li>","\n").replace( "<b>","**").replace("</b>","**").replace( '<span>','').replace('</span>','') anchor_expr = re.compile(R'<a\s+(?:[^>]*?\s+)?href="([^"]*)">(.+?)<\/a>') for _ in anchor_expr.findall(description): match = anchor_expr.search(description) description = description.replace(match.group(0), f"<{match.group(1)}>") msg = f"**Starting soon: {event['title']}** ({self.format_start(event['start'])})" if event['location']: msg += f"\n{event['location']}" msg += f"\n<@&{ROLE_NOTIFY_EVENT}>" if description and len(description) > 0: msg += f"\n\n{description}" channel = await self.bot.fetch_channel(CHANNEL_EVENT_ANNOUNCE) await channel.send(msg, allowed_mentions=AllowedMentions(roles=True))
def edit_message( self, token: str, message_id: int = None, *, content: str = None, embed: discord.Embed = None, embeds: List[discord.Embed] = None, allowed_mentions: discord.AllowedMentions = None, original: bool = False, components: list = None, ): url = "/webhooks/{application_id}/{token}/messages/" url += "@original" if original else "{message_id}" route = Route( "PATCH", url, application_id=self.application_id, token=token, message_id=message_id, ) if embed is not None: embeds = [embed] if allowed_mentions is None: allowed_mentions = self.bot.allowed_mentions payload = {"content": content} if embeds: payload["embeds"] = [e.to_dict() for e in embeds] if components is not None: payload["components"] = [c.to_dict() for c in components] payload["allowed_mentions"] = allowed_mentions.to_dict() return self.request(route, json=payload)
def __init__( self, *, prefix: str, admin_user_ids: Set[int], redis: Redis, ): super().__init__( command_prefix=prefix, owner_ids=admin_user_ids, case_insensitive=True, allowed_mentions=AllowedMentions.none(), activity=Activity( name=f"everyone ({prefix}help)", type=ActivityType.listening, ), ) self.redis = redis self.http_session = aiohttp.ClientSession() self.registered_users = RedisSet(self.redis, "registered_users") self.learning_channels = RedisSet(self.redis, "learning_channels") self.speaking_channels = RedisSet(self.redis, "speaking_channels") self.corpora = CorpusManager(self) self.avatars = AvatarManager(self) self.load_extension("jishaku") self._load_folder("events") self._load_folder("commands")
async def on_member_update(self, before: Member, after: Member): if after.activities is None: after.activities = ("dummy", ) if before.activities is None: before.activities = ("dummy", ) ch_twitch = self.bot.get_channel(const.CH_TWITCH) # 後が配信中 if any([ isinstance(after_activity, Streaming) for after_activity in after.activities ]): if any([ isinstance(before_activity, Streaming) for before_activity in before.activities ]): return # 前が配信中でない for after_activity in after.activities: if not isinstance(after_activity, Streaming): continue if after_activity.platform != "Twitch": continue await ch_twitch.send( f"{after.mention} が配信を始めました!", embed=self.to_embed(after_activity, after), allowed_mentions=AllowedMentions.none(), ) return
async def eval(self, ctx: commands.Context, *, code: str) -> None: """Evaluates Python code safely. Powered by Snekbox.""" code = code.strip("`") if code.startswith(("py\n", "python\n")): code = "\n".join(code.split("\n")[1:]) async with aiohttp.ClientSession() as session: async with session.post(Bot_constants.snekbox_url, json={"input": code}) as result: output = (await result.json())["stdout"] status_code = (await result.json())["returncode"] lines = output.split("\n") output = "\n".join(line for number, line in enumerate(lines) if number < 10) output = output[:1850] await ctx.send( content=(f"{ctx.author.mention} " f"Your code exited with status code {status_code}.\n" f"Result:\n" f"```\n" f"{output}" f"```"), allowed_mentions=AllowedMentions(everyone=False, roles=False, users=False))
async def db_set_thread_id( self, ctx: Context, member: Member, channel: TextChannel = None ): if channel is None: channel = ctx.channel # データベースからデータをもらう data_ch = await self.bot.database.fetch_row( constant.TABLE_NAME, channel_id=channel.id ) # データがなければ新規作成 if data_ch is None: await self.bot.database.insert( constant.TABLE_NAME, channel_id=channel.id, author_id=member.id, channel_type="thread", ) # データの上書き else: await self.bot.database.update( constant.TABLE_NAME, {"author_id": member.id}, channel_id=channel.id, channel_type="thread", ) await ctx.send( f"{channel.mention}の所有者は{member.mention}にセットされました。", allowed_mentions=AllowedMentions.none(), )
async def edit(self, message_id: typing.Union[int, str] = "@original", content: str = "", embeds: typing.List[discord.Embed] = None, tts: bool = False, allowed_mentions: discord.AllowedMentions = None): """ Edits response of the slash command. :param message_id: Response message ID. Default initial message. :param content: Text of the response. Can be ``None``. :type content: str :param embeds: Embeds of the response. Maximum 10, can be empty. :type embeds: List[discord.Embed] :param tts: Whether to speak message using tts. Default ``False``. :type tts: bool :param allowed_mentions: AllowedMentions of the message. :type allowed_mentions: discord.AllowedMentions :return: ``None`` """ if embeds and len(embeds) > 10: raise error.IncorrectFormat("Embed must be 10 or fewer.") base = { "content": content, "tts": tts, "embeds": [x.to_dict() for x in embeds] if embeds else [], "allowed_mentions": allowed_mentions.to_dict() if allowed_mentions else self._discord.allowed_mentions.to_dict() if self._discord.allowed_mentions else {} } await self._http.edit(base, self._discord.user.id, self.__token, message_id)
async def log(message, bot, level="INFO", debug=""): if (os.getenv('debugEnabled') == "False") and (level == "DEBUG"): return channel = bot.get_channel(int(os.getenv('botlog'))) time = datetime.datetime.now().strftime('%H:%M:%S') if level == "DEBUG": levelemote = "🔧" elif level == "ERROR": levelemote = "❌" elif level == "WARNING": levelemote = "❗" elif level == "CRITICAL": levelemote = "🔥" else: levelemote = "🔎" if level == "DEBUG": await channel.send("`[" + time + "]` **" + levelemote + " " + level + ":** " + message, allowed_mentions=AllowedMentions(everyone=False, users=False, roles=False)) else: await channel.send("`[" + time + "]` **" + levelemote + " " + level + ":** " + message) if debug == "": logDebug(message, level) return logDebug(debug, level)
async def translate(self, ctx, *, query=None, timeout=10, settings=None): """ A google translate API. -s (source language) and -d (destination language) are optional arguments which may be added to the command to translate between selected languages. """ if timeout == 0: await ctx.send("The google API has timed out; please try again.") return if settings is None or settings == constants.lang_settings: settings = constants.lang_settings.copy() for option in settings: pos = query.find(option) if pos != -1: setting = query[pos + 3:].split(" ")[0] settings[option] = setting query = query[:pos] + query[pos + len(setting) + 4:] try: translated = Translator().translate(query, src=settings['-s'], dest=settings['-d']) src = constants.lang_codes[translated.src] dest = constants.lang_codes[translated.dest] text = "[{0} -> {1}] {2.text}".format(src, dest, translated) except ValueError: text = "Language could not be found." except AttributeError: return await self.translate(ctx, query=query, timeout=timeout - 1, settings=settings) await ctx.send(text, allowed_mentions=AllowedMentions(everyone=False, roles=False))
async def ppsize(self, ctx, user_mention=None): async with ctx.channel.typing(): if (user_mention is None): member = ctx.author elif (is_mention.match(user_mention)): converter = MemberConverter() member = await converter.convert(ctx, user_mention) else: member = None text = "Command usage: `fbot ppsize` or `fbot ppsize <@mention>`" if (member is not None): ppsize = None if member.bot: text = "Bots don't have pps, you do know that?" else: try: ppsize = db.getppsize(member.id) if ppsize < 0: ppsize = random.randint(0, 16) db.updateppsize(member.id, ppsize) except: db.register(member.id) ppsize = random.randint(0, 16) db.updateppsize(member.id, ppsize) if (ppsize is not None): pp = "8" + "=" * ppsize + "D" text = f"{member.mention}'s ppsize: `{pp}`" await ctx.send(text, allowed_mentions=AllowedMentions.all())
async def list(self, ctx: commands.Context): """ See all your reminders. """ out = "" your_reminders = sorted(filter( lambda reminder: reminder["meta"]["member"] == ctx.author.id, self._reminders.all()), key=remsort(datetime.datetime.utcnow())) if len(your_reminders) == 0: await ctx.reply("You don't have any reminders set.", mention_author=False) else: for reminder in your_reminders: then = datetime.datetime.strptime(reminder["datetime"], TIME_FORMAT) msg = remshort(reminder) out += fmt_list_item( f"{fmt_code(str(reminder.doc_id).rjust(3))} - " + f"{fmt_code(reminder['datetime'])}, " + f"{readable_delta(datetime.datetime.utcnow() - then)}:\n" + f" {msg}") await ctx.reply(out, allowed_mentions=AllowedMentions.none(), mention_author=False)
async def open_signups(self, manual=False, ping: str = None): if ping == 'noping': ping = '' else: ping = ping or '@everyone' # Get the channel announcements: TextChannel = self.bot.get_channel( int(self.conf['channels']['announcements'])) # Send the message, add the reactions msg = await announcements.send( settings.messages.SIGNUP_MESSAGE.format( ping if ping != '' else 'everyone'), allowed_mentions=AllowedMentions(everyone=True)) await msg.add_reaction(settings.emojis.white_check_mark) await msg.add_reaction(settings.emojis.blue_check_mark) day = settings.next_day(0) db.SignupMessage(message_id=msg.id, is_open=True, close_at=day).save() self.message_id = msg.id logger.info( f'Signups have been {"automatically " if not manual else ""}' f'opened. They will close at {day}, UTC time.')