Skip to content

Commit 010e2ff

Browse files
committedFeb 16, 2021
Update Day-40
1 parent 721bb10 commit 010e2ff

File tree

7 files changed

+214
-0
lines changed

7 files changed

+214
-0
lines changed
 

‎Day-40-FlightFinderV2/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Flight Finder V2
2+
3+
### Sign up [here](https://repl.it/@abhijeetpandit/FlightDealsClub?embed=1&output=1#main.py), We'll let you know when flights to amazing destinations go really, reaaally cheap!
4+
5+
### Here's is How it Works
6+
7+
- Join Flight Club
8+
- Get cheapest flight deals
9+
- You get to go on a holiday
10+
11+
<img src= 'https://user-images.githubusercontent.com/65078610/108055938-a6b0f980-7076-11eb-971c-41370a14bfb8.PNG' width="500">

‎Day-40-FlightFinderV2/data_manager.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#This class is responsible for talking to the Google Sheet.
2+
import os
3+
import json
4+
from pprint import pprint
5+
import requests
6+
from dotenv import load_dotenv
7+
load_dotenv()
8+
9+
class DataManager:
10+
11+
def __init__(self):
12+
self.sheety_endpoint = "https://api.sheety.co/126f9e38bb1fc18f122cb26e242ee654/flightDeals"
13+
self.headers = {
14+
'Authorization': os.getenv('AUTH_TOKEN')
15+
}
16+
17+
def get_data(self):
18+
response = requests.get(url=self.sheety_endpoint+'/prices', headers=self.headers)
19+
data = json.loads(response.text)['prices']
20+
return data
21+
22+
def update_data(self, row_id, new_price):
23+
sheety_update_endpoint = f"{self.sheety_endpoint+'/prices'}/{row_id}"
24+
price_config = {
25+
'price': {
26+
"lowestPrice": round(new_price)
27+
}
28+
}
29+
response = requests.put(url=sheety_update_endpoint, json=price_config , headers=self.headers)
30+
print(response.text)
31+
32+
def get_users(self):
33+
response = requests.get(url=self.sheety_endpoint+'/users', headers=self.headers)
34+
data = json.loads(response.text)['users']
35+
return data

‎Day-40-FlightFinderV2/flight_data.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#This class is responsible for structuring the flight data.
2+
class FlightData:
3+
4+
def compare(self, price_data, lowest_price):
5+
# Normalize API price hike
6+
lowest_price += lowest_price*14.8/100
7+
self.price_data = price_data
8+
self.price_array = []
9+
self.date_array = []
10+
for data in self.price_data:
11+
self.price_array.append(int(data['price']))
12+
self.date_array.append((data['route'][0]['local_arrival'])[:10])
13+
self.min_price = min(self.price_array)
14+
return self.min_price < lowest_price
15+
16+
def get_data(self):
17+
low_limit = self.price_array.index(self.min_price)
18+
self.price_array.reverse()
19+
high_limit = self.price_array.index(self.min_price)
20+
self.min_price -= self.min_price*13/100
21+
flight_details = {
22+
'price': round(self.min_price),
23+
'cityFrom': self.price_data[0]['route'][0]['cityFrom'],
24+
'cityCodeFrom': self.price_data[0]['route'][0]['cityCodeFrom'],
25+
'cityTo': self.price_data[0]['route'][0]['cityTo'],
26+
'cityCodeTo': self.price_data[0]['route'][0]['cityCodeTo'],
27+
'dateFrom': self.date_array[low_limit],
28+
'dateTo': ''
29+
}
30+
self.date_array.reverse()
31+
flight_details['dateTo'] = self.date_array[high_limit]
32+
return flight_details
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#This class is responsible for talking to the Flight Search API.
2+
from dotenv import load_dotenv
3+
from pprint import pprint
4+
from datetime import *
5+
import requests
6+
import os
7+
8+
load_dotenv()
9+
FLY_FROM = 'BOM'
10+
CURRENCY = 'INR'
11+
FLIGHT_TYPE = 'oneway'
12+
SORT_BY = 'date'
13+
14+
class FlightSearch:
15+
16+
def __init__(self):
17+
self.from_date =(datetime.now()+timedelta(days=1)).strftime('%d/%m/%Y')
18+
self.to_date =(datetime.now()+timedelta(days=180)).strftime('%d/%m/%Y')
19+
self.kiwi_endpoint = "https://tequila-api.kiwi.com/v2/search/"
20+
self.headers = {
21+
'apikey': os.getenv('API_KEY')
22+
}
23+
self.parameters = {
24+
'fly_from': FLY_FROM,
25+
'fly_to': '',
26+
'date_from': self.from_date,
27+
'date_to': self.to_date,
28+
'curr': CURRENCY,
29+
'flight_type': FLIGHT_TYPE,
30+
'one_per_date': 1,
31+
'sort': SORT_BY
32+
}
33+
34+
def get_data(self, fly_to):
35+
self.parameters['fly_to'] = fly_to
36+
response = requests.get(url=self.kiwi_endpoint, params=self.parameters, headers=self.headers)
37+
try:
38+
data = response.json()['data']
39+
except KeyError:
40+
print(f"No flights available to {fly_to}")
41+
return []
42+
else:
43+
# pprint(data[0])
44+
return data

