Exemple #1
0
    async def vote(self, ctx):
        message = ctx.message
        lines = message.content.split("\n")
        if len(lines) < 3:
            await ctx.send(
                ">>> " + text.fill("vote", "vote_help", prefix=config.prefix))
            return
        now = datetime.now()
        try:
            timex = re.compile(r"[ ](\d*[h])*[ ]*(\d*[m])*[ ]*(\d*[s])*[ ]")
            if timex.search(str(lines[0])) is not None:
                now = datetime.now()
                t = dparser.parse(lines[0], dayfirst=True, fuzzy=True)
                diff = t - now.replace(hour=0, minute=0, second=0)
                date = now + diff
            else:
                date = dparser.parse(lines[0], dayfirst=True, fuzzy=True)
            if now > date:
                date += timedelta(days=1)
        except dateutil.parser._parser.ParserError:
            date = now + timedelta(hours=1)
        votes = []
        for idx, line in enumerate(lines):
            if idx > 0:
                emote = re.match(r"<:\w*:\d*>", line)
                if emote is not None:
                    for emoji in self.bot.emojis:
                        if str(emoji) in line:
                            votes.append({
                                "emote":
                                emoji,
                                "option":
                                line.replace(str(emoji) + " ", ""),
                                "num_votes":
                                0,
                            })
                            break
                    else:
                        await ctx.send(text.get("vote", "emote_unknown"))
                        return
                else:
                    await ctx.send(text.get("vote", "emote_unknown"))
                    return

        for option in votes:
            await ctx.message.add_reaction(option["emote"])

        edit_msg = await ctx.send(
            text.fill("vote",
                      "waiting",
                      date=date.strftime("%Y-%m-%d %H:%M:%S")))
        repository.add_vote(
            channel_id=message.channel.id,
            message_id=message.id,
            edit_id=edit_msg.id,
            date=date.strftime("%Y-%m-%d %H:%M:%S"),
        )

        await self.loop(ctx.message, edit_msg, date)
        return
Exemple #2
0
    async def channelboard(self, ctx, offset: int = 1):
        await asyncio.sleep(0.5)
        user_channels = repository.get_user_channels()

        if not user_channels:
            return ctx.send(text.get("boards", "not found"))

        # convert to be zero-indexed
        offset -= 1
        if offset < 0:
            return await ctx.send(text.get("boards", "invalid offset"))

        results = await self.sort_channels(user_channels, False)

        if offset > len(results):
            return await ctx.send(text.get("boards", "offset too big"))

        embed = discord.Embed(
            title=text.get("boards", "channel board title"),
            description=text.get("boards", "channel board desc"),
            color=config.color,
        )

        # get data for "TOP X" list
        lines = []
        for position, item in enumerate(results):
            if position < offset:
                continue

            if position - offset >= config.board_top:
                break

            channel = self.bot.get_channel(item["channel_id"])
            if not hasattr(channel, "name"):
                # channel was not found
                continue

            # fmt: off
            if ctx.guild is not None and channel.guild.id == ctx.guild.id:
                lines.append(text.fill("boards", "channel template",
                    index=f"{position + 1:>2}",
                    count=f"{item['count']:>5}",
                    name=discord.utils.escape_markdown(channel.name)))
            else:
                # channel is on some other guild
                lines.append(text.fill("boards", "channel template guild",
                    index=f"{position + 1:>2}",
                    count=f"{item['count']:>5}",
                    name=discord.utils.escape_markdown(channel.name),
                    guild=discord.utils.escape_markdown(channel.guild.name)))
            # fmt: on
        title = "top number" if offset == 0 else "top offset"
        # fmt: off
        embed.add_field(
            name=text.fill("boards", title, top=config.board_top, offset=offset + 1),
            value="\n".join(lines),
            inline=False,
        )
        # fmt: on
        await ctx.send(embed=embed)
    def fill_subject_embed(self, embed: discord.Embed, review: object,
                           average: float) -> discord.Embed:
        # reset any previous
        embed.clear_fields()

        # add content
        # fmt: off
        name = self.bot.get_user(int(review.discord_id)) or text.get(
            "judge", "embed_no_user")
        if review.anonym:
            name = text.get("judge", "embed_anonymous")

        embed.add_field(
            inline=False,
            name=text.fill("judge", "embed_no", num=str(review.id)),
            value=text.fill("judge", "embed_average", num=f"{average:.1f}"),
        )
        embed.add_field(name=name, value=review.date)
        embed.add_field(name=text.get("judge", "embed_mark"),
                        value=review.tier)
        embed.add_field(
            inline=False,
            name=text.get("judge", "embed_text"),
            value=review.text_review,
        )
        # fmt: on

        embed.add_field(name="👍",
                        value=f"{repo_r.get_votes_count(review.id, True)}")
        embed.add_field(name="👎",
                        value=f"{repo_r.get_votes_count(review.id, False)}")

        return embed
