from __future__ import print_function from mongoengine import * from rtmbot.core import Plugin from datetime import datetime from random import SystemRandom import string from db import DataStore _random = SystemRandom() def random_string(size=5, chars=string.ascii_lowercase + string.digits): return ''.join(_random.choice(chars) for j in range(size)) class Vote: def __init__(self, pollid=None, user=None, choice=None): self.p = pollid self.u = user self.c = choice @staticmethod def load(d): v = Vote() v.__dict__ = d return v class Poll: def __init__(self, name=None, pollid=None, owner=None, options=None): self.n = name self.i = pollid self.u = owner self.o = options or [] @staticmethod def load(d): p = Poll() p.__dict__ = d return p PLUGIN = 'poll' PREFIX = '!' class PollPlugin(Plugin): def __init__(self, slack_client, plugin_config): Plugin.__init__(self, "poll", slack_client, plugin_config) self.polls = {} self.votes = {} self._load() def _save_votes(self): tmp = {k: {j: self.votes[k][j].__dict__ for j in self.votes[k]} for k in self.votes} DataStore.save(PLUGIN, 'votes', tmp) def _save_poll(self): tmp = {k: self.polls[k].__dict__ for k in self.polls} DataStore.save(PLUGIN, 'polls', tmp) def _save(self): self._save_poll() self._save_votes() def _load(self): data = DataStore.get(PLUGIN, 'votes', {}) for d in data.values(): # for each poll for k in d: # for each user d[k] = Vote.load(d[k]) self.votes = data print(data) data = DataStore.get(PLUGIN, 'polls', {}) for k,v in data.items(): self.polls[k] = Poll.load(v) print(self.polls) def is_owner(self, user, pollid): if pollid not in self.polls: return False return self.polls[pollid].u == user def poll_create(self, name, owner): pollid = random_string() p = Poll(name, pollid, owner) self.polls[pollid] = p self.votes[pollid] = {} self._save() return pollid def poll_vote(self, user, pollid, choice): if pollid not in self.polls: return False if choice >= len(self.polls[pollid].o): return False v = Vote(pollid, user, choice) self.votes[pollid][user] = v self._save_votes() return True def poll_unvote(self, user, pollid): if pollid not in self.polls: return False del self.votes[pollid][user] self._save_votes() return True def poll_delete(self, pollid): if pollid not in self.polls: return False del self.polls[pollid] del self.votes[pollid] self._save() return True def poll_add_option(self, user, pollid, option): if pollid not in self.polls: return False if not self.is_owner(user, pollid): return False self.polls[pollid].o.append(option) self._save_poll() return True def poll_get_results(self, pollid): if pollid not in self.polls: return False if len(self.polls[pollid].o) == 0: return [] res = [0] * len(self.polls[pollid].o) for el in self.votes[pollid].values(): res[el.c] += 1 return res def poll_get_name(self, pollid): if pollid not in self.polls: return False return self.polls[pollid].n def poll_get_options(self, pollid): if pollid not in self.polls: return False if len(self.polls[pollid].o) == 0: return [] return self.polls[pollid].o def get_polls(self): res = [] for poll in self.polls: res.append((self.polls[poll].n, self.polls[poll].i)) return res def _say(self, data, message): print(message) self.outputs.append([data['channel'], message]) def process_message(self, data): arg = data['text'].split() if arg[0] != PREFIX + 'poll': return if len(arg) == 1 or arg[1] == 'help': commands = [ 'create - create a poll with the given question. responds with the new poll\'s id', 'choice - add to the list of options for ', 'choices - list available choices for ', 'vote