예제 #1
0
    async def register(self, ctx):
        """Add yourself to the database"""
        if repo_u.exists(ctx.author.id):
            return await ctx.author.send("You are already registered.")

        nickname = self.sanitise(ctx.author.name, limit=12).replace(")", "").replace("(", "")

        # get first available nickname
        i = 0
        name_orig = nickname
        while repo_u.is_nickname_used(nickname):
            nickname = f"{name_orig}{i}"
            i += 1

        # register
        repo_u.add(discord_id=ctx.author.id, nickname=nickname)
        if isinstance(ctx.channel, discord.TextChannel) and repo_w.get(ctx.channel.id):
            beam_name = repo_w.get(ctx.channel.id).beam
            repo_u.set(ctx.author.id, key=f"home_id:{beam_name}", value=ctx.channel.id)

        await self.event.user(ctx, f"Registered as **{nickname}**.")
        await ctx.author.send(
            f"You are now registered as `{nickname}`. "
            f"You can display your information with `{self.p}me`.\n"
            f"To see information about another user, enter `{self.p}whois [nickname]`.\n\n"
            f"You can tag other registered users with `((nickname))`."
        )
예제 #2
0
    async def wormhole_remove(self, ctx, channel_id: int = None):
        """Remove wormhole from database"""
        if channel_id is None:
            if hasattr(ctx.channel, "id"):
                channel_id = ctx.channel.id
            else:
                raise errors.BadArgument("Missing channel ID")

        channel = self._get_channel(ctx=ctx, channel_id=channel_id)
        if channel is not None:
            beam_name = repo_w.get_attribute(channel_id, "beam")
            repo_w.delete(discord_id=channel_id)
            await self.event.sudo(ctx, f"{self._w2str_log(channel)} removed.")
            await self.announce(
                beam=beam_name,
                message=f"Wormhole closed: {self._w2str_out(channel)}.")
            await channel.send(f"Wormhole closed: {self._w2str_out(channel)}.")
            return

        # channel is not available
        wormhole = repo_w.get(channel_id)
        if wormhole is not None:
            await self.event.sudo(ctx, f"Wormhole {channel_id} removed.")
            repo_w.delete(discord_id=channel_id)
            return

        await ctx.send("Not found.")
예제 #3
0
    async def settings(self, ctx: commands.Context):
        """Display settings for current beam"""
        db_w = repo_w.get(ctx.channel.id)
        db_b = repo_b.get(db_w.beam)
        db_u = repo_u.get(ctx.author.id)

        msg = ">>> **Settings**:\n"
        # beam settings
        pars = []
        # fmt: off
        pars.append("active" if db_b.active else "inactive")
        pars.append(f"replacing (timeout **{db_b.timeout} s**)" if db_b.
                    replace else "not replacing")
        pars.append(f"anonymity level **{db_b.anonymity}**")
        # fmt: on
        msg += ", ".join(pars)

        # wormhole settings
        pars = []
        if db_w.active is False:
            pars.append("inactive")
        if db_w.readonly is True:
            pars.append("read only")
        if len(pars) > 0:
            msg += "\n**Wormhole overrides**:\n"
            msg += ", ".join(pars)

        # user settings
        if db_u is not None and db_u.readonly is True:
            msg += "\n**User overrides**:\n"
            msg += "read only"

        await ctx.send(msg, delete_after=self.delay())
예제 #4
0
    def _get_prefix(self, message: discord.Message, first_line: bool = True):
        """Get prefix for message"""
        db_w = repo_w.get(message.channel.id)
        db_b = repo_b.get(db_w.beam)
        db_u = repo_u.get(message.author.id)

        # get user nickname
        if db_u is not None:
            if db_b.name in db_u.home_ids:
                # user has home wormhole
                home = repo_w.get(db_u.home_ids[db_b.name])
            else:
                # user is registered without home
                home = None

            if home is not None:
                name = "__" + db_u.nickname + "__"
            else:
                name = db_u.nickname
        else:
            name = self.sanitise(message.author.name, limit=32)
            home = db_w

        # get logo
        if hasattr(home, "logo") and len(home.logo):
            if first_line:
                logo = home.logo
            else:
                logo = config["logo fill"]
        else:
            logo = self.sanitise(message.guild.name)

        # get prefix
        if db_b.anonymity == "none":
            # display everything
            prefix = f"{logo} **{name}**: "
        elif db_b.anonymity == "guild" and len(logo):
            # display guild logo
            prefix = logo + " "
        elif db_b.anonymity == "guild" and len(logo) == 0:
            # display guild name
            prefix = f"{logo}, **{name}**"
        else:
            # wrong configuration or full anonymity
            prefix = ""

        return prefix
