Example #1
0
class Player(models.Model):
    room = models.ForeignKey(Room, on_delete=models.CASCADE)
    uuid = models.UUIDField(default=uuid4, editable=False)
    name = models.CharField(max_length=50)
    color_value = models.IntegerField("Color",
                                      default=Color.player_default().value,
                                      choices=Color.player_choices())
    created_date = models.DateTimeField("Creation Time", default=timezone.now)
    is_spectator = models.BooleanField("Is Spectator", default=False)

    @staticmethod
    def get_for_encoded_uuid(encoded_player_uuid):
        decoded_uuid = decode_uuid(encoded_player_uuid)
        return Player.objects.get(uuid=decoded_uuid)

    def __str__(self):
        return self.name

    def __repr__(self):
        return "<Player: id: {!r}, uuid: {!r}, name: {!r}>".format(
            self.id, self.encoded_uuid, self.name)

    @property
    def encoded_uuid(self):
        return encode_uuid(self.uuid)

    @property
    def color(self):
        if self.is_spectator:
            return Color.blank
        return Color.for_value(self.color_value)

    @property
    def connected(self):
        last_connection_event = ConnectionEvent.objects.filter(
            player=self).order_by("timestamp").last()
        return not last_connection_event or last_connection_event.event_type == ConnectionEventType.connected

    def update_color(self, color):
        with transaction.atomic():
            color_event = ColorEvent(player=self,
                                     player_color_value=self.color.value,
                                     color_value=color.value)
            color_event.save()
            self.color_value = color.value
            self.save()
        return color_event

    def to_json(self):
        return {
            "uuid": self.encoded_uuid,
            "name": self.name,
            "color": self.color.name,
            "is_spectator": self.is_spectator
        }
Example #2
0
def select_color(request):
    data = parse_body_json_or_400(request, required_keys=["room", "color"])

    room = Room.get_for_encoded_uuid_or_404(data["room"])
    player = _get_session_player(request.session, room)
    color = Color.for_name(data["color"])

    color_event = player.update_color(color)
    publish_color_event(color_event)
    return HttpResponse("Received data: ", str(data))
Example #3
0
class ColorEvent(Event):
    color_value = models.IntegerField(choices=Color.player_choices())

    @property
    def color(self):
        return Color.for_value(self.color_value)

    def to_json(self):
        return {
            "type": "color",
            "player": self.player.to_json(),
            "player_color": self.player_color.name,
            "color": self.color.name,
            "timestamp": self.json_timestamp
        }
Example #4
0
def goal_selected(request):
    data = parse_body_json_or_400(request, required_keys=["room", "slot", "color", "remove_color"])

    room = Room.get_for_encoded_uuid_or_404(data["room"])
    player = _get_session_player(request.session, room)
    game = room.current_game
    slot = int(data["slot"])
    color = Color.for_name(data["color"])
    remove_color = data["remove_color"]

    goal_event = game.update_goal(player, slot, color, remove_color)
    if not goal_event:
        return HttpResponseBadRequest("Blocked by Lockout")
    publish_goal_event(goal_event)
    return HttpResponse("Recieved data: " + str(data))
Example #5
0
class GoalEvent(Event):
    square = models.ForeignKey("bingosync.Square", on_delete=models.CASCADE)
    color_value = models.IntegerField(choices=Color.goal_choices())
    remove_color = models.BooleanField(default=False)

    @property
    def color(self):
        return Color.for_value(self.color_value)

    def to_json(self):
        return {
            "type": "goal",
            "player": self.player.to_json(),
            "square": self.square.to_json(),
            "player_color": self.player_color.name,
            "color": self.color.name,
            "remove": self.remove_color,
            "timestamp": self.json_timestamp
        }
Example #6
0
 def color(self):
     if self.is_spectator:
         return Color.blank
     return Color.for_value(self.color_value)
Example #7
0
 def player_color(self):
     return Color.for_value(self.player_color_value)
Example #8
0
 def color(self):
     return Color.for_value(self.color_value)
Example #9
0
class Event(models.Model):
    player = models.ForeignKey("bingosync.Player", on_delete=models.CASCADE)
    timestamp = models.DateTimeField("Sent", default=timezone.now)
    player_color_value = models.IntegerField(choices=Color.player_choices())

    @property
    def player_color(self):
        return Color.for_value(self.player_color_value)

    @property
    def json_timestamp(self):
        return self.timestamp.replace().timestamp()

    @staticmethod
    def event_classes():
        return [
            ChatEvent, GoalEvent, ColorEvent, RevealedEvent, ConnectionEvent,
            NewCardEvent
        ]

    @staticmethod
    def get_all_for_room(room):
        all_events = []
        for event_class in Event.event_classes():
            all_events.extend(event_class.objects.filter(player__room=room))
        return sorted(all_events, key=lambda event: event.timestamp)

    @staticmethod
    def get_all_recent_for_room(room):
        recent_events = []
        total_events = 0
        for event_class in Event.event_classes():
            total_events += event_class.objects.filter(
                player__room=room).count()
            recent_events.extend(
                event_class.objects.filter(player__room=room).filter(
                    timestamp__gte=datetime.datetime.now(
                        datetime.timezone.utc) - datetime.timedelta(hours=24)))
        all_included = total_events == len(recent_events)
        recent_events = sorted(recent_events,
                               key=lambda event: event.timestamp)
        return {'events': recent_events, 'all_included': all_included}

    @staticmethod
    def get_latest_for_room(room):
        latest_events = []
        for event_class in Event.event_classes():
            try:
                latest_event = event_class.objects.filter(
                    player__room=room).latest()
                latest_events.append(latest_event)
            except event_class.DoesNotExist:
                pass
        if latest_events:
            return sorted(latest_events, key=lambda event: event.timestamp)[-1]
        else:
            return None

    class Meta:
        abstract = True
        get_latest_by = "timestamp"