def _closevote(self, voteid): """ Called when a vote is to be closed """ vote = Election.get(Election.id == voteid) vclass = VOTE_NAMES[vote.vote_type](self) suffrages = Suffrage.select().where(Suffrage.election == vote) if suffrages.count() < vclass.quorum: self.msg( _("\002#{0}\002: Failed to reach quorum: \002{1}\002 of " "\002{2}\002 required votes.").format( voteid, suffrages.count(), vclass.quorum)) vote.status = 2 # Closed - quorum vote.save() return yeas = 0 nays = 0 for sf in suffrages: if sf.yea: yeas += 1 else: nays += 1 perc = int((yeas / suffrages.count()) * 100) if (perc < 75 and vclass.supermajority) or (perc < 51): self.msg( _("\002#{0}\002: \002{1}\002: \037{2}\037. \002\00300,04The nays have it.\003\002 " "Yeas: \00303{3}\003. Nays: \00304{4}\003. \00304{5}\003% of approval (required at least \002{6}%)" ).format(voteid, vote.vote_type, vote.vote_target, yeas, nays, perc, 75 if vclass.supermajority else 51)) vote.status = 3 # closed - not approved vote.save() return self.msg( _("\002#{0}\002: \002{1}\002: \037{2}\037. \002\00300,03The yeas have it.\003\002 Yeas: \00303{3}\003. Nays: \00304{4}\003. " "\00303{5}\003% of approval (required at least \002{6}%)"). format(voteid, vote.vote_type, vote.vote_target, yeas, nays, perc, 75 if vclass.supermajority else 51)) vote.status = 1 # closed - passed vote.save() vclass.on_pass(vote.vote_target) act = Effective(vote_type=vote.vote_type, close=datetime.utcnow() + timedelta(seconds=vclass.duration), vote_target=vote.vote_target, election=vote) act.save() self.eventloop.schedule_in(vclass.duration, self._expire, act.id)
def vote_info(self, by, voteid): try: elec = Election.get(Election.id == voteid) except Election.DoesNotExist: return self.notice(by, 'Failed: Vote not found') vtype = VOTE_NAMES[elec.vote_type](self) if elec.status == 0: tdel = elec.close - datetime.utcnow() ostr = self._resolve_time(tdel, 'left') else: tdel = datetime.utcnow() - elec.close ostr = self._resolve_time(tdel, 'ago') self.notice( by, "Information on vote #{0}: \002{1}\002 ({2})".format( elec.id, self._resolve_status(elec.status), ostr)) votes = Suffrage.select().where(Suffrage.election == elec) yeacount = 0 yeas = "" naycount = 0 nays = "" for vot in votes: if vot.yea: yeacount += 1 yeas += vot.emitted_by.name + " " else: naycount += 1 nays += vot.emitted_by.name + " " votecount = yeacount + naycount perc = int((yeacount / votecount) * 100) if votecount != 0 else 0 percneeded = 75 if vtype.supermajority else 50 if elec.status == 1: try: eff = Effective.get(Effective.election == elec) tdel = eff.close - datetime.utcnow() ostr = self._resolve_time(tdel, 'left') self.notice(by, " - \002\00303ACTIVE\003\002 {0}".format(ostr)) except Effective.DoesNotExist: self.notice( by, " - \002\00304NOT EFFECTIVE ANYMORE\003\002 (expired)") pass elif elec.status == 0: if votecount < vtype.quorum: self.notice( by, " - \002\00307Needs {0} more votes for quorum\002".format( vtype.quorum - votecount)) else: if perc < percneeded: self.notice( by, " - \002\00304Motion is not passing ({0}% of approval, needs {1}%)\002" .format(perc, percneeded)) else: self.notice( by, " - \002\00303Motion is passing ({0}% of approval, needs {1}%)\002" .format(perc, percneeded)) if yeacount == 0: yeas = " - " if naycount == 0: nays = " - " self.notice( by, " - \002\00303YEA\003\002 - \002{0}\002: {1}".format( yeacount, yeas)) self.notice( by, " - \002\00304NAY\003\002 - \002{0}\002: {1}".format( naycount, nays))
def on_message(self, target, by, message): try: account = self.users[by]['account'] except KeyError: print("{0}: Not identified/not found".format(by)) return if not account: return # Unregistered users don't exist account = account.lower() if target == config.CHANNEL: self.count_line(account) message = message.strip().lower() if not message.startswith('!'): return command = message[1:].split()[0] args = message.split()[1:] if command == 'vote': if not args: return args[0] = args[0].strip('#') if args[0] in list(VOTE_NAMES): # creating a vote! self.start_vote(by, args) elif args[0] == "list" and target == config.CHANNEL: print('list ', by) if by not in self.channels[config.CHANNEL]['modes'].get( 'v', []): if by not in self.channels[config.CHANNEL]['modes'].get( 'o', []): return self.notice( by, 'Failed: You are not enfranchised.') vpar, unk = votelistParser.parse_known_args(args[1:]) if not vpar.type: votes = Election.select().where(Election.status == 0) \ .order_by(Election.id.desc()).limit(5) else: if vpar.type not in list(VOTE_NAMES): return self.notice(by, 'Failed: Unknown vote type') votes = Election.select() \ .where(Election.vote_type == vpar.type) \ .order_by(Election.id.desc()).limit(10) if not votes: return self.notice(by, 'No matching results.') user = User.get(User.name == account) for vote in votes: posit = Suffrage.select() \ .where((Suffrage.election == vote) & (Suffrage.yea == True)).count() negat = Suffrage.select() \ .where((Suffrage.election == vote) & (Suffrage.yea == False)).count() try: yv = Suffrage.get((Suffrage.election == vote) & (Suffrage.emitted_by == user)) if yv.yea: you = '\00300,03YEA\003' else: you = '\00300,04NAY\003' except Suffrage.DoesNotExist: you = '\00300,01---\003' stat = self._resolve_status(vote.status) if vote.status == 0: tdel = vote.close - datetime.utcnow() ostr = self._resolve_time(tdel, _('left')) else: tdel = datetime.utcnow() - vote.close ostr = self._resolve_time(tdel, _('ago')) self.msg( _('\002#{0} YEA: \00303{1}\003 NAY: \00305{2}\003 ' 'YOU: {3} {4} {5}\002 \037{6}\037 - {7}').format( vote.id, posit, negat, you, stat, vote.vote_type, vote.vote_target, ostr)) elif args[0].isdigit() or args[0] in ['y', 'yes', 'n', 'no']: if by not in self.channels[config.CHANNEL]['modes'].get( 'v', []): if by not in self.channels[config.CHANNEL]['modes'].get( 'o', []): return self.notice( by, 'Failed: You are not enfranchised.') user = User.get(User.name == account) if args[0].isdigit(): if len(args) == 1: return self.vote_info(by, args[0]) voteid = args[0] positive = True if args[1] in ['y', 'yes'] else False else: positive = True if args[0] in ['y', 'yes'] else False if len(args) == 1: xe = Election.select().where(Election.status == 1) if xe.count() == 1: voteid = xe.get().id else: return self.notice( by, 'Failed: Usage: !vote y/n ' '<vote id>') else: voteid = args[1].strip('#') if not voteid.isdigit(): self.notice(by, 'Usage: !vote y/n <vote id>') return try: elec = Election.get(Election.id == voteid) except Election.DoesNotExist: return self.notice(by, 'Failed: Vote not found') if elec.status != 0: return self.notice(by, 'Failed: This vote already ' 'ended') return self.vote(elec, user, by, positive, (target != config.CHANNEL))