def _brew_countdown(channel): session = get_session() server = session.query(Server).filter_by(completed=False).first() if not server: return server.completed = True customers = session.query(Customer).filter_by(server_id=server.id) for customer in customers.all(): customer.user.teas_drunk += 1 customer.user.teas_received += 1 server.user.teas_brewed += 1 server.user.teas_brewed += 1 # Account for server's tea server.user.teas_drunk += 1 server.user.times_brewed += 1 if not customers.count(): session.commit() return post_message('Time is up! Looks like no one else wants a cuppa.', channel) # There must be at least 1 customer to get a nomination point. server.user.nomination_points += 1 session.commit() return post_message("\n".join( ['Time is up!'] + ['%s wants %s' % (customer.user.display_name, customer.user.tea_type) for customer in customers] ), channel)
def post_vote(room_code): sessid = request.cookies.get("sessid") you = Player.select(Player, Room).join(Room).where(Player.sessid == sessid, Room.code == room_code).get() room = you.room vote = request.params["vote"] mission_id = request.params["missionId"] mission = Mission.get(Mission.id == mission_id, Mission.room == room) Vote.insert(player=you, mission=mission, vote=vote).execute() votes = Vote.select(Vote, Player).join(Player).where(Vote.mission == mission).execute() if votes.count == room.size: upvotes = sum(1 for v in votes if v.vote == "yes") agreed = True if (upvotes * 2 > votes.count) else False votes_message_data = { "votes": [ {"player": {"id": vote.player.id, "name": vote.player.name}, "vote": vote.vote} for vote in votes ], "agreed": agreed, } messages = [Msg("votes", votes_message_data)] if agreed: room.phase = Room.PHASE_MISSION room.save() else: room.phase = Room.PHASE_TEAM_BUILD leader = next_leader(room) leader_message_data = {"leader": {"id": leader.id, "name": leader.name}} messages.append(Msg("leader", leader_message_data)) post_message(messages, room=room)
def start_game(room_code): sessid = request.cookies.get("sessid") room = Room.select(Room).join(Player, on=Room.owner).where(Player.sessid == sessid, Room.code == room_code).get() init_game(room) message_data = {"url": "/game/%s" % room_code} post_message([Msg("start", message_data)], room=room) return redirect("/game/%s" % room_code)
def nominate(self): if ServerManager.has_active_server(): return post_message( 'Someone else is already making tea, I\'ll save your nomination for later :smile:', self.channel) try: slack_id = MENTION_RE.search(self.command_body).groups()[0] except AttributeError: return post_message('You must nominate another user to brew!', self.channel) nominated_user = UserManager.get_by_slack_id(slack_id) if self.request_user.nomination_points < NOMINATION_POINTS_REQUIRED: return post_message( 'You can\'t nominate someone unless you brew tea %s times!' % NOMINATION_POINTS_REQUIRED, self.channel) # Subtract nomination points from request user. nominated_user.nomination_points -= NOMINATION_POINTS_REQUIRED server = Server(user_id=nominated_user.id) session.add(server) session.flush() session.add(Customer(user_id=self.request_user.id, server_id=server.id)) session.commit() brew_countdown.apply_async(countdown=BREW_COUNTDOWN, args=(self.channel, )) return post_message( '%s has nominated %s to make tea! Who wants in?' % (self.request_user.first_name, nominated_user.first_name), self.channel)
def me(self): server = session.query(Server).filter_by(completed=False) if not server.count(): return post_message( 'No one has volunteered to make tea, why dont you make it %s?' % self.request_user.first_name, self.channel) server = server.first() if server.user_id == self.request_user.id: return post_message( '%s you are making tea! :face_with_rolling_eyes:' % self.request_user.first_name, self.channel) if session.query(Customer).filter_by(user_id=self.request_user.id, server_id=server.id).count(): return post_message( 'You said it once already %s.' % self.request_user.first_name, self.channel) session.add(Customer(user_id=self.request_user.id, server_id=server.id)) session.commit() return post_message( 'Hang tight %s, tea is being served soon' % self.request_user.first_name, self.channel)
def test_submit_valid_coin(client, valid_cactuscoin, badge_keys): pytest.redis.flushdb( ) # this is a hack for now, need to redo tests to work directly with db response = post_message(client, badge_keys[1], '/coin/1', valid_cactuscoin) assert response.status_code == 200 response = post_message(client, badge_keys[2], '/coin/2', valid_cactuscoin) assert response.status_code == 409
def test_get_coins(mocker, client, valid_cactuscoin, badge_keys, conference_key): pytest.redis.flushdb( ) # this is a hack for now, need to redo tests to work directly with db post_message(client, badge_keys[2], '/badge/2', {'name': 'cybaix'}) response = post_message(client, badge_keys[1], '/coin/1', valid_cactuscoin) assert response.status_code == 200 coins = get_message(client, conference_key, '/coin/1') assert coins[0]['other_id'] == 2 assert coins[0]['other_name'] == 'cybaix'
def test_register_someone_elses_badge(client, badge_keys, conference_key): """ Ensures a badge cannot register with an ID not associated with it. """ badge = {'name': 'cybaix'} response = post_message(client, badge_keys[2], '/badge/1', badge) assert response.status_code == 403 # make sure the real badge owner can still claim the badge badge = {'name': 'cybaix'} response = post_message(client, badge_keys[1], '/badge/1', badge) assert response.status_code == 200 saved_badge = get_message(client, conference_key, '/badge/1') assert saved_badge == badge
def register(self): if not self.command_body: return post_message( 'You didn\'t tell me what type of tea you like. Try typing `@teabot register green tea`', self.channel) message = 'Welcome to the tea party %s' % self.request_user.first_name if self.request_user.tea_type: message = 'I have updated your tea preference.' self.request_user.tea_type = self.command_body session.commit() return post_message(message, self.channel)
def test_register_badge_bad_data(client, badge_keys, conference_key): """ Attempts to register a badge with a bunch of bogus data. """ badge = {'name': 'cybaix'} response = post_message(client, badge_keys[1], '/badge/a2_+9U*Eji2*Y*AOINHF', badge) assert response.status_code == 404 badge = {'name': 'cybaix'} response = post_message(client, badge_keys[1], '/badge/a_\/', badge) assert response.status_code == 404 badge = {'name': '`^&%'} response = post_message(client, badge_keys[1], '/badge/1', badge) assert response.status_code == 400
def test_register_and_update_badge(client, badge_keys, conference_key): """ Test to successfully register badge, and also update badge information. """ badge = {'name': 'cybaix'} response = post_message(client, badge_keys[1], '/badge/1', badge) assert response.status_code == 200 saved_badge = get_message(client, conference_key, '/badge/1') assert saved_badge == badge # Test 'doh' scenario and ensure attendees can update information badge = {'name': 'mark'} response = post_message(client, badge_keys[1], '/badge/1', badge) assert response.status_code == 200 saved_badge = get_message(client, conference_key, '/badge/1') assert saved_badge == badge
def brew(self): # Make sure the user is not brewing already if ServerManager.has_active_server(): return post_message('Someone else is already making tea. Want in?', self.channel) session.add(Server(user_id=self.request_user.id)) session.commit() brew_countdown.apply_async(countdown=BREW_COUNTDOWN, args=(self.channel, )) return post_message( random.choice([ '%s is making tea, who is in?' % self.request_user.first_name, 'Who wants a cuppa?' ]), self.channel)
def test_get_coins(mocker, client, valid_cactuscoin, badge_keys, conference_key): pytest.redis.flushdb( ) # this is a hack for now, need to redo tests to work directly with db fake_badges = [i for i in range(3, 200)] responded_badges = [] badge_batch_size = 10 pos = 0 for i in range(3, 200): pytest.redis.lpush('badge_coins_2', i) while True: signature = crypto.sign( json.dumps({ 'start': 0, 'numBadges': badge_batch_size }), badge_keys[2]) message = {'start': pos, 'numBadges': badge_batch_size} response = post_message(client, badge_keys[2], '/coin_list/2', message) assert response.status_code == 200 response = json.loads(response.get_json()['msg']) for badge in response: responded_badges.append(badge) if len(response) < badge_batch_size: break pos += badge_batch_size responded_badges.reverse() assert responded_badges == fake_badges
def leaderboard(self): leaderboard = session.query(User).filter( User.tea_type.isnot(None)).order_by(User.teas_brewed.desc()).all() _message = '*Teabot Leaderboard*\n\n' for index, user in enumerate(leaderboard): _message += '%s. _%s_ has brewed *%s* cups of tea\n' % ( index + 1, user.real_name, user.teas_brewed) return post_message(_message, self.channel)
def input_post(): #TODO, error handling for privacy checks """ Write a post to the current page. Assumes the post should be written by the page (NOT by the user) visibility field identifies if this is a published or unpublished post """ message = request.form['message'] page_token = session['page']['access_token'] resp = utils.post_message(message, page_token, session['visibility']) return render_template('success.html', post_id = resp['id'])
def post_team(room_code): sessid = request.cookies.get("sessid") you = Player.select(Player, Room).join(Room).where(Player.sessid == sessid, Room.code == room_code).get() room = you.room if you.queue_position != room.leader_queue: return HTTPError(400, "You are not the leader") team_ids = request.params.getall("team[]") team = room.players.where(Player.id << team_ids).execute() mission = Mission.create(room=room, leader=you, team_size=0) with db.atomic(): for plr in team: PlayerMission.insert(player=plr, mission=mission).execute() room.phase = "vote" room.save() message_data = { "mission_id": mission.id, "leader": {"id": you.id, "name": you.name}, "team": [{"id": plr.id, "name": plr.name} for plr in team], } post_message([Msg("team", message_data)], room=room)
def join(): """ Route invoked when a new player joins the room. Adds player to the room and sets his session cookie. Posts the join message to other players in the room. """ username = request.forms.get("username") if len(username) == 0: return HTTPError(403, "Username too short") room_code = request.forms.get("room").upper() try: room = Room.select(Room).where(Room.code == room_code).get() except Room.DoesNotExist: return HTTPError(404, "Room does not exist") sessid = request.cookies.get("sessid", generate_sessid()) player, created = Player.get_or_create(sessid=sessid, room=room, defaults={"name": username}) if created: message_data = {"player": {"id": player.id, "name": player.name}} post_message([Msg("join", message_data)], room=room) response.set_cookie("sessid", sessid, path="/") return redirect("/game/%s/lobby" % room.code)
def dispatch(self, event): self.channel = event[0].get('channel', '') text = event[0].get('text', '') try: slack_user_id, command, command_body = COMMAND_RE.search( text).groups() if slack_user_id != self.teabot.slack_id: return command = command.strip() self.command_body = command_body.strip() self.request_user = UserManager.get_by_slack_id(event[0].get( 'user', '')) if not self.request_user: return # Call the appropriate function getattr(self, command)() except AttributeError: regex = TEABOT_MENTION_RE.search(text) if regex and regex.groups()[0] == self.teabot.slack_id: post_message('No idea what that means mate.', self.channel)
def stats(self): """ Get stats for user(s) - (# of teas drunk, # of teas brewed, # of times brewed, # of teas received) :param command_body: can either be empty (get stats for all users) or can reference a specific user """ try: slack_id = MENTION_RE.search(self.command_body).groups()[0] except AttributeError: slack_id = None if slack_id: users = [UserManager.get_by_slack_id(slack_id)] else: users = session.query(User).filter(User.tea_type.isnot(None)).all() results = [] for user in users: results.append({ 'real_name': user.real_name, 'teas_drunk': user.teas_drunk, 'teas_brewed': user.teas_brewed, 'times_brewed': user.times_brewed, 'teas_received': user.teas_received }) return post_message( '', self.channel, attachments=[{ "fallback": "Teabot Stats", "pretext": "", "author_name": "%s" % result['real_name'], "fields": [ { "value": "Number of tea cups consumed -> %(teas_drunk)s\nNumber of tea cups brewed -> %(teas_brewed)s\nNumber of times you've brewed tea -> %(times_brewed)s\nNumber of tea cups you were served -> %(teas_received)s" % result, "short": False }, ] } for result in results])
def test_get_scoreboard(client, badge_keys, valid_cactuscoin): """ Test to successfully register badge, and also update badge information. """ pytest.redis.flushdb() # this is a hack for now, need to redo tests to work directly with db badge = {'name':'cybaix'} post_message(client, badge_keys[1], '/badge/1', badge) post_message(client, badge_keys[1], '/badge/1', badge) # name changes shouldn't get extra coins post_message(client, badge_keys[1], '/coin/1', valid_cactuscoin) response = client.get('/scoreboard').get_json() assert response['scoreboard'][0][0] == '1' assert response['scoreboard'][0][1] == 2.0 assert response['scoreboard'][1][0] == '2' assert response['scoreboard'][1][1] == 1.0
def ping(self): return post_message('pong', self.channel)
def func_wrapper(self, *args, **kwargs): if not self.request_user.tea_type: return post_message('You need to register first.', self.channel) else: return func(self, *args, **kwargs)
def yo(self): return post_message('Sup?', self.channel)
def help(self): return post_message(HELP_TEXT, self.channel)
key = get_random_bytes(32) key = base64.b64encode(key).decode('utf-8') current_time = datetime.datetime.now().strftime("%d-%b-%y (%H:%M:%S)") yours = input('') if yours == 'exit()': isExit = True elif yours == 'r': history = get_history(height=10, secret=my_secret, server='/' + server) history_v = print_history(history) clear_screen() print('Chatroom: ' + server + '\n' + history_v + 'Enter: ', end='') elif yours == '': clear_screen() print('Chatroom: ' + server + '\n' + history_v + 'Enter: ', end='') else: post_message(message=yours, aes_key=key, addressees=read_roster(), secret=my_secret, server='/' + server + '/', nick_name=my_nick_name) history = get_history(height=10, secret=my_secret, server='/' + server) history_v = print_history(history) clear_screen() print('Chatroom: ' + server + '\n' + history_v + 'Enter: ', end='')
def test_submit_invalid_coin(client, invalid_cactuscoin, badge_keys): response = post_message(client, badge_keys[1], '/coin/1', invalid_cactuscoin) assert response.status_code == 403