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)
Exemple #3
0
    async def voice_rename(self, ctx: commands.Context, *args):
        """Rename current voice channel"""
        await ctx.send(text.fill("voice", "wip", mention=ctx.author.mention),
                       delete_after=10)
        await utils.delete(ctx)
        return

        name = " ".join(args)
        if len(name) <= 0:
            await ctx.send(
                delete_after=config.delay_embed,
                content=text.fill("voice", "rename empty", user=ctx.author),
            )
            return
        if len(name) > 25:
            await ctx.send(
                delete_after=config.delay_embed,
                content=text.fill("voice", "rename long", user=ctx.author),
            )
            return

        v = self.getVoiceChannel(ctx)
        name = name.replace(" " + self.lock, "").replace(self.lock, "")
        if v.id in self.locked:
            name = name + " " + self.lock
        await v.edit(name=name)

        await utils.delete(ctx)
    async def _role_remove(self, location: discord.abc.Messageable,
                           member: discord.Member, role: discord.Role):
        if role < self.getLimitProgrammes(
                location) and role > self.getLimitInterests(location):
            # role is programme, check if user has permission
            for programme_role in config.get("faceshifter", "programme roles"):
                if programme_role in [r.id for r in member.roles]:
                    break
            else:
                await location.send(
                    text.fill("faceshifter",
                              "deny role",
                              mention=member.mention),
                    delete_after=config.get("delay", "user error"),
                )
                return
        elif role < self.getLimitInterests(location):
            # role is below interests limit, continue
            pass
        else:
            # role is limit itself or something above programmes
            await location.send(
                text.fill("faceshifter",
                          "deny high role",
                          mention=member.mention),
                delete_after=config.get("delay", "user error"),
            )
            return

        await member.remove_roles(role)
    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")
    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 #7
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 #8
0
    def fillBoard(self, embed, *, member, order: str, offset: int) -> discord.Embed:
        limit = config.get("karma", "leaderboard limit")
        # around = config.get("karma", "leaderboard around")
        template = "`{position:>2}` … `{karma:>5}` {username}"

        embed.clear_fields()

        # get repository parameters
        column = "karma"
        if order == "give":
            column = "positive"
        if order == "take":
            column == "negative"

        if order == "desc":
            attr = DB_Karma.karma.desc()
        elif order == "asc":
            attr = DB_Karma.karma
        elif order == "give":
            attr = DB_Karma.positive.desc()
        elif order == "take":
            attr = DB_Karma.negative.desc()

        # construct first field
        value = []
        board = repo_k.getLeaderboard(attr, offset, limit)

        for i, db_user in enumerate(board, start=offset):
            # fmt: off
            user = self.bot.get_user(int(db_user.discord_id))
            username = (
                self.sanitise(user.display_name)
                if hasattr(user, "display_name")
                else "_unknown_"
            )

            if int(db_user.discord_id) == member.id:
                username = f"**{username}**"

            value.append(template.format(
                position=i + 1,
                karma=getattr(db_user, column),
                username=username,
            ))
            # fmt: on

        if offset == 0:
            name = text.fill("karma", "board_1", num=limit)
        else:
            name = text.fill("karma", "board_x", num=limit, offset=offset + 1)
        embed.add_field(name=name, value="\n".join(value))

        # construct second field
        # FIXME How to get user's position?
        # value = []
        # board = repo_k.getLeaderboard(attr, offset=user_position - around, limit=around*2+1)

        return embed
    async def _announceDuplicate(self, message: discord.Message,
                                 original: object, hamming: int):
        """Send message that a post is a original

        original: object
        hamming: Hamming distance between the image and closest database entry
        """
        if hamming <= self.limit_full:
            t = "**♻️ To je repost!**"
            await message.add_reaction("♻️")
        elif hamming <= self.limit_hard:
            t = "**♻️ To je asi repost**"
            await message.add_reaction("🤔")
        else:
            t = "To je možná repost"
            await message.add_reaction("🤷🏻")
        prob = "{:.1f} %".format((1 - hamming / 128) * 100)
        timestamp = original.timestamp.strftime("%Y-%m-%d %H:%M:%S")

        src_chan = self.getGuild().get_channel(original.channel_id)
        try:
            src_post = await src_chan.fetch_message(original.message_id)
            link = src_post.jump_url
            author = discord.utils.escape_markdown(
                src_post.author.display_name)
        except:
            link = "404 " + emote.sad
            author = "_??? (404)_"

        d = text.fill(
            "warden",
            "repost description",
            name=discord.utils.escape_markdown(message.author.display_name),
            value=prob,
        )
        embed = discord.Embed(title=t,
                              color=config.color,
                              description=d,
                              url=message.jump_url)
        embed.add_field(name=f"**{author}**, {timestamp}",
                        value=link,
                        inline=False)

        embed.add_field(
            name=text.get("warden", "repost title"),
            value="_" +
            text.fill("warden",
                      "repost content",
                      limit=config.get("warden", "not duplicate limit")) + "_",
        )
        embed.set_footer(text=f"{message.author.id} | {message.id}")
        m = await message.channel.send(embed=embed)
        await m.add_reaction("❎")
        await m.add_reaction("🆗")
