1 from __future__
import unicode_literals
2 from sqlalchemy.ext.declarative
import declared_attr
3 from sqlalchemy.orm
import backref, relationship
4 from sqlalchemy.schema
import Column, ForeignKey
5 from sqlalchemy.types
import DateTime, Integer, Numeric, SmallInteger
13 __tablename__ =
'workouts'
14 __mapper_args__ = {
'polymorphic_on':
'challenge_type_id',
'with_polymorphic':
'*'}
15 id = Column(Integer(unsigned=
True), primary_key=
True)
16 user_id = Column(Integer(unsigned=
True), ForeignKey(
'users.id'), nullable=
False)
17 challenge_id = Column(Integer(unsigned=
True), ForeignKey(
'challenges.id'), nullable=
False)
18 challenge_type_id = Column(
19 Integer(unsigned=
True), ForeignKey(
'challenge_types.id', ondelete=
'cascade'),
21 points = Column(SmallInteger(unsigned=
True), nullable=
False)
22 created_at = Column(DateTime, nullable=
False, default=current_timestamp)
25 'User', lazy=
'joined', backref=backref(
'workouts', lazy=
'dynamic'))
26 challenge = relationship(
27 'Challenge', lazy=
'joined', backref=backref(
'workouts', lazy=
'dynamic'))
35 Integer(unsigned=
True), ForeignKey(
'workouts.id', ondelete=
'cascade'),
46 def create(cls, user, challenge, samples):
47 return super(DeviceWorkout, cls).
create(
48 user=user, challenge=challenge, samples=samples)
57 repetitions = Column(SmallInteger(unsigned=
True), nullable=
False)
60 def create(cls, user, challenge, repetitions):
61 return super(WeightWorkout, cls).
create(
62 user=user, challenge=challenge, repetitions=repetitions)
67 __tablename__ =
'speed_workouts'
68 __mapper_args__ = {
'polymorphic_identity': ChallengeType.lookup_data.index(
'speed') + 1}
69 speed = Column(Numeric(4, 2), nullable=
False, doc=
'speed in meters per second')
74 total_distance = samples[
'distance'][-1]
75 if not total_distance >= challenge.distance:
79 distance_samples = zip(samples[
'timestamp'], samples[
'distance'])
81 for t, d
in distance_samples:
82 if d >= challenge.distance:
86 self.
speed = float(distance / time)
88 avg_speed = user.get_average_speed(challenge.distance)
90 delta = 100 * float(self.
speed - avg_speed) / avg_speed
101 __tablename__ =
'endurance_workouts'
102 __mapper_args__ = {
'polymorphic_identity': ChallengeType.lookup_data.index(
'endurance') + 1}
103 heart_rate = Column(SmallInteger(unsigned=
True), nullable=
False)
104 calories_burned = Column(SmallInteger(unsigned=
True), nullable=
False)
109 total_duration = samples[
'timestamp'][-1] / 1000.0
110 total_duration = total_duration / 60.0
111 if not total_duration >= challenge.duration:
115 duration = challenge.duration * 60.0 * 1000.0
116 heart_rate_samples = zip(samples[
'timestamp'], samples[
'heart_rate'])
117 calories_burned_samples = zip(samples[
'timestamp'], samples[
'calories_burned'])
120 for t, h
in heart_rate_samples:
124 for t, c
in calories_burned_samples:
127 self.
heart_rate = float(sum(heart_rate)) / len(heart_rate)
130 avg_heart_rate = user.get_average_heart_rate(challenge.duration)
131 avg_calories_burned = user.get_average_calories_burned(challenge.duration)
133 delta = 100 * float(self.
heart_rate - avg_heart_rate) / avg_heart_rate
140 if avg_calories_burned:
141 delta = 100 * float(self.
calories_burned - avg_calories_burned) / avg_calories_burned
152 __tablename__ =
'bench_press_workouts'
153 __mapper_args__ = {
'polymorphic_identity': ChallengeType.lookup_data.index(
'bench_press') + 1}
159 self.
points = challenge.calculate_user_weight(user) * repetitions
160 avg_repetitions = user.get_average_bench_press_repetitions(challenge.percentage)
162 delta = 100 * float(self.
repetitions - avg_repetitions) / avg_repetitions
175 __tablename__ =
'squat_workouts'
176 __mapper_args__ = {
'polymorphic_identity': ChallengeType.lookup_data.index(
'squat') + 1}
182 self.
points = challenge.calculate_user_weight(user) * repetitions
183 avg_repetitions = user.get_average_squat_repetitions(challenge.percentage)
185 delta = 100 * float(repetitions - avg_repetitions) / avg_repetitions