Exemple #4
0
    async def on_member_update(self, before, after):
        booster_role = discord.utils.get(self.getGuild().roles, id=config.booster_role)

        if booster_role in before.roles:
            before_booster = True
        else:
            before_booster = False

        if booster_role in after.roles:
            after_booster = True
        else:
            after_booster = False

        if not before_booster and not after_booster:
            return
        elif before_booster and after_booster:
            return
        elif not before_booster and after_booster:
            embed = discord.Embed(
                title=text.get("base", "new_server_booster"),
                color=config.color_boost,
                timestamp=datetime.datetime.now().replace(microsecond=0),
            )
        elif before_booster and not after_booster:
            embed = discord.Embed(
                title=text.get("base", "not_booster_anymore"),
                color=config.color_boost,
                timestamp=datetime.datetime.now().replace(microsecond=0),
            )
        embed.set_thumbnail(url=after.avatar_url)
        embed.add_field(name="User", value=f"{after.name}#{after.discriminator}")
        embed.set_footer(text=f"UserID: {after.id}")
        channel = discord.utils.get(self.getGuild().channels, id=config.boost_channel)
        await channel.send(embed=embed)
    async def power_on(self, ctx):
        """Restore"""
        jail = self.getGuild().get_channel(config.get("channels", "jail"))
        everyone = self.getGuild().default_role
        botspam = self.getGuild().get_channel(config.get(
            "channels", "botspam"))

        visited = []

        if jail is not None:
            # remove the message
            messages = await jail.history(limit=10).flatten()
            for message in messages:
                if message.content.startswith(
                        text.get("admin", "poweroff jail")):
                    await message.delete()
                    break
            # switch to read-write
            await jail.set_permissions(everyone,
                                       send_messages=True,
                                       reason="?power on")
            visited.append(jail.mention)

        if botspam is not None:
            # send message
            await botspam.send(text.get("admin", "poweron botspam"))
            visited.append(botspam.mention)

        # send confirmation message
        if len(visited) > 0:
            await ctx.send(
                text.fill("admin", "poweron ok", channels=", ".join(visited)))
        else:
            await ctx.send(text.fill("admin", "power fail"))
        await self.event.sudo(ctx.author, ctx.channel, "Power on")
Exemple #6
0
 async def karma_stalk(self, ctx, member: discord.Member):
     """See someone's karma"""
     k = repo_k.get_karma(member.id)
     embed = self.embed(
         ctx=ctx,
         description=text.fill(
             "karma", "stalk_user", user=self.sanitise(member.display_name, limit=32)
         ),
     )
     embed.add_field(
         name=text.get("karma", "stalk_karma"),
         value=f"**{k.karma.value}** ({k.karma.position}.)",
         inline=False,
     )
     embed.add_field(
         name=text.get("karma", "stalk_positive"),
         value=f"**{k.positive.value}** ({k.positive.position}.)",
     )
     embed.add_field(
         name=text.get("karma", "stalk_negative"),
         value=f"**{k.negative.value}** ({k.negative.position}.)",
     )
     await ctx.send(embed=embed)
     await self.event.user(ctx.author, ctx.channel, f"Karma stalk on {member.name}.")
     await utils.room_check(ctx)
