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.
97 lines
3.7 KiB
97 lines
3.7 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 usernames(self): |
|
return [user.name for user in self.users] |
|
|
|
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
|
|
|