예제 #1
0
파일: models.py 프로젝트: homdx/mj-scorer
class UsersGames(db.Model):
    ''' this maps users to games, and provides the score and placement '''
    __tablename = 'user_game'
    user_id = db.Column('user_id',
                        db.Integer(),
                        db.ForeignKey('user.id'),
                        primary_key=True)
    game_id = db.Column('game_id',
                        db.Unicode(255),
                        db.ForeignKey('game.id'),
                        primary_key=True)
    score = db.Column(db.Integer())
    place = db.Column(db.Integer())

    player = db.relationship(User,
                             backref=db.backref('played_games',
                                                lazy='dynamic',
                                                cascade="all, delete-orphan"))

    game = db.relationship(
        Game,
        backref=db.backref(
            'games_players',
            lazy='immediate',
            cascade="all, delete-orphan",
            collection_class=attribute_mapped_collection("place"),
        ),
    )

    def __init__(self, user=None, game=None, score=-9999, place=-1):
        self.user = user
        self.game = game
        self.score = score
        self.place = place
예제 #2
0
class SeasonsPlayers(db.Model):
    '''
    Stores score for each player for each season
    '''
    __tablename__ = 'seasonsplayers'

    season_id = db.Column(db.Integer,
                          db.ForeignKey('season.season_id'),
                          nullable=False,
                          primary_key=True)

    player_id = db.Column(db.Integer,
                          db.ForeignKey('player.player_id'),
                          nullable=False,
                          primary_key=True)

    score = db.Column(db.Integer, default=0, nullable=True)  # score x 10
    place = db.Column(db.Integer, nullable=True)
    note = db.Column(db.UnicodeText(), nullable=True)

    player = db.relationship(
        Player,
        backref=db.backref(
            'played_seasons',
            lazy='joined',
            cascade="all,delete-orphan",
        ),
    )

    season = db.relationship(
        Season,
        backref=db.backref(
            'seasons_players',
            lazy='dynamic',
            cascade="all, delete-orphan",
            collection_class=attribute_mapped_collection("place"),
        ),
    )

    def __init__(self,
                 player=None,
                 season_id=None,
                 score=None,
                 place=None,
                 note=None):
        self.player = player
        self.season_id = season_id
        self.score = score
        self.place = place
        self.note = note

    def __str__(self):
        return ('id: ' + self.season_id + '\n player: ' + self.player_id +
                '\n started: ' + str(self.firstgame) + '\n score: ' +
                str(self.aggscore))
예제 #3
0
class Game(db.Model):
    '''
    The heart of the database: an individual game record
    '''
    __tablename__ = 'game'
    game_id = db.Column(db.Unicode(255),
                        primary_key=True,
                        default=datetime.utcnow().isoformat())
    description = db.Column(db.UnicodeText())
    json = db.Column(db.UnicodeText())
    log = db.Column(db.LargeBinary())
    public = db.Column(db.Boolean())
    started = db.Column(db.DateTime())
    last_updated = db.Column(db.DateTime(), default=datetime.utcnow())
    is_active = db.Column(db.Boolean())

    players = association_proxy('games_players', 'player')
    player_names = association_proxy('games_players', 'player.name')
    scores = association_proxy('games_players', 'score')
    places = association_proxy('games_players', 'place')
    usersgames = db.relationship('UsersGames')

    def __str__(self):
        return ('id: ' + self.game_id + '\n desc: ' + self.description +
                '\n started: ' + str(self.started) + '\n last_updated: ' +
                str(self.last_updated) + '\n public: ' + str(self.public) +
                '\n is_active: ' + str(self.is_active))

    def get_score_table(self):
        json = json_loads(self.json)
        if 'hands' in json and 'deltas' not in json['hands'][-1]:
            del json['hands'][-1]

        return json
예제 #4
0
파일: models.py 프로젝트: homdx/mj-scorer
class Game(db.Model):
    '''
    The heart of the database: an individual game record
    '''
    __tablename__ = 'game'
    id = db.Column(db.Unicode(255), primary_key=True)
    description = db.Column(db.UnicodeText())
    json = db.Column(db.UnicodeText())
    log = db.Column(db.UnicodeText())
    public = db.Column(db.Boolean())
    started = db.Column(db.DateTime())
    last_updated = db.Column(db.DateTime())
    is_active = db.Column(db.Boolean())

    players = association_proxy('games_players', 'player')
    player_names = association_proxy('games_players', 'player.username')
    scores = association_proxy('games_players', 'score')
    places = association_proxy('games_players', 'place')
    usersgames = db.relationship('UsersGames')

    def get_score_table(self):
        hands = json_loads(self.json)['current']
        return hands

        # taken from client app, for repurposing:
        self.__score_table.reset()
        self.__score_table.column_headings[1:] = self.__game_dict['current'][
            'players']
        self.__score_table.starting_points = self.rules.starting_points
        for hand in self.__game_dict['current']['hands']:
            if 'deltas' in hand:
                self.__score_table.add_row(
                    hand['deltas'], hand['dealership'] == 1
                    and hand['hand_redeals'] == 0)
        # if there are results, use them
        if 'net_scores' in self.__game_dict['current']:
            self.__score_table.ids.net_scores.data_items[1:] = \
                self.__game_dict['current']['net_scores']
        if 'uma' in self.__game_dict['current']:
            self.__score_table.ids.scoretable_uma.data_items[1:] = \
                self.__game_dict['current']['uma']
        if 'chombos' in self.__game_dict['current']:
            self.__score_table.ids.scoretable_chombos.data_items[1:] = \
                self.__game_dict['current']['chombos']
        if 'adjustments' in self.__game_dict['current']:
            self.__score_table.ids.scoretable_adjustments.data_items[1:] = \
                self.__game_dict['current']['adjustments']
        if 'final_score' in self.__game_dict['current']:
            self.__score_table.ids.scoretable_final_totals.data_items[1:] = \
                self.__game_dict['current']['final_score']
