예제 #1
0
def add_deck(mongodb):
    response.content_type = "application/json"

    '''' Try to convert the payload to JSON '''
    json_request = None
    try:
        json_request = request.json
    except JSONDecodeError:
        response.status = 400
        return '{"status": "nok", "error": "Malformed JSON"}'

    deck = None
    # noinspection PyBroadException
    try:
        deck = Deck(
            name=json_request['name'],
            description=json_request['description'],
            lang=json_request['lang'],
            cards=json_request['cards']
        )
    except:
        response.status = 400
        return '{"status": "nok", "error": "Invalid deck submitted"}'
    if deck is not None:
        result = mongodb['decks'].insert_one(deck.to_json_obj())
        if not result.acknowledged:
            response.status = 500
            return '{"status": "nok", "error": "Unknown error upon inserting"}'
        else:
            return '{"status": "ok", "id": "' + str(result.inserted_id) + '"}'
예제 #2
0
 def setUp(self):
     prompt_card = Card(type=CardType.PROMPT,
                        content="Why did the chicken cross the road?",
                        pick=1)
     response_card1 = Card(type=CardType.RESPONSE,
                           content="A homoerotic subplot")
     response_card2 = Card(type=CardType.RESPONSE,
                           content="To get to the other side")
     card_list = [prompt_card, response_card1, response_card2]
     self.deck = Deck(name="Animals",
                      description="The animal pack",
                      cards=card_list)
예제 #3
0
    def test_eq(self):
        prompt_card = Card(type=CardType.PROMPT,
                           content="Why did the chicken cross the road?",
                           pick=1)
        response_card1 = Card(type=CardType.RESPONSE,
                              content="A homoerotic subplot")
        response_card2 = Card(type=CardType.RESPONSE,
                              content="To get to the other side")
        card_list_a = [prompt_card, response_card1, response_card2]
        deck_a = Deck(name="Animals",
                      description="The animal pack",
                      cards=card_list_a)

        deck_b = Deck(name="Animals", description="The animal pack", cards=[])

        self.assertEqual(self.deck, deck_a)
        self.assertNotEqual(self.deck, deck_b)
