Example #1
0
 def cog_check(self, ctx):
     """Ensure user has permissions and heavy command is not active for cog commands."""
     if not ctx.author.guild_permissions.manage_roles:
         raise CommandError(f"You need Manage Roles permission")
     if ctx.guild.id in cfg.heavy_command_active:
         raise CommandError("Please wait for the current command to finish")
     return True
Example #2
0
class Other(Cog, name="Other Commands"):

    def __init__(self, bot) -> None:
        self.bot: Bot = bot

    @commands.command(name="run")
    @supported_languages_docs
    async def run(self, ctx, *, args: str):
        """
        run some code
        """

        if not (match := re.fullmatch(r"((```)?)([a-zA-Z\d]+)\n(.+?)\1", args, re.DOTALL)):
            await ctx.send(
                embed=Embed(
                    title="Usage",
                    description=strings.run_usage
                )
            )
            return

        *_, language, source = match.groups()

        await ctx.trigger_typing()

        try:
            api_result: dict = await Emkc.run_code(language, source)
        except EmkcAPIException as e:
            if e.message == "Supplied language is not supported by Piston":
                raise CommandError(f"language: {language} is not supported")

            raise CommandError(f"Error: {e.message}")
        except ClientError:
            raise CommandError("Error")

        output: str = api_result["output"]
        if len(output) > N_CHARS:
            newline = output.find("\n", N_CHARS, N_CHARS + 20)
            if newline == -1:
                newline = N_CHARS
            output = output[:newline] + "\n..."

        description = "```\n" + output.replace("`", "`\u200b") + "\n```"

        embed = Embed(title=f"Run Output ({language})", description=description)
        if api_result["stderr"] and not api_result["stdout"]:
            embed.colour = 0xFF0000

        embed.set_footer(text=f"requested by {ctx.author}", icon_url=ctx.author.avatar_url)

        await ctx.send(embed=embed)
Example #3
0
    async def start(self, ctx: Context):

        session = self.get_session(ctx.guild)
        if session:
            session.stop()
            await sleep(0.5)

        session_config = self.config.hgetall(f"sessions:{ctx.guild.id}")

        if session_config:

            guild = self.bot.get_guild(int(session_config.pop("guild_id")))
            voice = self.bot.get_channel(int(session_config.pop("voice")))

            l_id = session_config.pop("log", None)
            if l_id:
                log = self.bot.get_channel(int(l_id))
            else:
                log = None

            self.bot.loop.create_task(
                self.init_session(guild,
                                  voice,
                                  log=log,
                                  run_forever=True,
                                  **session_config))

        else:
            raise CommandError(f"Player not configured for {ctx.guild.name}")
Example #4
0
    async def request(self, ctx: Context, *, request):
        """Adds a YouTube video to the requests queue.

        request: YouTube search query.
        """

        if isinstance(request, str):
            try:
                request = YouTubeTrack(request,
                                       self.config,
                                       requester=ctx.author)
            except Exception as error:
                await self.bot.errorlog.send(error, ctx)
                raise CommandError(
                    f"An error occurred trying to load YouTubeTrack `{request}`"
                )

        session = self.get_session(ctx.guild)

        if session is None:
            session = self.sessions[ctx.guild] = Session(
                self.bot, self.config, self, ctx.author.voice.channel)

        await ctx.send(**request.request_message)
        session.queue.add_request(request)
Example #5
0
    async def saucenao(self, ctx, skip: int = 0):
        """
        Performs a reverse image query on the last uploaded
        or embedded image using the SauceNAO reverse image engine.

        Can specify number of images to skip when looking at logs
        (in case you want to look 3 images back, e.g.)

        Will only look at the previous 100 messages at most."""

        found_url = await _find_uploaded_image(ctx, skip)

        if found_url is None:
            raise CommandError("No images in the last 100 messages.")

        try:
            with ctx.typing():
                s = saucenao.SauceNAO(self.saucenao_api_key.value)
                results = await s.search(found_url)

            if len(results) > 0 and results[0].similarity > 90:
                await ctx.send("Found result: \n{}\n{}".format(
                    results[0].desc(), results[0].url()))
            else:
                await ctx.send("No results found")
        except saucenao.HTTPError as e:
            if e.resp == 429:
                await ctx.send("Rate limited :(")
            else:
                raise
