예제 #1
0
    def check_flights(self, origin_city_code, destination_city_code, from_time,
                      to_time):
        headers = {"apikey": TEQUILA_API_KEY}
        query = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_time.strftime("%d/%m/%Y"),
            "date_to": to_time.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "GBP"
        }

        response = requests.get(
            url=f"{TEQUILA_ENDPOINT}/v2/search",
            headers=headers,
            params=query,
        )
        try:
            data = response.json()["data"][0]
        except IndexError:
            query["max_stopovers"] = 1
            response = requests.get(
                url=f"{TEQUILA_ENDPOINT}/v2/search",
                headers=headers,
                params=query,
            )

            try:
                data = response.json()["data"][0]

            except IndexError:
                return None
            else:
                flight_data = FlightData(
                    price=data["price"],
                    origin_city=data["route"][0]["cityFrom"],
                    origin_airport=data["route"][0]["flyFrom"],
                    destination_city=data["route"][1]["cityTo"],
                    destination_airport=data["route"][1]["flyTo"],
                    out_date=data["route"][0]["local_departure"].split("T")[0],
                    return_date=data["route"][1]["local_departure"].split(
                        "T")[0],
                    stop_overs=1,
                    via_city=data["route"][0]["cityTo"])
                return flight_data
        else:
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][0]["cityTo"],
                destination_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0])

            return flight_data
예제 #2
0
    def search_flights(self, destination):
        now = datetime.now()
        today = now.strftime("%d/%m/%Y")
        six_months_from_today = now + relativedelta(months=6)
        end_date = six_months_from_today.strftime("%d/%m/%Y")
        url = f"{self.endpoint}search"
        headers = {"apikey": self.key}
        params = {
            "fly_from": "SFO",
            "fly_to": destination,
            "date_from": today,
            "date_to": end_date,
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "GBP"
        }

        response = requests.get(url="https://tequila-api.kiwi.com/v2/search?",
                                headers=headers,
                                params=params)

        try:
            data = response.json()["data"][0]
        except IndexError:

            ##########################
            params["max_stopovers"] = 1
            response = requests.get(
                url="https://tequila-api.kiwi.com/v2/search?",
                headers=headers,
                params=params,
            )
            data = response.json()["data"][0]
            pprint(data)
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][1]["cityTo"],
                destination_airport=data["route"][1]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][2]["local_departure"].split("T")[0],
                stop_overs=1,
                via_city=data["route"][0]["cityTo"])
            return flight_data
            ###########################
        else:
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][0]["cityTo"],
                destination_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0])

            return flight_data
예제 #3
0
    def search_flights(self, destination_city_code):
        tmr_date = dt.datetime.today() + dt.timedelta(days=1)
        max_date = dt.datetime.today() + dt.timedelta(days=180)
        headers = {'apikey': self.tequila_api}
        parameters = {
            'fly_from': ORIGIN_CITY_IATA,
            'fly_to': destination_city_code,
            'date_from': tmr_date.strftime(date_format),
            'date_to': max_date.strftime(date_format),
            'max_stopovers': 0,
            'curr': 'GBP',
            'nights_in_dst_from': 7,
            'nights_in_dst_to': 28,
            'flight_type': 'round',
            "one-for-city": 1
        }

        response = requests.get(url=f'{TEQUILA_ENDPOINT}/v2/search',
                                headers=headers,
                                params=parameters)
        response.raise_for_status()

        try:
            data = response.json()['data'][0]
        except IndexError:
            parameters['max_stopovers'] = 1
            response = requests.get(url=f'{TEQUILA_ENDPOINT}/v2/search',
                                    headers=headers,
                                    params=parameters)
            response.raise_for_status()
            print(response.json())
            if len(response.json()['data']) > 0:
                data = response.json()['data'][0]

                flight_data = FlightData(price=data['price'],
                                         city_from=data['cityFrom'],
                                         fly_from=data['flyFrom'],
                                         city_to=data['cityTo'],
                                         fly_to=data['flyTo'],
                                         leave_date=data["route"][0]
                                         ["local_departure"].split("T")[0],
                                         return_date=data["route"][1]
                                         ["local_departure"].split("T")[0],
                                         stop_overs=1,
                                         via_city=data["route"][0]["cityTo"])
                return flight_data
            else:
                return None

        else:
            flight_data = FlightData(
                price=data['price'],
                city_from=data['cityFrom'],
                fly_from=data['flyFrom'],
                city_to=data['cityTo'],
                fly_to=data['flyTo'],
                leave_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0],
            )
            return flight_data
예제 #4
0
    def search_flight(self, destination_code):
        tomorrow = datetime.now() + timedelta(1)
        six_months = datetime.now() + timedelta(180)
        formated_tomorrow = tomorrow.strftime("%d/%m/%Y")
        formated_six_months = six_months.strftime("%d/%m/%Y")

        headers = {"apikey": KIWI_FLIGHT_API_KEY}
        query = {
            "fly_from": "LON",
            "fly_to": destination_code,
            "date_from": formated_tomorrow,
            "date_to": formated_six_months,
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "GBP"
        }

        response = requests.get(url=f"{KIWI_BASE_URL}/v2/search",
                                params=query,
                                headers=headers)
        response.raise_for_status()
        try:
            data = response.json()["data"][0]
            #print(f"{destination_code}: £{data['price']}")
        except IndexError:
            query["max_stopovers"] = 1
            response = requests.get(url=f"{KIWI_BASE_URL}/v2/search",
                                    params=query,
                                    headers=headers)
            response.raise_for_status()
            try:
                data = response.json()["data"][0]
            except IndexError:
                flight_data = None
            else:
                flight_data = FlightData(
                    price=data["price"],
                    origin_city=data["route"][0]["cityFrom"],
                    origin_airport=data["route"][0]["flyFrom"],
                    destination_city=data["route"][1]["cityTo"],
                    destination_airport=data["route"][1]["flyTo"],
                    out_date=data["route"][0]["local_departure"].split("T")[0],
                    return_date=data["route"][2]["local_departure"].split(
                        "T")[0],
                    stop_overs=1,
                    via_city=data["route"][0]["cityTo"])
        else:
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][0]["cityTo"],
                destination_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0])
        return flight_data
 def __init__(self, own_city):
     self.now = datetime.datetime.now()
     tmr = self.now + datetime.timedelta(days=1)
     six_month = self.now + datetime.timedelta(days=180)
     self.date_tmr = tmr.strftime("%d/%m/%Y")
     self.date_six_month = six_month.strftime("%d/%m/%Y")
     self.flight_data = FlightData()
     self.own_city = own_city