예제 #4
0
def websocket_handler(ws):
    global game_phase
    global prompt_cards
    global response_cards
    player = None
    try:
        """ Ask websocket connection to identify itself """
        ws.send('{ "event": "identity_request", "instance_id": "' +
                instance_id + '" }')

        while True:
            msg = None
            if player is None:
                msg = ws.receive()
            else:
                msg = player.websocket.receive()

            if msg is not None:
                response = None
                try:
                    response = json.loads(msg)
                    print("Client sent us: " + str(response))
                except JSONDecodeError as e:
                    print(player.username + " send us invalid JSON: " + str(e))

                try:
                    if response['event'] == "existing_player":
                        existing_player = get_player(response['player_id'])
                        if existing_player is not None:
                            print("Player " + existing_player.username + " (" +
                                  existing_player.uuid + ") rejoined")
                            existing_player.websocket.close()
                            player = existing_player
                            player.websocket = ws
                            ''' Let the player know that he rejoined successfully '''
                            player.websocket.send('{ "event": "rejoin_ack" }')
                            """ Send current game state """
                            broadcast_state()
                        else:
                            ''' We don't recognize this player, so adding him '''
                            player = Player(websocket=ws)
                            player.websocket.send(
                                '{ "event": "player_creation", "instance_id": "'
                                + instance_id + '", "player_id": "' +
                                player.uuid + '" }')
                            players.append(player)
                            """ Send current game state """
                            broadcast_state()
                    elif response['event'] == "set_username":
                        # TODO: sanitize HTML entities
                        """ Check if another player hasn't already this username is use """
                        if not username_taken(response['username']):
                            if not player:
                                ''' Make admin if only player '''
                                is_admin = True if len(players) == 0 else False
                                ''' New player, send instance UUID '''
                                player = Player(websocket=ws,
                                                username=response['username'],
                                                isAdmin=is_admin)
                                player.websocket.send(
                                    '{ "event": "player_creation", "instance_id": "'
                                    + instance_id + '", "player_id": "' +
                                    player.uuid + '" }')
                                players.append(player)
                                """ Send current game state """
                                broadcast_state()
                                broadcast_message(
                                    '{ "event": "player_joined", "username": "******", "timestamp": "' +
                                    str(datetime.now().timestamp()) + '" }')
                            else:
                                player.username = response['username']
                                player.websocket.send(
                                    '{ "event": "username_ok" }')
                                """ Send current game state """
                                broadcast_state()
                        else:
                            player.websocket.send(
                                '{ "event": "username_nok" }')
                    elif response['event'] == 'game_start':
                        if player.isAdmin:
                            if game_phase is GamePhase.SETUP:
                                """ Fetch the decks """
                                for deck_id in response['deck_ids']:
                                    response = requests.get(deckapi_uri +
                                                            "/decks/" +
                                                            deck_id)
                                    if response.status_code == 200:
                                        entry = json.loads(
                                            response.content.decode('utf-8'))
                                        deck = Deck(
                                            name=entry['name'],
                                            description=entry['description'],
                                            lang=entry['lang'],
                                            cards=[])
                                        ''' Attempt to create Card objects '''
                                        if len(entry['cards']) > 0:
                                            for card_entry in entry['cards']:
                                                card = Card(
                                                    type=CardType(
                                                        card_entry['type']),
                                                    content=conform_content(
                                                        str(card_entry[
                                                            'content'])),
                                                    pick=int(
                                                        card_entry['pick']),
                                                    draw=int(
                                                        card_entry['draw']))
                                                deck.cards.append(card)
                                        prompt_cards.extend(deck.prompt_cards)
                                        response_cards.extend(
                                            deck.response_cards)
                                    game_phase = GamePhase.CARDS_SELECTION
                                    print('Player ' + player.username +
                                          ' started the game.')
                                    ''' Choose the next Czar '''
                                    choose_next_czar(players)
                                    ''' Shuffle the cards '''
                                    shuffle(prompt_cards)
                                    shuffle(response_cards)
                                    rotate_prompt_cards(prompt_cards)
                                    deal_cards(response_cards)
                                    broadcast_state()
                            else:
                                player.websocket.send(
                                    '{ "event": "unauthorized", "message": "You cannot change game settings while game '
                                    'in progress." }')
                        else:
                            player.websocket.send(
                                '{ "event": "unauthorized", "message": "You are unauthorized for this action" }'
                            )
                    else:
                        print("I have no idea what to do with that message")
                except TypeError as e:
                    print("We received an invalid request: " + str(e))
    except WebSocketError as e:
        if hasattr(player, 'username'):
            print(player.username + " had a websocket error: " + str(e))
    except AttributeError as e:
        if hasattr(player, 'username'):
            print(player.username + "'s websocket attribute doesn't exist: " +
                  str(e))
    finally:
        if player is not None:
            '''players.remove(player)'''
예제 #5
0
def import_decks(mongodb):
    response.content_type = "application/json"

    '''' Try to convert the payload to JSON '''
    json_request = None
    try:
        json_request = request.json
    except JSONDecodeError:
        response.status = 400
        return '{"status": "nok", "error": "Malformed JSON"}'

    ''' Check if we're dealing with an array or single submission '''
    ''' Single JSON -> dict, JSON array -> list of dicts '''
    ''' Force dict to list to simplify code '''
    if isinstance(json_request, dict):
        json_request = [json_request]

    ''' Check for empty payload '''
    if len(json_request) == 0:
        response.status = 400
        return '{"status": "nok", "error": "Invalid deck submitted"}'

    decks = []

    ''' Loop through objects and test for correctness '''
    for entry in json_request:
        # noinspection PyBroadException
        try:
            ''' Attempt to create a Deck object '''
            ''' cards initially empty because we are going to evaluate them in the next step '''
            deck = Deck(
                name=entry['name'],
                description=entry['description'],
                lang=entry['lang'],
                cards=[]
            )

            ''' Attempt to create Card objects '''
            if len(entry['cards']) > 0:
                for card_entry in entry['cards']:
                    card = Card(
                        type=CardType(card_entry['type']),
                        content=conform_content(str(card_entry['content'])),
                        pick=int(card_entry['pick']),
                        draw=int(card_entry['draw'])
                    )
                    deck.cards.append(card)

            ''' Looks fine, we add it to the validated decks list '''
            decks.append(deck)
        except:
            response.status = 400
            return '{"status": "nok", "error": "Invalid deck submitted"}'

    if decks is not None and len(decks) > 0:
        deck: Deck
        result = mongodb['decks'].insert_many(deck.to_json_obj() for deck in decks)
        if not result.acknowledged:
            response.status = 500
            return '{"status": "nok", "error": "Unknown error upon inserting"}'
        else:
            id_list = []
            for id in result.inserted_ids:
                id_list.append(str(id))
            return '{"status": "ok", "ids": ' + json.dumps(id_list) + '}'
