Code Dump: Recruit

  • 0 Replies
  • 35 Views

0 Members and 1 Guest are viewing this topic.

Luca

  • *
  • Arch-Administrator
  • Tea Dragon
  • *****
  • Posts: 679
  • Karma: +47/-0
  • SMF Practitioner
« on: July 16, 2021, 06:49:03 pm »
Hello,

I don't use the "GitHub" for a variety of largely political reasons, but I thought it would be a fun exercise to release some source code  :smile:

CalRef has a long history of having open-source public infrastructure projects, I'm just rather shit at coding and don't often have much to contribute on the topic. Can't promise the methods or organisation will be great because I'm sorta making things up as I go, but at least it works. I'll post here whenever there is interest in me doing so, or it becomes otherwise prudent. If there's something you want to see posted here, send me a PM/DM.

To start, here's Dot's NationStates manual recruitment function, as seen here.


     I wrote most of this at 1-3am at the time, so don't get your hopes up.
     Imports: os, asyncio, requests, ElementTree, numpy, discord

Recruit


Added to Dot: Mar 4 2021
Puppet Filter Added: Mar 28 2021
Public Feature Release: Jul 10 2021

Code released is free to use, with proper attribution to Luca McGrath, or Refuge Isle on NationStates.

#RECRUIT

@bot.command(name="recruit", aliases=["r"])
@commands.cooldown(1, 10, BucketType.guild)
async def recruit(ctx):
    server = ctx.guild.id
    txt = ctx.message.content.lower()
    lucabaduka = "https://calref.network/post/lucabaduka.png"
    selfdot = ctx.guild.get_member(773675626771120139)
    recruiter = ctx.message.author.id

    if not os.path.isdir(f"servers/{server}"):
        server_dir = f"servers/{server}"
        os.mkdir(server_dir)
    if not os.path.isdir(f"servers/{server}/recruit"):
        server_dir = f"servers/{server}/recruit"
        os.mkdir(server_dir)
    if not os.path.isfile(f"servers/{server}/recruit/recruiter.txt"):
        embed=discord.Embed(
        description="You need to designate a recruiter role before you can recruit. Use **I cast set recruit X**, where X is either you pinging the role you want to designate, or that role's ID.",
        color=0xf31a71)
        await ctx.send(embed=embed)
        return
    else:
        with open(f"servers/{server}/recruit/recruiter.txt", "r") as f:
            rec = int(f.read())
            f.close()
        try:
            rec_role = get(ctx.guild.roles, id=rec)
        except:
            embed=discord.Embed(
            description="The role that's been selected for recruiters appears to be invalid or no longer exists. Try setting that recruiter role again to see if we can freshen it up.",
            color=0xf31a71)
            await ctx.send(embed=embed)
            return
        if rec_role in ctx.author.roles:

            # Recruiter template settings
            if "i cast recruit set" in txt:
                text = ctx.message.content.partition("recruit set ")
                template = text[2]
                async with ctx.channel.typing():
                    await asyncio.sleep(1)
                if template.startswith("%TEMPLATE-"): 
                    with open("servers/{}/recruit/{}.txt".format(server, recruiter), "w") as f:
                        f.write(template)
                        f.close()
                    await ctx.send("Okay, I've got your template set.")
                else:
                    await ctx.send("This does not appear to be a valid recruitment template. Make sure that you have something that looks like **%TEMPLATE-538543943%**")

            # Lazy mode
            elif "i cast recruit timer" in txt or "i cast r t" in txt:
                pingu = ctx.message.author.mention
                async with ctx.channel.typing():
                    await ctx.send("Counting. . .")
                    await asyncio.sleep(45)
                    await ctx.send("Ready to send, {}!".format(pingu))
           
            # Actually recruiting now
            else:
                # Check if recruit has been used before and make a comparison file
                if os.path.isfile("servers/{}/recruit/rec.xml".format(server)):
                    root = et.parse('servers/{}/recruit/rec.xml'.format(server)).getroot()
                    for node in root:
                        oldnations = root.find('NEWNATIONS').text
                    lastnations = oldnations.split(",")

                    if not os.path.isfile("servers/{}/recruit/oldNations.txt".format(server)):
                        with open("servers/{}/recruit/oldNations.txt".format(server), "w") as f:
                            f.write(oldnations)
                            f.close()

                # API Request
                url = "https://www.nationstates.net/cgi-bin/api.cgi?q=newnations"
                r = requests.get(url, headers = {'User-Agent': 'Your User-Agent Here'})
                with open("servers/{}/recruit/rec.xml".format(server), "wb") as f:
                    f.write(r.content)
                    f.close()

                # Load the old nations, if there are any
                if os.path.isfile("servers/{}/recruit/oldNations.txt".format(server)):
                    with open("servers/{}/recruit//oldNations.txt".format(server), "r") as f:
                        lastnations = f.read()
                        lastnations = lastnations.split(",")
                        f.close()
                else:
                    lastnations = []

                # Read the new file from the API
                root = et.parse('servers/{}/recruit/rec.xml'.format(server)).getroot()
                for node in root:
                    nations = root.find('NEWNATIONS').text
                nations = nations.split(",")

                # Filter the API data from the local storage to find what's different
                newnations = np.setdiff1d(nations,lastnations)
                if newnations == []:
                    prep = nations
                else:
                    prep = newnations
                bees = ""
                for x in newnations:
                    bees += x + ","
                newnations = bees
             
                # Save the new nations to local data and break responses into groups of eight
                prepared = ""
                count = 0
                prep = prep.tolist()

                # Puppet filter
                if len(prep) > 0:
                    numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
                    vanquish = []
                    for x in prep:
                        for y in numbers:
                            if y in x:
                                if not prep.index(x) in vanquish:
                                    vanquish.append(prep.index(x))
               
                    vanquish.reverse()
                    for x in vanquish:
                        prep.pop(x)

                for i in prep:
                    if count < 9:
                        prepared += (str(i) + ",")
                        count += 1
                    if count == 8:
                        prepared += "\n"
                        count = 0

                with open("servers/{}/recruit/newNations.txt".format(server), "w") as f:
                    f.write(prepared)
                    f.close()

                if newnations is not "":
                    with open("servers/{}/recruit/oldNations.txt".format(server), "a") as f:
                        f.write(newnations)
                        f.close()

                # Fetch the author's recruitment template from storage (if there is one)
                if os.path.isfile("servers/{}/recruit/{}.txt".format(server, recruiter)):
                    with open("servers/{}/recruit/{}.txt".format(server, recruiter), "r") as f:
                        template = f.read()
                        template = template.replace("%", "%25")
                        f.close()
                        footerText = "New nation batches since you last checked."
                        authorText = "Personalised recruitment for {}".format(ctx.author.display_name)
                else:
                    template = ""
                    footerText = "Did you know? \nYou can auto-fill your telegrams with your personal recruitment template with 'I cast recruit set'"
                    authorText = "Generic recruitment for {}".format(ctx.author.display_name)

                # Report the new nations and prep their links
                counter = 0
                lines = open("servers/{}/recruit/newNations.txt".format(server), "r").read().splitlines()
                rready = ">>> "
                for line in lines:
                    counter += 1
                    rready += "• [Batch {}](https://www.nationstates.net/page=compose_telegram?tgto={}&message={})".format(counter, line, template) + "\n\n"
               
                if newnations == "":
                    rready = "Hooray! No new nations detected since the last time you checked."
                    icon = "https://calref.network/post/HappyPanda.png"
                else:
                    icon = ctx.guild.icon_url_as(format="png")
               
                # Send the channel response
                async with ctx.channel.typing():
                    await asyncio.sleep(1)
                embed=discord.Embed(
                title="Dot Recruitment for {}".format(ctx.guild.name),
                description="{}".format(rready),
                color=0x0099FF)
                embed.set_author(name="{}".format(authorText), icon_url="{}".format(ctx.author.avatar_url))
                embed.set_thumbnail(url="{}".format(icon))
                embed.set_footer(text="{}".format(footerText), icon_url = selfdot.avatar_url)
                await ctx.send(embed=embed)
        else:
            embed=discord.Embed(
            description="Alas, you do not appear to have the recruiter role for this server. \nOmw to report you to the recruitment police <:RecruitmentPolice:860715280324755506>",
            color=0xf31a71)
            await ctx.send(embed=embed)

From Nightly

        async for guild in bot.fetch_guilds():

            # Wipe the old recruitment data daily.
            server = guild.id
            if not os.path.isdir("servers/{}".format(server)):
                server_dir = "servers/{}".format(server)
                os.mkdir(server_dir)
            if not os.path.isdir("servers/{}/recruit".format(server)):
                rec_dir = "servers/{}/recruit".format(server)
                os.mkdir(rec_dir)
            with open("servers/{}/recruit/oldNations.txt".format(server), "w") as f:
                f.close()

« Last Edit: July 18, 2021, 10:58:59 am by Luca »

 

Page created in 0.064 seconds with 20 queries.