Exemple #7
0
    async def get_embed(self, row):
        user = self.bot.get_user(row.user_id)
        if user is None:
            try:
                user = await self.bot.fetch_user(row.user_id)
            except discord.errors.NotFound:
                return

        reminder_user = self.bot.get_user(row.reminder_user_id)
        if reminder_user is None:
            try:
                reminder_user = await self.bot.fetch_user(row.reminder_user_id)
                reminder_user_name = discord.utils.escape_markdown(
                    reminder_user.display_name)
            except discord.errors.NotFound:
                reminder_user_name = "_(Unknown user)_"
        else:
            reminder_user_name = discord.utils.escape_markdown(
                reminder_user.display_name)

        embed = self.create_embed(author=reminder_user,
                                  title=text.get("remindme", "reminder"))
        if row.user_id != row.reminder_user_id:
            embed.add_field(name=text.get("remindme", "reminder by"),
                            value=reminder_user_name,
                            inline=True)
        if row.message != "":
            embed.add_field(name=text.get("remindme", "reminder message"),
                            value=row.message,
                            inline=False)
        embed.add_field(name=text.get("remindme", "reminder link"),
                        value=row.permalink,
                        inline=True)

        return embed, user
Exemple #8
0
    async def karma_emotes(self, ctx):
        """See karma for all emotes"""
        emotes = await ctx.guild.fetch_emojis()
        content = []

        emotes_positive = self._getEmoteList(emotes, "1")
        if len(emotes_positive) > 0:
            content.append(text.get("karma", "emotes_positive"))
            content += self._emoteListToMessage(emotes_positive, 10)

        emotes_negative = self._getEmoteList(emotes, "-1")
        if len(emotes_negative) > 0:
            content.append(text.get("karma", "emotes_negative"))
            content += self._emoteListToMessage(emotes_negative, 10)

        emotes_nonvoted = self._getNonvotedEmoteList(emotes)
        if len(emotes_nonvoted) > 0:
            content.append(text.get("karma", "emotes_nonvoted"))
            content += self._emoteListToMessage(emotes_nonvoted, 10)

        if len(content) == 0:
            content.append(text.get("karma", "no emotes"))

        for line in [x for x in content if (x and len(x) > 0)]:
            await ctx.send(line)

        await utils.room_check(ctx)
    async def review_add(self, ctx, subject: str, mark: int, *, text: str):
        """Add a review

        subject: Subject code
        mark: 1-5 (one being best)
        text: Your review
        """
        if mark < 1 or mark > 5:
            return await ctx.send(text.get("judge", "wrong mark"))

        if len(text) > 1024:
            return await ctx.send(text.get("judge", "text too long"))

        # check if subject is in database
        db_subject = repo_s.get(subject)
        if db_subject is None:
            return await ctx.send(text.get("judge", "no subject"))

        anonymous = isinstance(ctx.channel, discord.DMChannel)
        past_review = repo_r.get_review_by_author_subject(
            ctx.author.id, subject)

        if past_review is None:
            # add
            repo_r.add_review(ctx.author.id, subject, mark, anonymous, text)
        else:
            # update
            repo_r.update_review(past_review.id, mark, anonymous, text)

        # send confirmation
        await self.event.user(ctx.author, ctx.channel,
                              f"Review by {ctx.author} for {subject} added")
        return await ctx.send(text.get("judge", "added"))
    async def database_remove(self,
                              ctx: commands.Context,
                              member: discord.Member = None,
                              force: str = None):
        """Remove user from database

        member: A server member
        force: "force" string. If omitted, show what will be deleted
        """
        if member is None:
            return await utils.send_help(ctx)

        # define variables
        guild = self.bot.get_guild(config.guild_id)
        force = self.parseArg(force)

        try:
            if force:
                result = repository.deleteId(discord_id=member.id)
            else:
                result = repository.filterId(discord_id=member.id)
        except Exception as e:
            return await self.output.error(ctx, text.get("db", "read"), e)

        d = "Result" if force else "Simulation, run with `force` to apply"
        if force:
            embed = self.embed(description=d, color=config.color_success)
            # delete
            if result is None or result < 1:
                return await self.output.error(ctx,
                                               text.get("db", "delete error"))
            embed.add_field(inline=False,
                            name="Success",
                            value=text.fill("db", "delete success",
                                            num=result))
            embed.add_field(
                name="Warning",
                value="Roles and channel access haven't been removed")
            await self.event.sudo(ctx.author, ctx.channel,
                                  "User removed from database: " + member.name)
            # TODO remove all roles
        else:
            # simulate
            embed = discord.Embed(color=config.color_notify, description=d)
            for r in result:
                embed.add_field(
                    inline=False,
                    name=self.dbobj2email(r),
                    value=discord.utils.get(guild.members,
                                            id=int(r.discord_id)).mention,
                )
            if len(result) < 1:
                embed.add_field(name="No entry",
                                value=text.get("db", "not found"),
                                inline=False)
        await ctx.send(embed=embed, delete_after=config.delay_embed)

        await utils.delete(ctx)
