def get_elevations_for_flight(flight): cached_elevations = cache.get("elevations_" + flight.__repr__()) if cached_elevations: return cached_elevations """ WITH src AS (SELECT ST_DumpPoints(flights.locations) AS location, flights.timestamps AS timestamps, flights.locations AS locations FROM flights WHERE flights.id = 30000) SELECT timestamps[(src.location).path[1]] AS timestamp, ST_Value(elevations.rast, (src.location).geom) AS elevation FROM elevations, src WHERE src.locations && elevations.rast AND (src.location).geom && elevations.rast; """ # Prepare column expressions location = Flight.locations.ST_DumpPoints() # Prepare cte cte = ( db.session.query( location.label("location"), Flight.locations.label("locations"), Flight.timestamps.label("timestamps") ) .filter(Flight.id == flight.id) .cte() ) # Prepare column expressions timestamp = literal_column("timestamps[(location).path[1]]") elevation = Elevation.rast.ST_Value(cte.c.location.geom) # Prepare main query q = ( db.session.query(timestamp.label("timestamp"), elevation.label("elevation")) .filter(and_(cte.c.locations.intersects(Elevation.rast), cte.c.location.geom.intersects(Elevation.rast))) .all() ) if len(q) == 0: return [] start_time = q[0][0] start_midnight = start_time.replace(hour=0, minute=0, second=0, microsecond=0) elevations = [] for time, elevation in q: if elevation is None: continue time_delta = time - start_midnight time = time_delta.days * 86400 + time_delta.seconds elevations.append((time, elevation)) cache.set("elevations_" + flight.__repr__(), elevations, timeout=3600 * 24) return elevations
def get_elevations_for_flight(flight): cached_elevations = cache.get('elevations_' + flight.__repr__()) if cached_elevations: return cached_elevations ''' WITH src AS (SELECT ST_DumpPoints(flights.locations) AS location, flights.timestamps AS timestamps, flights.locations AS locations FROM flights WHERE flights.id = 30000) SELECT timestamps[(src.location).path[1]] AS timestamp, ST_Value(elevations.rast, (src.location).geom) AS elevation FROM elevations, src WHERE src.locations && elevations.rast AND (src.location).geom && elevations.rast; ''' # Prepare column expressions location = Flight.locations.ST_DumpPoints() # Prepare cte cte = db.session.query(location.label('location'), Flight.locations.label('locations'), Flight.timestamps.label('timestamps')) \ .filter(Flight.id == flight.id).cte() # Prepare column expressions timestamp = literal_column('timestamps[(location).path[1]]') elevation = Elevation.rast.ST_Value(cte.c.location.geom) # Prepare main query q = db.session.query(timestamp.label('timestamp'), elevation.label('elevation')) \ .filter(and_(cte.c.locations.intersects(Elevation.rast), cte.c.location.geom.intersects(Elevation.rast))).all() if len(q) == 0: return [] start_time = q[0][0] start_midnight = start_time.replace(hour=0, minute=0, second=0, microsecond=0) elevations = [] for time, elevation in q: if elevation is None: continue time_delta = time - start_midnight time = time_delta.days * 86400 + time_delta.seconds elevations.append((time, elevation)) cache.set('elevations_' + flight.__repr__(), elevations, timeout=3600 * 24) return elevations
trace = _encode_flight_path(fp, qnh=flight.qnh) infringements = get_airspace_infringements(fp, qnh=flight.qnh) db.session.add(igc_file) db.session.add(flight) # flush data to make sure we don't get duplicate files from ZIP files db.session.flush() # Store data in cache for image creation cache_key = hashlib.sha1(str(flight.id) + '_' + str(current_user.id)).hexdigest() cache.set('upload_airspace_infringements_' + cache_key, infringements, timeout=15 * 60) cache.set('upload_airspace_flight_path_' + cache_key, fp, timeout=15 * 60) airspace = db.session.query(Airspace) \ .filter(Airspace.id.in_(infringements.keys())) \ .all() results.append( UploadResult(name, flight, UploadStatus.SUCCESS, str(prefix), trace, airspace, cache_key)) create_flight_notifications(flight)
def index_post(): current_user = User.get(request.user_id) try: data = FlightUploadSchema().load(request.form).data except ValidationError as e: return jsonify(error="validation-failed", fields=e.messages), 422 pilot_id = data.get("pilot_id") if pilot_id: pilot = User.get(pilot_id) if not pilot: return jsonify(error="unknown-pilot"), 422 else: pilot = None club_id = (pilot and pilot.club_id) or current_user.club_id results = [] weglide_uploads = [] _files = request.files.getlist("files") prefix = 0 for name, f in iterate_upload_files(_files): prefix += 1 filename = files.sanitise_filename(name) filename = files.add_file(filename, f) # check if the file already exists with files.open_file(filename) as f: md5 = file_md5(f) other = Flight.by_md5(md5) if other: files.delete_file(filename) results.append(UploadResult.for_duplicate(name, other, str(prefix))) continue igc_file = IGCFile() igc_file.owner = current_user igc_file.filename = filename igc_file.md5 = md5 igc_file.update_igc_headers() if igc_file.date_utc is None: files.delete_file(filename) results.append(UploadResult.for_missing_date(name, str(prefix))) continue flight = Flight() flight.pilot_id = pilot_id flight.pilot_name = data.get("pilot_name") flight.club_id = club_id flight.igc_file = igc_file flight.model_id = igc_file.guess_model() if igc_file.registration: flight.registration = igc_file.registration else: flight.registration = igc_file.guess_registration() flight.competition_id = igc_file.competition_id fp = flight_path(flight.igc_file, add_elevation=True, max_points=None) analyzed = False try: analyzed = analyse_flight(flight, fp=fp) except: current_app.logger.exception("analyse_flight() raised an exception") if not analyzed: files.delete_file(filename) results.append(UploadResult.for_parser_error(name, str(prefix))) continue if not flight.takeoff_time or not flight.landing_time: files.delete_file(filename) results.append(UploadResult.for_no_flight(name, str(prefix))) continue if flight.landing_time > datetime.now(): files.delete_file(filename) results.append(UploadResult.for_future_flight(name, str(prefix))) continue if not flight.update_flight_path(): files.delete_file(filename) results.append(UploadResult.for_no_flight(name, str(prefix))) continue flight.privacy_level = Flight.PrivacyLevel.PRIVATE trace = _encode_flight_path(fp, qnh=flight.qnh) infringements = get_airspace_infringements(fp, qnh=flight.qnh) db.session.add(igc_file) db.session.add(flight) # flush data to make sure we don't get duplicate files from ZIP files db.session.flush() # Queue WeGlide upload if requested weglide_user_id = data.get("weglideUserId") weglide_birthday = data.get("weglideBirthday") if weglide_user_id and weglide_birthday: # Save `upload_to_weglide` task parameters for later. We can't start # the task directly here, because the DB transaction has not been # committed at this point. weglide_uploads.append( (igc_file.id, weglide_user_id, weglide_birthday.isoformat()) ) # Update `weglide_status` in the database igc_file.weglide_status = 1 db.session.flush() # Store data in cache for image creation cache_key = hashlib.sha1( (to_unicode(flight.id) + u"_" + to_unicode(current_user.id)).encode("utf-8") ).hexdigest() cache.set( "upload_airspace_infringements_" + cache_key, infringements, timeout=15 * 60 ) cache.set("upload_airspace_flight_path_" + cache_key, fp, timeout=15 * 60) airspace = ( db.session.query(Airspace) .filter(Airspace.id.in_(infringements.keys())) .all() ) results.append( UploadResult( name, flight, UploadStatus.SUCCESS, str(prefix), trace, airspace, cache_key, ) ) create_flight_notifications(flight) db.session.commit() # Schedule the deferred WeGlide upload tasks from above for weglide_upload in weglide_uploads: tasks.upload_to_weglide.delay(*weglide_upload) results = UploadResultSchema().dump(results, many=True).data club_members = [] if current_user.club_id: member_schema = UserSchema(only=("id", "name")) club_members = ( User.query(club_id=current_user.club_id) .order_by(func.lower(User.name)) .filter(User.id != current_user.id) ) club_members = member_schema.dump(club_members.all(), many=True).data aircraft_models = ( AircraftModel.query() .order_by(AircraftModel.kind) .order_by(AircraftModel.name) .all() ) aircraft_models = AircraftModelSchema().dump(aircraft_models, many=True).data return jsonify( results=results, club_members=club_members, aircraft_models=aircraft_models )
flight.privacy_level = Flight.PrivacyLevel.PRIVATE trace = _encode_flight_path(fp, qnh=flight.qnh) infringements = get_airspace_infringements(fp, qnh=flight.qnh) db.session.add(igc_file) db.session.add(flight) # flush data to make sure we don't get duplicate files from ZIP files db.session.flush() # Store data in cache for image creation cache_key = hashlib.sha1(str(flight.id) + '_' + str(current_user.id)).hexdigest() cache.set('upload_airspace_infringements_' + cache_key, infringements, timeout=15 * 60) cache.set('upload_airspace_flight_path_' + cache_key, fp, timeout=15 * 60) airspace = db.session.query(Airspace) \ .filter(Airspace.id.in_(infringements.keys())) \ .all() results.append(UploadResult(name, flight, UploadStatus.SUCCESS, str(prefix), trace, airspace, cache_key)) create_flight_notifications(flight) db.session.commit() results = UploadResultSchema().dump(results, many=True).data club_members = []
def index_post(): current_user = User.get(request.user_id) form = request.form if form.get("pilotId") == u"": form = form.copy() form.pop("pilotId") try: data = FlightSchema(only=("pilotId", "pilotName")).load(form).data except ValidationError as e: return jsonify(error="validation-failed", fields=e.messages), 422 pilot_id = data.get("pilot_id") pilot = pilot_id and User.get(pilot_id) pilot_id = pilot and pilot.id club_id = (pilot and pilot.club_id) or current_user.club_id results = [] _files = request.files.getlist("files") prefix = 0 for name, f in iterate_upload_files(_files): prefix += 1 filename = files.sanitise_filename(name) filename = files.add_file(filename, f) # check if the file already exists with files.open_file(filename) as f: md5 = file_md5(f) other = Flight.by_md5(md5) if other: files.delete_file(filename) results.append(UploadResult.for_duplicate(name, other, str(prefix))) continue igc_file = IGCFile() igc_file.owner = current_user igc_file.filename = filename igc_file.md5 = md5 igc_file.update_igc_headers() if igc_file.date_utc is None: files.delete_file(filename) results.append(UploadResult.for_missing_date(name, str(prefix))) continue flight = Flight() flight.pilot_id = pilot_id flight.pilot_name = data.get("pilot_name") flight.club_id = club_id flight.igc_file = igc_file flight.model_id = igc_file.guess_model() if igc_file.registration: flight.registration = igc_file.registration else: flight.registration = igc_file.guess_registration() flight.competition_id = igc_file.competition_id fp = flight_path(flight.igc_file, add_elevation=True, max_points=None) analyzed = False try: analyzed = analyse_flight(flight, fp=fp) except: current_app.logger.exception("analyse_flight() raised an exception") if not analyzed: files.delete_file(filename) results.append(UploadResult.for_parser_error(name, str(prefix))) continue if not flight.takeoff_time or not flight.landing_time: files.delete_file(filename) results.append(UploadResult.for_no_flight(name, str(prefix))) continue if flight.landing_time > datetime.now(): files.delete_file(filename) results.append(UploadResult.for_future_flight(name, str(prefix))) continue if not flight.update_flight_path(): files.delete_file(filename) results.append(UploadResult.for_no_flight(name, str(prefix))) continue flight.privacy_level = Flight.PrivacyLevel.PRIVATE trace = _encode_flight_path(fp, qnh=flight.qnh) infringements = get_airspace_infringements(fp, qnh=flight.qnh) db.session.add(igc_file) db.session.add(flight) # flush data to make sure we don't get duplicate files from ZIP files db.session.flush() # Store data in cache for image creation cache_key = hashlib.sha1( (to_unicode(flight.id) + u"_" + to_unicode(current_user.id)).encode("utf-8") ).hexdigest() cache.set( "upload_airspace_infringements_" + cache_key, infringements, timeout=15 * 60 ) cache.set("upload_airspace_flight_path_" + cache_key, fp, timeout=15 * 60) airspace = ( db.session.query(Airspace) .filter(Airspace.id.in_(infringements.keys())) .all() ) results.append( UploadResult( name, flight, UploadStatus.SUCCESS, str(prefix), trace, airspace, cache_key, ) ) create_flight_notifications(flight) db.session.commit() results = UploadResultSchema().dump(results, many=True).data club_members = [] if current_user.club_id: member_schema = UserSchema(only=("id", "name")) club_members = ( User.query(club_id=current_user.club_id) .order_by(func.lower(User.name)) .filter(User.id != current_user.id) ) club_members = member_schema.dump(club_members.all(), many=True).data aircraft_models = ( AircraftModel.query() .order_by(AircraftModel.kind) .order_by(AircraftModel.name) .all() ) aircraft_models = AircraftModelSchema().dump(aircraft_models, many=True).data return jsonify( results=results, club_members=club_members, aircraft_models=aircraft_models )