예제 #6
0
 def flight_search(self, city_code):
     parameters = {
         "fly_from": "RDU",
         "fly_to": city_code,
         "date_from": fly_from_date,
         "date_to": fly_to_date,
         "nights_in_dst_from": length_stay_min,
         "nights_in_dst_to": length_stay_max,
         "curr": "USD",
         "adults": 4,
         "one_for_city": 1,
         "max_stopovers": 0,
     }
     print(f"Now searching for flights to {city_code}")
     f_search = requests.get(url=f"{self.api_url}v2/search", params=parameters, headers=self.api_headers)
     f_search.raise_for_status()
     print(f_search.json())
     try:
         f_dict = f_search.json()['data'][0]
     except IndexError:
         parameters['max_stopovers'] = 2
         f_search = requests.get(url=f"{self.api_url}v2/search", params=parameters, headers=self.api_headers)
         f_search.raise_for_status()
         print(f" Rerunning with up to 2 max stopovers\n {f_search.json()}")
         try:
             f_dict = f_search.json()['data'][0]
         except IndexError:
             print("No flights are available")
             return None
         f_fare = f_dict['price']
         f_dep_city = "Raleigh"
         f_dep_code = "RDU"
         f_arr_city = f_dict['cityTo']
         f_arr_code = city_code
         f_dep_date = f_dict['route'][0]['local_departure'].split('T')[0]
         f_ret_date = f_dict['route'][1]['local_departure'].split('T')[0]
         f_stop_over = 1
         f_via_city = f_dict['route'][0]['cityTo']
         flight = FlightData(f_fare, f_arr_city, f_arr_code, f_dep_date, f_ret_date, f_stop_over, f_via_city)
         return flight
     else:
         f_fare = f_dict['price']
         f_dep_city = "Raleigh"
         f_dep_code = "RDU"
         f_arr_city = f_dict['cityTo']
         f_arr_code = city_code
         f_dep_date = f_dict['route'][0]['local_departure'].split('T')[0]
         f_ret_date = f_dict['route'][1]['local_departure'].split('T')[0]
         flight = FlightData(f_fare, f_arr_city, f_arr_code, f_dep_date, f_ret_date)
         print(f"Fare:{f_fare}")
         print(f"Departure City:{f_dep_city}")
         print(f"Departure Code:{f_dep_code}")
         print(f"Arrival City:{f_arr_city}")
         print(f"Arrival Code:{f_arr_code}")
         print(f"Departure Date:{f_dep_date}")
         print(f"Return Date:{f_ret_date}")
         return flight
예제 #7
0
    def check_flights(self, origin_city_code, destination_city_code, from_time,
                      to_time):
        """Method to query API for flight information."""
        print(f"Check flights triggered for {destination_city_code}")
        query = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_time.strftime("%d/%m/%Y"),
            "date_to": to_time.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "GBP"
        }

        response = requests.get(
            url=f"{TEQUILA_ENDPOINT}/v2/search",
            headers=HEADERS,
            params=query,
        )

        try:
            data = response.json()["data"][0]
            print(f"{destination_city_code} {data['price']}")
        except IndexError:
            query["max_stopovers"] = 1
            response = requests.get(
                url=f"{TEQUILA_ENDPOINT}/v2/search",
                headers=HEADERS,
                params=query,
            )
            data = response.json()["data"][0]
            pprint(data)
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][1]["cityTo"],
                destination_airport=data["route"][1]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][2]["local_departure"].split("T")[0],
                stop_overs=1,
                via_city=data["route"][0]["cityTo"])
            return flight_data
        else:
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][0]["cityTo"],
                destination_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0])
            return flight_data
예제 #8
0
    def check_flights(self, fly_from, fly_to, date_from, date_to):
        check_data = {
            'fly_from': fly_from,
            'fly_to': fly_to,
            'date_from': date_from,
            'date_to': date_to,
            'nights_in_dst_from': 7,
            'nights_in_dst_to': 28,
            'flight_type': 'round',
            'one_for_city': 1,
            'curr': 'USD',
            'max_stopovers': 0
        }

        tequila_flights_response = requests.get(self.tequila_flights_endpoint,
                                                headers=self.tequila_header,
                                                params=check_data)
        # tequila_flights_response.raise_for_status()  # Creates extra errors as there are many missing flights w/ covid

        try:
            data = tequila_flights_response.json()["data"][0]
        except IndexError:
            try:
                check_data[
                    "max_stopovers"] = 1  # There just aren't many flights now due to covid, change to 10 to get results
                tequila_flights_response = requests.get(
                    url=self.tequila_flights_endpoint,
                    headers=self.tequila_header,
                    params=check_data)
                data = tequila_flights_response.json()["data"][0]
                print(data)
                flight_data = FlightData(
                    price=data["price"],
                    origin_city=data["route"][0]["cityFrom"],
                    origin_airport=data["route"][0]["flyFrom"],
                    destination_city=data["route"][1]["cityTo"],
                    destination_airport=data["route"][1]["flyTo"],
                    out_date=data["route"][0]["local_departure"].split("T")[0],
                    return_date=data["route"][2]["local_departure"].split(
                        "T")[0],
                    stop_overs=1,
                    via_city=data["route"][0]["cityTo"])
                return flight_data
            except IndexError:
                return None
        else:
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][0]["cityTo"],
                destination_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0])

            return flight_data
    def search_for_flight(self, origin_city_code, destination_city_code,
                          from_date, to_date):
        """The default flight is to get a direct flight, however if none is found the Tequila API will provide an
        empty request. The exception will request changing the stops to 2 in order to obtain a request with information.
        """
        headers = {"apikey": TEQUILA_API_KEY}
        query = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_date.strftime("%d/%m/%Y"),
            "date_to": to_date.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 0,
            "max_stopovers": 0,
            "cur": "USD",
        }
        response = requests.get(url=f"{TEQUILA_ENDPOINT}/v2/search",
                                headers=headers,
                                params=query)
        try:
            data = response.json()['data'][0]
        except IndexError:
            query["max_stopovers"] = 2
            result = requests.get(url=f"{TEQUILA_ENDPOINT}/v2/search",
                                  headers=headers,
                                  params=query)
            data = result.json()['data'][0]
            flight_data = FlightData(
                price=data['price'],
                origin_city=data['route'][0]['cityFrom'],
                origin_airport=data['route'][0]['flyFrom'],
                destination_city=data['route'][1]['cityTo'],
                destination_airport=data['route'][1]['flyTo'],
                out_date=data['route'][0]['local_departure'].split('T')[0],
                return_date=data['route'][1]['local_departure'].split('T')[0],
                stop_overs=1,
                via_city=data['route'][0]['cityTo'],
                flight_link=data['deep_link'])
            return flight_data

        else:
            flight_data = FlightData(
                price=data['price'],
                origin_city=data['route'][0]['cityFrom'],
                origin_airport=data['route'][0]['flyFrom'],
                destination_city=data['route'][0]['cityTo'],
                destination_airport=data['route'][0]['flyTo'],
                out_date=data['route'][0]['local_departure'].split('T')[0],
                return_date=data['route'][1]['local_departure'].split('T')[0],
                flight_link=data['deep_link'])
            return flight_data
 def find_flight(self, origin_city_code, destination_city_code, from_time, to_time):
   body = {
     "fly_from": origin_city_code,
     "fly_to": destination_city_code,
     "date_from": from_time.strftime("%d/%m/%Y"),
     "date_to": to_time.strftime("%d/%m/%Y"),
     "nights_in_dst_from": 7,
     "nights_in_dst_to": 28,
     "flight_type": "round",
     "one_for_city": 1,
     "max_stopovers": 0,
     "curr": "USD"
   }
   header = {'apikey': API}
   response = requests.get(url=SEARCH_URL, headers=header, params=body)
   try:
     data = response.json()["data"][0]
   except IndexError:
     #print(f"No flights found for {destination_city_code}.")
     body['max_stopovers'] = 1
     response = requests.get(
       url=SEARCH_URL,
       headers=header,
       params=body
     )
     if len(response.json()["data"]) == 0:
       print("No flights found.")
       return None
     data = response.json()["data"][0]
     flight_data = FlightData(
       price=data["price"],
       origin_city=data["route"][0]["cityFrom"],
       origin_airport=data["route"][0]["flyFrom"],
       destination_city=data["route"][1]["cityTo"],
       destination_airport=data["route"][1]["flyTo"],
       out_date=data["route"][0]["local_departure"].split("T")[0],
       return_date=data["route"][2]["local_departure"].split("T")[0],
       stop_overs=1,
       via_city=data["route"][0]["cityTo"]
     )
     return flight_data
   else:
     flight_data = FlightData(
       price=data["price"],
       origin_city=data["route"][0]["cityFrom"],
       origin_airport=data["route"][0]["flyFrom"],
       destination_city=data["route"][0]["cityTo"],
       destination_airport=data["route"][0]["flyTo"],
       out_date=data["route"][0]["local_departure"].split("T")[0],
       return_date=data["route"][1]["local_departure"].split("T")[0]
     )
     print(f"{flight_data.destination_city}: ${flight_data.price}")
     return flight_data