Exemple #11
0
    async def reschedule(self, ctx, idx: int):
        """Přesune upomínku na jindy"""
        row = repository.get_idx(idx)
        if row == []:
            await ctx.send(text.get("remindme", "wrong ID"))
            return
        if row[0].user_id != ctx.author.id:
            await ctx.send(
                text.get("remindme", "cannot edit other's reminders"))
            return

        message = ctx.message.content
        message = message.replace("weekend", "saturday").replace(str(idx), "")
        date, date_str = await self.parse_datetime(message)
        print_date = date.strftime("%d.%m.%Y %H:%M")

        embed, user = await self.get_embed(row[0])
        embed.add_field(name=text.get("remindme", "reminder edit new time"),
                        value=print_date,
                        inline=False)
        embed.add_field(
            name=text.get("remindme", "reminder edit confirmation"),
            value=text.get("remindme", "reminder edit text"),
            inline=False,
        )

        user_id = user.id
        message = await ctx.send(embed=embed)
        await message.add_reaction("✅")
        await message.add_reaction("❎")
        while True:

            def chk(reaction, usr):
                return (reaction.message.id == message.id
                        and (str(reaction.emoji) == "✅"
                             or str(reaction.emoji) == "❎")
                        and usr.id == user_id)

            try:
                reaction, user = await self.bot.wait_for(
                    "reaction_add", check=chk, timeout=config.delay_embed)
            except asyncio.TimeoutError:
                pass
            else:
                if str(reaction.emoji) == "✅":
                    await self.log(
                        level="debug",
                        message=
                        f"Rescheduling reminder - ID: {row[0].idx}, time: {date}, status: {row[0].status}, \n    message: {row[0].message}",
                    )
                    repository.postpone(row[0].idx, date)
            try:
                await message.delete()
            except discord.errors.Forbidden:
                pass
            except discord.errors.NotFound:
                pass