Exemple #10
0
    async def remind(self, ctx, member: discord.Member):
        message = ctx.message
        lines = message.content.split("\n")
        arg = lines[0]
        arg = arg.replace("weekend", "saturday")
        date, date_str = await self.parse_datetime(arg)

        lines = "\n".join(lines)
        for prefix in config.prefixes:
            if lines[0] == prefix:
                lines = lines.replace(f"{prefix}remind ", "")
        lines = lines.replace(f"<@!{member.id}>", "")

        lines = lines.replace(date_str, "")
        lines = re.split(" ", lines)
        while "" in lines:
            lines.remove("")
        lines = " ".join(lines)

        if len(lines) == 0:
            await ctx.send(
                ">>> " +
                text.fill("remindme", "remind help", prefix=config.prefix))
            return
        elif len(lines) > 1024:
            lines = lines[:1024]

        if date is None:
            await ctx.send(text.get("remindme", "datetime not found"))
            date = datetime.now() + timedelta(days=1)
        repository.add(
            user_id=member.id,
            reminder_user_id=ctx.author.id,
            permalink=ctx.message.jump_url,
            message=lines,
            origin_date=ctx.message.created_at,
            new_date=date,
        )
        date = date.strftime("%d.%m.%Y %H:%M")

        await self.log(level="debug",
                       message=f"Reminder created for {ctx.author.name}")

        await ctx.message.add_reaction("✅")
        await ctx.message.author.send(
            text.fill("remindme",
                      "reminder confirmation",
                      name=member.display_name,
                      date=date))
        return
Exemple #11
0
    async def loop(self, vote_msg, edit_msg, date):
        votes = await self.find_emotes(vote_msg)

        while True:
            if date < datetime.now():
                break
            timeout = (date - datetime.now()).seconds
            pending_tasks = [
                self.bot.wait_for("raw_reaction_add"),
                self.bot.wait_for("raw_reaction_remove"),
            ]

            done_tasks, pending_tasks = await asyncio.wait(
                pending_tasks,
                return_when=asyncio.FIRST_COMPLETED,
                timeout=timeout)
            for task in done_tasks:
                raw_reaction = await task

            await self.check_reactions(raw_reaction, vote_msg, votes, edit_msg,
                                       date)

        if vote_msg not in self.bot.cached_messages:
            vote_msg = await vote_msg.channel.fetch_message(vote_msg.id)

        for reaction in vote_msg.reactions:
            for option in votes:
                if reaction.emoji == option["emote"]:
                    option["num_votes"] = reaction.count

        lines = vote_msg.content.split("\n")

        content = text.fill("vote",
                            "ended",
                            now=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        content += lines[0] + "\n"
        votes = sorted(votes, key=lambda i: (i["num_votes"]), reverse=True)
        for option in votes:
            content += text.fill(
                "vote",
                "option",
                option=option["option"],
                num=option["num_votes"] - 1,
            )
        content = escape_mentions(escape_markdown(content))

        await edit_msg.channel.send(content=content)
        repository.del_vote(channel_id=vote_msg.channel.id,
                            message_id=vote_msg.id)
        return
    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, ProblematicVerification):
            await self.output.error(
                ctx,
                text.fill("gatekeeper",
                          "ProblematicVerification",
                          status=error.status))

            await self.event.user(
                ctx.author, ctx.location,
                f"Problem with verification: {error.login}: {error.status}")

        elif isinstance(error, BadEmail):
            await self.output.error(
                ctx,
                text.fill("gatekeeper",
                          "BadEmail",
                          constraint=error.constraint))

        elif isinstance(error, WrongVerificationCode):
            await self.output.error(
                ctx,
                text.fill("gatekeeper",
                          "WrongVerificationCode",
                          mention=ctx.author.mention))

            await self.event.user(
                ctx.author, ctx.channel,
                f"User ({error.login}) code mismatch: `{error.their}` != `{error.database}`"
            )

        # exceptions without parameters
        elif isinstance(error, VerificationException):
            await self.output.error(
                ctx, text.get("gatekeeper",
                              type(error).__name__))
