def merge_response(self, initial_response, new_response): #since it's not the first call to kraken, some kraken's id #might not be uniq anymore logger = logging.getLogger(__name__) change_ids(new_response, len(initial_response.journeys)) if len(new_response.journeys) == 0: return #if the initial response was an error we remove the error since we have result now if initial_response.HasField('error'): initial_response.ClearField('error') #we don't want to add a journey already there tickets_to_add = set() for new_j in new_response.journeys: if any( are_equals(new_j, old_j) for old_j in initial_response.journeys): logger.debug("the journey tag={}, departure={} " "was already there, we filter it".format( new_j.type, new_j.departure_date_time)) continue # already there, we don't want to add it initial_response.journeys.extend([new_j]) for t in new_j.fare.ticket_id: tickets_to_add.add(t) # we have to add the additional fares too # if at least one journey has the ticket we add it initial_response.tickets.extend( [t for t in new_response.tickets if t.id in tickets_to_add])
def merge_responses(responses, debug): """ Merge all responses in one protobuf response """ merged_response = response_pb2.Response() for response_index, r in enumerate(responses): if r.HasField(str('error')) or not r.journeys: # we do not take responses with error, but if all responses have errors, we'll aggregate them continue change_ids(r, response_index) # we don't want to add a journey already there merged_response.journeys.extend(r.journeys) # we have to add the additional fares too # if at least one journey has the ticket we add it tickets_to_add = set(t for j in r.journeys for t in j.fare.ticket_id) merged_response.tickets.extend( (t for t in r.tickets if t.id in tickets_to_add)) initial_feed_publishers = {} for fp in merged_response.feed_publishers: initial_feed_publishers[fp.id] = fp # Add feed publishers from the qualified journeys only # Note : For BSS, it can happen that one journey in the response has returned a walking fallback. # If all other journeys in the response are to delete, the feed publisher will still be added # TODO: link feed publisher to a journey instead of a response with several journeys merged_response.feed_publishers.extend( fp for fp in r.feed_publishers if fp.id not in initial_feed_publishers and (debug or all( 'to_delete' not in j.tags for j in r.journeys))) # handle impacts for i in r.impacts: if any(other.uri == i.uri for other in merged_response.impacts): continue merged_response.impacts.extend([i]) if not merged_response.journeys: # we aggregate the errors found errors = { r.error.id: r.error for r in responses if r.HasField(str('error')) } # Only one errors field if len(errors) == 1: merged_response.error.id = list(errors.values())[0].id merged_response.error.message = list(errors.values())[0].message # we need to merge the errors elif len(errors) > 1: merged_response.error.id = response_pb2.Error.no_solution merged_response.error.message = "several errors occured: \n * {}".format( "\n * ".join([m.message for m in errors.values()])) return merged_response
def merge_responses(responses): """ Merge all responses in one protobuf response """ merged_response = response_pb2.Response() for r in responses: if r.HasField(str('error')) or not r.journeys: # we do not take responses with error, but if all responses have errors, we'll aggregate them continue change_ids(r, len(merged_response.journeys)) # we don't want to add a journey already there merged_response.journeys.extend(r.journeys) # we have to add the additional fares too # if at least one journey has the ticket we add it tickets_to_add = set(t for j in r.journeys for t in j.fare.ticket_id) merged_response.tickets.extend( [t for t in r.tickets if t.id in tickets_to_add]) initial_feed_publishers = {} for fp in merged_response.feed_publishers: initial_feed_publishers[fp.id] = fp merged_response.feed_publishers.extend([ fp for fp in r.feed_publishers if fp.id not in initial_feed_publishers ]) # handle impacts for i in r.impacts: if any(other.uri == i.uri for other in merged_response.impacts): continue merged_response.impacts.extend([i]) if not merged_response.journeys: # we aggregate the errors found errors = { r.error.id: r.error for r in responses if r.HasField(str('error')) } # Only one errors field if len(errors) == 1: merged_response.error.id = list(errors.values())[0].id merged_response.error.message = list(errors.values())[0].message # we need to merge the errors elif len(errors) > 1: merged_response.error.id = response_pb2.Error.no_solution merged_response.error.message = "several errors occured: \n * {}"\ .format("\n * ".join([m.message for m in errors.values()])) return merged_response
def merge_responses(responses): """ Merge all responses in one protobuf response """ merged_response = response_pb2.Response() for r in responses: if r.HasField('error') or not r.journeys: # we do not take responses with error, but if all responses have errors, we'll aggregate them continue change_ids(r, len(merged_response.journeys)) #we don't want to add a journey already there merged_response.journeys.extend(r.journeys) # we have to add the additional fares too # if at least one journey has the ticket we add it tickets_to_add = set(t for j in r.journeys for t in j.fare.ticket_id) merged_response.tickets.extend( [t for t in r.tickets if t.id in tickets_to_add]) initial_feed_publishers = {} for fp in merged_response.feed_publishers: initial_feed_publishers[fp.id] = fp merged_response.feed_publishers.extend([ fp for fp in r.feed_publishers if fp.id not in initial_feed_publishers ]) if not merged_response.journeys: # we aggregate the errors found errors = { r.error.id: r.error for r in responses if r.HasField('error') } if len(errors) == 1: merged_response.error.id = next(errors.itervalues()).id merged_response.error.message = next(errors.itervalues()).message else: # we need to merge the errors merged_response.error.id = response_pb2.Error.no_solution merged_response.error.message = "several errors occured: \n * {}".format( "\n * ".join(errors.itervalues())) return merged_response