Exemple #12
0
    async def channelinfo(self, ctx, channel: discord.TextChannel):
        await self.deleteCommand(ctx, now=True)
        await asyncio.sleep(0.1)
        channels = repository.get_user_channels()
        all_results = await self.sort_channels(channels)
        users = await self.sort_users(repository.get_channel(channel.id))
        offset = -1

        if not users:
            return await ctx.send(text.get("boards", "not found"))

        for idx, result in enumerate(all_results, start=1):
            if result["channel_id"] == channel.id:
                total_count = result["count"]
                last_msg_at = result["last_msg_at"]
                position = idx

        for user in users:
            if user["last_msg_at"] == last_msg_at:
                user = self.bot.get_user(user["user_id"])
                if user is None:
                    try:
                        user = await self.bot.fetch_user(user["user_id"])
                        user_name = discord.utils.escape_markdown(f"{user.display_name}#{user.discriminator}")
                    except discord.errors.NotFound:
                        user_name = "_(Unknown user)_"
                else:
                    user_name = discord.utils.escape_markdown(f"{user.display_name}#{user.discriminator}")
                break
        else:
            user_name = "_(Unknown user)_"

        last_msg_at = last_msg_at.replace(tzinfo=timezone.utc).astimezone(tz=None)
        last_msg_at = last_msg_at.strftime("%d.%m.%Y %H:%M:%S")

        embed = self.create_embed(author=ctx.message.author, title=text.get("boards", "channel info title"))
        embed.add_field(name="Jméno", value=str(channel.name), inline=True)
        embed.add_field(name="ID", value=str(channel.id), inline=True)
        embed.add_field(name="Server", value=str(channel.guild.name), inline=True)
        try:
            embed.add_field(name="Kategorie", value=str(channel.category.name), inline=True)
        except AttributeError:
            pass
        embed.add_field(name="Poslední zpráva", value=f"{user_name}\n{last_msg_at}", inline=True)
        embed.add_field(name="Celkový počet zpráv", value=str(total_count), inline=True)
        embed.add_field(
            name="Pozice mezi kanály", value="{0}/{1}".format(position, len(all_results)), inline=True
        )
        embeds = []
        embeds.append(embed)
        boards, pagenum = await self.boards_generator(ctx, users, offset, "channel info")
        embeds += boards

        await self.board_pages(ctx, embeds, pagenum)
        return
Exemple #13
0
    async def image_remove(self, ctx, filename: str):
        """Remove image

        filename: An image filename
        """
        if "/" in filename or "\\" in filename or ".." in filename:
            return self.output.error(ctx, text.get("actress", "BadCharacter"))

        os.remove(self.path + filename)
        await self.output.info(text.get("actress", "deleted"))

        await utils.delete(ctx)
    async def sudo_subject_remove(self, ctx, subject: str):
        """Remove subject

        subject: Subject code
        """
        db_subject = repo_s.get(subject)
        if db_subject is None:
            return await ctx.send(text.get("judge", "no subject"))

        repo_s.remove(subject)
        await self.event.sudo(ctx.author, ctx.channel,
                              f"Subject {subject} removed")
        await ctx.send(text.get("judge", "subject removed"))
    async def database_add(
        self,
        ctx: commands.Context,
        member: discord.Member = None,
        login: str = None,
        group: discord.Role = None,
    ):
        """Add user to database

        member: A server member
        login: xlogin (FEKT, VUT) or e-mail
        group: A role from `roles_native` or `roles_guest` in config file
        """
        if member is None or login is None or group is None:
            return await utils.send_help(ctx)

        # define variables
        guild = self.bot.get_guild(config.guild_id)
        verify = discord.utils.get(guild.roles, name="VERIFY")

        # try to write to database
        try:
            repository.filterId(discord_id=member.id)[0]
            return await self.output.error(ctx, text.get("db", "duplicate"))
        except IndexError:
            # no result is good, we won't have collision
            pass

        try:
            repository.add_user(
                discord_id=member.id,
                login=login,
                group=group.name,
                status="verified",
                code="MANUAL",
            )
        except Exception as e:
            return await self.output.error(ctx, text.get("db", "write"), e)

        # assign roles, if neccesary
        if verify not in member.roles:
            await member.add_roles(verify)
        if group not in member.roles:
            await member.add_roles(group)

        # display the result
        await self.whois_member(ctx, member, log=False)

        await self.event.sudo(ctx.author, ctx.channel,
                              f"New user {member} ({group.name})")
    async def _send_verification_email(self, member: discord.Member,
                                       email: str, code: str) -> bool:
        cleartext = text.get("gatekeeper", "plaintext mail").format(
            guild_name=self.getGuild().name,
            code=code,
            bot_name=self.bot.user.name,
            git_hash=utils.git_hash()[:7],
            prefix=config.prefix,
        )

        richtext = text.get("gatekeeper", "html mail").format(
            # styling
            color_bg="#54355F",
            color_fg="white",
            font_family="Arial,Verdana,sans-serif",
            # names
            guild_name=self.getGuild().name,
            bot_name=self.bot.user.name,
            user_name=member.name,
            # codes
            code=code,
            git_hash=utils.git_hash()[:7],
            prefix=config.prefix,
            # images
            bot_avatar=self.bot.user.avatar_url_as(static_format="png",
                                                   size=128),
            bot_avatar_size="120px",
            user_avatar=member.avatar_url_as(static_format="png", size=32),
            user_avatar_size="20px",
        )

        msg = MIMEMultipart("alternative")
        msg["Subject"] = text.fill("gatekeeper",
                                   "mail subject",
                                   guild_name=self.getGuild().name,
                                   user_name=member.name)
        msg["From"] = config.get("email", "address")
        msg["To"] = email
        msg["Bcc"] = config.get("email", "address")
        msg.attach(MIMEText(cleartext, "plain"))
        msg.attach(MIMEText(richtext, "html"))

        with smtplib.SMTP(config.get("email", "server"),
                          config.get("email", "port")) as server:
            server.starttls()
            server.ehlo()
            server.login(config.get("email", "address"),
                         config.get("email", "password"))
            server.send_message(msg)