예제 #5
0
    async def on_message(self, message: discord.Message):
        # ignore non-textchannel sources
        if not isinstance(message.channel, discord.TextChannel):
            return

        # do not act if author is bot
        if message.author.bot:
            return

        # get wormhole
        db_w = repo_w.get(message.channel.id)

        if db_w is None:
            return

        # get additional information
        db_b = repo_b.get(db_w.beam)

        # check for attributes
        # fmt: off
        if db_b.active == 0 \
        or db_w.active == 0 \
        or repo_u.get_attribute(message.author.id, "readonly") == 1:
            return await self.delete(message)
        # fmt: on

        # do not act if message is bot command
        if message.content.startswith(config["prefix"]):
            return await self.delete(message)

        # get wormhole channel objects
        if db_b.name not in self.wormholes or len(
                self.wormholes[db_b.name]) == 0:
            self.reconnect(db_b.name)

        # process incoming message
        content = await self._process(message)

        # convert attachments to links
        first_line = True
        if message.attachments:
            for f in message.attachments:
                # don't add newline if message has only attachments
                if first_line:
                    content += " " + f.url
                    first_line = False
                else:
                    content += "\n" + f.url

        if len(content) < 1:
            return

        # count the message
        self._update_stats(message)

        # send the message
        await self.send(message=message,
                        text=content,
                        files=message.attachments)
예제 #6
0
    async def smart_send(self, ctx, *, content: str = None, embed: discord.Embed = None):
        if content is None and embed is None:
            return

        if hasattr(ctx.channel, "id") and repo_w.get(ctx.channel.id) is not None:
            await ctx.send(content=content, embed=embed, delete_after=self.delay())
        else:
            await ctx.send(content=content, embed=embed)
예제 #7
0
    async def send(self, ctx: commands.Context, error, text: str):
        if config["log level"] == "CRITICAL":
            return

        prefix = "> **Error:** "
        if hasattr(ctx.channel, "id") and repo_w.get(ctx.channel.id) is not None:
            # do not leave errors in wormhole
            await ctx.send(prefix + text, delete_after=20.0)
        else:
            await ctx.send(prefix + text)
예제 #8
0
    async def info(self, ctx: commands.Context):
        """Display information about wormholes"""
        public = hasattr(ctx.channel, "id") and repo_w.get(ctx.channel.id) is not None

        if public:
            await ctx.send(
                self._get_info(repo_w.get_attribute(ctx.channel.id, "beam")),
                delete_after=self.delay(),
            )
            return

        user_beams = repo_u.get_home(ctx.author.id).keys()
        for beam_name in user_beams:
            await ctx.send(self._get_info(beam_name, title=True))
예제 #9
0
    async def set_home(self, ctx):
        """Set current channel as your home wormhole"""
        if not repo_u.exists(ctx.author.id):
            return await ctx.author.send(f"Register with `{self.p}register`")
        if repo_u.get_attribute(ctx.author.id, "restricted") == 1:
            return await ctx.author.send("You are forbidden to alter your settings.")
        if not isinstance(ctx.channel, discord.TextChannel) or not repo_w.exists(ctx.channel.id):
            return await ctx.author.send("Home has to be a wormhole")

        beam_name = repo_w.get(ctx.channel.id).beam
        repo_u.set(ctx.author.id, key=f"home_id:{beam_name}", value=ctx.channel.id)
        await ctx.author.send("Home set to " + ctx.channel.mention)
        await self.event.user(
            ctx, f"Home in **{beam_name}** set to **{ctx.channel.id}** ({ctx.guild.name})."
        )
예제 #10
0
    async def send(
        self,
        *,
        message: discord.Message,
        text: str,
        files: list = None,
    ):
        """Distribute the message"""
        deleted_original = False

        # get variables
        messages = [message]
        db_w = repo_w.get(message.channel.id)
        db_b = repo_b.get(db_w.beam)

        # access control
        if db_b.active == 0:
            return
        if db_w.active == 0 or db_w.readonly == 1:
            return
        if repo_u.get_attribute(message.author.id, "readonly") == 1:
            return

        # remove the original, if possible
        manage_messages_perm = message.guild.me.permissions_in(
            message.channel).manage_messages
        if manage_messages_perm and db_b.replace == 1 and not files:
            try:
                messages[0] = message.author
                await self.delete(message)
                deleted_original = True
            except discord.Forbidden:
                pass

        # limit message length
        text = text[:1024]

        # update wormhole list
        if db_b.name not in self.wormholes.keys():
            self.reconnect(db_b.name)
        wormholes = self.wormholes[db_b.name]

        users = self._get_users_from_tags(beam_name=db_b.name, text=text)

        # replicate messages
        tasks = []
        for wormhole in wormholes:
            task = asyncio.ensure_future(
                self.replicate(
                    wormhole,
                    message,
                    messages,
                    users,
                    text,
                    files,
                    db_b,
                    manage_messages_perm,
                ))
            tasks.append(task)
        await asyncio.gather(*tasks, return_exceptions=True)

        # add checkmark to original, if it hasn't been deleted
        if not deleted_original:
            await message.add_reaction("✅")

        # save message objects in case of editing/deletion
        if db_b.timeout > 0:
            self.sent.append(messages)
            await asyncio.sleep(db_b.timeout)
            self.sent.remove(messages)