예제 #5
0
class Season(db.Model):
    '''
    Stores start and end dates of each season
    '''
    __tablename__ = 'season'
    season_id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.UnicodeText(), nullable=False)
    start_date = db.Column(db.DateTime(), nullable=True)
    end_date = db.Column(db.DateTime(), nullable=True)
    ranking = db.Column(db.Float(), nullable=True)
    country = db.Column(db.String(2), nullable=True)
    note = db.Column(db.UnicodeText(), nullable=True)
예제 #6
0
class PlayersGames(db.Model):
    ''' this maps players to games, and provides the score and placement '''
    __tablename = 'playersgames'
    player_id = db.Column('player_id',
                          db.Integer,
                          db.ForeignKey('player.player_id'),
                          primary_key=True)
    game_id = db.Column('game_id',
                        db.Integer,
                        db.ForeignKey('game.game_id'),
                        primary_key=True)
    score = db.Column(db.Integer)
    penalties = db.Column(db.Integer)
    place = db.Column(db.Integer)
    note = db.Column(db.UnicodeText())

    player = db.relationship(
        Player,
        backref=db.backref(
            'played_games',
            lazy='joined',
            cascade="all,delete-orphan",
        ),
    )

    game = db.relationship(
        Game,
        backref=db.backref(
            'games_players',
            lazy='dynamic',
            cascade="all, delete-orphan",
            collection_class=attribute_mapped_collection("place"),
        ),
    )

    def __init__(self, player=None, game=None, score=-9999, place=-1):
        self.player = player
        self.game = game
        self.score = score
        self.place = place
예제 #7
0
class Player(db.Model, UserMixin):
    """
    Currently we work on the basis that every registered player has a website account, and
    every registered website account is a (potential) player. So this class is used
    both for players and for website players, as there's a one-to-one mapping between them.
    """
    __tablename__ = 'player'
    player_id = db.Column(db.Integer, primary_key=True)
    name_last_updated = db.Column(db.DateTime(),
                                  default=datetime.utcnow,
                                  onupdate=datetime.utcnow)
    token = db.Column(db.String(255))
    email = db.Column(db.Unicode(255), unique=True)
    name = db.Column(db.Unicode(255), unique=True)
    login_count = db.Column(db.Integer)
    pin = db.Column(db.String(4), default='0000')
    password_hash = db.Column(db.String(128))
    last_login_at = db.Column(db.DateTime())
    current_login_at = db.Column(db.DateTime())
    login_count = db.Column(db.Integer)
    active = db.Column(db.Boolean(), default=True)
    email_confirmed = db.Column(db.Boolean(), default=False)
    country = db.Column(db.String(2))
    ema_number = db.Column(db.Text())
    note = db.Column(db.UnicodeText())

    games = association_proxy('played_games', 'game')
    games_scores = association_proxy('played_games', 'score')
    games_places = association_proxy('played_games', 'place')
    seasons = association_proxy('played_seasons', 'season')
    seasons_scores = association_proxy('played_seasons', 'score')
    seasons_places = association_proxy('played_seasons', 'place')

    def __repr__(self):
        ''' just for pretty printing '''
        return '<Player {}>'.format(self.name)

    @classmethod
    def check_token(cls, token):
        return cls.query.filter_by(token=token).first()

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

    def create_token(self):
        ''' provide random 4-word sequence for logins '''
        token = ''
        sep = ''
        for idx in random.sample(range(wordlist_len), 4):
            token += sep + wordlist[idx]
            sep = ' '
        self.token = token
        db.session.commit()

    def gdpr_dump(self):

        keys = [
            'id', 'token', 'email', 'name', 'login_count', 'pin',
            'password_hash', 'last_login_at', 'current_login_at',
            'login_count', 'active', 'email_confirmed'
        ]

        out = {}
        for key in keys:
            out[key] = str(getattr(self, key))

        out['games'] = []
        for game in self.games:
            out['games'].append(game.json)

        return jsonify(out)

    @classmethod
    def get_all_names(cls, modified):
        if modified:
            out = db.session.query(cls.player_id, cls.name).filter(
                cls.active == True,
                cls.name_last_updated > modified).order_by(cls.name)
        else:
            out = db.session.query(
                cls.player_id,
                cls.name).filter(cls.active == True).order_by(cls.name)
        return out

    def get_id(self):
        return str(self.player_id)

    def get_token(self):
        '''
        issue an authentication token for logins that is a random 4-word sequence
        and store it with the player in the database.
        Currently, the token does not expire.
        '''
        if not self.token:
            self.create_token()

        return self.token

    def is_active(self):
        return self.active

    def merge_with(self, other):
        '''
        Merge another player into this one. Note that this will currently
        only be used from the shell, as it makes irreversible changes
        that could really mess things up
        '''
        games_to_move = []
        for game in other.games:
            games_to_move.append(game)

        for game in games_to_move:
            player_game = PlayersGames.query.filter_by(
                player_id=other.player_id, game_id=game.game_id).first()
            player_game.player = self
            game_json = json_loads(game.json)
            for player in game_json['players']:
                if player['player_id'] == other.player_id:
                    player['player_id'] = self.player_id
                    player['name'] = self.name

            game.json = json_dumps(game_json)
            db.session.commit()

        db.session.delete(other)
        db.session.commit()

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def set_pin(self, pin):
        self.pin = pin

    def to_dict(self):
        pass

    @classmethod
    def unique_name(cls, name):
        suffix = ''
        counter = 2
        name = name.rstrip('1234567890 ')
        while cls.query.filter_by(name=name + suffix).first():
            suffix = '%d' % counter
            counter += 1

        return name + suffix