Exemple #17
0
    async def delete(self, ctx, idx: int):
        """Smaže upomínku"""
        row = repository.get_idx(idx)
        if row == []:
            await ctx.send(text.get("remindme", "wrong ID"))
            return
        if row[0].user_id != ctx.author.id:
            await ctx.send(
                text.get("remindme", "cannot delete other's reminders"))
            return

        embed, user = await self.get_embed(row[0])
        embed.add_field(
            name=text.get("remindme", "reminder delete confirmation"),
            value=text.get("remindme", "reminder delete text"),
            inline=False,
        )
        user_id = user.id
        message = await ctx.send(embed=embed)
        await message.add_reaction("✅")
        await message.add_reaction("❎")
        while True:

            def chk(reaction, usr):
                return (reaction.message.id == message.id
                        and (str(reaction.emoji) == "✅"
                             or str(reaction.emoji) == "❎")
                        and usr.id == user_id)

            try:
                reaction, user = await self.bot.wait_for(
                    "reaction_add", check=chk, timeout=config.delay_embed)
            except asyncio.TimeoutError:
                pass
            else:
                if str(reaction.emoji) == "✅":
                    await self.log(
                        level="debug",
                        message=
                        f"Deleting reminder from db - ID: {row[0].idx}, time: {row[0].new_date}, status: {row[0].status}, \n    message: {row[0].message}",
                    )
                    repository.delete(row[0].idx)
            try:
                await message.delete()
            except discord.errors.Forbidden:
                pass
            except discord.errors.NotFound:
                pass
Exemple #18
0
    async def send(
        self,
        source: Union[commands.Context, discord.Message],
        level: str,
        message: str = None,
        error: Exception = None,
    ):
        """Send output to source channel"""

        template = ">>> **{level}**: {message}"
        template_cont = "\n{error} ```{traceback}```"

        # make sure there is something after the colon
        if message is None and error is None:
            message = "unspecified"

        result = template.format(level=text.get("bot", level).upper(),
                                 message=message)

        # parse error
        if error is not None:
            tr = "".join(
                traceback.format_exception(type(error), error,
                                           error.__traceback__))
            if len(tr) > 1000:
                tr = "…" + tr[-999:]

            # escape
            error = discord.utils.escape_markdown(str(error)).replace(
                "@", "@\u200b")
            tr = tr.replace("```", "`\u200b`\u200b`")

            result += template_cont.format(error=error, traceback=tr)

        await source.send(result)
Exemple #19
0
    async def on_command_error(self, ctx: commands.Context, error):
        # try to get original error
        if hasattr(ctx.command, "on_error") or hasattr(ctx.command,
                                                       "on_command_error"):
            return
        error = getattr(error, "original", error)

        # non-rubbergoddess exceptions are handled globally
        if not isinstance(error, rubbercog.RubbercogException):
            return

        # fmt: off
        # exceptions with parameters
        if isinstance(error, InvalidReactionKey):
            await self.output.error(
                ctx, text.fill("actress", "InvalidReactionKey", key=error.key))
        elif isinstance(error, ReactionParsingException):
            await self.output.error(
                ctx,
                text.fill("actress",
                          "ReactionParsingException",
                          key=error.key,
                          value=error.value))
        # exceptions without parameters
        elif isinstance(error, ActressException):
            await self.output.error(ctx,
                                    text.get("actress",
                                             type(error).__name__))
