async def user_edit(self, ctx, member: discord.Member, key: str,
                        value: str):
        """Edit user"""
        if (ctx.author.id != config["admin id"]
                and repo_u.get_attribute(member.id, "mod") == 1):
            return await ctx.send(
                "> You do not have permission to alter mod accounts")
        if ctx.author.id != config["admin id"] and member.id == config[
                "admin id"]:
            return await ctx.send(
                "> You do not have permission to alter admin account")

        if key in ("mod", "readonly", "restricted"):
            try:
                value = int(value)
            except ValueError:
                raise errors.BadArgument("Value has to be integer.")
        elif key.startswith("home_id:"):
            try:
                value = int(value)
            except ValueError:
                raise errors.BadArgument("Value has to be integer.")

        repo_u.set(discord_id=member.id, key=key, value=value)
        await self.event.sudo(ctx, f"{member.id} updated: {key} = {value}.")
Exemple #2
0
    async def wormhole_edit(self, ctx, channel_id: int, key: str, value: str):
        """Edit wormhole"""
        if key in ("admin_id", "active", "readonly", "messages"):
            try:
                value = int(value)
            except ValueError:
                raise errors.BadArgument("Value has to be integer.")

        announce = True
        if key in ("invite", "messages", "admin_id"):
            announce = False

        channel = self._get_channel(ctx=ctx, channel_id=channel_id)

        beam_name = repo_w.get_attribute(channel_id, "beam")
        repo_w.set(discord_id=channel.id, key=key, value=value)
        await self.event.sudo(ctx,
                              f"{self._w2str_log(channel)}: {key} = {value}.")

        if not announce:
            return
        await self.announce(
            beam=beam_name,
            message=
            f"Womhole {self._w2str_out(channel)} updated: {key} is {value}.",
        )
Exemple #3
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.")
Exemple #4
0
    def _get_channel(self,
                     *,
                     ctx: commands.Context,
                     channel_id: int = None) -> discord.TextChannel:
        if channel_id:
            return self.bot.get_channel(channel_id)
        if isinstance(ctx.channel, discord.TextChannel):
            return ctx.channel

        raise errors.BadArgument("Missing channel ID.")
Exemple #5
0
    async def beam_add(self, ctx, name: str):
        """Add new beam"""
        # check names
        pattern = r"[a-zA-Z0-9_]+"
        if re.fullmatch(pattern, name) is None:
            raise errors.BadArgument(f"Beam name must match `{pattern}`")

        repo_b.add(name=name, admin_id=ctx.author.id)
        await self.event.sudo(ctx, f"Beam **{name}** created.")
        await self.feedback(ctx,
                            private=False,
                            message=f"Beam **{name}** created and opened.")
Exemple #6
0
    async def wormhole_add(self, ctx, beam: str, channel_id: int = None):
        """Open new wormhole"""
        channel = self._get_channel(ctx=ctx, channel_id=channel_id)
        if channel is None:
            raise errors.BadArgument("No such channel")

        repo_w.add(beam=beam, discord_id=channel.id)
        await self.event.sudo(
            ctx,
            f"{self._w2str_log(channel)} added. {ctx.author.mention}, can you set the local admin?",
        )
        await self.announce(
            beam=beam, message=f"Wormhole opened: {self._w2str_out(channel)}.")
Exemple #7
0
    async def beam_edit(self, ctx, name: str, key: str, value: str):
        """Edit beam"""
        if not repo_b.exists(name):
            raise errors.BadArgument("Invalid beam")

        if key in ("active", "admin_id", "replace", "timeout"):
            try:
                value = int(value)
            except ValueError:
                raise errors.BadArgument("Value has to be integer.")

        announce = True
        if key in ("admin_id"):
            announce = False

        repo_b.set(name=name, key=key, value=value)

        await self.event.sudo(ctx,
                              f"Beam **{name}** updated: {key} = {value}.")
        if not announce:
            return
        await self.announce(beam=name,
                            message=f"Beam updated: {key} is now {value}.")
Exemple #8
0
    async def user_list(self, ctx, restraint: str = None):
        """List all registered users

        restraint: beam name, wormhole ID or user attribute
        """
        if restraint is None:
            db_users = repo_u.list_objects()
        elif repo_b.exists(restraint):
            db_users = repo_u.list_objects_by_beam(restraint)
        elif restraint in ("restricted", "readonly", "mod"):
            db_users = repo_u.list_objects_by_attribute(restraint)
        elif is_id(restraint) and repo_w.exists(int(restraint)):
            db_users = repo_u.list_objects_by_wormhole(int(restraint))
        else:
            raise errors.BadArgument("Value is not beam name nor wormhole ID.")

        template = "\n{nickname} ({name}, {id}):"
        template_home = "- {beam}: {home} ({name}, {guild})"

        # sort
        db_users.sort(key=lambda x: x.nickname)

        result = []
        for db_user in db_users:
            # get user
            user = self.bot.get_user(db_user.discord_id)
            user_name = str(user) if hasattr(user, "name") else "---"
            result.append(
                template.format(id=db_user.discord_id,
                                name=user_name,
                                nickname=db_user.nickname))
            for beam, discord_id in db_user.home_ids.items():
                if restraint and restraint != beam and restraint != str(
                        discord_id):
                    continue
                channel = self.bot.get_channel(discord_id)
                result.append(
                    template_home.format(
                        beam=beam,
                        home=discord_id,
                        name=channel.name
                        if hasattr(channel, "name") else "---",
                        guild=channel.guild.name if hasattr(
                            channel.guild, "name") else "---",
                    ))
            # attributes
            attrs = []
            if db_user.mod:
                attrs.append("MOD")
            if db_user.readonly:
                attrs.append("READ ONLY")
            if db_user.restricted:
                attrs.append("RESTRICTED")
            if len(attrs):
                result.append("- " + ", ".join(attrs))

        async def send_output(output: str):
            if hasattr(ctx.channel, "id") and repo_w.exists(ctx.channel.id):
                await ctx.author.send("```" + output + "```")
            else:
                await ctx.send("```" + output + "```")

        # iterate over the result
        output = ""
        for line in result:
            if len(output) > 1600:
                await send_output(output)
                output = ""
            output += "\n" + line
        if len(result) == 0:
            output = "No users."
        await send_output(output)