예제 #1
0
 async def uhoh(self, ctx):
     await ctx.send(utils.fill_message("uhoh_counter", uhohs=uhoh_counter))
예제 #2
0
 async def cog_after_invoke(self, ctx):
     if ctx.channel.id not in config.allowed_channels:
         await ctx.message.channel.send(
             utils.fill_message("bot_room_redirect",
                                user=ctx.message.author.id,
                                bot_room=config.bot_room))
예제 #3
0
 async def diplom_error(self, ctx, error):
     await ctx.send(utils.fill_message("absolvent_help", command=ctx.invoked_with))
예제 #4
0
 async def bonk_error(self, ctx, error):
     if isinstance(error, commands.BadArgument):
         await ctx.send(
             utils.fill_message("member_not_found", user=ctx.author.id))
예제 #5
0
 async def karma_error(self, ctx, error):
     if isinstance(error, commands.CheckFailure):
         await ctx.send(
             utils.fill_message("insufficient_rights", user=ctx.author.id))
예제 #6
0
class Absolvent(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command(
        aliases=["absolvent"],
        brief=Messages.absolvent_brief,
        description=utils.fill_message("absolvent_help", command="diplom")
    )
    async def diplom(self, ctx, degree, name, surname, diploma_number, thesis_web_id):
        """Command for diploma verification and honourable role addition

        :param ctx: discord context
        :param name: first name (case-sensitive)
        :param surname: last name (case-sensitive)
        :param degree: strictly either "Bc." or "Ing." (case-sensitive)
        :param diploma_number: ID of diploma, in format NNNNNN/YYYY
        :param thesis_web_id: ID from URL https://dspace.vutbr.cz/handle/11012/<num> can be discovered via https://dspace.vutbr.cz/handle/11012/19121 
        """
        # prepare
        htmlparser = etree.HTMLParser()
        diploma_year = re.search(r"\d+/(\d+)", diploma_number)
        if not diploma_year:
            await ctx.send(Messages.absolvent_wrong_diploma_format)
            return
        diploma_year = diploma_year.group(1)
        full_name_without_degree = f"{name} {surname}"
        full_name_without_degree_surname_first = f"{surname}, {name}"

        # CHECK WHETHER THE PROVIDED NAME MATCHES THE ONE STORED FOR FIT VUT VERIFICATION

        def remove_accents(input_str):
            nfkd_form = unicodedata.normalize("NFKD", input_str)
            only_ascii = nfkd_form.encode("ASCII", "ignore").decode("ASCII")
            return only_ascii

        # get "surname name" for bot database fot the current command caller
        name_from_db = user_r.get_user_by_id(ctx.author.id).name
        # remove diacritics from the user-supplied name
        name_from_user_without_diacritics = remove_accents(f"{surname} {name}")

        if ctx.guild:
            await ctx.message.delete()

        if name_from_db != name_from_user_without_diacritics:
            await ctx.send(Messages.absolvent_wrong_name)
            return

        # CHECK OWNERSHIP, TYPE AND YEAR OF THE QUALIFICATION WORK / THESIS

        thesis_url = f"https://dspace.vutbr.cz/handle/11012/{thesis_web_id}?locale-attribute=cs"

        # download the page
        result_thesis = requests.get(thesis_url)
        # parse it using lxml
        xDoc_thesis = etree.fromstring(result_thesis.text, htmlparser)
        not_found = "".join(
            xDoc_thesis.xpath('//*[@id="main-container"]//h2/text()')
        )
        master_thesis = "".join(
            xDoc_thesis.xpath(
               "/html/body/div[1]/div/div/div/ul[contains(@class,'breadcrumb')]/li[3]/a[.='diplomové práce']/text()"
            )
        )
        bachelor_thesis = "".join(
            xDoc_thesis.xpath(
               "/html/body/div[1]/div/div/div/ul[contains(@class,'breadcrumb')]/li[3]/a[.='bakalářské práce']/text()"
            )
        )
        thesis_author_without_degree_surname_first = "".join(
            xDoc_thesis.xpath(
                '//*[@id="aspect_artifactbrowser_ItemViewer_div_item-view"]/div/div[2]/div[1]/div[./h5/b="Autor"]/div/a/text()'
            )
        )
        habilitation_date = "".join(
            xDoc_thesis.xpath(
                '//*[@id="aspect_artifactbrowser_ItemViewer_div_item-view"]/div/div[2]/div[2]/div[./h5="Termín obhajoby"]/span/text()'
            )
        )
        result = "".join(
            xDoc_thesis.xpath(
                '//*[@id="aspect_artifactbrowser_ItemViewer_div_item-view"]/div/div[2]/div[2]/div[./h5="Výsledek obhajoby"]/span/text()'
            )
        )
        faculty = "".join(
            xDoc_thesis.xpath(
               "/html/body/div[1]/div/div/div/ul[contains(@class,'breadcrumb')]/li[4]/a[.='Fakulta informačních technologií']/text()"
            )
        )
        
        #await ctx.send(f"""
        #DEBUG:
        #nf: {not_found}
        #mt: {master_thesis}
        #bt: {bachelor_thesis}
        #ta: {thesis_author_without_degree_surname_first}
        #hd: {habilitation_date}
        #re: {result}
        #fa: {faculty}
        #""")

        if "Page cannot be found" in not_found:
            await ctx.send(Messages.absolvent_thesis_not_found_error)
            return

        habilitation_year = re.search(r"(\d+)-\d+-\d+", habilitation_date).group(1)

        if not (
            ((degree == "Ing." and master_thesis != "") or (degree == "Bc." and bachelor_thesis != ""))
            and diploma_year == habilitation_year
            and faculty != ""
            and result == "práce byla úspěšně obhájena"
            and thesis_author_without_degree_surname_first == full_name_without_degree_surname_first
        ):
            await ctx.send(Messages.absolvent_web_error)
            return
        
        # DIPLOMA VALIDITY CHECK

        diplom_url1 = "https://www.vutbr.cz/overeni-diplomu"
        diplom_url2 = "https://www.vutbr.cz/overeni-diplomu?aid_redir=1"
        diplom_url3 = "https://www.vutbr.cz/overeni-diplomu"
        data = {}
        session = requests.session()

        # load initial cookies + download the HTML-security codes in hidden input fields
        session.get(diplom_url1)
        result2 = session.get(diplom_url2)
        # parse it using lxml
        xDoc2 = etree.fromstring(result2.text, htmlparser)
        # get all hidden server-generated inputs
        inputs = xDoc2.xpath("//*[@id='over_studenta']/input[@type='hidden']")
        for input in inputs:
            data[input.attrib["name"]] = input.attrib["value"]

        # add user-supplied values
        data["data[form_el_cislo]"] = diploma_number
        data["data[form_el_jmeno]"] = name
        data["data[form_el_prijmeni]"] = surname
        data["data[form_el_overit]"] = "Ověřit"

        # send the POST to check the diploma validity
        result3 = session.post(diplom_url3, data)
        xDoc3 = etree.fromstring(result3.text, htmlparser)
        # parse the success text (in czech)
        absolventText = "".join(
            xDoc3.xpath(
                "//*[@id='main']/div[contains(@class,'alert-success')]/div[@class='alert-text']/div//text()"
            )
        )
        if not (
            absolventText != ""
            and "úspěšně ověřen" in absolventText
            and absolventText.endswith(", Fakulta informačních technologií")
        ):
            await ctx.send(Messages.absolvent_diploma_error)
            return

        guild = self.bot.get_guild(Config.guild_id)
        role = None
        if degree == "Bc.":
            role = discord.utils.get(guild.roles, id=Config.bc_role_id)
        if degree == "Ing.":
            role = discord.utils.get(guild.roles, id=Config.ing_role_id)
        if role:
            member = guild.get_member(ctx.author.id)
            for drop_role in member.roles:
                if "Dropout" in drop_role.name:
                    await member.remove_roles(drop_role, reason="Diploma verification")
            await member.add_roles(role)
            await ctx.send(Messages.absolvent_success)

    @diplom.error
    async def diplom_error(self, ctx, error):
        await ctx.send(utils.fill_message("absolvent_help", command=ctx.invoked_with))
예제 #7
0
파일: roles.py 프로젝트: solumath/rubbergod
 async def clone(self, ctx, src: Union[discord.TextChannel,
                                       discord.VoiceChannel], name):
     """Clone channel with same permissions as src."""
     new = await src.clone(name=name)
     await ctx.send(utils.fill_message("channel_clone_done", id=new.id))
예제 #8
0
 async def leaderboard_error(self, ctx, error):
     if isinstance(error, commands.BadArgument):
         await ctx.send(
             utils.fill_message("karma_lederboard_offser_error",
                                user=ctx.author.id))
예제 #9
0
 async def review_error(self, ctx, error):
     if isinstance(error, commands.BadArgument):
         await ctx.send(messages.review_add_format)
     if isinstance(error, commands.CheckFailure):
         await ctx.send(
             utils.fill_message("insufficient_rights", user=ctx.author.id))
예제 #10
0
    async def send_code(self, message):
        if len(str(message.content).split(" ")) != 2:
            await message.channel.send(Messages.verify_send_format)
            return

        # Check if the user doesn't have the verify role
        if not await self.has_role(message.author, Config.verification_role):
            login = str(message.content).split(" ")[1]

            # Some of them will use 'xlogin00' as stated in help,
            # cuz they dumb
            if login == "xlogin00":
                guild = self.bot.get_guild(Config.guild_id)
                fp = await guild.fetch_emoji(585915845146968093)
                await message.channel.send(
                    utils.fill_message("verify_send_dumbshit",
                                       user=message.author.id,
                                       emote=str(fp)))
                return
            if login[0] == 'x':
                # VUT
                # Check if the login we got is in the database
                if self.repo.has_unverified_login(login):
                    await self.gen_code_and_send_mail(message, login,
                                                      "@stud.fit.vutbr.cz")
                else:
                    await message.channel.send(
                        utils.fill_message("verify_send_not_found",
                                           user=message.author.id,
                                           admin=Config.admin_id))

                    embed = discord.Embed(title="Neuspesny pokus o verify",
                                          color=0xeee657)
                    embed.add_field(name="User",
                                    value=utils.generate_mention(
                                        message.author.id))
                    embed.add_field(name="Message",
                                    value=message.content,
                                    inline=False)
                    channel = self.bot.get_channel(Config.log_channel)
                    await channel.send(embed=embed)
            else:
                # MUNI
                try:
                    int(login)
                except ValueError:
                    await message.channel.send(
                        utils.fill_message("verify_send_not_found",
                                           user=message.author.id,
                                           admin=Config.admin_id))

                    embed = discord.Embed(title="Neuspesny pokus o verify",
                                          color=0xeee657)
                    embed.add_field(name="User",
                                    value=utils.generate_mention(
                                        message.author.id))
                    embed.add_field(name="Message",
                                    value=message.content,
                                    inline=False)
                    channel = self.bot.get_channel(Config.log_channel)
                    await channel.send(embed=embed)
                    try:
                        await message.delete()
                        return
                    except discord.errors.Forbidden:
                        return
                if self.repo.get_user(login, status=2) is None and\
                   self.repo.get_user(login, status=0) is None:

                    if self.repo.get_user(login, status=1) is None:
                        self.repo.add_user(login, "MUNI", status=1)

                    await self.gen_code_and_send_mail(message, login,
                                                      "@mail.muni.cz")
                else:
                    await message.channel.send(
                        utils.fill_message("verify_send_not_found",
                                           user=message.author.id,
                                           admin=Config.admin_id))

                    embed = discord.Embed(title="Neuspesny pokus o verify",
                                          color=0xeee657)
                    embed.add_field(name="User",
                                    value=utils.generate_mention(
                                        message.author.id))
                    embed.add_field(name="Message",
                                    value=message.content,
                                    inline=False)
                    channel = self.bot.get_channel(Config.log_channel)
                    await channel.send(embed=embed)
        else:
            await message.channel.send(
                utils.fill_message("verify_already_verified",
                                   user=message.author.id,
                                   admin=Config.admin_id))
        try:
            await message.delete()
        except discord.errors.Forbidden:
            return
예제 #11
0
    async def verify(self, message):
        """"Verify if VUT login is from database"""
        if len(str(message.content).split(" ")) != 3:
            await message.channel.send(Messages.verify_verify_format)
            return

        login = str(message.content).split(" ")[1]
        code = str(message.content).split(" ")[2]

        # Check if the user doesn't have the verify role
        # otherwise they wouldn't need to verify, right?
        if not await self.has_role(message.author, Config.verification_role):
            # Some of them will use 'xlogin00' as stated in help
            # yet again, cuz they dumb
            if login == "xlogin00":
                guild = self.bot.get_guild(Config.guild_id)
                fp = await guild.fetch_emoji(585915845146968093)
                await message.channel.send(
                    utils.fill_message("verify_send_dumbshit",
                                       user=message.author.id,
                                       emote=str(fp)))
                return
            # Same here
            if code == "kód" or code == "[kód]":
                guild = self.bot.get_guild(Config.guild_id)
                fp = await guild.fetch_emoji(585915845146968093)
                await message.channel.send(
                    utils.fill_message("verify_verify_dumbshit",
                                       user=message.author.id,
                                       emote=str(fp)))
                return

            new_user = self.repo.get_user(login)

            if new_user is not None:
                # Check the code
                if code != new_user.code:
                    await message.channel.send(
                        utils.fill_message("verify_verify_wrong_code",
                                           user=message.author.id))
                    embed = discord.Embed(
                        title="Neuspesny pokus o verify(kod)", color=0xeee657)
                    embed.add_field(name="User",
                                    value=utils.generate_mention(
                                        message.author.id))
                    embed.add_field(name="Message",
                                    value=message.content,
                                    inline=False)
                    channel = self.bot.get_channel(Config.log_channel)
                    await channel.send(embed=embed)
                    return

                # Try and transform the year into the role name
                year = self.transform_year(new_user.year)

                if year is None:
                    await message.channel.send(
                        utils.fill_message("verify_verify_manual",
                                           user=message.author.id,
                                           admin=Config.admin_id,
                                           year=str(new_user.year)))

                    embed = discord.Embed(
                        title="Neuspesny pokus o verify(manual)",
                        color=0xeee657)
                    embed.add_field(name="User",
                                    value=utils.generate_mention(
                                        message.author.id))
                    embed.add_field(name="Message",
                                    value=message.content,
                                    inline=False)
                    channel = self.bot.get_channel(Config.log_channel)
                    await channel.send(embed=embed)
                    return

                try:
                    # Get server verify role
                    verify = discord.utils.get(message.guild.roles,
                                               name=Config.verification_role)
                    year = discord.utils.get(message.guild.roles, name=year)
                    member = message.author
                except AttributeError:
                    # jsme v PM
                    guild = self.bot.get_guild(Config.guild_id)
                    verify = discord.utils.get(guild.roles,
                                               name=Config.verification_role)
                    year = discord.utils.get(guild.roles, name=year)
                    member = guild.get_member(message.author.id)

                await member.add_roles(verify)
                await member.add_roles(year)

                self.repo.save_verified(login, message.author.id)

                await member.send(
                    utils.fill_message("verify_verify_success",
                                       user=message.author.id))

                await member.send(Messages.verify_post_verify_info)

                if message.channel.type is not discord.ChannelType.private:
                    await message.channel.send(
                        utils.fill_message("verify_verify_success",
                                           user=message.author.id))
            else:
                await message.channel.send(
                    utils.fill_message("verify_verify_not_found",
                                       user=message.author.id,
                                       admin=Config.admin_id))

                embed = discord.Embed(title="Neuspesny pokus o verify",
                                      color=0xeee657)
                embed.add_field(name="User",
                                value=utils.generate_mention(
                                    message.author.id))
                embed.add_field(name="Message",
                                value=message.content,
                                inline=False)
                channel = self.bot.get_channel(Config.log_channel)
                await channel.send(embed=embed)
        else:
            await message.channel.send(
                utils.fill_message("verify_already_verified",
                                   user=message.author.id,
                                   admin=Config.admin_id))

        try:
            await message.delete()
        except discord.errors.Forbidden:
            return
예제 #12
0
    async def __repost_message(self, ctx: ReactionContext,
                               reactions: List[disnake.Reaction]):
        if self.repost_channel is None and config.meme_repost_room != 0:
            self.repost_channel = await self.bot.fetch_channel(
                config.meme_repost_room)

        # Invalid ID
        if self.repost_channel is None:
            return

        async with self.repost_lock:
            if self.repost_repo.find_repost_by_original_message_id(
                    ctx.message.id) is not None:
                return

            # Generate string with all reactions on post at the time
            title_string = ""
            for reaction in reactions:
                if not isinstance(reaction.emoji, str):
                    # Remove all emoji reactions that are not from current server
                    if disnake.utils.get(ctx.guild.emojis,
                                         id=reaction.emoji.id) is None:
                        continue

                tmp_string = title_string + f"{reaction.count}x{reaction.emoji} "

                if len(tmp_string) >= 255:
                    break

                title_string = tmp_string

            embed = disnake.Embed(color=disnake.Color.dark_blue(),
                                  title=title_string)
            utils.add_author_footer(embed, author=ctx.message.author)
            embed.timestamp = ctx.message.created_at

            # Create link to original post
            link = utils.fill_message(
                "meme_repost_link",
                original_message_url=ctx.message.jump_url,
                original_channel=config.meme_room)
            embed.add_field(name="Link", value=link, inline=False)

            # Get all attachments of original post
            main_image = None
            other_attachments = []
            for attachment in ctx.message.attachments:
                content_type = attachment.content_type
                if content_type is not None and content_type.split(
                        "/")[0] == "image" and main_image is None:
                    # Set main image if its image and main image is not set
                    main_image = await attachment.to_file()
                else:
                    # Other attachments convert to file and append to list of attachments
                    attachment_file = await attachment.to_file()
                    if attachment_file is not None:
                        other_attachments.append(attachment_file)

            # Set content from original message if present
            if ctx.message.content:
                content_splits = ctx.message.content.split(" ")
                for content_split in content_splits:
                    if content_split.startswith("https://"):
                        # Its attachement URL
                        for extension in config.meme_repost_image_extensions:
                            # Check for extension in URL
                            if f".{extension}" in content_split:
                                if main_image is None:
                                    main_image = content_split
                                else:
                                    other_attachments.append(content_split)
                                break
                        else:
                            other_attachments.append(content_split)

                content = ctx.message.content[:900]
                embed.add_field(name="Obsah", value=content)

            # Set main image if present
            if main_image is not None:
                if isinstance(main_image, disnake.File):
                    embed.set_image(url=f"attachment://{main_image.filename}")
                elif isinstance(main_image, str):
                    embed.set_image(url=main_image)
                    main_image = None
                else:
                    main_image = None

            repost_message_id = -1
            secondary_message_id = None
            if len(embed) < 6000:
                repost_message = await self.repost_channel.send(
                    embed=embed, file=main_image)
                repost_message_id = repost_message.id

                if len(other_attachments) > 0:
                    # Files are getting send as files
                    files = [
                        file for file in other_attachments
                        if isinstance(file, disnake.File)
                    ]
                    files = files[:10] if files else None

                    # And urls as string in separated message
                    urls = [
                        file for file in other_attachments
                        if isinstance(file, str)
                    ]
                    urls = "\n".join(urls) if urls else None

                    secondary_message = await self.repost_channel.send(
                        urls, files=files)
                    secondary_message_id = secondary_message.id

            self.repost_repo.create_repost(ctx.message.id, repost_message_id,
                                           ctx.member.id, secondary_message_id)
예제 #13
0
 async def reviews(self,
                   ctx,
                   subcommand=None,
                   subject=None,
                   tier: int = None,
                   *args):
     if subcommand is None:
         await ctx.send(messages.review_format)
     else:
         if isinstance(ctx.message.channel, discord.DMChannel):
             guild = self.bot.get_guild(config.guild_id)
             roles = guild.get_member(ctx.message.author.id).roles
         else:
             roles = ctx.message.author.roles
         if subcommand == 'add':
             for role in roles:
                 if role.name in config.reviews_forbidden_roles:
                     await ctx.send(
                         utils.fill_message("review_add_denied",
                                            user=ctx.message.author.id))
                     return
             if subject is None or tier is None:
                 await ctx.send(messages.review_add_format)
                 return
             author = ctx.message.author.id
             anonym = False
             if tier < 0 or tier > 4:
                 await ctx.send(messages.review_tier)
                 return
             if args:
                 if args[0] == "anonym":
                     anonym = True
                     args = args[1:]
                 args = ' '.join(args)
             args_len = len(args)
             if args_len == 0:
                 args = None
             try:
                 self.rev.add_review(author, subject.lower(), tier, anonym,
                                     args)
             except Exception:
                 await ctx.send(messages.review_wrong_subject)
                 return
             await ctx.send(messages.review_added)
         elif subcommand == 'remove':
             if subject is None:
                 if ctx.author.id == config.admin_id:
                     await ctx.send(messages.review_remove_format_admin)
                 else:
                     await ctx.send(messages.review_remove_format)
             elif subject == 'id':
                 if ctx.author.id == config.admin_id:
                     if tier is None:
                         await ctx.send(messages.review_remove_id_format)
                     else:
                         review_repo.remove(tier)  # tier => ID of review
                         await ctx.send(messages.review_remove_success)
                 else:
                     await ctx.send(
                         utils.fill_message("insufficient_rights",
                                            user=ctx.author.id))
             else:
                 subject = subject.lower()
                 if self.rev.remove(str(ctx.message.author.id), subject):
                     await ctx.send(messages.review_remove_success)
                 else:
                     await ctx.send(messages.review_remove_error)
         else:
             subject = subcommand
             embed = self.rev.list_reviews(subject.lower())
             if not embed:
                 await ctx.send(messages.review_wrong_subject)
                 return
             msg = await ctx.send(embed=embed)
             footer = msg.embeds[0].footer.text.split('|')[0]
             if msg.embeds[0].description[-1].isnumeric():
                 if footer != "Review: 1/1 ":
                     await msg.add_reaction("⏪")
                     await msg.add_reaction("◀")
                     await msg.add_reaction("▶")
                 await msg.add_reaction("👍")
                 await msg.add_reaction("🛑")
                 await msg.add_reaction("👎")
                 if msg.embeds[0].fields[3].name == "Text page":
                     await msg.add_reaction("🔼")
                     await msg.add_reaction("🔽")