Exemple #13
0
    async def react_add(self, ctx, name: str = None, *, parameters=None):
        """Add new reaction

        ```
        ?react add <reaction name>
        type <image | text>
        match <full | start | end | any>
        sensitive <true | false>
        triggers "a b c" "d e" f
        responses "abc def"

        users 0 1 2
        channels 0 1 2
        counter 10
        ```
        """
        if name is None:
            return await utils.send_help(ctx)
        elif name in self.reactions.keys():
            raise ReactionNameExists()

        reaction = await self.parse_react_message(ctx.message, strict=True)
        self.reactions[name] = reaction
        self._save_reactions()

        await self.output.info(
            ctx, text.fill("actress", "reaction added", name=name))
        await self.event.sudo(ctx.author, ctx.channel,
                              f"Reaction **{name}** added.")
    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 #15
0
    async def urban(self, ctx):
        await self.deleteCommand(ctx, now=True)
        message = ctx.message
        args = message.content.split(" ")
        if len(args) == 1:
            await ctx.send(
                ">>> " +
                text.fill("urban", "urban_help", prefix=config.prefix))
            return
        args.pop(0)
        search = " ".join(args)
        term = url_parse.quote(search)
        async with ctx.typing():
            try:
                response = requests.get(
                    "http://api.urbandictionary.com/v0/define?term={term}".
                    format(term=term))
                dic = response.json()
                response.raise_for_status()

            except requests.HTTPError as http_err:
                await ctx.send(f"HTTP error occurred: {http_err}")
            except Exception as err:
                await ctx.send(f"Error occurred: {err}")
            else:
                # Request was successful
                embeds = self.urban_embeds(ctx, dic)

        await self.urban_pages(ctx, embeds)

        return
Exemple #16
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 verify(self, ctx, email: str):
        """Ask for verification code"""
        await utils.delete(ctx)

        if "@" not in email or len(email.split("@")) > 2:
            raise NotAnEmail()

        # check the database for member ID
        if repo_u.get(ctx.author.id) is not None:
            raise IDAlreadyInDatabase()

        # check the database for email
        if repo_u.getByLogin(email) is not None:
            raise EmailAlreadyInDatabase()

        # check e-mail format
        role = await self._email_to_role(ctx, email)

        # generate code
        code = await self._add_user(ctx.author, login=email, role=role)

        # send mail
        await self._send_verification_email(ctx.author, email, code)
        anonymised = "[redacted]@" + email.split("@")[1]
        await ctx.send(
            text.fill(
                "gatekeeper",
                "verify successful",
                mention=ctx.author.mention,
                email=anonymised,
                prefix=config.prefix,
            ),
            delete_after=config.get("delay", "verify"),
        )
    async def reverify_prove(self, ctx):
        """Ask for verification code"""
        await utils.delete(ctx)

        db_user = repo_u.get(ctx.author.id)

        if db_user is None:
            await self.console.error(
                "User in `?reverify prove` is not in database.")
            raise NotInDatabase()

        if db_user.status != "quarantined":
            await self.console.error(
                "User in `?reverify prove` did not have `quarantined` status.")
            raise UnexpectedReverify()

        if db_user.group == "FEKT" and "@" not in db_user.login:
            email = db_user.login + "@stud.feec.vutbr.cz"
        elif db_user.group == "VUT" and "@" not in db_user.login:
            email = db_user.login + "@vutbr.cz"
        else:
            email = db_user.login

        # generate new code
        code = await self._update_user(ctx.author)

        # send mail
        await self._send_verification_email(ctx.author, email, code)

        await ctx.send(
            text.fill("gatekeeper",
                      "reverify successful",
                      mention=ctx.author.mention),
            delete_after=config.get("delay", "verify"),
        )