‎Day-40-FlightFinderV2/main.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#This file will need to use the DataManager,FlightSearch, FlightData, NotificationManager classes to achieve the program requirements.
2+
from notification_manager import NotificationManager
3+
from flight_search import FlightSearch
4+
from flight_data import FlightData
5+
from data_manager import DataManager
6+
7+
notification_manager = NotificationManager()
8+
flight_search = FlightSearch()
9+
flight_data = FlightData()
10+
data_manger = DataManager()
11+
user_list = data_manger.get_users()
12+
destination_list = data_manger.get_data()
13+
14+
for city in destination_list:
15+
city_id = city['id']
16+
lowest_price = city['lowestPrice']
17+
fly_to = city['iataCode']
18+
price_data = flight_search.get_data(fly_to)
19+
# Check if no flights available
20+
if not price_data:
21+
continue
22+
is_cheap_deal = flight_data.compare(price_data, lowest_price)
23+
if is_cheap_deal:
24+
flight_details = flight_data.get_data()
25+
data_manger.update_data(city_id, flight_data.min_price)
26+
notification_manager.send_alert(flight_details, user_list)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This class is responsible for sending notifications with the deal flight details.
2+
from calendar import month_name
3+
from dotenv import load_dotenv
4+
import smtplib
5+
import os
6+
7+
load_dotenv()
8+
my_email = os.getenv('EMAIL')
9+
my_password = os.getenv('PASSWORD')
10+
11+
class NotificationManager:
12+
13+
def send_alert(self, data, users):
14+
link = (f"https://www.google.co.in/flights?hl=en#flt={data['cityCodeFrom']}.{data['cityCodeTo']}."+
15+
f"{data['dateFrom']}*{data['cityCodeTo']}.{data['cityCodeFrom']}.{data['dateTo']}")
16+
with smtplib.SMTP(host="smtp.gmail.com", port=587) as connection:
17+
connection.starttls()
18+
connection.login(my_email, my_password)
19+
for user in users:
20+
to_email = user['email']
21+
fName = user['firstName']
22+
connection.sendmail(
23+
from_addr=my_email,
24+
to_addrs=to_email,
25+
msg=("Subject:Flight Deals Alert!✈️\n\n"+
26+
f"Hi, {fName},\n"
27+
f"Super cheap fares to {data['cityTo']}. Get in. On this!\n"+
28+
f"This is the cheapest deal to {data['cityTo']} in the upcoming 6 months.\n\n"
29+
f"Only ₹{data['price']:,} to fly from, \n"+
30+
f"{data['cityFrom']} ({data['cityCodeFrom']}) "+
31+
f"to {data['cityTo']} ({data['cityCodeTo']}).\n"+
32+
f"Tickets available from {self.dateFormat(data['dateFrom'])} to {self.dateFormat(data['dateTo'])}\n"+
33+
f"{link}\n\n"+
34+
"Cheers, \nAbhijeet").encode('utf-8')
35+
)
36+
37+
def dateFormat(self, str):
38+
arr = str.split('-')
39+
return (f"{arr[2]} {month_name[int(arr[1].strip('0'))]}, {arr[0]}")

‎Day-40-FlightFinderV2/signup.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Sign up for new user
2+
import os
3+
import requests
4+
from dotenv import load_dotenv
5+
load_dotenv()
6+
7+
print("Welcome to the Flight Club!.")
8+
print("Join our Flight Club and never pay full fare again")
9+
fName = input("What is your first name?\n")
10+
lName = input("What is your last name?\n")
11+
email = input("What is your email?\n")
12+
print("You're in the club, We'll email you with amazing flight deals!")
13+
14+
# Add new user to sheets
15+
sheety_endpoint = "https://api.sheety.co/126f9e38bb1fc18f122cb26e242ee654/flightDeals/users"
16+
headers = {
17+
'Authorization': os.getenv('AUTH_TOKEN')
18+
}
19+
user_config = {
20+
'user': {
21+
"firstName": fName,
22+
"lastName": lName,
23+
"email": email
24+
}
25+
}
26+
response = requests.post(url=sheety_endpoint, json=user_config, headers=headers)
27+
print(response.text)

0 commit comments

Comments
 (0)
Please sign in to comment.