예제 #1
0
파일: search.py 프로젝트: iXioN/skyscraper
    def handle(self, *args, **options):
        # make sure origin and destination options are present
        if options['from_city'] == None:
            raise CommandError("Option `--from_city=...` must be specified.")
        if options['to_city'] == None:
            raise CommandError("Option `--to_city=...` must be specified.")
        origin_city_name = options['from_city']
        destination_city_name = options['to_city']
        print_limit = options['print_limit']
        depart_date = datetime.datetime.strptime(options['depart_date'],
                                                 ARGUMENT_DATE_FORMAT).date()
        #if no return date given, the flight is a on way
        return_date = ""
        if options['return_date']:
            return_date = datetime.datetime.strptime(
                options['return_date'], ARGUMENT_DATE_FORMAT).date()

        #instantiate a skyscanner client
        client = SkyscannerClient()
        now = timezone.now()

        origin_station = models.get_model(
            "skyscanner_scraper",
            "Station").objects.get_or_fetch(origin_city_name)
        destination_station = models.get_model(
            "skyscanner_scraper",
            "Station").objects.get_or_fetch(destination_city_name)

        search_params = {
            "short_from": origin_station.code,
            "short_to": destination_station.code,
            "depart_date": depart_date,
            "return_date": return_date,
        }

        #get the result, if no result found at first call, wait and retry (retry max = 6)`
        pricing_option_qs = None
        i = 0
        max_val = 5
        pbar = ProgressBar(maxval=max_val).start()
        while i < max_val:
            i += 1
            query_flight, flights = client.get_flights(**search_params)
            seen_flights_pk = [f.pk for f in flights]
            pricing_option_qs = models.get_model(
                'skyscanner_scraper', 'PricingOption').objects.all()
            #One way flight
            if not query_flight.inbound_date:
                pricing_option_qs = pricing_option_qs.filter(
                    outbound_flight_id__in=seen_flights_pk,
                    inbound_flight__isnull=True,
                    quote__is_return=False,
                )
            #if the query for a return flight, remove the one way flights
            if query_flight.outbound_date and query_flight.inbound_date:
                pricing_option_qs = pricing_option_qs.filter(
                    Q(inbound_flight_id__in=seen_flights_pk)
                    | Q(outbound_flight_id__in=seen_flights_pk),
                    quote__is_return=True)
                pricing_option_qs = pricing_option_qs.exclude(
                    Q(inbound_flight__isnull=True)
                    | Q(outbound_flight__isnull=True), )
            if len(pricing_option_qs) > 0:
                break
            pbar.update(i)
            time.sleep(1)
        pbar.finish()
        pricing_option_qs = pricing_option_qs.order_by('quote__price')

        #then print the result
        print "---------------------------------------------------------"
        print "search on SkyScanner from %s(%s) to %s(%s)" % (
            origin_station.name, origin_station.code, destination_station.name,
            destination_station.code)
        if return_date:
            print "%s - %s" % (depart_date.strftime(PRINT_DATE_FORMAT),
                               return_date.strftime(PRINT_DATE_FORMAT))
        else:
            print "one way from %s" % (depart_date.strftime(PRINT_DATE_FORMAT))
        print "---------------------------------------------------------"

        limit_number = print_limit
        print_count = 0
        #to remove the duplicate flight we will create a key with outbound_flight.pk+inboud_flight.pk
        #if this id is already seen, don't add the price_option
        printed_combination = set()
        for price_option in pricing_option_qs:
            #outbound
            outbound_flight_id = price_option.outbound_flight_id
            #inbound
            inbound_flight_id = price_option.inbound_flight_id
            #printed_combination pk
            combination = "%s_%s" % (outbound_flight_id, inbound_flight_id)
            if not combination in printed_combination:
                self.print_flight_details(price_option)
                #print the informations
                printed_combination.add(combination)
                print_count += 1
                if print_count >= limit_number:
                    break
        print "%s of %s results" % (limit_number, len(pricing_option_qs))

        #TODO : fix this bug(maybe by adding the query_flight in quote and price_option)
        #delete all quote and pricing_option to avoid complexe mistakes
        models.get_model('skyscanner_scraper', 'Quote').objects.all().delete()
        models.get_model('skyscanner_scraper',
                         'PricingOption').objects.all().delete()