예제 #6
0
class TestDeck(TestCase):
    def setUp(self):
        prompt_card = Card(type=CardType.PROMPT,
                           content="Why did the chicken cross the road?",
                           pick=1)
        response_card1 = Card(type=CardType.RESPONSE,
                              content="A homoerotic subplot")
        response_card2 = Card(type=CardType.RESPONSE,
                              content="To get to the other side")
        card_list = [prompt_card, response_card1, response_card2]
        self.deck = Deck(name="Animals",
                         description="The animal pack",
                         cards=card_list)

    def test_prompt_cards(self):
        self.assertEqual(len(self.deck.prompt_cards), 1)

    def test_response_cards(self):
        self.assertEqual(len(self.deck.response_cards), 2)

    def test_name(self):
        self.assertEqual(self.deck.name, "Animals")

    def test_description(self):
        self.assertEqual(self.deck.description, "The animal pack")

    def test_len(self):
        self.assertEqual(self.deck.len, 3)

    def test_eq(self):
        prompt_card = Card(type=CardType.PROMPT,
                           content="Why did the chicken cross the road?",
                           pick=1)
        response_card1 = Card(type=CardType.RESPONSE,
                              content="A homoerotic subplot")
        response_card2 = Card(type=CardType.RESPONSE,
                              content="To get to the other side")
        card_list_a = [prompt_card, response_card1, response_card2]
        deck_a = Deck(name="Animals",
                      description="The animal pack",
                      cards=card_list_a)

        deck_b = Deck(name="Animals", description="The animal pack", cards=[])

        self.assertEqual(self.deck, deck_a)
        self.assertNotEqual(self.deck, deck_b)

    def test_add_card(self):
        card = Card(type=CardType.RESPONSE, content="A wombat")
        self.deck.add_card(card)
        self.assertIn(card, self.deck.response_cards)

    def test_remove_card(self):
        card = Card(type=CardType.RESPONSE, content="To get to the other side")
        self.deck.remove_card(card)
        self.assertNotIn(card, self.deck.response_cards)

    def test_to_json_obj(self):
        json_obj = self.deck.to_json_obj()
        self.assertTrue(isinstance(json_obj, dict))
        self.assertEqual(json_obj['name'], self.deck.name)
        self.assertEqual(json_obj['description'], self.deck.description)
        self.assertEqual(json_obj['lang'], self.deck.lang)
        for card in self.deck.cards:
            card_obj = card.to_json_obj()
            self.assertIn(card_obj, json_obj['cards'])

    def test_to_json(self):
        json_str = self.deck.to_json()
        self.assertTrue(isinstance(json_str, str))
        self.assertEqual(
            json_str,
            '{"name": "Animals", "description": "The animal pack", "lang": "en", "cards": [{'
            '"type": "prompt", "content": "Why did the chicken cross the road?", "pick": 1, '
            '"draw": 1}, {"type": "response", "content": "A homoerotic subplot", "pick": 0, '
            '"draw": 0}, {"type": "response", "content": "To get to the other side", '
            '"pick": 0, "draw": 0}]}')