def calc_event_stats(self): info = {"all": {"Approved": 0, "Denied": 0, "Submitted": 0}} total = dict() lists = dict() vs = dict() for id, board in self.config.boards.items(): info[id] = {"Approved": 0, "Denied": 0, "Submitted": 0} lists[id] = dict() for l in board["lists"]: lists[id][l] = 0 total[board["name"]] = 0 for id in self.participants.keys(): info[id] = {"Approved": 0, "Denied": 0, "Submitted": 0} vs[id] = 0 for report in self.reported_cards.values(): info["all"][report["status"]] += 1 info[report["board"]][report["status"]] += 1 info[report["author_id"]][report["status"]] += 1 total[self.config.boards[report["board"]]["name"]] += 1 lists[report["board"]][report["list"]] += 1 vs[report["author_id"]] += 1 info["total"] = total #transform lists to use their names rather then IDs info["lists"] = dict() info["vs"] = vs for board_id, content in lists.items(): info["lists"][board_id] = dict() for k, v in content.items(): list_info = TrelloUtils.getListInfo(k) info["lists"][board_id][list_info["name"]] = v return info
def template(self, event, submission = None): """Make a new submission""" if self.status != "Started": return # no event going on, pretend nothing happened #noleeks if event.channel.id != self.config.event_channel: # ignore users running this in the wrong channel, also prevents non hunters from submitting return help_message = "<@{}> It seems you're missing parts, the syntax for this command is `+submit <trello link> | <where this ticket should be moved to> | <why it should be moved there and/or new steps>`".format( event.author.id) if submission is None: # no params given, print help info event.msg.reply(help_message) return parts = submission.split("|") if len(parts) < 3: # missing things we need event.msg.reply(help_message) return if len(parts) > 3: # for some reason they used a | in their report, re-assemble it so we don't void things parts[2] = "|".join(parts[2:]) link = parts[0] destination = parts[1] info = parts[2] # fetch the trello info and validate trello_info = TrelloUtils.getCardInfo(event, link) error = None if trello_info is False: # wrong type of link, user already informed, we're done here return if trello_info is None: # no info, non existant card or from a private board error = "<@{}> Unable to fetch info about that card, are you sure it exists? Cause I don't feel like playing hide and seek.".format( event.author.id) elif trello_info["idBoard"] not in self.config.boards.keys(): # not a discord board error = "This card is not from one of the discord bug boards, what do you expect me to do with this?" elif trello_info['id'] in self.reported_cards.keys(): # already reported report = self.reported_cards[trello_info['id']] # hit by sniper? timediv = datetime.utcnow() - datetime.utcfromtimestamp(report["report_time"]) hours, remainder = divmod(int(timediv.total_seconds()), 3600) minutes, seconds = divmod(remainder, 60) error = "<@{}> Looks like {} beat you to the punch. Better luck next time {}".format(event.author.id, self.participants[str( report[ "author_id"])], "SNIPED!" if minutes < 2 else "<:dupebutton:341981924010491904>") if error is None: # all good so far board = self.config.boards[trello_info["idBoard"]] listname = TrelloUtils.getListInfo(trello_info["idList"])["name"] if trello_info["idList"] not in board["lists"]: # this list is not valid for this event error = "<@{}> This card is in the {} list instead of an event list, thanks for the submission but no thanks.".format( event.author.id, listname) elif trello_info["closed"] is True: # archived card error = "<@{}> _cough cough_ that card has been archived and collected way too much dust for me to do anything with it".format( event.author.id) if error is not None: # card failed one of the checks, inform user and terminate processing event.msg.reply(error) return else: # valid submission, processing... message = """ **Board**: {} {} **Source list**: {} **Destination**: {} **Submitted by**: {} **Detailed info**: {} **Trello link**: {}""".format(board["name"], board["emoji"], listname, destination, str(event.author.id), info, trello_info["shortUrl"]) # sanitze the entire thing, no pinging or breaking codeblocks message = sanitize.S(message, escape_codeblocks=True) if len(message) > 2000: # discord only accepts essays up to 2000 characters event.msg.reply( "<@{}> Sorry, but that report is too long for me to process, would you mind removing {} characters? Then everything should be fine again.".format( event.author.id, len(message) - 2000)) return # send the submission and clean input dmessage = event.msg.reply(message) event.msg.delete() # add to tracking self.reported_cards[trello_info['id']] = dict( author_id=str(event.author.id), board=trello_info["idBoard"], list=trello_info["idList"], message_id=dmessage.id, status="Submitted", report_time=datetime.utcnow().timestamp() ) if not str(event.author.id) in self.participants.keys(): # this person has not submitted anything yet, special message self.participants[str(event.author.id)] = str(event.author) event.msg.reply( "<@{}> Achievement get! Successfully submitted your first event entry :tada:".format(event.author.id)) else: event.msg.reply("<@{}> Thanks for your submission!".format(event.author.id)) log_to_bot_log(self.bot, f":inbox_tray: {event.author} (``{event.author.id}``) has submitted <https://trello.com/c/{trello_info['shortLink']}>") self.save_event_stats()