예제 #2
0
파일: search.py 프로젝트: Drowze/skyscraper
    def handle(self, *args, **options):
        # make sure origin and destination options are present
        if options['from_city'] == None :
            raise CommandError("Option `--from_city=...` must be specified.")
        if options['to_city'] == None :
            raise CommandError("Option `--to_city=...` must be specified.")
        origin_city_name = options['from_city']
        destination_city_name = options['to_city']
        print_limit = options['print_limit']
        depart_date = datetime.datetime.strptime(options['depart_date'], ARGUMENT_DATE_FORMAT).date()
        #if no return date given, the flight is a on way
        return_date = ""
        if options['return_date']:
            return_date = datetime.datetime.strptime(options['return_date'], ARGUMENT_DATE_FORMAT).date()
        
        #instantiate a skyscanner client
        client = SkyscannerClient()
        now = timezone.now()

        origin_station = models.get_model("skyscanner_scraper", "Station").objects.get_or_fetch(origin_city_name)
        destination_station = models.get_model("skyscanner_scraper", "Station").objects.get_or_fetch(destination_city_name)
        
        search_params = {
           "short_from":origin_station.code,
           "short_to":destination_station.code,
           "depart_date":depart_date,
           "return_date":return_date,
        }
        
        #get the result, if no result found at first call, wait and retry (retry max = 6)`
        pricing_option_qs = None
        i = 0
        max_val = 5
        pbar = ProgressBar(maxval=max_val).start()
        while i < max_val:
            i += 1
            query_flight, flights = client.get_flights(**search_params)
            seen_flights_pk  = [f.pk for f in flights]            
            pricing_option_qs = models.get_model('skyscanner_scraper', 'PricingOption').objects.all()            
            #One way flight
            if not query_flight.inbound_date:
                pricing_option_qs = pricing_option_qs.filter(
                   outbound_flight_id__in=seen_flights_pk,
                   inbound_flight__isnull=True,
                   quote__is_return=False,
                )
            #if the query for a return flight, remove the one way flights
            if query_flight.outbound_date and query_flight.inbound_date:
                pricing_option_qs = pricing_option_qs.filter(
                    Q(inbound_flight_id__in=seen_flights_pk) | Q(outbound_flight_id__in=seen_flights_pk),
                    quote__is_return=True
                )
                pricing_option_qs = pricing_option_qs.exclude(
                    Q(inbound_flight__isnull=True) | Q(outbound_flight__isnull=True),
                )
            if len(pricing_option_qs) > 0:
                break
            pbar.update(i)
            time.sleep(1)
        pbar.finish()
        pricing_option_qs = pricing_option_qs.order_by('quote__price')

        #then print the result
        print "---------------------------------------------------------"
        print "search on SkyScanner from %s(%s) to %s(%s)" % (origin_station.name, origin_station.code, destination_station.name, destination_station.code)
        if return_date:
            print "%s - %s" % (depart_date.strftime(PRINT_DATE_FORMAT), return_date.strftime(PRINT_DATE_FORMAT) )
        else:
            print "one way from %s" % (depart_date.strftime(PRINT_DATE_FORMAT))
        print "---------------------------------------------------------"
        
        limit_number = print_limit
        print_count = 0
        #to remove the duplicate flight we will create a key with outbound_flight.pk+inboud_flight.pk
        #if this id is already seen, don't add the price_option
        printed_combination = set()
        for price_option in pricing_option_qs:
            #outbound
            outbound_flight_id = price_option.outbound_flight_id
            #inbound
            inbound_flight_id = price_option.inbound_flight_id
            #printed_combination pk
            combination = "%s_%s" % (outbound_flight_id, inbound_flight_id)
            if not combination in printed_combination:
                self.print_flight_details(price_option)
                #print the informations
                printed_combination.add(combination)
                print_count += 1
                if print_count >= limit_number:
                    break
        print "%s of %s results" % (limit_number, len(pricing_option_qs)) 
        
        #TODO : fix this bug(maybe by adding the query_flight in quote and price_option)
        #delete all quote and pricing_option to avoid complexe mistakes
        models.get_model('skyscanner_scraper', 'Quote').objects.all().delete()
        models.get_model('skyscanner_scraper', 'PricingOption').objects.all().delete()