Example #6
0
 async def confirm(self, preview):
     if not self.skip_confirm:
         embed = discord.Embed(color=discord.Colour.gold())
         embed.description = f"This will do the following:\n```{preview}```\n\n Press ✉ to mention, 📝 to not mention, ❌ to cancel."
         view = DoneView(
             timeout=15,
             author_id=self.ctx.author.id,
             reacquire=True,
             delete_after=True,
         )
         message = await self.ctx.send(embed=embed, view=view)
         await view.wait()
         if view.value:
             await self.ctx.message.add_reaction("✅")
             return discord.AllowedMentions(everyone=True,
                                            users=True,
                                            roles=True)
         elif view.value is False:
             await self.ctx.message.add_reaction("✅")
             return discord.AllowedMentions(everyone=False,
                                            users=False,
                                            roles=False)
         elif view.value is None:
             raise CommandError("Command Cancelled.")
     else:
         return discord.AllowedMentions(everyone=False,
                                        users=False,
                                        roles=False)
Example #7
0
async def make_mute(ctx: Context,
                    user_id: int,
                    time: timedelta,
                    reason: str = None) -> db.Mute:
    with db_session:
        user = await get_user(user_id)
        guild = await get_guild(ctx.guild.id)

        if not guild.mute_role:
            raise CommandError("This server doesn't have mute role set.")

        mute = db.Mute(
            given_by=ctx.author.id,
            # Pony doesn't like assigning None to an Optional field
            # reason=reason,
            user=user,
            guild=guild,
            start=datetime.now(),
            end=datetime.now() + time,
            active=True)

        if reason:
            mute.reason = reason

        return mute
Example #8
0
    async def request_youtube(self, ctx: Context, *, request):
        """Adds a YouTube video to the requests queue.

        request: YouTube search query.
        """

        try:
            request = YouTubeTrack(request, self.config, requester=ctx.author)
        except Exception as error:
            await self.bot.errorlog.send(error, ctx)
            raise CommandError(
                f"An error occurred trying to load YouTubeTrack `{request}`")

        await ctx.invoke(self.request, request=request)
Example #9
0
    async def request_mp3(self, ctx: Context, *, request):
        """Adds a local MP3 file to the requests queue.

        request: Local track search query.
        """

        try:
            request = MP3Track(request, config=self.config)
        except Exception as error:
            await self.bot.errorlog.send(error, ctx)
            raise CommandError(
                f"An error occurred trying to load MP3Track `{request}`")

        await ctx.invoke(self.request, request=request)
Example #10
0
    async def assign(self, ctx: CstmContext, *, flags: AssignFlags):
        """
        Description
        ==============
        Assign a staffmember (or yourself) for a step on a chapter.

        Required Role
        =====================
        Role `Neko Workers`.

        Arguments
        ===========
        Required
        ---------
        :chapter:
            | The chapter to edit, in format: projectName chapterNbr [:doc:`/Types/chapter`]
        :step:
            | The step to assign the staffmember to. Can be one of: tl, rd, ts, pr or qc. [:doc:`/Types/literals`]
        :link:
            | The link to the folder on box. [:doc:`/Types/Text`]
        Optional
        ----------
        :staff:
            | The staffmember to assign. If omitted, the command's author is assigned instead. [:doc:`/Types/literals`]
        """
        chapter = flags.chapter
        staff = flags.staff
        step = flags.step
        if not staff:
            staff = await Staff.convert(ctx, ctx.author.id)
        if step == "tl" and not chapter.translator:
            chapter.translator = staff
        elif step == "rd" and not chapter.redrawer:
            chapter.redrawer = staff
        elif step == "ts" and not chapter.typesetter:
            chapter.typesetter = staff
        elif step in ("qc", "pr") and not chapter.proofreader:
            chapter.proofreader = staff
        else:
            raise CommandError(
                "A staffmember has already been assigned for this step.\nConsider using $editchapter to edit the staffmember for a step."
            )
        await ctx.monitor_changes(
            text=
            f"Do you really want to assign {'yourself' if staff.discord_id == ctx.author.id else staff.name} "
            f"as the {staffroles.get(step, 'Proofreader')} for {chapter}?",
            color=discord.Colour.dark_magenta(),
            entity=chapter,
        )
