Ejemplo n.º 1
0
* 28 June 2015:  **Promotion to Lieutenant Commander** for PotW 
* 21 May 2015: **Contribution towards Lieutenant Commander** for DELPHI entry
* 26 April 2015: **Promoted to Lieutenant** for PotW win 
* 29 March 2015: **Promoted to Lieutenant j.g.** for PotW win 
* 4 January 2015: **Promoted to Ensign** for PotW win 

## Section that ought to be ignored.

powt 
* Post of the week for blub
""",(7, 2, 9)],
[
"""

""", None],
["""
#### Service Record
* 11 September 2016: **Post of the Week** 


* 28 December 2014: **Promoted to Lieutenant j.g.** for Post of the Week 

* 11 March 2013: **Commissioned at Ensign.**

* Post of the week for this invalid line of a continued service record after a commmission.
""", None]
]

for testcase in testcases:
    ret = RankUtils.analyzeServiceRecord(testcase[0].split("\n"))
    print("Got \"{}\", expected \"{}\"".format(ret, testcase[1]))
Ejemplo n.º 2
0
    def step2(self, state, input, subreddit):
        """Post of the Week Step 2 - Calculate Promotions"""

        if len(input) < 1 or len(input) > 2:
            state["error"] = "Your comment has a line number other than two or one. Please keep to the aforementioned syntax."
            return state

        if not input[0].lower().startswith("potw "):
            state["error"] = "Your comments first line must start with 'POTW '"
            return state

        potwIndices = input[0][len("POTW "):].split(" ")
        ecIndices = []
        if len(input) == 2:
            if not input[1].lower().startswith("ec "):
                state["error"] = "Your comments second line must start with 'EC '"
                return state
            ecIndices = input[1][len("EC "):].split(" ")

        # important: user-facing indices are in [1,n+1], move them back to [0,n], also convert them to numbers
        try:
            potwIndices = [int(x)-1 for x in potwIndices]
            ecIndices = [int(x)-1 for x in ecIndices]
            # remove duplicates
            potwIndices = list(set(potwIndices))
            ecIndices = list(set(ecIndices))

            if any([x < 0 or x >= len(state["voteEntries"]) for x in potwIndices]):
                raise ValueError("")
            if any([x < 0 or x >= len(state["voteEntries"]) for x in ecIndices]):
                raise ValueError("")
        except:
            return {"error": "Some of the indices you provided were not numbers, or not within the required range."}

        if len(set(ecIndices) ^ set(potwIndices)) != len(ecIndices) + len(potwIndices):
            return {"error": "No post can win BOTH Exemplary Contribution and Post of the Week."}

        # Assemble the winners and candidates for the CPO position
        cpoCandidates = [] # list of (user, current_flair_css)
        winnersInfo = []
        for idx,voteEntry in enumerate(state["voteEntries"]):
            # Do not check for winning-state in a misguided attempt at optimization here, need to go through it all to be 
            #  able to see if anyone's rank entitles them to a CPO promotion.
            winnerInfo = RedditUtils.findFirstLinkedObject(voteEntry.body, subreddit, self.r)
            if winnerInfo is None:
                state["error"] = "Couldn't find the thread/comment referenced by the vote entry {}\n\n".format(idx)
                return state
            linkText, linkURL, contributionObject = winnerInfo

            # get the user from the vote comment
            match = re.search(r'\/u\/(.*?)\s', voteEntry.body, re.IGNORECASE)
            if match is None:
                state["error"] = "Couldn't find the username from the vote comment for '{}'\n\n".format(voteEntry.body)
                return state

            # ensure that they are both the same
            username = match.group(1).strip()
            if contributionObject.author is None or username.lower() != contributionObject.author.name.lower():
                state["error"] = ("Username in the voting thread doesn't match the username of the nominated object."
                                  + " Username: {}, Nominated Object: {}").format(username, idx)
                return state

            winnerUser = contributionObject.author
            # returns dict {"flair_css_class":?, "flair_text":?, "user":?}
            winnerFlair = self.r.get_flair(subreddit, winnerUser)
            winnerCurrentRank = RankUtils.getRankLevelFromFlair(winnerFlair["flair_css_class"])

            # cpo possible at all?
            if winnerCurrentRank in RankUtils.cpoStepRanks:
                cpoCandidates.append((winnerUser, winnerFlair["flair_css_class"] if winnerFlair["flair_css_class"] is not None else ""))
                logging.info("CPO Candidate: " + winnerUser.name)

            if not idx in potwIndices+ecIndices:
                continue

            logging.info("{} - {} - {}".format(winnerUser.name,
                                               winnerCurrentRank, RankUtils.rankLevels[winnerCurrentRank]["name"]))
            winnersInfo.append({"user": winnerUser, "currentRank": winnerCurrentRank, "promotionKind": "potw" if idx in potwIndices else "ec",
                                "comment": voteEntry, "text": winnerInfo[0]})

        notes = ""
        message = ""
        finalWinnerInfo = []
        # now that we have all the winners, lets see who gets promoted to what
        for wi in winnersInfo:
            # calculate the promotion of that person, to that end get his service
            # record
            username = wi["user"].name
            careerPotW = 0
            careerDelphi = 0
            total = 0
            serviceRecord = self.r.get_wiki_page(subreddit, username)

            # check if the record exists. This combersome way currently seems to be
            # the only working one
            pageExists = False
            try:
                serviceRecord.content_md
                pageExists = True
            except:
                pageExists = False

            temporaryNoPromotion = False

            if serviceRecord is None or pageExists is False:
                if wi["currentRank"] >= RankUtils.serviceRecordThresholdRank:  # Ensign ought to have a page ...
                    notes += "* Person /u/{} ought to have a service record, but hasn't gotten one. Setting them to not promoted temporarily, **please review and, if applicable, change this**.\n".format(username)
                    temporaryNoPromotion = True
            else:
                # split into lines
                lines = serviceRecord.content_md.split("\n")
                ret = RankUtils.analyzeServiceRecord(lines)
                if ret is None:
                    notes += "* Couldn't read the [service record](https://reddit.com/r/DaystromInstitute/wiki/{}) of user /u/{}. Setting them to not promoted temporarily, **please review and, if applicable, change this**.\n".format(username, username)
                    temporaryNoPromotion = True
                else:
                    careerPotW, careerDelphi, total = ret
                    logging.info("Analyzed the service record of /u/{}. They have {} PotW, {} DELPHI totalling {}".format(username, careerPotW, careerDelphi, total))
           

            # check the next promotion
            total += 1  # if they were promoted
            careerPotW += 1
            resDict = {"serviceRecord": serviceRecord, "user": wi["user"], "currentRank": RankUtils.rankLevels[wi["currentRank"]], "promotionKind": wi["promotionKind"],
                       "comment": wi["comment"], "text": wi["text"]}
            res = None
            newRank = wi["currentRank"]
            if temporaryNoPromotion:
                res = (False, "")
            elif wi["currentRank"] < 3:
                # crewman, cpo and citizen get autopromoted to ensign on PotW
                res = (True, "")
                newRank = RankUtils.stepFinishRank  # ensign
            elif wi["currentRank"] < len(RankUtils.rankLevels) - 1:
                nextRank = RankUtils.rankLevels[wi["currentRank"] + 1]
                res = nextRank["advanceFunction"](total, careerPotW, careerDelphi)
                newRank = newRank + 1
            else:
                res = (False, "")
            resDict["willBePromoted"] = res[0]
            resDict["promoteAftermessage"] = res[1]
            resDict["promoteTo"] = RankUtils.rankLevels[newRank]
            finalWinnerInfo.append(resDict)

        # format this for the message
        message += "\n\n"
        message += formatFinalWinnerInfo(finalWinnerInfo)
        message += "\nPlease note: \n\n"
        message += notes
        message += "\n" + InfoMessages.step2

        self.messageHandler.dispatchOutput(message)
        # put it into the state
        state["finalWinnerInfo"] = finalWinnerInfo
        state["cpoCandidates"] = cpoCandidates
        state["reminders"].append(notes)
        return state