def get_flight_path2(pilot, last_update=None): query = DBSession.query(TrackingFix) query = query.filter(and_(TrackingFix.pilot == pilot, TrackingFix.location != None, TrackingFix.altitude != None, TrackingFix.max_age_filter(12))) if pilot.tracking_delay > 0 and not pilot.is_readable(request.identity): query = query.filter(TrackingFix.delay_filter(pilot.tracking_delay)) query = query.order_by(TrackingFix.time) start_fix = query.first() if not start_fix: return None start_time = start_fix.time.hour * 3600 + start_fix.time.minute * 60 + start_fix.time.second if last_update: query = query.filter(TrackingFix.time >= start_fix.time + timedelta(seconds=(last_update - start_time))) result = [] for fix in query: location = fix.location if location is None: continue time_delta = fix.time - start_fix.time time = start_time + time_delta.days * 86400 + time_delta.seconds result.append((time, location.latitude, location.longitude, fix.altitude, fix.engine_noise_level)) return result
def run(self, user): i = randint(0, 100) _longitude = randint(6500, 7500) / 1000. _latitude = randint(50500, 51500) / 1000. _altitude = 500 while True: longitude = sin(i / 73.) * 0.001 + _longitude latitude = sin(i / 50.) * 0.004 + _latitude altitude = sin(i / 20.) * 300 + _altitude fix = TrackingFix() fix.pilot_id = user fix.set_location(longitude, latitude) fix.altitude = altitude db.session.add(fix) db.session.commit() print '.', sys.stdout.flush() sleep(1) i += 1
def _get_flight_path2(pilot, last_update=None): query = TrackingFix.query().filter( and_( TrackingFix.pilot == pilot, TrackingFix.location != None, TrackingFix.altitude != None, TrackingFix.max_age_filter(12), TrackingFix.time_visible <= datetime.utcnow(), ) ) query = query.order_by(TrackingFix.time) start_fix = query.first() if not start_fix: return None start_time = ( start_fix.time.hour * 3600 + start_fix.time.minute * 60 + start_fix.time.second ) if last_update: query = query.filter( TrackingFix.time >= start_fix.time + timedelta(seconds=(last_update - start_time)) ) result = [] for fix in query: location = fix.location if location is None: continue time_delta = fix.time - start_fix.time time = start_time + time_delta.days * 86400 + time_delta.seconds result.append( FlightPathFix( datetime=fix.time, seconds_of_day=time, location={ "latitude": location.latitude, "longitude": location.longitude, }, gps_altitude=fix.altitude, enl=fix.engine_noise_level, track=fix.track, groundspeed=fix.ground_speed, tas=fix.airspeed, elevation=fix.elevation, ) ) return result
def _parse_fix(pilot_id): fix = TrackingFix() fix.ip = request.remote_addr fix.pilot_id = pilot_id # Time if 'tm' not in request.values: raise BadRequest('`tm` (time) parameter is missing.') try: fix.time = datetime.utcfromtimestamp(int(request.values['tm'])) except ValueError: raise BadRequest('`tm` (time) has to be a POSIX timestamp.') # Location if 'lat' in request.values and 'lon' in request.values: try: fix.set_location(float(request.values['lon']), float(request.values['lat'])) except ValueError: raise BadRequest('`lat` and `lon` have to be floating point value in degrees (WGS84).') # Altitude if 'alt' in request.values: try: fix.altitude = int(request.values['alt']) except ValueError: raise BadRequest('`alt` has to be an integer value in meters.') if not -1000 <= fix.altitude <= 15000: raise BadRequest('`alt` has to be a valid altitude in the range of -1000 to 15000 meters.') # Speed if 'sog' in request.values: try: fix.ground_speed = int(request.values['sog']) / 3.6 except ValueError: raise BadRequest('`sog` (speed over ground) has to be an integer value in km/h.') if not 0 <= fix.ground_speed <= (500 / 3.6): raise BadRequest('`sog` (speed over ground) has to be a valid speed in the range of 0 to 500 km/h.') # Track if 'cog' in request.values: try: fix.track = int(request.values['cog']) except ValueError: raise BadRequest('`cog` (course over ground) has to be an integer value in degrees.') if not 0 <= fix.track < 360: raise BadRequest('`cog` (course over ground) has to be a valid angle between 0 and 360 degrees.') fix.elevation = Elevation.get(fix.location_wkt) return fix
def test_empty_fix(self): """ Tracking server accepts empty fixes """ # Create fake fix message message = self.create_fix_message(123456, 0) utcnow_return_value = datetime(year=2005, month=4, day=13) with patch('skylines.tracking.server.datetime') as datetime_mock: datetime_mock.combine.side_effect = \ lambda *args, **kw: datetime.combine(*args, **kw) # Connect utcnow mockup datetime_mock.utcnow.return_value = utcnow_return_value # Send fake ping message self.server.datagramReceived(message, self.HOST_PORT) # Check if the message was properly received and written to the database fixes = TrackingFix.query().all() eq_(len(fixes), 1) fix = fixes[0] eq_(fix.ip, self.HOST_PORT[0]) eq_(fix.time, utcnow_return_value) eq_(fix.location_wkt, None) eq_(fix.track, None) eq_(fix.ground_speed, None) eq_(fix.airspeed, None) eq_(fix.altitude, None) eq_(fix.vario, None) eq_(fix.engine_noise_level, None)
def test_empty_fix(server, test_user): """ Tracking server accepts empty fixes """ # Create fake fix message message = create_fix_message(test_user.tracking_key, 0) utcnow_return_value = datetime(year=2005, month=4, day=13) with patch("skylines.tracking.server.datetime") as datetime_mock: datetime_mock.combine.side_effect = lambda *args, **kw: datetime.combine(*args, **kw) # Connect utcnow mockup datetime_mock.utcnow.return_value = utcnow_return_value # Send fake ping message server.handle(message, HOST_PORT) # Check if the message was properly received and written to the database fixes = TrackingFix.query().all() assert len(fixes) == 1 fix = fixes[0] assert fix.ip == HOST_PORT[0] assert fix.time == utcnow_return_value assert fix.location_wkt is None assert fix.track is None assert fix.ground_speed is None assert fix.airspeed is None assert fix.altitude is None assert fix.vario is None assert fix.engine_noise_level is None
def index(): fix_schema = TrackingFixSchema(only=('time', 'location', 'altitude', 'elevation', 'pilot')) airport_schema = AirportSchema(only=('id', 'name', 'countryCode')) @cache.memoize(timeout=(60 * 60)) def get_nearest_airport(track): airport = Airport.by_location(track.location, None) if not airport: return None return dict(airport=airport_schema.dump(airport).data, distance=airport.distance(track.location)) tracks = [] for t in TrackingFix.get_latest(): nearest_airport = get_nearest_airport(t) track = fix_schema.dump(t).data if nearest_airport: track['nearestAirport'] = nearest_airport['airport'] track['nearestAirportDistance'] = nearest_airport['distance'] tracks.append(track) if request.user_id: followers = [f.destination_id for f in Follower.query(source_id=request.user_id)] else: followers = [] return jsonify(friends=followers, tracks=tracks)
def index(): if 'application/json' not in request.headers.get('Accept', ''): return render_template('ember-page.jinja', active_page='tracking') fix_schema = TrackingFixSchema(only=('time', 'location', 'altitude', 'elevation', 'pilot')) airport_schema = AirportSchema(only=('id', 'name', 'countryCode')) @current_app.cache.memoize(timeout=(60 * 60)) def get_nearest_airport(track): airport = Airport.by_location(track.location, None) if not airport: return None return dict(airport=airport_schema.dump(airport).data, distance=airport.distance(track.location)) tracks = [] for t in TrackingFix.get_latest(): nearest_airport = get_nearest_airport(t) track = fix_schema.dump(t).data if nearest_airport: track['nearestAirport'] = nearest_airport['airport'] track['nearestAirportDistance'] = nearest_airport['distance'] tracks.append(track) if g.current_user: followers = [f.destination_id for f in Follower.query(source=g.current_user)] else: followers = [] return jsonify(friends=followers, tracks=tracks)
def latest(): fixes = [] for fix in TrackingFix.get_latest(): json = dict( time=fix.time.isoformat() + "Z", location=fix.location.to_wkt(), pilot=dict(id=fix.pilot_id, name=fix.pilot.name), ) optional_attributes = [ "track", "ground_speed", "airspeed", "altitude", "vario", "engine_noise_level", ] for attr in optional_attributes: value = getattr(fix, attr) if value is not None: json[attr] = value fixes.append(json) return jsonify(fixes=fixes)
def trafficRequestReceived(self, host, port, key, payload): if len(payload) != 8: return pilot = User.by_tracking_key(key) if pilot is None: log.err("No such pilot: %d" % key) return data = struct.unpack('!II', payload) or_filters = [] flags = data[0] if flags & TRAFFIC_FLAG_FOLLOWEES: subq = db.session \ .query(Follower.destination_id) \ .filter(Follower.source_id == pilot.id) \ .subquery() or_filters.append(TrackingFix.pilot_id.in_(subq)) if flags & TRAFFIC_FLAG_CLUB: subq = db.session \ .query(User.id) \ .filter(User.club_id == pilot.club_id) \ .subquery() or_filters.append(TrackingFix.pilot_id.in_(subq)) if len(or_filters) == 0: return query = TrackingFix.query() \ .distinct(TrackingFix.pilot_id) \ .filter(and_(TrackingFix.time >= datetime.utcnow() - timedelta(hours=2), TrackingFix.pilot_id != pilot.id, TrackingFix.location_wkt != None, TrackingFix.altitude != None, or_(*or_filters))) \ .order_by(TrackingFix.pilot_id, TrackingFix.time.desc()) \ .limit(32) response = '' count = 0 for fix in query: location = fix.location if location is None: continue t = fix.time t = t.hour * 3600000 + t.minute * 60000 + t.second * 1000 + t.microsecond / 1000 response += struct.pack('!IIiihHI', fix.pilot_id, t, int(location.latitude * 1000000), int(location.longitude * 1000000), int(fix.altitude), 0, 0) count += 1 response = struct.pack('!HBBI', 0, 0, count, 0) + response response = struct.pack('!IHHQ', MAGIC, 0, TYPE_TRAFFIC_RESPONSE, 0) + response response = set_crc(response) self.transport.write(response, (host, port))
def run(self, user_id): user = User.get(user_id) if not user: print 'User with id "{}" not found.'.format(user_id) sys.exit(1) i = randint(0, 100) _longitude = randint(6500, 7500) / 1000. _latitude = randint(50500, 51500) / 1000. _altitude = 500 while True: longitude = sin(i / 73.) * 0.001 + _longitude latitude = sin(i / 50.) * 0.004 + _latitude altitude = sin(i / 20.) * 300 + _altitude fix = TrackingFix() fix.pilot = user fix.set_location(longitude, latitude) fix.altitude = altitude fix.time = datetime.now() fix.time_visible = fix.time + timedelta(minutes=user.tracking_delay) db.session.add(fix) db.session.commit() print '.', sys.stdout.flush() sleep(1) i += 1
def _get_flight_path2(pilot, last_update=None): query = TrackingFix.query() \ .filter(and_(TrackingFix.pilot == pilot, TrackingFix.location != None, TrackingFix.altitude != None, TrackingFix.max_age_filter(12))) if pilot.tracking_delay > 0 and not pilot.is_readable(g.current_user): query = query.filter(TrackingFix.delay_filter(pilot.tracking_delay)) query = query.order_by(TrackingFix.time) start_fix = query.first() if not start_fix: return None start_time = start_fix.time.hour * 3600 + start_fix.time.minute * 60 + start_fix.time.second if last_update: query = query.filter(TrackingFix.time >= start_fix.time + timedelta(seconds=(last_update - start_time))) result = [] for fix in query: location = fix.location if location is None: continue time_delta = fix.time - start_fix.time time = start_time + time_delta.days * 86400 + time_delta.seconds result.append(FlightPathFix(datetime=fix.time, seconds_of_day=time, location={'latitude': location.latitude, 'longitude': location.longitude}, gps_altitude=fix.altitude, enl=fix.engine_noise_level, track=fix.track, groundspeed=fix.ground_speed, tas=fix.airspeed, elevation=fix.elevation)) return result
def test_empty_tracking_key(server): """ Tracking server declines fixes without tracking key """ # Create fake fix message message = create_fix_message(0, 0) # Send fake ping message server.handle(message, HOST_PORT) # Check if the message was properly received assert TrackingFix.query().count() == 0
def test_empty_tracking_key(self): """ Tracking server declines fixes without tracking key """ # Create fake fix message message = self.create_fix_message(0, 0) # Send fake ping message self.server.datagramReceived(message, self.HOST_PORT) # Check if the message was properly received eq_(TrackingFix.query().count(), 0)
def test_real_fix(server, test_user): """ Tracking server accepts real fixes """ utcnow_return_value = datetime( year=2013, month=1, day=1, hour=12, minute=34, second=56 ) # Create fake fix message now = utcnow_return_value now_s = ((now.hour * 60) + now.minute) * 60 + now.second message = create_fix_message( test_user.tracking_key, now_s * 1000, latitude=52.7, longitude=7.52, track=234, ground_speed=33.25, airspeed=32.0, altitude=1234, vario=2.25, enl=10, ) with patch("skylines.tracking.server.datetime") as datetime_mock: datetime_mock.combine.side_effect = lambda *args, **kw: datetime.combine( *args, **kw ) # Connect utcnow mockup datetime_mock.utcnow.return_value = utcnow_return_value # Send fake ping message server.handle(message, HOST_PORT) # Check if the message was properly received and written to the database fixes = TrackingFix.query().all() assert len(fixes) == 1 fix = fixes[0] assert fix.ip == HOST_PORT[0] assert fix.time == utcnow_return_value assert fix.time_visible == utcnow_return_value + timedelta(minutes=2) assert fix.location.to_wkt() == "POINT(7.52 52.7)" assert fix.track == 234 assert fix.ground_speed == 33.25 assert fix.airspeed == 32.0 assert fix.altitude == 1234 assert fix.vario == 2.25 assert fix.engine_noise_level == 10
def test_failing_fix(server, test_user): """ Tracking server handles SQLAlchemyError gracefully """ # Mock the transaction commit to fail commitmock = Mock(side_effect=SQLAlchemyError()) with patch.object(db.session, "commit", commitmock): # Create fake fix message message = create_fix_message(test_user.tracking_key, 0) # Send fake ping message server.handle(message, HOST_PORT) # Check if the message was properly received assert TrackingFix.query().count() == 0 assert commitmock.called
def test_failing_fix(self): """ Tracking server handles SQLAlchemyError gracefully """ # Mock the transaction commit to fail commitmock = Mock(side_effect=SQLAlchemyError()) with patch.object(db.session, 'commit', commitmock): # Create fake fix message message = self.create_fix_message(123456, 0) # Send fake ping message self.server.datagramReceived(message, self.HOST_PORT) # Check if the message was properly received eq_(TrackingFix.query().count(), 0) ok_(commitmock.called)
def latest(): fixes = [] for fix in TrackingFix.get_latest(): json = dict(time=isoformat_utc(fix.time), location=fix.location.to_wkt(), pilot=dict(id=fix.pilot_id, name=unicode(fix.pilot))) optional_attributes = ['track', 'ground_speed', 'airspeed', 'altitude', 'vario', 'engine_noise_level'] for attr in optional_attributes: value = getattr(fix, attr) if value is not None: json[attr] = value fixes.append(json) return jsonify(fixes=fixes)
def test_failing_fix(server, test_user): """ Tracking server handles SQLAlchemyError gracefully """ now = datetime.utcnow() now_s = ((now.hour * 60) + now.minute) * 60 + now.second # Mock the transaction commit to fail commitmock = Mock(side_effect=SQLAlchemyError()) with patch.object(db.session, 'commit', commitmock): # Create fake fix message message = create_fix_message(test_user.tracking_key, now_s * 1000) # Send fake ping message server.handle(message, HOST_PORT) # Check if the message was properly received assert TrackingFix.query().count() == 0 assert commitmock.called
def index(self, **kw): na_cache = cache.get_cache('tracking.nearest_airport', expire=60 * 60) def add_nearest_airport_data(track): def get_nearest_airport(): airport = Airport.by_location(track.location, None) if airport is None: return None, None distance = airport.distance(track.location) return airport, distance airport, distance = na_cache.get(key=track.id, createfunc=get_nearest_airport) return track, airport, distance tracks = [] tracks.extend(map(add_nearest_airport_data, TrackingFix.get_latest())) return dict(tracks=tracks)
def latest(self, **kw): if not request.path.endswith('.json'): raise HTTPNotFound fixes = [] for fix in TrackingFix.get_latest(): json = dict(time=isoformat_utc(fix.time), location=fix.location_wkt.geom_wkt, pilot=dict(id=fix.pilot_id, name=unicode(fix.pilot))) optional_attributes = ['track', 'ground_speed', 'airspeed', 'altitude', 'vario', 'engine_noise_level'] for attr in optional_attributes: value = getattr(fix, attr) if value is not None: json[attr] = value fixes.append(json) return dict(fixes=fixes)
def test_real_fix(self): """ Tracking server accepts real fixes """ utcnow_return_value = datetime(year=2013, month=1, day=1, hour=12, minute=34, second=56) # Create fake fix message now = utcnow_return_value now_s = ((now.hour * 60) + now.minute) * 60 + now.second message = self.create_fix_message( 123456, now_s * 1000, latitude=52.7, longitude=7.52, track=234, ground_speed=33.25, airspeed=32., altitude=1234, vario=2.25, enl=10) with patch('skylines.tracking.server.datetime') as datetime_mock: datetime_mock.combine.side_effect = \ lambda *args, **kw: datetime.combine(*args, **kw) # Connect utcnow mockup datetime_mock.utcnow.return_value = utcnow_return_value # Send fake ping message self.server.datagramReceived(message, self.HOST_PORT) # Check if the message was properly received and written to the database fixes = TrackingFix.query().all() eq_(len(fixes), 1) fix = fixes[0] eq_(fix.ip, self.HOST_PORT[0]) eq_(fix.time, utcnow_return_value) eq_(fix.location.to_wkt(), 'POINT(7.52 52.7)') eq_(fix.track, 234) eq_(fix.ground_speed, 33.25) eq_(fix.airspeed, 32.) eq_(fix.altitude, 1234) eq_(fix.vario, 2.25) eq_(fix.engine_noise_level, 10)
def index(): tracks = TrackingFix.get_latest() @current_app.cache.memoize(timeout=(60 * 60)) def get_nearest_airport(track): airport = Airport.by_location(track.location, None) if not airport: return None distance = airport.distance(track.location) return { 'name': airport.name, 'country_code': airport.country_code, 'distance': distance, } tracks = [(track, get_nearest_airport(track)) for track in tracks] if g.current_user: followers = [ f.destination_id for f in Follower.query(source=g.current_user) ] def is_self_or_follower(track): pilot_id = track[0].pilot_id return pilot_id == g.current_user.id or pilot_id in followers friend_tracks = [t for t in tracks if is_self_or_follower(t)] other_tracks = [t for t in tracks if t not in friend_tracks] else: friend_tracks = [] other_tracks = tracks return render_template('tracking/list.jinja', friend_tracks=friend_tracks, other_tracks=other_tracks)
def index(): tracks = TrackingFix.get_latest() @current_app.cache.memoize(timeout=(60 * 60)) def get_nearest_airport(track): airport = Airport.by_location(track.location, None) if not airport: return None distance = airport.distance(track.location) return { 'name': airport.name, 'country_code': airport.country_code, 'distance': distance, } tracks = [(track, get_nearest_airport(track)) for track in tracks] if g.current_user: followers = [f.destination_id for f in Follower.query(source=g.current_user)] def is_self_or_follower(track): pilot_id = track[0].pilot_id return pilot_id == g.current_user.id or pilot_id in followers friend_tracks = [t for t in tracks if is_self_or_follower(t)] other_tracks = [t for t in tracks if t not in friend_tracks] else: friend_tracks = [] other_tracks = tracks return render_template('tracking/list.jinja', friend_tracks=friend_tracks, other_tracks=other_tracks)
def index(): if 'application/json' not in request.headers.get('Accept', ''): return render_template('ember-page.jinja', active_page='tracking') fix_schema = TrackingFixSchema(only=('time', 'location', 'altitude', 'elevation', 'pilot')) airport_schema = AirportSchema(only=('id', 'name', 'countryCode')) @current_app.cache.memoize(timeout=(60 * 60)) def get_nearest_airport(track): airport = Airport.by_location(track.location, None) if not airport: return None return dict(airport=airport_schema.dump(airport).data, distance=airport.distance(track.location)) tracks = [] for t in TrackingFix.get_latest(): nearest_airport = get_nearest_airport(t) track = fix_schema.dump(t).data if nearest_airport: track['nearestAirport'] = nearest_airport['airport'] track['nearestAirportDistance'] = nearest_airport['distance'] tracks.append(track) if g.current_user: followers = [ f.destination_id for f in Follower.query(source=g.current_user) ] else: followers = [] return jsonify(friends=followers, tracks=tracks)
def index(): fix_schema = TrackingFixSchema( only=("time", "location", "altitude", "elevation", "pilot") ) airport_schema = AirportSchema(only=("id", "name", "countryCode")) @cache.memoize(timeout=(60 * 60)) def get_nearest_airport(track): airport = Airport.by_location(track.location, None) if not airport: return None return dict( airport=airport_schema.dump(airport).data, distance=airport.distance(track.location), ) tracks = [] for t in TrackingFix.get_latest(): nearest_airport = get_nearest_airport(t) track = fix_schema.dump(t).data if nearest_airport: track["nearestAirport"] = nearest_airport["airport"] track["nearestAirportDistance"] = nearest_airport["distance"] tracks.append(track) if request.user_id: followers = [ f.destination_id for f in Follower.query(source_id=request.user_id) ] else: followers = [] return jsonify(friends=followers, tracks=tracks)
def _parse_fix(pilot): fix = TrackingFix() fix.ip = request.remote_addr fix.pilot = pilot # Time if "tm" not in request.values: raise BadRequest("`tm` (time) parameter is missing.") try: fix.time = datetime.utcfromtimestamp(int(request.values["tm"])) except ValueError: raise BadRequest("`tm` (time) has to be a POSIX timestamp.") fix.time_visible = fix.time + timedelta(minutes=pilot.tracking_delay) # Location if "lat" in request.values and "lon" in request.values: try: fix.set_location(float(request.values["lon"]), float(request.values["lat"])) except ValueError: raise BadRequest( "`lat` and `lon` have to be floating point value in degrees (WGS84)." ) # Altitude if "alt" in request.values: try: fix.altitude = int(request.values["alt"]) except ValueError: raise BadRequest("`alt` has to be an integer value in meters.") if not -1000 <= fix.altitude <= 15000: raise BadRequest( "`alt` has to be a valid altitude in the range of -1000 to 15000 meters." ) # Speed if "sog" in request.values: try: fix.ground_speed = int(request.values["sog"]) / 3.6 except ValueError: raise BadRequest( "`sog` (speed over ground) has to be an integer value in km/h." ) if not 0 <= fix.ground_speed <= (500 / 3.6): raise BadRequest( "`sog` (speed over ground) has to be a valid speed in the range of 0 to 500 km/h." ) # Track if "cog" in request.values: try: fix.track = int(request.values["cog"]) except ValueError: raise BadRequest( "`cog` (course over ground) has to be an integer value in degrees." ) if not 0 <= fix.track < 360: raise BadRequest( "`cog` (course over ground) has to be a valid angle between 0 and 360 degrees." ) fix.elevation = Elevation.get(fix.location_wkt) return fix
# # Clear all live tracks for a certain user. # import sys import os import argparse from config import to_envvar sys.path.append(os.path.dirname(sys.argv[0])) parser = argparse.ArgumentParser(description='Clear all live tracks for a certain user.') parser.add_argument('--config', metavar='config.ini', help='path to the configuration INI file') parser.add_argument('user', type=int, help='a user ID') args = parser.parse_args() if not to_envvar(args.config): parser.error('Config file "{}" not found.'.format(args.config)) from skylines import db from skylines.model import TrackingFix result = TrackingFix.query(pilot_id=args.user).delete() db.session.commit() print '%d live tracks cleared.' % result
def fixReceived(self, host, key, payload): if len(payload) != 32: return data = struct.unpack('!IIiiIHHHhhH', payload) pilot = User.by_tracking_key(key) if not pilot: log.err("No such pilot: %d" % key) return flags = data[0] fix = TrackingFix() fix.ip = host fix.pilot = pilot # import the time stamp from the packet if it's within a # certain range time_of_day_ms = data[1] % (24 * 3600 * 1000) time_of_day_s = time_of_day_ms / 1000 time_of_day = datetime.time(time_of_day_s / 3600, (time_of_day_s / 60) % 60, time_of_day_s % 60, (time_of_day_ms % 1000) * 1000) now = datetime.datetime.utcnow() now_s = ((now.hour * 60) + now.minute) * 60 + now.second if now_s - 1800 < time_of_day_s < now_s + 180: fix.time = datetime.datetime.combine(now.date(), time_of_day) elif now_s < 1800 and time_of_day_s > 23 * 3600: # midnight rollover occurred fix.time = datetime.datetime.combine(now.date(), time_of_day) \ - datetime.timedelta(days=1) else: log.msg("ignoring time stamp from FIX packet: " + str(time_of_day)) if flags & FLAG_LOCATION: fix.location = Location(latitude=data[2] / 1000000., longitude=data[3] / 1000000.) if flags & FLAG_TRACK: fix.track = data[5] if flags & FLAG_GROUND_SPEED: fix.ground_speed = data[6] / 16. if flags & FLAG_AIRSPEED: fix.airspeed = data[7] / 16. if flags & FLAG_ALTITUDE: fix.altitude = data[8] if flags & FLAG_VARIO: fix.vario = data[9] / 256. if flags & FLAG_ENL: fix.engine_noise_level = data[10] log.msg(u"%s %s %s %s" % (fix.time and fix.time.time(), host, pilot, fix.location)) DBSession.add(fix) try: transaction.commit() except SQLAlchemyError, e: log.err(e, 'database error') transaction.abort()
from math import sin from random import randint from time import sleep from skylines import db from skylines.model import TrackingFix i = randint(0, 100) _longitude = randint(6500, 7500) / 1000. _latitude = randint(50500, 51500) / 1000. _altitude = 500 while True: longitude = sin(i / 73.) * 0.001 + _longitude latitude = sin(i / 50.) * 0.004 + _latitude altitude = sin(i / 20.) * 300 + _altitude fix = TrackingFix() fix.pilot_id = args.user fix.set_location(longitude, latitude) fix.altitude = altitude db.session.add(fix) db.session.commit() print '.', sys.stdout.flush() sleep(1) i += 1
def trafficRequestReceived(self, host, port, key, payload): if len(payload) != 8: return pilot = User.by_tracking_key(key) if pilot is None: log("%s TRAFFIC_REQUEST unknown pilot (key: %x)" % (host, key)) return data = struct.unpack('!II', payload) or_filters = [] flags = data[0] if flags & TRAFFIC_FLAG_FOLLOWEES: subq = db.session \ .query(Follower.destination_id) \ .filter(Follower.source_id == pilot.id) \ .subquery() or_filters.append(TrackingFix.pilot_id.in_(subq)) if flags & TRAFFIC_FLAG_CLUB: subq = db.session \ .query(User.id) \ .filter(User.club_id == pilot.club_id) \ .subquery() or_filters.append(TrackingFix.pilot_id.in_(subq)) if len(or_filters) == 0: return # Add a db.Column to the inner query with # numbers ordered by time for each pilot row_number = db.over(db.func.row_number(), partition_by=TrackingFix.pilot_id, order_by=TrackingFix.time.desc()) # Create inner query subq = db.session \ .query(TrackingFix.id, row_number.label('row_number')) \ .join(TrackingFix.pilot) \ .filter(TrackingFix.pilot_id != pilot.id) \ .filter(TrackingFix.max_age_filter(2)) \ .filter(TrackingFix.delay_filter(User.tracking_delay_interval())) \ .filter(TrackingFix.location_wkt != None) \ .filter(TrackingFix.altitude != None) \ .filter(or_(*or_filters)) \ .subquery() # Create outer query that orders by time and # only selects the latest fix query = TrackingFix.query() \ .filter(TrackingFix.id == subq.c.id) \ .filter(subq.c.row_number == 1) \ .order_by(TrackingFix.time.desc()) \ .limit(32) response = '' count = 0 for fix in query: location = fix.location if location is None: continue t = fix.time t = t.hour * 3600000 + t.minute * 60000 + t.second * 1000 + t.microsecond / 1000 response += struct.pack('!IIiihHI', fix.pilot_id, t, int(location.latitude * 1000000), int(location.longitude * 1000000), int(fix.altitude), 0, 0) count += 1 response = struct.pack('!HBBI', 0, 0, count, 0) + response response = struct.pack('!IHHQ', MAGIC, 0, TYPE_TRAFFIC_RESPONSE, 0) + response response = set_crc(response) self.socket.sendto(response, (host, port)) log("%s TRAFFIC_REQUEST %s -> %d locations" % (host, unicode(pilot).encode('utf8', 'ignore'), count))
def fixReceived(self, host, key, payload): if len(payload) != 32: return pilot = User.by_tracking_key(key) if not pilot: log("%s FIX unknown pilot (key: %x)" % (host, key)) return data = struct.unpack('!IIiiIHHHhhH', payload) fix = TrackingFix() fix.ip = host fix.pilot = pilot # import the time stamp from the packet if it's within a # certain range time_of_day_ms = data[1] % (24 * 3600 * 1000) time_of_day_s = time_of_day_ms / 1000 time_of_day = time(time_of_day_s / 3600, (time_of_day_s / 60) % 60, time_of_day_s % 60, (time_of_day_ms % 1000) * 1000) now = datetime.utcnow() now_s = ((now.hour * 60) + now.minute) * 60 + now.second if now_s - 1800 < time_of_day_s < now_s + 180: fix.time = datetime.combine(now.date(), time_of_day) elif now_s < 1800 and time_of_day_s > 23 * 3600: # midnight rollover occurred fix.time = (datetime.combine(now.date(), time_of_day) - timedelta(days=1)) else: log("bad time stamp: " + str(time_of_day)) flags = data[0] if flags & FLAG_LOCATION: latitude = data[2] / 1000000. longitude = data[3] / 1000000. fix.set_location(longitude, latitude) fix.elevation = Elevation.get(fix.location_wkt) if flags & FLAG_TRACK: fix.track = data[5] if flags & FLAG_GROUND_SPEED: fix.ground_speed = data[6] / 16. if flags & FLAG_AIRSPEED: fix.airspeed = data[7] / 16. if flags & FLAG_ALTITUDE: fix.altitude = data[8] if flags & FLAG_VARIO: fix.vario = data[9] / 256. if flags & FLAG_ENL: fix.engine_noise_level = data[10] log("{} FIX {} {} {}".format( host, unicode(pilot).encode('utf8', 'ignore'), fix.time and fix.time.time(), fix.location)) db.session.add(fix) try: db.session.commit() except SQLAlchemyError, e: log('database error:' + str(e)) db.session.rollback()
def fixReceived(self, host, key, payload): if len(payload) != 32: return pilot = User.by_tracking_key(key) if not pilot: log.err("No such pilot: %x" % key) return data = struct.unpack('!IIiiIHHHhhH', payload) fix = TrackingFix() fix.ip = host fix.pilot = pilot # import the time stamp from the packet if it's within a # certain range time_of_day_ms = data[1] % (24 * 3600 * 1000) time_of_day_s = time_of_day_ms / 1000 time_of_day = time(time_of_day_s / 3600, (time_of_day_s / 60) % 60, time_of_day_s % 60, (time_of_day_ms % 1000) * 1000) now = datetime.utcnow() now_s = ((now.hour * 60) + now.minute) * 60 + now.second if now_s - 1800 < time_of_day_s < now_s + 180: fix.time = datetime.combine(now.date(), time_of_day) elif now_s < 1800 and time_of_day_s > 23 * 3600: # midnight rollover occurred fix.time = (datetime.combine(now.date(), time_of_day) - timedelta(days=1)) else: log.msg("ignoring time stamp from FIX packet: " + str(time_of_day)) flags = data[0] if flags & FLAG_LOCATION: latitude = data[2] / 1000000. longitude = data[3] / 1000000. fix.set_location(longitude, latitude) fix.elevation = Elevation.get(fix.location_wkt) if flags & FLAG_TRACK: fix.track = data[5] if flags & FLAG_GROUND_SPEED: fix.ground_speed = data[6] / 16. if flags & FLAG_AIRSPEED: fix.airspeed = data[7] / 16. if flags & FLAG_ALTITUDE: fix.altitude = data[8] if flags & FLAG_VARIO: fix.vario = data[9] / 256. if flags & FLAG_ENL: fix.engine_noise_level = data[10] log.msg("{} {} {} {}".format(fix.time and fix.time.time(), host, unicode(pilot).encode('utf8', 'ignore'), fix.location)) db.session.add(fix) try: db.session.commit() except SQLAlchemyError, e: log.err(e, 'database error') db.session.rollback()
def server(app, db_session): _server.TrackingServer.__init__ = Mock(return_value=None) server = _server.TrackingServer() server.app = app yield server TrackingFix.query().delete()
def run(self, user): result = TrackingFix.query(pilot_id=user).delete() db.session.commit() print("%d live tracks cleared." % result)
def fix_received(self, host, key, payload): if len(payload) != 32: return pilot = User.by_tracking_key(key) if not pilot: log("%s FIX unknown pilot (key: %x)" % (host, key)) return data = struct.unpack("!IIiiIHHHhhH", payload) fix = TrackingFix() fix.ip = host fix.pilot = pilot # import the time stamp from the packet if it's within a # certain range time_of_day_ms = data[1] % (24 * 3600 * 1000) time_of_day_s = time_of_day_ms / 1000 time_of_day = ms_to_time(data[1]) now = datetime.utcnow() now_s = ((now.hour * 60) + now.minute) * 60 + now.second if now_s - 1800 < time_of_day_s < now_s + 180: fix.time = datetime.combine(now.date(), time_of_day) elif now_s < 1800 and time_of_day_s > 23 * 3600: # midnight rollover occurred fix.time = datetime.combine(now.date(), time_of_day) - timedelta(days=1) else: log("bad time stamp: " + str(time_of_day)) fix.time = datetime.utcnow() fix.time_visible = fix.time + timedelta(minutes=pilot.tracking_delay) flags = data[0] if flags & FLAG_LOCATION: latitude = data[2] / 1000000.0 longitude = data[3] / 1000000.0 fix.set_location(longitude, latitude) fix.elevation = Elevation.get(fix.location_wkt) if flags & FLAG_TRACK: fix.track = data[5] if flags & FLAG_GROUND_SPEED: fix.ground_speed = data[6] / 16.0 if flags & FLAG_AIRSPEED: fix.airspeed = data[7] / 16.0 if flags & FLAG_ALTITUDE: fix.altitude = data[8] if flags & FLAG_VARIO: fix.vario = data[9] / 256.0 if flags & FLAG_ENL: fix.engine_noise_level = data[10] log("{} FIX {} {} {}".format( host, pilot.name.encode("utf8", "ignore"), fix.time and fix.time.time(), fix.location, )) db.session.add(fix) try: db.session.commit() except SQLAlchemyError as e: log("database error:" + str(e)) db.session.rollback()
from random import randint from time import sleep from skylines import db from skylines.model import TrackingFix i = randint(0, 100) _longitude = randint(6500, 7500) / 1000. _latitude = randint(50500, 51500) / 1000. _altitude = 500 while True: longitude = sin(i / 73.) * 0.001 + _longitude latitude = sin(i / 50.) * 0.004 + _latitude altitude = sin(i / 20.) * 300 + _altitude fix = TrackingFix() fix.pilot_id = args.user fix.set_location(longitude, latitude) fix.altitude = altitude db.session.add(fix) db.session.commit() print '.', sys.stdout.flush() sleep(1) i += 1
def tearDown(self): # Clear the database TrackingFix.query().delete()
def tearDown(self): # Clear the database TrackingFix.query().delete() db.session.commit()
def _parse_fix(pilot_id): fix = TrackingFix() fix.ip = request.remote_addr fix.pilot_id = pilot_id # Time if 'tm' not in request.values: raise BadRequest('`tm` (time) parameter is missing.') try: fix.time = datetime.utcfromtimestamp(int(request.values['tm'])) except ValueError: raise BadRequest('`tm` (time) has to be a POSIX timestamp.') # Location if 'lat' in request.values and 'lon' in request.values: try: fix.set_location(float(request.values['lon']), float(request.values['lat'])) except ValueError: raise BadRequest( '`lat` and `lon` have to be floating point value in degrees (WGS84).' ) # Altitude if 'alt' in request.values: try: fix.altitude = int(request.values['alt']) except ValueError: raise BadRequest('`alt` has to be an integer value in meters.') if not -1000 <= fix.altitude <= 15000: raise BadRequest( '`alt` has to be a valid altitude in the range of -1000 to 15000 meters.' ) # Speed if 'sog' in request.values: try: fix.ground_speed = int(request.values['sog']) / 3.6 except ValueError: raise BadRequest( '`sog` (speed over ground) has to be an integer value in km/h.' ) if not 0 <= fix.ground_speed <= (500 / 3.6): raise BadRequest( '`sog` (speed over ground) has to be a valid speed in the range of 0 to 500 km/h.' ) # Track if 'cog' in request.values: try: fix.track = int(request.values['cog']) except ValueError: raise BadRequest( '`cog` (course over ground) has to be an integer value in degrees.' ) if not 0 <= fix.track < 360: raise BadRequest( '`cog` (course over ground) has to be a valid angle between 0 and 360 degrees.' ) return fix
def run(self, user): result = TrackingFix.query(pilot_id=user).delete() db.session.commit() print '%d live tracks cleared.' % result