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) + '"}'
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_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 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)'''
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) + '}'
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}]}')