Created
November 23, 2013 20:22
-
-
Save dsmith/7619451 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sqlalchemy.ext.associationproxy import association_proxy | |
from sqlalchemy.orm.collections import attribute_mapped_collection | |
from theleagues import db | |
from theleagues import mongodb | |
from theleagues.competitions import constants as COMPETITIONS | |
from theleagues.mixins import ImportableModel, UniqueModelMixin, APIModelMixin | |
from theleagues.sports import constants as SPORTS | |
from theleagues.competitors import constants as COMPETITORS | |
from theleagues.sports.models import Color, Group, CompetitionCompetitor | |
class Competitor(db.Model, APIModelMixin): | |
"""Base model for anything that can compete in a competition. | |
Including, but not limited to: Player, Team, Country, etc. | |
""" | |
__tablename__ = 'competitor' | |
id = db.Column(db.Integer, primary_key=True) | |
type = db.Column(db.String(20)) | |
# proxies | |
competitions = association_proxy('competitor_competitions', 'competition', | |
creator=lambda competition: CompetitionCompetitor(competition=competition)) | |
__mapper_args__ = { | |
'polymorphic_on': type, | |
'polymorphic_identity': 'competitor', | |
'with_polymorphic': '*' | |
} | |
@classmethod | |
def importable_type(cls): | |
return cls.__tablename__ | |
class Player(Competitor, ImportableModel, UniqueModelMixin): | |
"""A competitor represented by a single person.""" | |
__tablename__ = 'player' | |
id = db.Column(db.Integer, db.ForeignKey('competitor.id'), primary_key=True) | |
first_name = db.Column(db.String(50)) | |
last_name = db.Column(db.String(50)) | |
pic_url = db.Column(db.String(100)) | |
hometown = db.Column(db.String(50)) | |
weight = db.Column(db.Integer) | |
height = db.Column(db.Integer) | |
__mapper_args__ = { | |
'polymorphic_identity': 'player' | |
} | |
def __init__(self, first_name, last_name): | |
self.first_name = first_name | |
self.last_name = last_name | |
def __repr__(self): | |
return '%s %s' % (self.first_name, self.last_name, ) | |
@classmethod | |
def unique_hash(cls): | |
pass | |
@classmethod | |
def unique_filter(cls): | |
pass | |
@classmethod | |
def importable_type(cls): | |
return cls.__tablename__ | |
def api_property_names(self): | |
return ('id', 'type', 'league_id', 'first_name', 'last_name', 'pic_url') | |
class BaseballPlayer(Player, ImportableModel): | |
__tablename__ = 'baseball_player' | |
id = db.Column(db.Integer, db.ForeignKey('competitor.id'), | |
primary_key=True) | |
bats = db.Column(db.Integer) | |
throws = db.Column(db.Enum(*COMPETITORS.HAND_TYPE)) | |
bats = db.Column(db.Enum(*COMPETITORS.HAND_TYPE)) | |
number = db.Column(db.Integer) | |
experience = db.Column(db.Integer) | |
__mapper_args__ = { | |
'polymorphic_identity': 'baseball_player' | |
} | |
class Team(Competitor, ImportableModel, UniqueModelMixin): | |
"""A group of players that compete together.""" | |
__tablename__ = 'team' | |
id = db.Column(db.Integer, db.ForeignKey('competitor.id'), primary_key=True) | |
location = db.Column(db.String(50)) | |
name = db.Column(db.String(50)) | |
abbreviation = db.Column(db.String(5)) | |
logo_url = db.Column(db.String(100)) | |
# proxies | |
players = association_proxy('team_players', 'player') | |
# TODO: It may make sense to move this to the Competitor class at some point | |
colors = association_proxy('team_colors', 'c', | |
creator=lambda k, v: TeamColor(color=v, priority=k)) | |
__mapper_args__ = { | |
'polymorphic_identity': 'team' | |
} | |
def __init__(self, location, name): | |
self.location = location | |
self.name = name | |
def __repr__(self): | |
return '%s %s' % (self.location, self.name, ) | |
@classmethod | |
def importable_type(cls): | |
return cls.__tablename__ | |
@classmethod | |
def from_json(cls, data): | |
team = Team.as_unique(data['location'], data['name']) | |
if 'abbreviation' in data: | |
team.abbreviation = data['abbreviation'] | |
team.logo_url = data['logo_url'] | |
if 'colors' in data: | |
for color in data['colors']: | |
team.add_color(**color) | |
if 'groups' in data: | |
for g in data['groups']: | |
group = Group.as_unique(g['type'], g['identifier']) | |
group.competitors.append(team) | |
return team | |
@classmethod | |
def get(cls, location, name): | |
return Team.query.filter_by(location=location, name=name).first() | |
@classmethod | |
def unique_hash(cls, location, name): | |
return '%s:%s' % (location, name,) | |
@classmethod | |
def unique_filter(cls, query, location, name): | |
return query.filter_by(location=location, name=name) | |
def api_property_names(self): | |
return ( | |
'id', 'type', 'league_id', 'location', 'name', 'abbreviation', 'logo_url', 'colors' | |
) | |
def api_related_resource_property_names(self): | |
return ('players', ) | |
def add_color(self, name, hex_value, type='primary'): | |
color = Color(name=name, hex_value=hex_value) | |
self.colors[type] = color | |
return color | |
class TeamColor(db.Model, ImportableModel): | |
"""Association table representing colors for a team""" | |
__tablename__ = 'team_color' | |
team_id = db.Column(db.Integer, db.ForeignKey('team.id'), primary_key=True) | |
color_id = db.Column(db.Integer, db.ForeignKey('color.id'), primary_key=True) | |
priority = db.Column(db.SmallInteger, default=SPORTS.PRIMARY) | |
# relationships | |
team = db.relationship('Team', | |
backref=db.backref( | |
'team_colors', collection_class=attribute_mapped_collection('priority') | |
) | |
) | |
color = db.relationship('Color') | |
# proxies | |
c = association_proxy('color', 'hex_value') | |
@classmethod | |
def importable_type(cls): | |
return cls.__tablename__ | |
class PlayerDocument(mongodb.DynamicDocument): | |
source = mongodb.StringField(max_length=50) | |
tags = mongodb.ListField() | |
league_id = mongodb.IntField() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment