Exemple #1
0
    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())
Exemple #2
0
    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]
Exemple #3
0
    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())
Exemple #4
0
    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())
Exemple #5
0
    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)
Exemple #6
0
    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())
Exemple #7
0
    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
Exemple #9
0
    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]
Exemple #11
0
    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)
Exemple #12
0
    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)
Exemple #14
0
    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)
Exemple #15
0
    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
Exemple #16
0
    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())
Exemple #17
0
    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)
Exemple #18
0
    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(
                "&nbsp;", " ").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))
Exemple #20
0
    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)
Exemple #21
0
    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")
Exemple #22
0
 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
Exemple #23
0
    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))
Exemple #24
0
 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)
Exemple #26
0
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)
Exemple #27
0
    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))
Exemple #28
0
    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())
Exemple #29
0
    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)
Exemple #30
0
    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.')