Exemple #1
0
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
Exemple #2
0
    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
Exemple #4
0
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)
Exemple #6
0
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
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #10
0
    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))
Exemple #11
0
    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
Exemple #12
0
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
Exemple #13
0
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
Exemple #16
0
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)
Exemple #18
0
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)
Exemple #19
0
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
Exemple #20
0
    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)
Exemple #21
0
    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)
Exemple #23
0
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)
Exemple #24
0
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)
Exemple #25
0
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)
Exemple #26
0
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)
Exemple #27
0
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
Exemple #28
0
#
# 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
Exemple #29
0
    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()
Exemple #30
0
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
Exemple #31
0
    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))
Exemple #32
0
    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()
Exemple #33
0
    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()
Exemple #34
0
def server(app, db_session):
    _server.TrackingServer.__init__ = Mock(return_value=None)
    server = _server.TrackingServer()
    server.app = app
    yield server
    TrackingFix.query().delete()
Exemple #35
0
    def run(self, user):
        result = TrackingFix.query(pilot_id=user).delete()
        db.session.commit()

        print("%d live tracks cleared." % result)
Exemple #36
0
    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()
Exemple #37
0
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
Exemple #38
0
 def tearDown(self):
     # Clear the database
     TrackingFix.query().delete()
Exemple #39
0
    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))
Exemple #40
0
 def tearDown(self):
     # Clear the database
     TrackingFix.query().delete()
     db.session.commit()
Exemple #41
0
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