예제 #11
0
    def search_flights(self, code):
        tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
        six_month = datetime.datetime.today() + datetime.timedelta(days=1) + datetime.timedelta(days=180)
        tomorrow_formatted = str(tomorrow.strftime("%d/%m/%Y")).split(" ")[0]
        six_month_formatted = str(six_month.strftime("%d/%m/%Y")).split(" ")[0]

        query = {
            "fly_from": 'LON',
            "fly_to": code,
            "date_from": tomorrow_formatted,
            "date_to": six_month_formatted,
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 30,
            "flight_type": "round",
            "selected_cabins": "M",
            "max_stopovers": 0,
            "curr": "GBP",
        }
        response = requests.get("https://tequila-api.kiwi.com/v2/search", params=query, headers=self.headers)
        try:
            data = response.json()['data'][0]
        except IndexError:
            print(f'No flights available to {code}')
            query["max_stopovers"] = 1
            response = requests.get("https://tequila-api.kiwi.com/v2/search", params=query, headers=self.headers)
            data = response.json()['data'][0]
            flight_data = FlightData(
                price=data['price'],
                dept_city_name=data["route"][0]['cityFrom'],
                dept_airport_iata_code=data["route"][0]['flyFrom'],
                arr_city_name=data["route"][2]['cityTo'],
                arr_airport_iata_code=data["route"][2]['flyTo'],
                outbound_date=data["route"][0]["local_departure"].split("T")[0],
                inbound_date=data["route"][2]["local_departure"].split("T")[0],
                via_city=data["route"][1]['cityFrom'],
                stop_overs=1
            )
            return flight_data
        else:
            flight_data = FlightData(
                price=data['price'],
                dept_city_name=data['cityFrom'],
                dept_airport_iata_code=data['flyFrom'],
                arr_city_name=data['cityTo'],
                arr_airport_iata_code=data['flyTo'],
                outbound_date=data["route"][0]["local_departure"].split("T")[0],
                inbound_date=data["route"][1]["local_departure"].split("T")[0]
            )
            print(f'City: {flight_data.arr_city_name}: {flight_data.price}')
            return flight_data
예제 #12
0
    def search_flights(self, origin_city_code, destination_city_code, from_time, to_time):
        headers = {
            'apikey': API_KEY
        }
        parameters = {
            'fly_from': origin_city_code,
            'fly_to': destination_city_code,
            'date_from': from_time.strftime('%d/%m/%Y'),
            'date_to': to_time.strftime('%d/%m/%Y'),
            'nights_in_dst_from': 7,
            'nights_in_dst_to': 28,
            'one_for_city': 1,
            'max_stopovers': 0,
            'curr': 'GBP'
        }
        response = requests.get(url=f'{FLIGHT_API_ENDPOINT}v2/search', params=parameters, headers=headers)

        try:
            data = response.json()['data'][0]
        except IndexError:
            parameters['max_stopovers'] = 1
            response = requests.get(
                url=f"{FLIGHT_API_ENDPOINT}/v2/search",
                headers=headers,
                params=parameters
            )
            data = response.json()['data'][0]
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][1]["cityTo"],
                destination_airport=data["route"][1]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][2]["local_departure"].split("T")[0],
                stop_overs=1,
                via_city=data["route"][0]["cityTo"]
            )
            return flight_data
        else:
            flight_data = FlightData(
                price=data["price"],
                origin_city=data["route"][0]["cityFrom"],
                origin_airport=data["route"][0]["flyFrom"],
                destination_city=data["route"][0]["cityTo"],
                destination_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0]
            )
            return flight_data
예제 #13
0
    def checkFlights(self, base_city_code, location_code, from_time, to_time):
        header = {"apikey": location_api}
        query = {
            "fly_from": base_city_code,
            "fly_to": location_code,
            "date_from": from_time.strftime("%d/%m/%Y"),
            "date_to": to_time.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "INR"
        }

        response = requests.get(url=f"{location_endpoint}/v2/search",
                                params=query,
                                headers=header)

        try:
            data = response.json()["data"]
        except IndexError:
            query["max_stopovers"] = 1

            data = data[0]
            flight_data = FlightData(
                price=data['price'],
                base_city=data["route"][0]["cityFrom"],
                base_airport=data["route"][0]["flyFrom"],
                location_city=data["route"][0]["cityTo"],
                location_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0],
                stop_overs=1,
                via_city=data["route"][0]["cityTo"])
            return flight_data
        else:
            data = data[0]
            flight_data = FlightData(
                price=data['price'],
                base_city=data["route"][0]["cityFrom"],
                base_airport=data["route"][0]["flyFrom"],
                location_city=data["route"][0]["cityTo"],
                location_airport=data["route"][0]["flyTo"],
                out_date=data["route"][0]["local_departure"].split("T")[0],
                return_date=data["route"][1]["local_departure"].split("T")[0],
                stop_overs=0,
                via_city='')
            return flight_data
예제 #14
0
    def check_flights(self, origin_city_code, destination_city_code, from_time, to_time):
        headers = {
            "apikey": self.TEQUILA_SEARCH_API_KEY
        }

        params = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_time.strftime("%d/%m/%Y"),
            "date_to": to_time.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "USD"

        }
        response = requests.get(url="https://tequila-api.kiwi.com/v2/search", headers=headers, params=params)
        data = response.json()["data"][0]

        flight_data = FlightData(
            price=data["price"],
            origin_city=data["route"][0]["cityFrom"],
            origin_airport=data["route"][0]["flyFrom"],
            destination_city=data["route"][0]["cityTo"],
            destination_airport=data["route"][0]["flyTo"],
            out_date=data["route"][0]["local_departure"].split("T")[0],
            return_date=data["route"][1]["local_departure"].split("T")[0]
        )
        print(f"{flight_data.destination_city}: £{flight_data.price}")
        return flight_data