Exemple #20
0
 async def finished(self, ctx):
     """Zobrazí dokončené upomínky"""
     repo = repository.get_finished()
     if repo is None:
         await ctx.send(text.get("remindme", "no reminders"))
         return
     await self.reminder_list(ctx, repo)
Exemple #21
0
 async def all(self, ctx):
     """Zobrazí všechny upomínky"""
     repo = repository.get_ordered()
     if repo is None:
         await ctx.send(text.get("remindme", "no reminders"))
         return
     await self.reminder_list(ctx, repo)
Exemple #22
0
    async def send_image(self, ctx, channel: discord.TextChannel, filename):
        """Send an image as a bot

        channel: Target text channel
        filename: A filename
        """
        now = time.monotonic()
        try:
            async with ctx.typing():
                message = await channel.send(file=discord.File(self.path +
                                                               filename))
                delta = time.monotonic() - now
                await self.output.info(
                    ctx, text.fill("actress", "file sent", delta=delta))
                mention = channel.mention if hasattr(
                    channel, "mention") else type(channel).__name__
                await self.event.sudo(
                    ctx.author,
                    ctx.channel,
                    f"Media file sent to {mention}:\n"
                    f"> _{filename}_\n> <{message.jump_url}>",
                )
        except Exception as e:
            await self.output.error(ctx, text.get("actress", "FileSendError"),
                                    e)
    async def sudo_subject_add(self, ctx, subject: str, name: str,
                               category: str):
        """Add subject

        subject: Subject code
        name: Subject name
        category: Subject faculty or other assignment
        """
        db_subject = repo_s.get(subject)
        if db_subject is not None:
            return await ctx.send(text.get("judge", "subject exists"))

        repo_s.add(subject, name, category)
        await self.event.sudo(ctx.author, ctx.channel,
                              f"Subject {subject} added")
        await ctx.send(text.get("judge", "subject added"))
    async def sudo_subject_update(self, ctx, subject: str, name: str,
                                  category: str):
        """Update subject

        subject: Subject code
        name: Subject name
        category: Subject faculty or other assignment
        """
        db_subject = repo_s.get(subject)
        if db_subject is None:
            return await ctx.send(text.get("judge", "no subject"))

        repo_s.update(subject, name, category)
        await self.event.sudo(ctx.author, ctx.channel,
                              f"Subject {subject} updated")
        await ctx.send(text.get("judge", "subject updated"))
    async def hoarders(self, ctx: commands.Context, warn: str = None):
        """Check for users with multiple programme roles

        warn: Optional. Use "warn" string to send warnings, else just list the users
        """
        warn = warn == "warn"

        hoarders = []
        limit_top = discord.utils.get(self.getGuild().roles,
                                      name="---PROGRAMMES")
        limit_bottom = discord.utils.get(self.getGuild().roles,
                                         name="---INTERESTS")

        for member in self.getGuild().members:
            prog = []
            for role in member.roles:
                if role < limit_top and role > limit_bottom:
                    prog.append(role.name)
            if len(prog) > 1:
                hoarders.append([member, prog])

        if len(hoarders) == 0:
            await ctx.send(text.get("janitor", "no hoarders"))
        else:
            all = len(hoarders)
            if warn:
                msg = await ctx.send(
                    "Odesílání zprávy 1/{all}.".format(all=all))
            embed = discord.Embed(title="Programme hoarders",
                                  color=config.color)
            for num, (hoarder, progs) in enumerate(hoarders, start=1):
                embed.add_field(
                    name="User",
                    value=
                    f"**{discord.utils.escape_markdown(hoarder.name)}** ({hoarder.id})",
                )
                embed.add_field(name="Status", value=hoarder.status)
                embed.add_field(name="Programmes",
                                value=", ".join(progs),
                                inline=False)
                if warn:
                    if num % 5 == 0:  # Do not stress the API too much
                        await msg.edit(content="Odesílání zprávy {num}/{all}.".
                                       format(num=num, all=all))
                    await hoarder.send(
                        text.fill("janitor",
                                  "hoarding warning",
                                  guild=self.getGuild().name))
                if num % 8 == 0:  # Can't have more than 25 fields in an embed
                    await ctx.channel.send(embed=embed,
                                           delete_after=config.delay_embed)
                    embed = discord.Embed(title="Programme hoarders",
                                          color=config.color)
            if warn and num % 5 != 0:
                await msg.edit(content="Odesílání zprávy {num}/{all}.".format(
                    num=num, all=all))
            await ctx.channel.send(embed=embed,
                                   delete_after=config.delay_embed)

        await utils.delete(ctx)
