def delete_card(deck_id, mongodb): response.content_type = "application/json" deck = mongodb['decks'].find_one({"_id": ObjectId(deck_id)}) if deck: '''' 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"}' card = None try: ''' Attempt to create a Card object ''' card = Card( type=CardType(json_request['type']), content=str(json_request['content']), pick=int(json_request['pick']), draw=int(json_request['draw']) ) except: response.status = 400 return '{"status": "nok", "error": "Malformed Card"}' result = mongodb['decks'].update_one({"_id": ObjectId(deck_id)}, {'$pull': {'cards': card.to_json_obj()}}) if not result.acknowledged: response.status = 500 return '{"status": "nok", "error": "Unknown error upon deleting"}' else: return '{"status": "ok"}' else: response.code = 404 return '{"status": "nok", "error": "Deck not found"}'
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 test_convert_to_dict(self): card = Card(type=CardType.PROMPT, content="Why did the chicken cross the road?") reference_dict = { 'type': CardType.PROMPT, 'content': 'Why did the chicken cross the road?', 'pick': 1, 'draw': 1, } card_dict = convert_to_dict(card) self.assertTrue(isinstance(card_dict, dict)) self.assertDictEqual(card_dict, reference_dict)
def test_dict_to_obj(self): reference_card = Card(type=CardType.PROMPT, content="Why did the chicken cross the road?") card_dict = { '__class__': type(reference_card).__name__, '__module__': reference_card.__module__, 'type': CardType.PROMPT, 'content': 'Why did the chicken cross the road?', 'pick': 1, 'draw': 1, } card = dict_to_obj(card_dict) self.assertEqual(card, reference_card)
def test_convert_to_dict_with_meta(self): card = Card(type=CardType.PROMPT, content="Why did the chicken cross the road?") reference_dict = { '__class__': type(card).__name__, '__module__': card.__module__, 'type': CardType.PROMPT, 'content': 'Why did the chicken cross the road?', 'pick': 1, 'draw': 1, } card_dict = convert_to_dict_with_meta(card) self.assertTrue(isinstance(card_dict, dict)) self.assertDictEqual(card_dict, reference_dict)
def add_card(id, mongodb): response.content_type = "application/json" deck = mongodb['decks'].find_one({"_id": ObjectId(id)}) if deck: # noinspection PyBroadException try: type = CardType(request.json['type']) content = conform_content(str(request.json['content'])) pick = int(request.json['pick']) draw = int(request.json['draw']) card = Card(type=type, content=content, pick=pick, draw=draw) result = mongodb['decks'].update_one({"_id": ObjectId(id)}, {'$push': {'cards': card.to_json_obj()}}) if not result.acknowledged: response.status = 500 return '{"status": "nok", "error": "Unknown error upon inserting"}' else: return '{"status": "ok"}' except: response.status = 500 return '{"status": "nok", "error": "Unknown error upon inserting"}' else: response.code = 404 return '{"status": "nok", "error": "Deck not found"}'
def remove_card(self, card: Card): self.cards.remove(card) print(self.username + " lost: " + card.to_json())
def add_card(self, card: Card): self.cards.append(card) print(self.username + " received: " + card.to_json())
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) + '}'
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_add_card(self): card = Card(type=CardType.RESPONSE, content="A wombat") self.deck.add_card(card) self.assertIn(card, self.deck.response_cards)