예제 #15
0
    def check_flights(self, origin_city_code, destination_city_code, from_time, to_time):
        header = {"apikey": TEQUILA_API_KEY}
        query = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_time.strftime("%d/%m/%Y"),
            "date_to": to_time.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "CAD"
        }
        end_point = f"TEQUILA_ENDPOINT/v2/search"
        response = requests.get(end_point=end_point,
                                params=query, headers=header)
        data = response.json()["data"][0]

        flight_data = FlightData(
            price=data["price"],
            origin_city=data["route"][0]["cityFrom"],
            origin_airport=data["route"][0]["flyFrom"],
            destination_city=data["route"][0]["cityTo"],
            destination_airport=data["route"][0]["flyTo"],
            out_date=data["route"][0]["local_departure"].split("T")[0],
            return_date=data["route"][1]["local_departure"].split("T")[0]
        )
        print(f"{flight_data.destination_city}: £{flight_data.price}")
        return flight_data
    def __init__(self):
        # # Check for correct input
        # if isinstance(vehicle, Vehicle) is False:
        #     raise TypeError('Expected object of type Vehicle, got '+type(vehicle).__name__)

        # Calling super class constructor
        StoppableThread.__init__(self)

        # These are the distances the drone passed in a certain direction.
        # They are used to know if I need to try to pass the obstacle from another direction.
        self.__right_distance = 0.0
        self.__left_distance = 0.0
        self.__up_distance = 0.0

        # Always keep track of my last move in order to know better what to do in certain situations.
        self.__last_move = None

        # In case the drone need to pass an obstacle from above - keeping 2 flags. One for indicating its in the
        # process of climbing, and another one to indicate it finished climbing and should now keep its altitude
        # until passing the obstacle.
        self.__keep_altitude = False
        self.__climbing = False

        # I want to maintain the drone's altitude for a short period of time before descending back to the
        # original constant altitude, so for that I keep tracking of the time since it ascended.
        self.__start_time_measure = 0.0

        # In case of emergency, keeping a flag to order the drone to land.
        self.__safety_protocol = False

        # Other classes within the software for giving flight orders, get sensors data and
        # calculate distances by geographic positioning system data.
        # the __flight_commands & __location objects should get as a parameter the vehicle object
        self.__flight_commands = FlightCommands()   # FlightCommands(vehicle)
        self.__sensors = Sensors()
        self.__flight_data = FlightData()           # FlightData(vehicle)

        # Get the drone's location and height for further calculations.
        self.__last_latitude = self.__flight_data.get_current_latitude()
        self.__last_longitude = self.__flight_data.get_current_longitude()
        self.__last_height = self.__flight_data.get_current_height()

        # Counter and flag for being aware of a sequence of illegal sensor inputs in order to be aware of a
        # malfunction in the system
        self.__illegal_input_counter = 0
        self.__last_input_legitimacy = True

        self.__num_of_lines = int(self.__get_number_of_line_in_file())  # Delete when moving to a full functioning system.

        # Initializing the sensors
        if self.__sensors.connect() == -1:
            raise ConnectionError('Cannot connect to sensors')

        print("Connected Successfuly to Sensors!")

        # Flag that indicates if the system is activated in order to give the user the knowledge if it should override
        # other flight commands given to the drone. The flag is 'True' only for left/right/up maneuvers and False
        # for all other cases including fixing the drone's altitude, since the altitude is fixed for 10 meters and
        # any other running software within the drone shouldn't change its height.
        self.__is_active = False
예제 #17
0
 def get_flight_details(self, origin, destination):
     """
     Gets particular details about cheapest flight found flight.
     """
     date_today = datetime.datetime.now().date().strftime("%d/%m/%Y")
     after_six_months = (datetime.datetime.now().date() + relativedelta(months=+6)).strftime("%d/%m/%Y")
     header = {
         "apikey": TEQUILA_API_KEY
     }
     query = {
         "fly_from": f"city:{origin}",
         "fly_to": f"city:{destination}",
         "date_from": date_today,
         "date_to": after_six_months,
         "one_for_city": 1,
         "curr": "KES",
     
     }
     response = requests.get(url=f"{TEQUILA_ENDPOINT}/search", params=query, headers=header)
     response.raise_for_status
     # Pick first index in case of flights with similar prices 
     try:
         data = response.json()['data'][0]
     except IndexError:
         print(f"There are currently no flights to {destination}")
         return None
     # Come back and check on what is happening to arrival and deprt. dates
     flight_details = FlightData(
         price = data['price'], 
         source_city = data['cityCodeFrom'],
         source_airport = data['flyFrom'],
         dest_city = data['cityCodeTo'],
         dest_airport = data['flyTo']
     )
     return flight_details
예제 #18
0
    def check_flights(self, from_city, to_city, from_date, to_date):
        params = {
            'fly_from': from_city,
            'fly_to': to_city,
            'date_from': from_date.strftime("%d/%m/%Y"),
            'date_to': to_date.strftime("%d/%m/%Y"),
            'nights_in_dst_from': 7,
            'nights_in_dst_to': 28,
            "max_stopovers": 0
        }

        response = requests.get(url=f"{TEQUILA_ENDPOINT}/v2/search",
                                headers=TEQUILA_HEADERS,
                                params=params).json()

        try:
            data = response['data'][0]
        except IndexError:
            print(f'No flights for {from_city} -- {to_city}')
            return None
        else:
            flight_data = FlightData(
                price=data['price'],
                origin_city=data['route'][0]['cityFrom'],
                destination_city=data['route'][0]['cityTo'],
                origin_airport=data['route'][0]['flyFrom'],
                destination_airport=data['route'][0]['flyTo'],
                flight_date=data['route'][0]['local_departure'].split("T")[0],
                return_date=data['route'][1]['local_departure'].split("T")[0],
            )
            return flight_data
예제 #19
0
    def search_price(self, origin_city_code, destination_city_code, from_date,
                     to_date):
        SEARCH_ENDPOINT = f'{ENDPOINT}/search'

        param = {
            'fly_from': origin_city_code,
            'fly_to': destination_city_code,
            'date_from': from_date,
            'date_to': to_date,
            'nights_in_dst_from': 7,
            'nights_in_dst_to': 28,
            'flight_type': 'round',
            'one_for_city': 1,
            'max_stopovers': 0,
            'curr': 'GBP'
        }

        response = requests.get(url=SEARCH_ENDPOINT,
                                headers=headers,
                                params=param)

        data = response.json()['data'][0]

        flight_data = FlightData(
            price=data['price'],
            origin_city=data['route'][0]['cityFrom'],
            origin_airport=data['route'][0]['flyFrom'],
            destination_city=data['route'][0]['cityTo'],
            destination_airport=data['route'][0]['flyTo'],
            out_date=data['route'][0]['local_departure'].split('T')[0],
            return_date=data['route'][1]['local_departure'].split('T')[0])

        print(f'{flight_data.destination_city}: £{flight_data.price}')
        return flight_data
