You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.6 KiB

from datetime import datetime
from sqlalchemy.ext.associationproxy import association_proxy
from app import db
from .game_state import GameState
from .game_player import GamePlayer
from .role import Role
from .review import Review
class Game(db.Model):
__tablename__ = 'game'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), index=True, unique=True, nullable=False)
#state = db.Column(db.Enum(GameState), server_default=GameState(1).name, nullable=False)
hidden = db.Column(db.Boolean, server_default='1', nullable=False)
paused = db.Column(db.Boolean, server_default='0', nullable=False)
start_time = db.Column(db.DateTime)
end_time = db.Column(db.DateTime)
players = db.relationship(
'GamePlayer',
back_populates='game',
cascade="save-update, merge, delete, delete-orphan")
users = association_proxy('players', 'user',
creator=lambda user: GamePlayer(user=user))
objectives = db.relationship(
'Objective',
lazy='select',
backref=db.backref('game', lazy='joined'),
cascade="save-update, merge, delete, delete-orphan")
notifications = db.relationship(
'Notification',
lazy='select',
backref=db.backref('game', lazy='joined'),
cascade="save-update, merge, delete, delete-orphan")
def last_player_locations(self, offset=None):
# pylint: disable=not-an-iterable
return [location for location in
[player.last_location(offset=offset) for player in self.players if player.user.locations]
if location is not None]
def last_locations(self, players, offset=None):
'''
Returns last locations for given players within time boundaries of game
Parameters:
players (Player or User list): players for whom the last location is returned
offset (int): Offset in minutes. Only locations older than this amount of minutes will be returned.
'''
locations = []
for player in players:
if isinstance(player, GamePlayer):
player = player.user
location = player.last_location(self, offset=offset)
if location:
locations.append(location)
return locations
def bunnies(self):
# pylint: disable=not-an-iterable
return [gameplayer for gameplayer in self.players if gameplayer.role == Role.bunny]
def owned_by(self, user):
'''given user is an owner of this game'''
# pylint: disable=not-an-iterable
return user in [gameplayer.user for gameplayer in self.players if gameplayer.role == Role.owner]
def unreviewed_bunny_photos(self):
# pylint: disable=not-an-iterable
return [pcp for pcps in
[player.player_caught_players for player in self.players]
for pcp in pcps if pcp.review == Review.none]
def is_active(self):
return self.get_state() == GameState.active
def get_state(self):
now = datetime.utcnow()
start = (self.start_time or datetime.min).replace(tzinfo=None)
if now < start: # Before Game
if self.hidden:
return GameState.hidden
return GameState.published
end = (self.end_time or datetime.max).replace(tzinfo=None)
if start < now < end: # During Game
if self.paused:
return GameState.paused
return GameState.active
if now > end: # After Game
if self.hidden:
return GameState.hidden
return GameState.finished