Ejemplo n.º 1
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})."
        )
Ejemplo n.º 2
0
    async def on_message_edit(self, before: discord.Message,
                              after: discord.Message):
        if before.content == after.content:
            return

        if after.author.bot:
            return

        if not repo_w.exists(after.channel.id):
            return

        # get forwarded messages
        forwarded = None
        for m in self.sent:
            if m[0].id == after.id:
                forwarded = m
                break
        if not forwarded:
            try:
                await after.add_reaction("❎")
                await asyncio.sleep(1)
                await after.remove_reaction("❎", self.bot.user)
            except discord.Forbidden:
                await after.channel.sent("_Edit not successful_ ❎",
                                         delete_after=1)
            return

        content = await self._process(after)
        beam_name = repo_w.get_attribute(after.channel.id, "beam")
        users = self._get_users_from_tags(beam_name=beam_name, text=content)
        for message in forwarded[1:]:
            await message.edit(content=self._process_tags(
                beam_name=beam_name,
                wormhole_id=after.channel.id,
                users=users,
                text=content,
            ))
        try:
            await after.add_reaction("✅")
            await asyncio.sleep(1)
            await after.remove_reaction("✅", self.bot.user)
        except discord.Forbidden:
            await after.channel.sent("_Edit successful_ ✅", delete_after=1)
Ejemplo n.º 3
0
    async def on_command_error(self, ctx, error):  # noqa: C901
        # ignore local handlers
        if hasattr(ctx.command, "on_error"):
            return

        # get original exception
        error = getattr(error, "original", error)

        # handle messages with prefix
        if isinstance(error, commands.CommandNotFound):
            # Only send in DMs and Wormhole channels
            if hasattr(ctx.channel,
                       "id") and not repo_w.exists(ctx.channel.id):
                return

            message = "Your message was not recognised as a command.\n>>> " + ctx.message.content
            await ctx.author.send(message[:2000])

            return

        # user interaction
        elif isinstance(error, commands.NotOwner):
            return await self.send(ctx, error, "You are not an owner")

        elif isinstance(error, commands.MissingRequiredArgument):
            return await self.send(
                ctx, error,
                f"Missing required argument: **{error.param.name}**")

        elif isinstance(error, commands.BadArgument):
            return await self.send(ctx, error, "Bad argument")

        elif isinstance(error, commands.ArgumentParsingError):
            return await self.send(ctx, error, "Bad argument quotes")

        elif isinstance(error, commands.BotMissingPermissions):
            return await self.send(
                ctx, error, "Wormhole does not have permission to do this")

        elif isinstance(error, commands.CheckFailure):
            return await self.send(ctx, error,
                                   "You are not allowed to do this")

        elif isinstance(error, commands.CommandOnCooldown):
            return await self.send(
                ctx, error, f"Cooldown ({seconds2str(error.retry_after)})")

        elif isinstance(error, commands.UserInputError):
            return await self.send(ctx, error, "Wrong input")

        # cog loading
        elif isinstance(error, commands.ExtensionAlreadyLoaded):
            return await self.send(ctx, error, "The cog is already loaded")
        elif isinstance(error, commands.ExtensionNotLoaded):
            return await self.send(ctx, error, "The cog is not loaded")
        elif isinstance(error, commands.ExtensionFailed):
            await self.send(ctx, error, "The cog failed")
        elif isinstance(error, commands.ExtensionNotFound):
            return await self.send(ctx, error, "No such cog")

        # print the rest
        s = "Wormhole error: {prefix}{command} by {author} in {channel}".format(
            prefix=config["prefix"],
            command=ctx.command,
            author=str(ctx.author),
            channel=ctx.channel.id
            if hasattr(ctx.channel, "id") else type(ctx.channel).__name__,
        )
        print(s, file=sys.stderr)
        if config["log level"] == "CRITICAL":
            return
        traceback.print_exception(type(error),
                                  error,
                                  error.__traceback__,
                                  file=sys.stderr)
        await self.send(ctx, error, str(error))
Ejemplo n.º 4
0
 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 + "```")
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
def in_wormhole(ctx: commands.Context):
    return is_admin(ctx) or (hasattr(ctx.channel, "id")
                             and repo_w.exists(ctx.channel.id))