Exemple #19
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 #20
0
    async def sauce(self, ctx):
        message = ctx.message
        args = message.content.split(" ")

        if not self.sauce_check(message):
            raise commands.MissingPermissions
        else:
            if len(args) != 2:
                await ctx.send(
                    ">>> " +
                    text.fill("weeb", "sauce_help", prefix=config.prefix))
                return
            BOOK_ID = args[1]
            async with ctx.typing():
                try:
                    response = requests.get(
                        "https://nhentai.net/api/gallery/{BOOK_ID}".format(
                            BOOK_ID=BOOK_ID))
                    dic = response.json()
                    response.raise_for_status()

                except requests.HTTPError as http_err:
                    await ctx.send(f"HTTP error occurred: {http_err}")
                except Exception as err:
                    await ctx.send(f"Error occurred: {err}")
                else:
                    # Request was successful
                    embed = self.sauce_embed(ctx, dic, BOOK_ID)

            await ctx.send(embed=embed)
Exemple #21
0
    async def nickname_unset(self, ctx):
        """Unset the nickname"""
        if ctx.author.nick is None:
            return await ctx.send(
                text.fill("shop", "no nick", author=ctx.author.mention))

        nick = ctx.author.nick

        await ctx.author.edit(nick=None, reason="?nickname unset")
        await ctx.send(
            text.fill(
                "shop",
                "nick removed",
                author=ctx.author.mention,
                nick=discord.utils.escape_markdown(nick),
            ))
        await self.event.user(ctx.author, ctx.channel, "Nickname reset.")
Exemple #22
0
 async def meniny(self, ctx):
     url = f"http://svatky.adresa.info/json?lang=sk&date={date.today().strftime('%d%m')}"
     res = requests.get(url).json()
     names = []
     for i in res:
         names.append(i["name"])
     await ctx.send(
         text.fill("librarian", "nameday sk", name=", ".join(names)))
    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 #24
0
    async def nickname_set(self, ctx, *, nick: str):
        """Set the nickname

        Use command `shop` to see prices

        nick: Your new nickname
        """
        # stop if user does not have nickname set
        if ctx.author.nick is None and nick is None:
            return await utils.send_help(ctx)

        # check if user has karma
        user = repo_k.getMember(ctx.author.id)
        if user is None:
            return await ctx.send(
                text.fill("shop", "no karma", author=ctx.author.mention))
        if user.karma < self.price_nick:
            return await ctx.send(
                text.fill(
                    "shop",
                    "not enough karma",
                    author=ctx.author.mention,
                    value=self.price_nick - user.karma,
                ))

        if "@" in nick:
            raise ForbiddenNicknameCharacter("@")

        # set nickname
        try:
            await ctx.author.edit(nick=nick, reason="?nickname")
        except discord.Forbidden:
            return await ctx.send(text.get("error", "higher permission"))

        repo_k.updateMemberKarma(ctx.author.id, -1 * self.price_nick)
        await ctx.send(
            text.fill(
                "shop",
                "new nick",
                author=ctx.author.mention,
                nick=discord.utils.escape_markdown(nick),
                value=self.price_nick,
            ))
        await self.event.user(ctx.author, ctx.channel,
                              f"Nickname changed to {nick}.")