예제 #8
0
class Game(db.Model):
    '''
    The heart of the database: an individual game record
    '''
    __tablename__ = 'game'
    game_id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.UnicodeText(), default=make_desc)
    json = db.Column(db.UnicodeText())
    log = db.Column(db.LargeBinary())
    public = db.Column(db.Boolean())
    started = db.Column(db.DateTime())
    last_updated = db.Column(db.DateTime(),
                             default=datetime.utcnow,
                             onupdate=datetime.utcnow)
    is_active = db.Column(db.Boolean())
    season_id = db.Column(
        'season_id',
        db.Integer,
        db.ForeignKey('season.season_id'),
    )
    season_index = db.Column(db.Integer)
    table = db.Column(db.UnicodeText())
    note = db.Column(db.UnicodeText())

    players = association_proxy('games_players', 'player')
    player_names = association_proxy('games_players', 'player.name')
    scores = association_proxy('games_players', 'score')
    places = association_proxy('games_players', 'place')

    def __str__(self):
        return ('id: ' + self.game_id + '\n desc: ' + self.description +
                '\n started: ' + str(self.started) + '\n last_updated: ' +
                str(self.last_updated) + '\n public: ' + str(self.public) +
                '\n is_active: ' + str(self.is_active))

    def get_score_table(self):
        if self.json is None:
            return {}
        json = json_loads(self.json)
        if 'hands' in json and 'deltas' not in json['hands'][-1]:
            del json['hands'][-1]

        return json
예제 #9
0
파일: models.py 프로젝트: homdx/mj-scorer
class User(db.Model, UserMixin):
    '''
    Currently we work on the basis that every registered player has a login, and
    every registered login is a (potential) player. So this class is used
    both for players and for website logins.
    '''
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    token = db.Column(db.String(255))
    email = db.Column(db.Unicode(255), unique=True)
    username = db.Column(db.Unicode(255), unique=True)
    login_count = db.Column(db.Integer)
    pin = db.Column(db.Integer)
    password_hash = db.Column(db.String(128))
    last_login_at = db.Column(db.DateTime())
    current_login_at = db.Column(db.DateTime())
    last_login_ip = db.Column(db.String(100))
    current_login_ip = db.Column(db.String(100))
    login_count = db.Column(db.Integer)
    active = db.Column(db.Boolean(), default=True)
    confirmed_at = db.Column(db.DateTime())

    games = association_proxy('played_games', 'game')
    scores = association_proxy('played_games', 'score')
    places = association_proxy('played_games', 'place')
    usersgames = db.relationship('UsersGames')

    def __repr__(self):
        ''' just for pretty printing '''
        return '<User {}>'.format(self.username)

    @classmethod
    def check_token(cls, token):
        return cls.query.filter_by(token=token).first()

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

    def create_token(self):
        ''' provide random 4-word sequence for logins '''
        token = ''
        sep = ''
        for idx in random.sample(range(wordlist_len), 4):
            token += sep + wordlist[idx]
            sep = ' '
        self.token = token
        db.session.commit()

    @classmethod
    def get_all_usernames(cls):
        query = db.session.query(
            cls.id, cls.username).filter_by(active=True).order_by(cls.username)
        return query.all()

    def get_token(self):
        '''
        issue an authentication token for logins that is a random 4-word sequence
        that lasts 84 days, and store it
        with the user in the database. Renew it if there's less than 28 days life
        left on it.
        '''
        if not self.token:
            self.create_token()

        return self.token

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def set_pin(self, pin):
        self.pin = pin

    def to_dict(self):
        pass