예제 #20
0
    def search_for_flights(self, departure_code, destination_code, from_date,
                           return_date):
        header = {"apikey": kiwi_apikey}
        param = {
            "fly_from": departure_code,
            "fly_to": destination_code,
            "date_from": from_date,
            "date_to": return_date,
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 21,
            "flight_type": "round",
            "max_stopovers": 0,
            "curr": "USD",
        }
        response = requests.get(url=f"{kiwi_get_url}/v2/search",
                                headers=header,
                                params=param)
        try:
            response_data = response.json()["data"][0]
        except IndexError:
            return None

        flight_data = FlightData(
            price=response_data["price"],
            origin_city=response_data["route"][0]["cityFrom"],
            origin_airport=response_data["route"][0]["flyFrom"],
            destination_city=response_data["route"][0]["cityTo"],
            destination_airport=response_data["route"][0]["flyTo"],
            day_you_leave=response_data["route"][0]["local_departure"].split(
                "T")[0],
            return_date=response_data["route"][1]["local_departure"].split(
                "T")[0],
            airline=response_data["airlines"])

        return flight_data
예제 #21
0
    def search_flight(self, origin_city_code, destination_city_code, from_time, to_time):
        param = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_time.strftime("%d/%m/%Y"),
            "date_to": to_time.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "INR"
        }
        response_from_api = requests.get(url=f"{END_POINT}/v2/search", headers=FLIGHT_SEARCH_API,
                                         params=param)

        # IF IN CASE THERE IS NO FLIGHT TO OUR DESTINATION
        try:
            data_from_api = response_from_api.json()["data"][0]
        except IndexError:
            print(f"No flights found for {destination_city_code}.")
            return None

        # THIS FUNCTION IS PASSING ALL DATA TO flight_data class to store data
        flight_data = FlightData(
            price=data_from_api["price"],
            origin_city=data_from_api["route"][0]["cityFrom"],
            origin_airport=data_from_api["route"][0]["flyFrom"],
            destination_city=data_from_api["route"][0]["cityTo"],
            destination_airport=data_from_api["route"][0]["flyTo"],
            out_date=data_from_api["route"][0]["local_departure"].split("T")[0],
            return_date=data_from_api["route"][1]["local_departure"].split("T")[0]
        )
        print(f"{flight_data.destination_city}: ₹{flight_data.price}")
        return flight_data
예제 #22
0
    def check_flights(self, origin_city_code=None, destination_city_code=None, from_time=None, to_time=None):
        check_query = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_time.strftime("%d/%m/%Y"),
            "date_to": to_time.strftime("%d/%m/%Y"),
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "GBP"
        }

        response = requests.get(url=f"{TEQUILA_ENDPOINT}/v2/search", headers=self.headers, params=check_query)
        response.raise_for_status()

        try:
            result = response.json()["data"][0]
        except IndexError:
            print(f"There are no flights found for {check_query['fly_to']}.")
            return None

        flight_data = FlightData(
            price=result["price"],
            city=result["route"][0]["cityFrom"],
            airport=result["route"][0]["flyFrom"],
            destination_city=result["route"][0]["cityTo"],
            destination_airport=result["route"][0]["flyTo"],
            date=result["route"][0]["local_departure"].split("T")[0],
            return_date=result["route"][1]["local_departure"].split("T")[0]
        )
        print(f"{flight_data.destination_city}: £{flight_data.price}")
        return flight_data
예제 #23
0
    def get_flight_prices(self, origin_city_code, destination_city_code,
                          from_date, to_date):
        headers = {"apikey": TEQUILA_API}
        query = {
            "fly_from": origin_city_code,
            "fly_to": destination_city_code,
            "date_from": from_date,
            "date_to": to_date,
            "flight_type": "round",
            "max_stopovers": 0,
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "curr": "GBP",
        }
        response = requests.get(url=f"{TEQUILA_ENDPOINT}/v2/search",
                                params=query,
                                headers=headers)
        data = response.json()["data"][0]
        print(data)

        flight_data = FlightData(
            price=data["price"],
            origin_city=data["route"][0]["cityFrom"],
            origin_airport=data["route"][0]["flyFrom"],
            destination_city=data["route"][0]["cityTo"],
            destination_airport=data["route"][0]["flyTo"],
            out_date=data["route"][0]["local_departure"].split("T")[0],
            return_date=data["route"][1]["local_departure"].split("T")[0])

        print(f"{flight_data.destination_city}: £{flight_data.price}")
        return flight_data
class FlightSearch:
    # This class is responsible for talking to the Flight Search API.
    def __init__(self, own_city):
        self.now = datetime.datetime.now()
        tmr = self.now + datetime.timedelta(days=1)
        six_month = self.now + datetime.timedelta(days=180)
        self.date_tmr = tmr.strftime("%d/%m/%Y")
        self.date_six_month = six_month.strftime("%d/%m/%Y")
        self.flight_data = FlightData()
        self.own_city = own_city

    def search_city(self, city):
        parameter = {
            "term": city,
            "location_types": "city",
        }
        response = requests.get(IATA_code_search_endpoint, parameter, headers=headers)
        response.raise_for_status()
        data = self.flight_data.check_city(response.json())
        return data

    def search_flight(self, city, lowest_price, stopover=0):
        parameter = {
            "curr": "GBP",
            "fly_from": self.own_city,
            "fly_to": city,
            "date_from": self.date_tmr,
            "date_to": self.date_six_month,
            "price_to": lowest_price,
            "sort": "price",
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "flight_type": "round",
            "max_stopovers": stopover,
        }
        response = requests.get(flight_search_endpoint, parameter, headers=headers)
        response.raise_for_status()
        data = response.json()
        if data["data"]:
            return self.flight_data.check_price(data, parameter["max_stopovers"])
        else:
            print(f"{parameter['max_stopovers']} no flight found")
            # print(data)
            if parameter["max_stopovers"] < 2:
                self.search_flight(city, lowest_price, parameter["max_stopovers"]+1)
예제 #25
0
 def get_prices(self, city):
     global data
     header = {
         "apikey": TEQUILA_API_KEY,
     }
     query = {
         "fly_from": departure_airport_code,
         "date_from": formatted_day,
         "date_to": formatted_period,
         "fly_to": city,
         "nights_in_dst_from": 7,
         "nights_in_dst_to": 28,
         "flight_type": "round",
         "one_for_city": 1,
         "max_stopovers": 0,
         "curr": "GBP",
     }
     response = requests.get(url=end_point, params=query, headers=header)
     try:
         data = response.json()["data"][0]
     except:
         print("There is no flight in specified days")
         flight_data = FlightData(
             price=data["price"],
             origin_city=data["route"][0]["cityFrom"],
             origin_airport=data["route"][0]["flyFrom"],
             destination_city=data["route"][0]["cityTo"],
             destination_airport=data["route"][0]["flyTo"],
             out_date=data["route"][0]["local_departure"].split("T")[0],
             return_date=data["route"][1]["local_departure"].split("T")[0],
             noinfo=False)
         return flight_data
     else:
         flight_data = FlightData(
             price=data["price"],
             origin_city=data["route"][0]["cityFrom"],
             origin_airport=data["route"][0]["flyFrom"],
             destination_city=data["route"][0]["cityTo"],
             destination_airport=data["route"][0]["flyTo"],
             out_date=data["route"][0]["local_departure"].split("T")[0],
             return_date=data["route"][1]["local_departure"].split("T")[0],
             noinfo=True)
         print(f"{flight_data.destination_city}: £{flight_data.price}")
         return flight_data