Exemple #25
0
    async def karma_vote(self, ctx, emote: str):
        """Vote for emote's karma value"""
        message = await ctx.send(
            text.fill(
                "karma",
                "vote info",
                emote=emote,
                time=config.get("karma", "vote time"),
                limit=config.get("karma", "vote limit"),
            )
        )
        await message.add_reaction("☑️")
        await message.add_reaction("0⃣")
        await message.add_reaction("❎")

        await self.event.sudo(ctx.author, ctx.channel, f"Vote over value of {emote} started.")
        await asyncio.sleep(config.get("karma", "vote time") * 60)

        # update cached message
        message = await ctx.channel.fetch_message(message.id)

        positive = 0
        negative = 0
        neutral = 0
        for reaction in message.reactions:
            if reaction.emoji == "☑️":
                positive = reaction.count - 1
            elif reaction.emoji == "❎":
                negative = reaction.count - 1
            elif reaction.emoji == "0⃣":
                neutral = reaction.count - 1

        if positive + negative + neutral < config.get("karma", "vote limit"):
            await self.event.sudo(ctx.author, ctx.channel, f"Vote for {emote} failed.")
            return await ctx.send(text.fill("karma", "vote failed", emote=emote))

        result = 0
        if positive > negative + neutral:
            result = 1
        elif negative > positive + neutral:
            result = -1

        repo_k.set_emoji_value(str(self._emoteToID(emote)), result)
        await ctx.send(text.fill("karma", "vote result", emote=emote, value=result))
        await self.event.sudo(ctx.author, ctx.channel, f"{emote} karma value voted as {result}.")
    async def flip(self, ctx):
        """Yes/No"""
        option = random.choice(text.get("random", "flip"))
        await ctx.send(
            text.fill("random",
                      "answer",
                      mention=ctx.author.mention,
                      option=option))

        await utils.room_check(ctx)
    async def sudo_review_remove(self, ctx, id: int):
        """Remove someone's review"""
        db_review = repo_r.get(id)
        if db_review is None:
            return await ctx.send(
                text.fill("judge", "no review", mention=ctx.author.mention))

        repo_r.remove(id)
        await self.event.sudo(ctx.author, ctx.channel, f"Review {id} removed")
        return await ctx.send(text.get("judge", "removed"))
Exemple #28
0
 async def roomCheck(self, ctx: commands.Context):
     """Send an message to prevent bot spamming"""
     if isinstance(ctx.channel, discord.DMChannel):
         return
     botspam = self.getGuild().get_channel(config.channel_botspam)
     if ctx.channel.id not in config.bot_allowed:
         await ctx.send(
             text.fill("server",
                       "botroom redirect",
                       user=ctx.author,
                       channel=botspam))
Exemple #29
0
    async def voice_unlock(self, ctx: commands.Context):
        """Make current voice channel visible"""
        await ctx.send(text.fill("voice", "wip", mention=ctx.author.mention),
                       delete_after=10)
        await utils.delete(ctx)
        return

        channel = self.getVoiceChannel(ctx)
        if channel.id not in self.locked:
            await ctx.send(
                delete_after=config.get("delay", "user error"),
                content=text.fill("voice", "unlock error", user=ctx.author),
            )
            return
        await channel.set_permissions(self.getVerifyRole(), view_channel=True)
        channel_name = channel.name.replace(" " + self.lock, "")
        await channel.edit(name=channel_name)
        self.locked.remove(channel.id)

        await utils.delete(ctx)
Exemple #30
0
    async def voice_lock(self, ctx: commands.Context):
        """Make current voice channel invisible"""
        await ctx.send(text.fill("voice", "wip", mention=ctx.author.mention),
                       delete_after=10)
        await utils.delete(ctx)
        return

        channel = self.getVoiceChannel(ctx)
        if channel.id in self.locked:
            await ctx.send(
                delete_after=config.get("delay", "user error"),
                content=text.fill("voice", "lock error", user=ctx.author),
            )
            return
        await channel.set_permissions(self.getVerifyRole(), overwrite=None)
        channel_name = channel.name + " " + self.lock
        await channel.edit(name=channel_name)
        self.locked.append(channel.id)

        await utils.delete(ctx)