Esempio n. 1
0
    def _parse_response(self, response_dict):
        routes = []
        for i, route in enumerate(response_dict['routes']):
            # filter by transfers
            if self._search_request.no_transfers and len(
                    route['segments']) > 1:
                continue

            # create route obj
            rt = Route(
                order=i,
                pl_from=self._search_request.req_from,
                pl_to=self._search_request.req_to,
                from_seg=response_dict['places'][route['depPlace']]
                ['shortName'],
                transfers=len(route['segments']) - 1,
                duration=self._parse_duration(route['totalDuration']),
                duration_raw=route['totalDuration'],
            )

            # filter by total price
            if not route.get('indicativePrices'):
                continue
            else:
                pr = route['indicativePrices'][-1]
                if self._search_request.price_lower_limit and \
                        int(pr['price']) < self._search_request.price_lower_limit:
                    continue

                if self._search_request.price_upper_limit and \
                        int(pr['price']) > self._search_request.price_upper_limit:
                    continue

            # parse total price
            self._parse_price(route, rt)

            # parse segments
            segments = []
            types_set = set()
            for segment in route['segments']:
                transport_type = response_dict['vehicles'][
                    segment['vehicle']]['kind']
                types_set.add(transport_type)

            if any(not self._names.get(tr) for tr in types_set):
                continue

            for segment in route['segments']:
                # create segment dict
                transport_type = response_dict['vehicles'][
                    segment['vehicle']]['kind']
                seg = Segment(
                    to=self._limit_name(response_dict['places'][
                        segment['arrPlace']]['shortName']),
                    to_full=response_dict['places'][segment['arrPlace']]
                    ['shortName'],
                    transport_type=TransportType(
                        name=self._names[transport_type],
                        icon=self._icons[transport_type],
                    ),
                )

                # parse segment price
                if segment.get('indicativePrices'):
                    self._parse_price(segment, seg)
                else:
                    seg.price = '-'
                    seg.price_raw = 0

                # parsing specific segment type
                if segment['segmentKind'] == 'surface':
                    seg.segment_type = 'surface'
                    seg.duration = self._parse_duration(
                        segment['transitDuration'] +
                        segment['transferDuration'])
                    seg.duration_raw = segment['transitDuration'] + segment[
                        'transferDuration']
                    if segment.get('agencies'):
                        seg.frequency = self._parse_frequency(
                            segment['agencies'][0]['frequency'])
                        links = segment['agencies'][0]['links']
                        for link in links:
                            if link['text'] == 'Book at':
                                seg.book_name = link['displayUrl']
                                seg.book_url = link['url']
                            elif link['text'] == 'Schedules at':
                                seg.schedule_name = link['displayUrl']
                                seg.schedule_url = link['url']
                # end
                else:
                    seg.segment_type = 'air'
                    if segment.get('outbound'):
                        duration = 0
                        leg = segment['outbound'][0]

                        start_index = leg['hops'][0]['depPlace']
                        time_start = leg['hops'][0]['depTime']
                        for hop in leg['hops']:
                            end_index = hop['arrPlace']
                            duration += hop['duration']
                            time_end = hop['arrTime']

                        seg.airport_start_code = response_dict['places'][
                            start_index]['code']
                        seg.airport_start_name = response_dict['places'][
                            start_index]['shortName']
                        seg.airport_end_code = response_dict['places'][
                            end_index]['code']
                        seg.airport_end_name = response_dict['places'][
                            end_index]['shortName']
                        seg.time_start = time_start
                        seg.time_end = time_end
                        seg.duration = self._parse_duration(duration)
                        seg.duration_raw = duration
                        seg.operating_days = self._parse_days(
                            leg['operatingDays'])

                        flights = []
                        for leg in segment['outbound']:
                            flight = Flight(operating_days=self._parse_days(
                                leg['operatingDays']))
                            if leg.get('indicativePrices'):
                                self._parse_price(leg, flight)

                            duration = 0
                            hops = []
                            airlines = []
                            for hop in leg['hops']:
                                duration += hop['duration']
                                start_index = hop['depPlace']
                                end_index = hop['arrPlace']
                                hp = FlightSegment(
                                    airport_start_code=response_dict['places']
                                    [start_index]['code'],
                                    airport_start_name=response_dict['places']
                                    [start_index]['shortName'],
                                    airport_end_code=response_dict['places']
                                    [end_index]['code'],
                                    airport_end_name=response_dict['places']
                                    [end_index]['shortName'],
                                    time_start=hop['depTime'],
                                    time_end=hop['arrTime'],
                                    duration=self._parse_duration(
                                        hop['duration']),
                                    duration_raw=hop['duration'],
                                    airline_name=response_dict['airlines'][
                                        hop['airline']]['name'],
                                )
                                hops.append(hp)
                                airlines.append(response_dict['airlines'][
                                    hop['airline']]['name'])

                            flight.flight_segments = hops
                            flight.duration_raw = duration
                            flight.duration = self._parse_duration(duration)
                            flight.airlines = ', '.join(a
                                                        for a in set(airlines))
                            flights.append(flight)

                        flights_obj = Flights(choices=flights).save()
                        seg.flights = flights_obj
                # end
                segments.append(seg)
            # end

            # parse transport types
            transport_types = [
                TransportType(
                    name=self._names[tp],
                    icon=self._icons[tp],
                ) for tp in types_set
            ]

            rt.segments = segments
            rt.transport_types = transport_types
            routes.append(rt)

        self._save_best_route(routes)
        self._search_request.routes = routes
        self._search_request.save()
        return self._search_request.result