Example #11
0
    async def playfile(self, ctx):
        if len(ctx.message.attachments) == 0:
            await on_command_error(
                ctx, CommandError("Dieser Nachricht liegt keine Datei bei."))
            return

        try:
            await ctx.author.voice.channel.connect()
        except:
            pass
        msg = ctx.message
        f = open("test/tmp.mp3", "wb")
        await msg.attachments[0].save(f)
        source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(f.name))
        self.bot.voice_clients[0].play(source,
                                       after=lambda e: self.raise_error(e)
                                       if e else None)
        await asyncio.sleep(10)
        os.remove(f.name)
Example #12
0
 async def suggest(self, ctx, *, args: Optional[str]):
     sNum = sn_add()
     if sNum == -1:
         await ctx.send("Command failed!")
         raise CommandError("error in sn file")
     
     embed = libneko.Embed(title = f"Suggestion #{sNum}")
     embed.colour = random.randint(0, 0xffffff)
     
     if ctx.channel.id == Constants.Suggestions[0]:
         await ctx.message.delete()
         
         if args.isspace() or args == "":
             await ctx.send(f"{ctx.author.mention}, please add what to suggest!")
             return
         else:
             embed.description = f"Suggested by {ctx.author}:\n\"{args}\""
             embed.set_footer(icon_url = ctx.author.avatar_url, text = f"\"c.suggest < suggestions > \" is the command.")
             await ctx.send(f"{ctx.author.mention}, your suggestion has been added!")
             await self.bot.get_channel(Constants.Suggestions[1]).send(content = None, embed = embed)
Example #13
0
    async def add_color(self, ctx, hexcode, *, name=""):
        """Add a color to the database colors."""
        colors = db.get(ctx.guild.id, "colors")

        if len(colors) >= cfg.color_limit:
            raise CommandError(f"Color Limit Reached ({len(colors)}/50)")

        if not utils.validate_hex(hexcode):
            raise UserInputError(
                f"Invalid hexcode. Get help at https://htmlcolorcodes.com/")

        if "|" in name or len(name) > 100:
            raise UserInputError(
                "Color names must be shorter than 100 characters and cannot include `|`"
            )

        if name in [color["name"] for color in colors]:
            raise UserInputError("Cannot have duplicate color names")

        # auto name if name not given
        if not name:
            name = f"Color {len(colors) + 1}"

        # change black color because #000000 in discord is transparent
        if hexcode in {"#000000", "#000"}:
            hexcode = "#000001"

        # create and add color
        new_color = {
            "name": name,
            "hexcode": hexcode,
            "role": None,
            "members": []
        }

        # update database
        db.guilds.update_one({"_id": ctx.guild.id},
                             {"$push": {
                                 "colors": new_color
                             }})
        await ctx.invoke(bot.get_command("colors"))  # show new set
Example #14
0
    async def repeat(self, ctx: Context):
        """Repeats the currently playing track."""

        session = self.get_session(ctx.guild)

        if ctx.author in session.repeat_requests:
            raise CommandError('You have already requested to repeat.')

        session.repeat_requests.append(ctx.author)
        repeats_needed = len(list(session.listeners)) // 2 + 1

        if len(session.repeat_requests) >= repeats_needed:
            session.queue.add_request(session.current_track, at_start=True)

        else:
            em = Embed(colour=Colour.dark_green(),
                       title='Repeat track',
                       description=f'You currently need '
                       f'**{repeats_needed - len(session.repeat_requests)}** '
                       f'more votes to repeat this track.')

            await ctx.send(embed=em)
Example #15
0
    async def skip(self, ctx: Context):
        """Skips the currently playing track."""

        session = self.get_session(ctx.guild)

        if ctx.author in session.skip_requests:
            raise CommandError("You have already requested to skip.")

        session.skip_requests.append(ctx.author)
        skips_needed = len(list(session.listeners)) // 2 + 1

        if len(session.skip_requests) >= skips_needed:
            session.voice.stop()

        else:
            em = Embed(colour=Colour.dark_green(),
                       title="Skip video",
                       description=f"You currently need "
                       f"**{skips_needed - len(session.skip_requests)}** "
                       f"more votes to skip this track.")

            await ctx.send(embed=em)
Example #16
0
 async def cog_check(self, ctx):
     if not await self.bot.is_owner(ctx.author):
         raise CommandError(f"{ctx.author.mention} isn't the bot owner.")
     else:
         return True