예제 #26
0
    def get_flights(
        self,
        departure_iata,
        destination_iata,
        departure_date,
        return_date,
        currency="GBP",
        min_nights=7,
        max_nights=28,
    ):
        """find flight information using Tequila Kiwi API and return a
        FlightData object

        Args:
            departure_iata (str): IATA Code for origin city
            destination_iata (str): IATA Code for destination city
            departure_date (str): dd/mm/YYYY for earliest departure
            return_date (str): dd/mm/YYYY for latest return
            currency (str, optional): currency to return. Defaults to "GBP".
            min_nights (int, optional): minimum nights. Defaults to 7.
            max_nights (int, optional): maximum nights. Defaults to 28.

        Returns:
            FlightData: FlightData for lowst cost flight
        """
        url = self.url_base + "/v2/search"
        params = {
            "fly_from": departure_iata,
            "fly_to": destination_iata,
            "date_from": departure_date,
            "date_to": return_date,
            "nights_in_dst_from": min_nights,
            "nights_in_dst_to": max_nights,
            "curr": currency,
            "flight_type": "round",
            "one_for_city": 1,
        }
        response = requests.get(url, params=params, headers=self.headers)
        data = response.json()
        if len(data["data"]) > 0:
            data = data["data"][0]
        else:
            return None

        flight_data = FlightData(
            departure_city=data["cityFrom"],
            departure_airport=data["flyFrom"],
            destination_city=data["cityTo"],
            destination_airport=data["flyTo"],
            departure_date=data["route"][0]["local_departure"].split("T")[0],
            return_date=data["route"][-1]["local_arrival"].split("T")[0],
            price=data["price"],
        )
        return flight_data
예제 #27
0
    def get_flights(self, flight_code):
        tomorrow = dt.datetime.today() + dt.timedelta(days=1)
        six_months_later = tomorrow + dt.timedelta(days=30 * 12)
        # print(flight_code)
        #
        # print(tomorrow.strftime("%d/%m/%Y"))
        # print(six_months_later.strftime("%d/%m/%Y"))
        self.parameters = {
            "fly_from": "DEL",
            "fly_to": flight_code,
            "date_from": str(tomorrow.strftime("%d/%m/%Y")),
            "date_to": str(six_months_later.strftime("%d/%m/%Y")),
            "flight-type": "round",
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 28,
            "curr": "INR",
            "one_for_city": 1,
            "max_stopovers": 0,
        }

        self.flight_response = requests.get(url=FLIGHT_ENDPOINT,
                                            params=self.parameters,
                                            headers=header)
        self.flight_response.raise_for_status()
        self.flight_response_data = self.flight_response.json()["data"]

        # print(self.flight_response_data)
        flight_data = FlightData()

        try:
            available_flight = flight_data.structure_flight_data(
                self.flight_response_data[0])
        except IndexError:
            print(f"No Flight Found for {flight_code}")
            return None

        # print(available_flight)
        # print(f"{available_flight['cityTo']} - ${available_flight['price']:,}")
        return available_flight
예제 #28
0
    def fetch_flight_data_from_google_sheet(self) -> list[FlightData]:
        """This method will fetch the flight data of an user from an Google Sheet."""
        response = requests.get(
            url=f"{SHEETY_BASE_URL}{self.sheety_sheet_endpoint}")
        response.raise_for_status()
        data = response.json()

        flight_data = [
            FlightData(record_id=destination["id"],
                       city=destination["city"],
                       iata_code=destination["iataCode"],
                       lowest_price=destination["lowestPrice"])
            for destination in data["prices"]
        ]

        return flight_data
예제 #29
0
 def search_flights(self):
     date_now = dt.datetime.now()
     search_url = f"{TEQUILA_URL}/v2/search"
     search_headers = {
         "apikey": TEQUILA_API_KEY,
         "accept": "application/json"
     }
     search_params = {
         "fly_from":
         "LON",
         "fly_to":
         self.city_obj['iataCode'],
         "date_from":
         date_now.strftime("%d/%m/%Y"),
         "date_to":
         (date_now + dt.timedelta(days=(6 * 30))).strftime("%d/%m/%Y"),
         "nights_in_dst_from":
         7,
         "nights_in_dst_to":
         28,
         "curr":
         "GBP",
         "flight_type":
         "round",
         "one_for_city":
         1
     }
     search_res = requests.get(url=search_url,
                               headers=search_headers,
                               params=search_params)
     search_data = search_res.json()
     if len(search_data['data']) > 0:
         flight_data_result = FlightData(search_data)
     else:
         flight_data_result = None
     if flight_data_result:
         if flight_data_result.price < self.city_obj['lowestPrice']:
             text_message = NotificationManager(
                 flight_data_result.flight_dict)
             text_message.send_text()
         else:
             print("No Deal")
예제 #30
0
def check_flights(fly_to, max_stopovers) -> [FlightData]:
    tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
    within_six_months = tomorrow + datetime.timedelta(days=180)

    json = {
        "apikey": TEQUILA_API_KEY,
        "fly_from": "LON",
        "fly_to": fly_to,
        "date_from": tomorrow.strftime("%d/%m/%Y"),
        "date_to": within_six_months.strftime("%d/%m/%Y"),
        "nights_in_dst_from": 7,
        "nights_in_dst_to": 28,
        "flight_type": "round",
        "one_for_city": 1,
        "curr": "GBP",
        "max_stopovers": max_stopovers
    }

    tequila = requests.get(
        url=f"{TEQUILA_ENDPOINT}/v2/search?{urlencode(json)}")
    tequila.raise_for_status()

    flights = []

    for flight_data in tequila.json()["data"]:
        flight = FlightData(
            arrival_airport_city=flight_data["cityTo"],
            arrival_airport_code=flight_data["flyTo"],
            arrival_city_code=flight_data["cityCodeTo"],
            departure_airport_city=flight_data["cityFrom"],
            departure_airport_code=flight_data["flyFrom"],
            inbound_date=flight_data["route"][
                (max_stopovers + 1) * 0]["utc_departure"].split("T")[0],
            outbound_date=flight_data["route"][
                (max_stopovers + 1) * 1]["utc_departure"].split("T")[0],
            price=flight_data["price"],
            stopovers=max_stopovers,
            via_city=flight_data["route"][0]["cityTo"])
        flights.append(flight)

    return flights
    def find_flights(self, src_city_iata, dest_city_iata, tomorrow_date,
                     to_date, city_name):

        flight_search_endpoint = f"{self.kiwi_endpoint}/v2/search"
        flight_search_params = {
            "fly_from": src_city_iata,
            "fly_to": dest_city_iata,
            "date_from": tomorrow_date,
            "date_to": to_date,
            "nights_in_dst_from": 7,
            "nights_in_dst_to": 10,
            "flight_type": "round",
            "one_for_city": 1,
            "max_stopovers": 0,
            "curr": "USD"
        }

        response = requests.get(
            url=flight_search_endpoint,
            headers=self.kiwi_header,
            params=flight_search_params,
        )

        try:
            data = response.json()["data"][0]
        except IndexError:
            return (f"No flights found for {city_name}")

        flight_data = FlightData(
            price=data['price'],
            src_city=data['route'][0]['cityFrom'],
            src_airport=data['route'][0]['flyFrom'],
            dest_city=data['route'][0]['cityTo'],
            dest_airport=data['route'][0]['flyTo'],
            out_date=data['route'][0]['local_departure'].split("T")[0],
            return_date=data['route'][1]['local_departure'].split("T")[0],
        )

        #print(f"{flight_data.dest_city} for {flight_data.price}.")
        return flight_data
