Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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