def handle(builder, real_time_update, trip_updates): """ Receive a RealTimeUpdate with at least one TripUpdate filled with the data received by the connector. Each TripUpdate is associated with the base-schedule VehicleJourney, complete/merge realtime is done using builder Then persist in db, publish for Navitia Returns real_time_update and the log_dict """ if not real_time_update: raise TypeError() id_timestamp_tuples = [(tu.vj.navitia_trip_id, tu.vj.start_timestamp) for tu in trip_updates] old_trip_updates = TripUpdate.find_by_dated_vjs(id_timestamp_tuples) for trip_update in trip_updates: # find if there is already a row in db old = next( (tu for tu in old_trip_updates if tu.vj.navitia_trip_id == trip_update.vj.navitia_trip_id and tu.vj.start_timestamp == trip_update.vj.start_timestamp), None, ) # merge the base schedule, the current realtime, and the new realtime current_trip_update = builder.merge_trip_updates( trip_update.vj.navitia_vj, old, trip_update) # manage and adjust consistency if possible if current_trip_update is not None and check_consistency( current_trip_update): # we have to link the current_vj_update with the new real_time_update # this link is done quite late to avoid too soon persistence of trip_update by sqlalchemy current_trip_update.real_time_updates.append(real_time_update) db_commit(real_time_update) feed = convert_to_gtfsrt(real_time_update.trip_updates, gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL) feed_str = feed.SerializeToString() publish(feed_str, builder.contributor.id) data_time = datetime.datetime.utcfromtimestamp(feed.header.timestamp) log_dict = { "contributor": builder.contributor.id, "timestamp": data_time, "output_trip_update_count": len(feed.entity), "output_feed_size": sys.getsizeof(feed_str), } # After merging trip_updates information of connector realtime, navitia and kirin database, if there is no new # information destined to navitia, update real_time_update with status = 'KO' and a proper error message. if not real_time_update.trip_updates and real_time_update.status == "pending": msg = "No new information destined for navitia on {}".format( real_time_update.contributor_id) set_rtu_status_ko(real_time_update, msg, is_reprocess_same_data_allowed=False) logging.getLogger(__name__).warning("RealTimeUpdate id={}: {}".format( real_time_update.id, msg), extra=log_dict) db_commit(real_time_update) return real_time_update, log_dict
def handle(real_time_update, trip_updates, contributor, is_new_complete=False): """ receive a RealTimeUpdate with at least one TripUpdate filled with the data received by the connector. each TripUpdate is associated with the VehicleJourney returned by jormugandr Returns real_time_update and the log_dict """ if not real_time_update: raise TypeError() id_timestamp_tuples = [(tu.vj.navitia_trip_id, tu.vj.get_start_timestamp()) for tu in trip_updates] old_trip_updates = TripUpdate.find_by_dated_vjs(id_timestamp_tuples) for trip_update in trip_updates: # find if there is already a row in db old = next((tu for tu in old_trip_updates if tu.vj.navitia_trip_id == trip_update.vj.navitia_trip_id and tu.vj.get_start_timestamp() == trip_update.vj.get_start_timestamp()), None) # merge the base schedule, the current realtime, and the new realtime current_trip_update = merge(trip_update.vj.navitia_vj, old, trip_update, is_new_complete=is_new_complete) # manage and adjust consistency if possible if current_trip_update and manage_consistency(current_trip_update): # we have to link the current_vj_update with the new real_time_update # this link is done quite late to avoid too soon persistence of trip_update by sqlalchemy current_trip_update.real_time_updates.append(real_time_update) persist(real_time_update) feed = convert_to_gtfsrt(real_time_update.trip_updates) feed_str = feed.SerializeToString() publish(feed_str, contributor) data_time = datetime.datetime.utcfromtimestamp(feed.header.timestamp) log_dict = {'contributor': contributor, 'timestamp': data_time, 'trip_update_count': len(feed.entity), 'size': len(feed_str)} return real_time_update, log_dict
def handle(real_time_update, trip_updates, contributor, is_new_complete=False): """ receive a RealTimeUpdate with at least one TripUpdate filled with the data received by the connector. each TripUpdate is associated with the VehicleJourney returned by jormungandr Returns real_time_update and the log_dict """ if not real_time_update: raise TypeError() id_timestamp_tuples = [(tu.vj.navitia_trip_id, tu.vj.get_start_timestamp()) for tu in trip_updates] old_trip_updates = TripUpdate.find_by_dated_vjs(id_timestamp_tuples) for trip_update in trip_updates: # find if there is already a row in db old = next( (tu for tu in old_trip_updates if tu.vj.navitia_trip_id == trip_update.vj.navitia_trip_id and tu. vj.get_start_timestamp() == trip_update.vj.get_start_timestamp()), None) # merge the base schedule, the current realtime, and the new realtime current_trip_update = merge(trip_update.vj.navitia_vj, old, trip_update, is_new_complete=is_new_complete) # manage and adjust consistency if possible if current_trip_update and manage_consistency(current_trip_update): # we have to link the current_vj_update with the new real_time_update # this link is done quite late to avoid too soon persistence of trip_update by sqlalchemy current_trip_update.real_time_updates.append(real_time_update) persist(real_time_update) feed = convert_to_gtfsrt(real_time_update.trip_updates) feed_str = feed.SerializeToString() publish(feed_str, contributor) data_time = datetime.datetime.utcfromtimestamp(feed.header.timestamp) log_dict = { 'contributor': contributor, 'timestamp': data_time, 'trip_update_count': len(feed.entity), 'size': len(feed_str) } # After merging trip_updates information of connector realtime, navitia and kirin database, if there is no new # information destined to navitia, update real_time_update with status = 'KO' and a proper error message. if not real_time_update.trip_updates and real_time_update.status == 'OK': real_time_update.status = 'KO' real_time_update.error = 'No new information destinated to navitia for this {}'.format( real_time_update.connector) logging.getLogger(__name__).error('RealTimeUpdate id={}: {}'.format( real_time_update.id, real_time_update.error)) model.db.session.add(real_time_update) model.db.session.commit() return real_time_update, log_dict