class ObstacleAvoidance(StoppableThread):
    # Class constants
    LEFT = "left"
    RIGHT = "right"
    UP = "up"
    DEVIATION_HORIZONTAL = 20
    DEVIATION_VERTICAL = 500
    NO_OBSTACLES_AHEAD = 1
    CAUTION_DISTANCE = 200    # Should be 4000, Measured in Centimeters
    DANGER_DISTANCE = 125     # Should be 1000, Measured in Centimeters
    CAUTION_ALTITUDE = 375    # Should be 3000, Measured in Centimeters.
    DANGER_ALTITUDE = 4000    # Should be 4000, Measured in Centimeters.
    CONSTANT_HEIGHT = 1000    # Should be 1000, Measured in Centimeters.
    MAX_LEFT_RIGHT = 0.875    # Should be 7.0, Maximum distance the drone would go right/left until trying to pass and obstacle from above. Measured in Meters.
    LEFT_SENSOR = "leftSensor"
    RIGHT_SENSOR = "rightSensor"
    FRONT_SENSOR = "frontSensor"
    BOTTOM_SENSOR = "bottomSensor"

    # In the final software, the __init__ function signature should look like:
    # def __init__(self, vehicle):
    # vehicle object is an object from external module that has been developed by a different person within
    # the company. Since this module use other modules which is not related
    # to this project, I put all the relevant code line for proper functioning in comment.

    # def __init__(self, vehicle):
    def __init__(self):
        # # Check for correct input
        # if isinstance(vehicle, Vehicle) is False:
        #     raise TypeError('Expected object of type Vehicle, got '+type(vehicle).__name__)

        # Calling super class constructor
        StoppableThread.__init__(self)

        # These are the distances the drone passed in a certain direction.
        # They are used to know if I need to try to pass the obstacle from another direction.
        self.__right_distance = 0.0
        self.__left_distance = 0.0
        self.__up_distance = 0.0

        # Always keep track of my last move in order to know better what to do in certain situations.
        self.__last_move = None

        # In case the drone need to pass an obstacle from above - keeping 2 flags. One for indicating its in the
        # process of climbing, and another one to indicate it finished climbing and should now keep its altitude
        # until passing the obstacle.
        self.__keep_altitude = False
        self.__climbing = False

        # I want to maintain the drone's altitude for a short period of time before descending back to the
        # original constant altitude, so for that I keep tracking of the time since it ascended.
        self.__start_time_measure = 0.0

        # In case of emergency, keeping a flag to order the drone to land.
        self.__safety_protocol = False

        # Other classes within the software for giving flight orders, get sensors data and
        # calculate distances by geographic positioning system data.
        # the __flight_commands & __location objects should get as a parameter the vehicle object
        self.__flight_commands = FlightCommands()   # FlightCommands(vehicle)
        self.__sensors = Sensors()
        self.__flight_data = FlightData()           # FlightData(vehicle)

        # Get the drone's location and height for further calculations.
        self.__last_latitude = self.__flight_data.get_current_latitude()
        self.__last_longitude = self.__flight_data.get_current_longitude()
        self.__last_height = self.__flight_data.get_current_height()

        # Counter and flag for being aware of a sequence of illegal sensor inputs in order to be aware of a
        # malfunction in the system
        self.__illegal_input_counter = 0
        self.__last_input_legitimacy = True

        self.__num_of_lines = int(self.__get_number_of_line_in_file())  # Delete when moving to a full functioning system.

        # Initializing the sensors
        if self.__sensors.connect() == -1:
            raise ConnectionError('Cannot connect to sensors')

        print("Connected Successfuly to Sensors!")

        # Flag that indicates if the system is activated in order to give the user the knowledge if it should override
        # other flight commands given to the drone. The flag is 'True' only for left/right/up maneuvers and False
        # for all other cases including fixing the drone's altitude, since the altitude is fixed for 10 meters and
        # any other running software within the drone shouldn't change its height.
        self.__is_active = False

    def run(self):
        while not self.stopped():
            simulator.altitude_change()     # Delete when moving to a full functioning system.

            self.__num_of_lines -= 1        # Delete when moving to a full functioning system.
            if self.__num_of_lines == 0:    # Delete when moving to a full functioning system.
                self.stopit()               # Delete when moving to a full functioning system.
                continue                    # Delete when moving to a full functioning system.

            print("-----------------------------------------------------------")
            if self.__safety_protocol is True:
                self.__follow_safety_protocol()

            ahead_distance = self.__get_sensor_reading(self.FRONT_SENSOR)
            print("Distance Ahead: %d" % ahead_distance)

            # In case the path ahead is clear of obstacles, reset counters and fix altitude.
            if ahead_distance == self.NO_OBSTACLES_AHEAD or ahead_distance >= self.CAUTION_DISTANCE:
                print("Way is Clear")
                self.__check_flags()
                self.__fix_altitude()
                self.__last_move = None
                self.__is_active = False
                print("Is Active = " + str(self.__is_active))
                self.__right_distance = self.__left_distance = self.__up_distance = 0.0
                continue

            if ahead_distance <= self.DANGER_DISTANCE:
                # There's an obstacle in less than 10 meters - DANGER!
                # In such case the algorithm would slow down the drone drastically in order to give it more
                # time to manouver and avoid a collision.
                print("CAUTION: Obstacle in less than 1.25 meters!")
                print("Slowing Down to avoid collision")
                self.__flight_commands.slow_down(ahead_distance)
            else:
                print("Obstacle in less than 2 meters")

            self.__is_active = True
            print("Is Active = " + str(self.__is_active))

            # Get a reading from the left side sensor.
            left_side_distance = self.__get_sensor_reading(self.LEFT_SENSOR)
            # Get a reading from the right side sensor.
            right_side_distance = self.__get_sensor_reading(self.RIGHT_SENSOR)
            print("Distance Left: %d, Distance Right: %d" % (left_side_distance, right_side_distance))

            # If already tried going to go to the left/right 7 meters and there's
            # still an obstacle ahead then I want to try from above.
            if self.__need_to_go_up() is True:
                self.__climbing = True
                if self.__flight_data.get_current_height() >= self.DANGER_ALTITUDE:
                    self.__safety_protocol = True
                    self.__follow_safety_protocol()
                else:
                    self.__move_in_direction(self.UP)
                    print("Going up")
                continue

            # Check if right side is clear.
            elif right_side_distance > left_side_distance + self.DEVIATION_HORIZONTAL:
                self.__move_in_direction(self.RIGHT)
                self.__check_flags()
                print("Going right")

            # Check if left side is clear.
            elif left_side_distance > right_side_distance + self.DEVIATION_HORIZONTAL:
                self.__move_in_direction(self.LEFT)
                self.__check_flags()
                print("Going left")

            # If both left and right gives about the same distance.
            elif self.__climbing:
                if self.__flight_data.get_current_height() >= self.DANGER_ALTITUDE:
                    self.__safety_protocol = True
                    self.__follow_safety_protocol()
                    continue
                else:
                    self.__move_in_direction(self.UP)
                    print("Going up")
                    continue

            # If both left and right side looks blocked and still want to try to pass the obstacle from one of its sides
            else:
                if self.__last_move is not None:
                    self.__move_in_direction(self.__last_move)
                    print("Going " + self.__last_move)

                else:
                    if left_side_distance > right_side_distance:
                        self.__move_in_direction(self.LEFT)
                        print("Going left")

                    elif left_side_distance < right_side_distance:
                        self.__move_in_direction(self.RIGHT)
                        print("Going right")

            self.__fix_altitude()

    def __need_to_go_up(self):
        if self.__right_distance >= self.MAX_LEFT_RIGHT or self.__left_distance >= self.MAX_LEFT_RIGHT:
            return True
        else:
            return False

    def __move_in_direction(self, direction):
        if direction == self.RIGHT:
            self.__flight_commands.go_right()

        elif direction == self.LEFT:
            self.__flight_commands.go_left()

        elif direction == self.UP:
            self.__flight_commands.go_up()
            self.__keep_altitude = True
            self.__start_time_measure = round(time.time())

        elif type(direction).__name__ is "str":
            raise ValueError('Expected "' + self.UP + '" / "' + self.LEFT + '" / "' + self.RIGHT + '", instead got ' +
                             str(direction))
        else:
            raise TypeError('Expected variable of type str and got a variable of type ' + type(direction).__name__)

        self.__update_distance(direction)
        self.__last_move = direction

    def __update_distance(self, direction):
        if direction != self.RIGHT \
                and direction != self.LEFT \
                and direction != self.UP \
                and isinstance(direction, str):
            raise ValueError('Expected "' + self.UP + '" / "' + self.LEFT + '" / "' + self.RIGHT + '", instead got ' +
                             str(direction))

        elif type(direction).__name__ != "str":
            raise TypeError('Expected variable of type str and got a variable of type ' + type(direction).__name__)

        # Get current location data.
        current_latitude = self.__flight_data.get_current_latitude()
        current_longitude = self.__flight_data.get_current_longitude()
        current_height = self.__flight_data.get_current_height()

        delta = self.__flight_data.calculate_distance(
            self.__last_latitude, self.__last_longitude, current_latitude, current_longitude)

        # Update the distance travelled in certain direction
        if direction == self.RIGHT:
            self.__right_distance += delta
            self.__left_distance = 0
            print("Distance went right: %f" % self.__right_distance)
        elif direction == self.LEFT:
            self.__left_distance += delta
            self.__right_distance = 0
            print("Distance went left: %f" % self.__left_distance)
        elif direction == self.UP:
            self.__up_distance += current_height - self.__last_height
            self.__left_distance = self.__right_distance = 0
            print("Distance went up: %f" % self.__up_distance)

        # Update last known location attributes
        self.__last_latitude = current_latitude
        self.__last_longitude = current_longitude
        self.__last_height = current_height

    def __get_sensor_reading(self, sensor):
        legal_input = False
        while legal_input is False:
            if sensor is self.FRONT_SENSOR:
                distance = self.__sensors.check_ahead()

            elif sensor is self.RIGHT_SENSOR:
                distance = self.__sensors.check_right_side()

            elif sensor is self.LEFT_SENSOR:
                distance = self.__sensors.check_left_side()

            elif sensor is self.BOTTOM_SENSOR:
                distance = self.__sensors.check_below()

            else:
                if isinstance(sensor, str):
                    raise ValueError('Expected "' + self.FRONT_SENSOR + '" / "' + self.BOTTOM_SENSOR + '" / "' +
                                     self.LEFT_SENSOR + '" / "' + self.RIGHT_SENSOR + '", instead got ' + sensor)
                else:
                    raise TypeError('Expected variable of type str and got a variable of type ' + type(sensor).__name__)

            legal_input = self.__check_measurement(distance)
            if legal_input:
                return distance

    def __check_measurement(self, measurement):
        is_int = isinstance(measurement, int)

        if is_int is False and measurement is not "NACK":
            raise TypeError('Expected variable of type int and got a variable of type ' + type(measurement).__name__)

        if is_int:
            if measurement > 0:
                self.__last_input_legitimacy = True
                return True

        if self.__last_input_legitimacy is True:
            self.__illegal_input_counter = 1
        else:
            self.__illegal_input_counter += 1
            if self.__illegal_input_counter >= 10:
                raise SystemError('Malfunction in sensors, check physical connections')


        self.__last_input_legitimacy = False
        return False

    def __check_flags(self):
        if self.__climbing is True:
            self.__climbing = False
            self.__keep_altitude = True

    def __safe_for_landing(self):
        print("Check if safe to land")
        drone_altitude = self.__flight_data.get_current_height()
        bottom_sensor_distance = self.__get_sensor_reading(self.BOTTOM_SENSOR)
        print("Pixhawk height: " + str(drone_altitude) + ", Sensor height: " + str(bottom_sensor_distance))
        heigh_difference = math.fabs(bottom_sensor_distance - drone_altitude)
        if heigh_difference > self.DEVIATION_HORIZONTAL:
            return False
        else:
            return True

    def __fix_altitude(self):
        bottom_sensor_distance = self.__get_sensor_reading(self.BOTTOM_SENSOR)
        altitude = self.__flight_data.get_current_height()
        print("Sensor Below: " + str(bottom_sensor_distance) + ", Pixhawk: " + str(altitude))

        if bottom_sensor_distance > self.DANGER_ALTITUDE:
            self.__safety_protocol = True
            self.__follow_safety_protocol()
            return

        if self.__keep_altitude:
            # This means the drone passed an obstacle from above. in that case I want to maintain my current altitude
            # for 10 seconds to make sure the drone passed the obstacle, before getting back to regular altitude.
            current_time = int(round(time.time()))
            print("maintaining altitude for " + str((current_time - self.__start_time_measure)) + " seconds")
            if current_time - self.__start_time_measure > 10.0:
                # 10 Seconds have passed, now before the drone start decending I want to make sure
                # there's nothing below and its safe for him to descend.
                self.__keep_altitude = False
            else:
                self.__flight_commands.maintain_altitude()
                return

        # Fix the height of the drone to 10 meters from the ground.
        delta_altitude = self.CONSTANT_HEIGHT - bottom_sensor_distance
        if math.fabs(delta_altitude) < self.DEVIATION_HORIZONTAL:
            return
        elif delta_altitude > 0:
            self.__flight_commands.go_up()
            print("Fixing altitude - Going up")
        elif delta_altitude < 0:
            self.__flight_commands.go_down()
            print("Fixing altitude - Going down")

    def __get_number_of_line_in_file(self):
        i = 0
        with open('Sensors Data\\leftSensorData.txt') as file:
            for i, l in enumerate(file):
                pass
            return i + 1

    def __follow_safety_protocol(self):
        # If the code reached here it means the drone raised 25 meters up and still see an obstacle.
        # so in this case we prefer it would abort the mission in so it won't get too high or damaged.
        if self.__safe_for_landing():
            # while(self.__get_sensor_reading(self.__BOTTOM_SENSOR) > 10):
            self.__flight_commands.land()   # Enter this into the while loop above.
            self.stopit()
        else:
            self.__flight_commands.go_back_to_base()

    def take_control(self):
        return self.__is_active