class FlightComment(db.Model): __tablename__ = 'flight_comments' id = db.Column(Integer, autoincrement=True, primary_key=True) time_created = db.Column(DateTime, nullable=False, default=datetime.utcnow) flight_id = db.Column(Integer, db.ForeignKey('flights.id', ondelete='CASCADE'), nullable=False, index=True) flight = db.relationship('Flight', innerjoin=True, backref=db.backref('comments', order_by=time_created, passive_deletes=True)) user_id = db.Column(Integer, db.ForeignKey('users.id', ondelete='SET NULL')) user = db.relationship('User', lazy='joined') def __repr__(self): return ( '<FlightComment: id=%d user_id=%d flight_id=%d>' % (self.id, self.user_id, self.flight_id)).encode('unicode_escape') text = db.Column(Unicode, nullable=False)
class UnlockedAchievement(db.Model): __tablename__ = 'achievements' __table_args__ = (db.UniqueConstraint('name', 'pilot_id', name='unique_achievement'), ) id = Column(Integer, autoincrement=True, primary_key=True) time_created = Column(DateTime, nullable=False, default=datetime.utcnow) time_achieved = Column(DateTime, nullable=False, default=datetime.utcnow) name = Column(String(), nullable=False, index=True) pilot_id = db.Column(Integer, db.ForeignKey('users.id', ondelete='CASCADE'), index=True, nullable=False) pilot = db.relationship('User', foreign_keys=[pilot_id], backref='achievements') flight_id = db.Column(Integer, db.ForeignKey('flights.id', ondelete='CASCADE'), index=True) flight = db.relationship('Flight', foreign_keys=[flight_id], backref=db.backref('achievements', order_by=name, passive_deletes=True)) def __repr__(self): r = "<UnlockedAchievement %s: id=%s>" % (self.name, self.id) return r.encode('utf-8') @property def title(self): return get_achievement(self.name).title
class Trace(db.Model): """ This table saves the locations and visiting times of the turnpoints of an optimized Flight. """ __tablename__ = 'traces' id = db.Column(Integer, autoincrement=True, primary_key=True) flight_id = db.Column(Integer, db.ForeignKey('flights.id', ondelete='CASCADE'), nullable=False) flight = db.relationship('Flight', innerjoin=True, backref=db.backref('traces', passive_deletes=True)) contest_type = db.Column(String, nullable=False) trace_type = db.Column(String, nullable=False) distance = db.Column(Integer) duration = db.Column(Interval) times = db.Column(postgresql.ARRAY(DateTime), nullable=False) _locations = db.Column('locations', Geometry('LINESTRING', srid=4326), nullable=False) @property def speed(self): if self.distance is None or self.duration is None: return None return float(self.distance) / self.duration.total_seconds() @property def locations(self): return [ Location(longitude=location[0], latitude=location[1]) for location in to_shape(self._locations).coords ] @locations.setter def locations(self, locations): points = [ '{} {}'.format(location.longitude, location.latitude) for location in locations ] wkt = "LINESTRING({})".format(','.join(points)) self._locations = WKTElement(wkt, srid=4326)
class FlightPhase(db.Model): __tablename__ = 'flight_phases' # Flight phase types PT_POWERED = 1 PT_CRUISE = 2 PT_CIRCLING = 3 # Circling directions CD_LEFT = 1 CD_MIXED = 2 CD_RIGHT = 3 CD_TOTAL = 4 id = db.Column(Integer, primary_key=True, autoincrement=True) flight_id = db.Column(Integer, db.ForeignKey('flights.id', ondelete='CASCADE'), nullable=False, index=True) start_time = db.Column(DateTime) end_time = db.Column(DateTime) flight = db.relationship('Flight', innerjoin=True, backref=db.backref( '_phases', passive_deletes=True, order_by=start_time, cascade='all, delete, delete-orphan')) aggregate = db.Column(Boolean, nullable=False) phase_type = db.Column(Integer) # see PT_* constants circling_direction = db.Column(Integer) # see CD_* constants alt_diff = db.Column(Integer) duration = db.Column(Interval) fraction = db.Column(Integer) distance = db.Column(Integer) speed = db.Column(Float) vario = db.Column(Float) glide_rate = db.Column(Float) count = db.Column(Integer, nullable=False)
class ContestLeg(db.Model): """ This table saves the legs of a optimized Flight. """ __tablename__ = 'contest_legs' id = db.Column(Integer, autoincrement=True, primary_key=True) flight_id = db.Column(Integer, db.ForeignKey('flights.id', ondelete='CASCADE'), nullable=False, index=True) flight = db.relationship('Flight', innerjoin=True, backref=db.backref( '_legs', passive_deletes=True, cascade='all, delete, delete-orphan')) contest_type = db.Column(String, nullable=False) trace_type = db.Column(String, nullable=False) # direct distance from start to end distance = db.Column(Integer) # total height and duration of cruise phases cruise_height = db.Column(Integer) cruise_distance = db.Column(Integer) cruise_duration = db.Column(Interval) # total height and duration of climb phases climb_height = db.Column(Integer) climb_duration = db.Column(Interval) # start and end height start_height = db.Column(Integer) end_height = db.Column(Integer) # start and end time start_time = db.Column(DateTime, nullable=False) end_time = db.Column(DateTime, nullable=False) # start and end locations start_location_wkt = db.Column('start_location', Geometry('POINT', srid=4326)) end_location_wkt = db.Column('end_location', Geometry('POINT', srid=4326)) @property def duration(self): return self.end_time - self.start_time @property def speed(self): if self.distance is None: return None return float(self.distance) / self.duration.total_seconds() @property def start_location(self): if self.start_location_wkt is None: return None coords = to_shape(self.start_location_wkt) return Location(latitude=coords.y, longitude=coords.x) @start_location.setter def start_location(self, location): if location is None: self.start_location_wkt = None else: self.start_location_wkt = location.to_wkt_element() @property def end_location(self): if self.end_location_wkt is None: return None coords = to_shape(self.end_location_wkt) return Location(latitude=coords.y, longitude=coords.x) @end_location.setter def end_location(self, location): if location is None: self.end_location_wkt = None else: self.end_location_wkt = location.to_wkt_element()