Exemple #26
0
 async def error(
     self,
     source: Union[commands.Context, discord.Message],
     message: str = None,
     error: Exception = None,
 ):
     if self.level <= logging.ERROR:
         await self.send(source, text.get("bot", "error"), message, error)
Exemple #27
0
 async def reminders(self, ctx):
     """Zobrazí upomínky uživatele"""
     if ctx.invoked_subcommand is None:
         repo = repository.get_user(user_id=ctx.author.id)
         if repo is None:
             await ctx.send(text.get("remindme", "no reminders for you"))
             return
         await self.reminder_list(ctx, repo)
Exemple #28
0
    async def karma_emote(self, ctx, emote: str):
        """See emote's karma"""
        if not self._isUnicode(emote):
            try:
                emote_id = int(self._emoteToID(emote))
                emote = await ctx.guild.fetch_emoji(emote_id)
            except (ValueError, IndexError):
                return await utils.send_help(ctx)
            except discord.NotFound:
                return await ctx.send(text.get("karma", "emote not found"))

        value = repo_k.emoji_value_raw(emote)
        if value is None:
            return await ctx.send(text.get("karma", "emote not voted"))

        await ctx.send(text.fill("karma", "emote", emote=str(emote), value=str(value)))
        await utils.room_check(ctx)
Exemple #29
0
    async def plot(self,
                   ctx,
                   xmin: Optional[float] = -10,
                   xmax: Optional[float] = 10,
                   *,
                   inp: str):

        equations = escape_mentions(escape_markdown(inp)).split(";")

        fig = plt.figure(dpi=300)
        ax = fig.add_subplot(1, 1, 1)

        if xmin < 0 < xmax:
            ax.spines["left"].set_position("zero")

        # Eliminate upper and right axes
        ax.spines["right"].set_color("none")
        ax.spines["top"].set_color("none")

        # Show ticks in the left and lower axes only
        ax.xaxis.set_tick_params(bottom=True, direction="inout")
        ax.yaxis.set_tick_params(left=True, direction="inout")

        successful_eq = 0
        msg = text.get("draw", "plot_err")
        numpy.seterr(divide="ignore", invalid="ignore")
        async with ctx.typing():
            for eq in equations:
                try:
                    func = self.string2func(eq)
                    x = numpy.linspace(xmin, xmax, 1000)
                    plt.plot(x, func(x))
                    plt.xlim(xmin, xmax)
                    successful_eq += 1
                except Exception as e:
                    msg += "\n" + eq + " - " + str(e)
            if msg != text.get("draw", "plot_err"):
                await ctx.send(msg)
            if successful_eq > 0:
                if not os.path.isdir("assets"):
                    os.mkdir("assets")
                plt.savefig("assets/plot.png", bbox_inches="tight", dpi=100)
                plt.clf()
                await ctx.send(file=discord.File("assets/plot.png"))
                os.remove("assets/plot.png")
        return
Exemple #30
0
 async def warning(
     self,
     source: Union[commands.Context, discord.Message],
     message: str = None,
     error: Exception = None,
 ):
     if self.level <= logging.WARNING:
         await self.send(source, text.get("bot", "warning"), message, error)