def userNameRequestReceived(self, host, port, key, payload): """The client asks for the display name of a user account.""" 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) user_id = data[0] user = User.get(user_id) if user is None: response = struct.pack('!IHHQIIIBBBBII', MAGIC, 0, TYPE_USER_NAME_RESPONSE, 0, user_id, USER_FLAG_NOT_FOUND, 0, 0, 0, 0, 0, 0, 0) response = set_crc(response) self.transport.write(response, (host, port)) return name = user.name[:64].encode('utf8', 'ignore') club_id = user.club_id or 0 response = struct.pack('!IHHQIIIBBBBII', MAGIC, 0, TYPE_USER_NAME_RESPONSE, 0, user_id, 0, club_id, len(name), 0, 0, 0, 0, 0) response += name response = set_crc(response) self.transport.write(response, (host, port))
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 _parse_user(): """Read and check the tracking key (supplied via 'user' field)""" if 'user' not in request.values: raise BadRequest('`user` parameter is missing.') try: key = int(request.values['user'], 16) except ValueError: raise BadRequest('`user` must be the hexadecimal tracking key.') return key, User.by_tracking_key(key)
def pingReceived(self, host, port, key, payload): if len(payload) != 8: return id, reserved, reserved2 = struct.unpack('!HHI', payload) flags = 0 pilot = User.by_tracking_key(key) if not pilot: flags |= FLAG_ACK_BAD_KEY data = struct.pack('!IHHQHHI', MAGIC, 0, TYPE_ACK, 0, id, 0, flags) data = set_crc(data) self.transport.write(data, (host, port))
def pingReceived(self, host, port, key, payload): if len(payload) != 8: return id, reserved, reserved2 = struct.unpack('!HHI', payload) flags = 0 pilot = User.by_tracking_key(key) if not pilot: log("%s PING unknown pilot (key: %x)" % (host, key)) flags |= FLAG_ACK_BAD_KEY else: log("%s PING %s -> PONG" % (host, unicode(pilot).encode('utf8', 'ignore'))) data = struct.pack('!IHHQHHI', MAGIC, 0, TYPE_ACK, 0, id, 0, flags) data = set_crc(data) self.socket.sendto(data, (host, port))
def userNameRequestReceived(self, host, port, key, payload): """The client asks for the display name of a user account.""" if len(payload) != 8: return pilot = User.by_tracking_key(key) if pilot is None: log("%s USER_NAME_REQUEST unknown pilot (key: %x)" % (host, key)) return data = struct.unpack('!II', payload) user_id = data[0] user = User.get(user_id) if user is None: response = struct.pack('!IHHQIIIBBBBII', MAGIC, 0, TYPE_USER_NAME_RESPONSE, 0, user_id, USER_FLAG_NOT_FOUND, 0, 0, 0, 0, 0, 0, 0) response = set_crc(response) self.transport.write(response, (host, port)) log("%s, USER_NAME_REQUEST %s -> NOT_FOUND" % (host, unicode(pilot).encode('utf8', 'ignore'))) return name = user.name[:64].encode('utf8', 'ignore') club_id = user.club_id or 0 response = struct.pack('!IHHQIIIBBBBII', MAGIC, 0, TYPE_USER_NAME_RESPONSE, 0, user_id, 0, club_id, len(name), 0, 0, 0, 0, 0) response += name response = set_crc(response) self.socket.sendto(response, (host, port)) log("%s USER_NAME_REQUEST %s -> %s" % (host, unicode(pilot).encode('utf8', 'ignore'), unicode(user).encode('utf8', 'ignore')))
def username_request_received(self, host, port, key, payload): """The client asks for the display name of a user account.""" if len(payload) != 8: return pilot = User.by_tracking_key(key) if pilot is None: log("%s USER_NAME_REQUEST unknown pilot (key: %x)" % (host, key)) return data = struct.unpack('!II', payload) user_id = data[0] user = User.get(user_id) if user is None: response = struct.pack('!IHHQIIIBBBBII', MAGIC, 0, TYPE_USER_NAME_RESPONSE, 0, user_id, USER_FLAG_NOT_FOUND, 0, 0, 0, 0, 0, 0, 0) response = set_crc(response) self.transport.write(response, (host, port)) log("%s, USER_NAME_REQUEST %s -> NOT_FOUND" % (host, pilot.name.encode('utf8', 'ignore'))) return name = user.name[:64].encode('utf8', 'ignore') club_id = user.club_id or 0 response = struct.pack('!IHHQIIIBBBBII', MAGIC, 0, TYPE_USER_NAME_RESPONSE, 0, user_id, 0, club_id, len(name), 0, 0, 0, 0, 0) response += name response = set_crc(response) self.socket.sendto(response, (host, port)) log("%s USER_NAME_REQUEST %s -> %s" % (host, pilot.name.encode('utf8', 'ignore'), user.name.encode('utf8', 'ignore')))
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()
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 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.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 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()