OqixDevs / OqixTS

Discord BOT intended for FIT@FI server.
MIT License
4 stars 3 forks source link

command /verify #9

Closed xvanick1 closed 2 years ago

xvanick1 commented 2 years ago

In the old version of the bot, there was verify feature to check if the user graduated FIT VUT and is a FI MUNI student atm. We need something similar in this new version. Below are parts of python code, enhancements are welcome.


programme_roles = {
    "Artificial intelligence and data processing": "n-UIZD",
    "Computer systems, communication and security": "n-PSKB",
    "Computer Systems, Communication and Security (eng)": "n-PSKB",
    "Informatics for secondary school teachers": "n-UCI",
    "Software Engineering": "n-SWE",
    "Software systems and services management": "n-RSSS",
    "Software Systems and Services Management (eng)": "n-RSSS",
    "Theoretical computer science": "n-TEI",
    "Visual informatics": "n-VIZ",
    "Computer Science": "d-INF",
    "Computer Science (eng)": "d-INF"
}

async def get_student_info_vut(thesis_id):
    page = requests.get('https://dspace.vutbr.cz/handle/11012/' + thesis_id + '?show=full')
    tree = html.fromstring(page.content)
    author = tree.xpath('//meta[@name="DC.creator"]/@content')[0]
    if len(author) == 0:
        return "Error: Could not retrieve VUT thesis author!"
    name = author.split(',')[1].strip()
    surname = author.split(',')[0].strip()
    return name, surname

async def get_student_info_muni(studies_confirmation_id):
    page = requests.get('https://is.muni.cz/confirmation-of-studies/' + studies_confirmation_id + '?lang=en')
    tree = html.fromstring(page.content)

    elements = tree.xpath("//div[@class='student_info']")
    assert len(elements) == 1
    element = elements[0]
    rows = element.xpath("./div[@class='row']")
    studies_confirmation_data = {}

    for row in rows:
        key = row.xpath("./div/span[@class='nedurazne uc']")[0].text
        value = row.xpath("./div/strong")[0].text

        # if key == 'Name' or key == 'Faculty' or key == 'Programme' or key.startswith('Status of studies as of ') or key.startswith('Confirmation issue date'):
        if key == 'Name' or key == 'Faculty' or key == 'Programme':
            studies_confirmation_data[key] = value

    return studies_confirmation_data

@bot.command()
async def verify(ctx, thesis_id, studies_confirmation_id):

    vut_info = await get_student_info_vut(thesis_id)
    muni_info = await get_student_info_muni(studies_confirmation_id)

    print(f"User {ctx.author} wants to verify with following data: \n\t{vut_info}\n\t{muni_info}")

    if not (vut_info[0] and vut_info[1] in muni_info['Name']):
        print(f'Error: Unable to match VUT and MUNI data for {ctx.author}')
        await ctx.reply('Error: Unable to match VUT and MUNI data. Contact admin.')

    if 'Faculty of Informatics' not in muni_info['Faculty']:
        await ctx.reply('Error: {ctx.author} is not a student of FI.')
        print(f'Error: Unable to match {ctx.author} with FI.')

    for role in ctx.author.roles:
        if role.name in programme_roles.values() or role.name == 'verified':
            try:
                await ctx.author.remove_roles(discord.utils.get(ctx.guild.roles, name=role.name), atomic=True)
            except discord.DiscordException:
                await ctx.reply(f'Error: Unable to remove role {role.name} from user {ctx.author}. Contact admin.')
                print(f'Error: Unable to remove role {role.name} from user {ctx.author}.')

    try:
        await ctx.author.add_roles(discord.utils.get(ctx.guild.roles, name=programme_roles[muni_info['Programme']]),
                                   atomic=True)
        await ctx.author.add_roles(discord.utils.get(ctx.guild.roles, name='verified'), atomic=True)

        await ctx.reply(f"Verified {ctx.author} with role {programme_roles[muni_info['Programme']]}")
        print(f"Verified user {ctx.author} with role {programme_roles[muni_info['Programme']]}.")
    except Exception:
        await ctx.reply(
            f"Error: Unable to add role {programme_roles[muni_info['Programme']]} user {ctx.author}. Contact admin.")
        print(f"Error: Unable to add/remove role {programme_roles[muni_info['Programme']]} to/from user {ctx.author}")

    await ctx.message.delete()
mimotej commented 2 years ago

resolved via #17