Skip to content

Commit

Permalink
Merge pull request #76 from hwakabh/refactor/71/flight_search
Browse files Browse the repository at this point in the history
feat: enabled render search result with directions
  • Loading branch information
hwakabh authored Jan 23, 2024
2 parents ced05c3 + 3e7e362 commit 3f8f62b
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 189 deletions.
184 changes: 80 additions & 104 deletions app/api/v1/cruds.py
Original file line number Diff line number Diff line change
@@ -1,151 +1,127 @@
import json
import random

import mysql.connector as mydb
import numpy as np
from sqlalchemy.orm import Session
import httpx

from app.api.v1 import models
from app.api.v1 import schemas
from app.api.v1.helpers import dist_on_sphere
from app.config import app_settings


# TODO: should be used with ORM
conn = mydb.connect(
host=app_settings.MYSQL_HOST,
user=app_settings.MYSQL_USER,
password=app_settings.MYSQL_PASSWORD,
database=app_settings.MYSQL_DATABASE,
charset="utf8"
)


def get_airports_from_db(db: Session) -> schemas.Airport:
return db.query(models.Airport).limit(5).all()


def get_destination():
# Bind cruds functions for return results to router
def get_destination(db: Session, req: schemas.SearchRequestBody):
#--- get ajax POST data
time_limit = httpx.json()["time_limit"]
expense_limit = httpx.json()["expense_limit"]
current_lat = httpx.json()["current_lat"]
current_lng = httpx.json()["current_lng"]
print("main.py ajax POST data - time_limit: " + time_limit)
print("main.py ajax POST data - expense_limit: " + expense_limit)
print("main.py ajax POST data - current_lat: " + current_lat)
print("main.py ajax POST data - current_lng: " + current_lng)
print(f'User conditions: {req}')

#--- search and get near airport from MySQL (airport table)
near_airport_IATA = get_near_airport(current_lat,current_lng)
print("main.py get values - near_airport_IATA: " + near_airport_IATA)
near_airport_IATA = get_near_airport(
db=db,
lat=req.current_lat,
lng=req.current_lng
)
print("near_airport_IATA: " + near_airport_IATA)

#--- search and get reachable location (airport and country) from skyscanner api
#--- exclude if time and travel expenses exceed the user input parameter
#--- select a country at random
destination = get_destination_from_skyscanner_by_random(near_airport_IATA,time_limit,expense_limit)
return destination
destination = get_destination_from_skyscanner_by_random(
db=db,
iata=near_airport_IATA
)
print('Destination: ')
print(destination)

return schemas.SearchResultResponseBody(**destination)

# --- search and get near airport from MySQL (airport table)
def get_near_airport(current_lat,current_lng):

conn.ping(reconnect=True)
cur = conn.cursor()

print("gacha.py get values - current_lat: " + current_lat)
print("gacha.py get values - current_lng: " + current_lng)

current = float(current_lat), float(current_lng)
# --- search and get near airport from MySQL (airport table)
def get_near_airport(db: Session, lat: float, lng: float) -> str:
target = []
dist_result = []
search_key = []
count = 0

cur.execute('select id,IATA,Name,Country,City,Latitude,Longitude from airport where not IATA="NULL"')

for sql_result in cur.fetchall():
target = sql_result[5], sql_result[6]
dist = dist_on_sphere(current, target)
dist_result.append([count,sql_result[0],sql_result[1],sql_result[2],sql_result[3],sql_result[4],dist])
airports = db.query(
models.Airport.id,
models.Airport.IATA,
models.Airport.name,
models.Airport.country,
models.Airport.city,
models.Airport.latitude,
models.Airport.longitude
).filter(
models.Airport.IATA != "NULL"
).all()

for airport in airports:
target = airport[5], airport[6]
dist = dist_on_sphere(
pos0=(lat, lng),
pos1=target
)
dist_result.append([count,airport[0],airport[1],airport[2],airport[3],airport[4],dist])
search_key.append(dist)
count = count + 1

cur.close()
conn.close()

#print(dist_result)
#print(search_key)

#--- return near airport IATA
return dist_result[np.argmin(search_key)][2]


#--- search and get reachable location (airport and country) from skyscanner api
#--- exclude if time and travel expenses exceed the user input parameter
#--- select a country at random
def get_destination_from_skyscanner_by_random(near_airport_IATA,time_limit,expense_limit):

print("gacha.py get values - near_airport_IATA: " + near_airport_IATA)
print("gacha.py get values - time_limit: " + time_limit)
print("gacha.py get values - expense_limit: " + expense_limit)

def get_destination_from_skyscanner_by_random(db: Session, iata: str) -> dict:
# --- search and get reachable location (airport and country) from skyscanner api
# --- exclude if time and travel expenses exceed the user input parameter

##########################################################################################
##################################### Update required #####################################
###########################################################################################

#reachable_airport_IATA = ["TXL","YTD","CQS","NYR","QFG","NZE","IWK"]

conn.ping(reconnect=True)
cur = conn.cursor()

cur.execute('select IATA from airport where not IATA="NULL"')
reachable_airport_IATA = []
for sql_result in cur.fetchall():
reachable_airport_IATA.append(sql_result[0])

cur.close()
conn.close()

##########################################################################################
##########################################################################################
##########################################################################################
airport_codes = db.query(models.Airport.IATA).filter(models.Airport.IATA != "NULL").all()

reachable_airport_IATA = [airport_code[0] for airport_code in airport_codes]
#--- select a country at random
random_airport_IATA = random.choice(reachable_airport_IATA)

#--- get lat/lng of near and selected airport from MySQL (airport table)
conn.ping(reconnect=True)
cur = conn.cursor()
transit_airports = db.query(
models.Airport.country,
models.Airport.city,
models.Airport.IATA,
models.Airport.name,
models.Airport.latitude,
models.Airport.longitude,
).filter(
models.Airport.IATA == iata
).all()

cur.execute('select Country,City,IATA,Name,Latitude,Longitude from airport where IATA="' + near_airport_IATA + '"')
transit = []
for sql_result in cur.fetchall():
transit.append([sql_result[0],sql_result[1],sql_result[2],sql_result[3],sql_result[4],sql_result[5]])
for airport in transit_airports:
transit.append([airport[0],airport[1],airport[2],airport[3],airport[4],airport[5]])

destination_airports = db.query(
models.Airport.country,
models.Airport.city,
models.Airport.IATA,
models.Airport.name,
models.Airport.latitude,
models.Airport.longitude,
).filter(
models.Airport.IATA == random_airport_IATA
).all()

cur.execute('select Country,City,IATA,Name,Latitude,Longitude from airport where IATA="' + random_airport_IATA + '"')
destination = []
for sql_result in cur.fetchall():
destination.append([sql_result[0],sql_result[1],sql_result[2],sql_result[3],sql_result[4],sql_result[5]])

cur.close()
conn.close()

return json.dumps({
"tran_country":transit[0][0],
"tran_city":transit[0][1],
"tran_iata":transit[0][2],
"tran_airport":transit[0][3],
"tran_lat":transit[0][4],
"tran_lng":transit[0][5],
"dest_country":destination[0][0],
"dest_city":destination[0][1],
"dest_iata":destination[0][2],
"dest_airport":destination[0][3],
"dest_lat":destination[0][4],
"dest_lng":destination[0][5]
})
for airport in destination_airports:
destination.append([airport[0],airport[1],airport[2],airport[3],airport[4],airport[5]])

return {
"tran_country": transit[0][0],
"tran_city": transit[0][1],
"tran_iata": transit[0][2],
"tran_airport": transit[0][3],
"tran_lat": transit[0][4],
"tran_lng": transit[0][5],
"dest_country": destination[0][0],
"dest_city": destination[0][1],
"dest_iata": destination[0][2],
"dest_airport": destination[0][3],
"dest_lat": destination[0][4],
"dest_lng": destination[0][5]
}
15 changes: 14 additions & 1 deletion app/api/v1/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sqlalchemy import Column, String, Integer
from sqlalchemy import Column, String, Integer, Float

from app.database import Base

Expand All @@ -7,3 +7,16 @@ class Airport(Base):
__tablename__ = 'airport'

id: int = Column(Integer, primary_key=True)
name: str = Column(String(74))
city: str = Column(String(35))
country: str = Column(String(34))
IATA: str = Column(String(3))
ICAO: str = Column(String(4))
latitude: float = Column(Float)
longitude: float = Column(Float)
altitude: int = Column(Integer)
tz_offset: float = Column(Float)
DST: str = Column(String(1))
tz_dbtime: str = Column(String(32))
types: str = Column(String(13))
datasource: str = Column(String(13))
32 changes: 16 additions & 16 deletions app/api/v1/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,37 @@
from app.api.v1 import services
from app.api.v1 import cruds
from app.api.v1 import schemas
from app.database import get_db
from app.api.v1 import models
from app.database import get_db, engine

router = APIRouter()
# Create table if not exists
models.Base.metadata.create_all(bind=engine)


@router.get('/')
def index(req: Request) -> schemas.RootResponse:
return {
return JSONResponse(content={
"path": req.url.path,
"detail": "v1 API root"
}
})


@router.get('/airports')
def get_airports(db: Session = Depends(get_db)) -> list[schemas.Airport]:
return cruds.get_airports_from_db(db=db)


@router.get('/search')
def get_flight_search_result():
return cruds.get_destination()
@router.get('/fetch')
def fetch() -> Response:
return services.load_google_map()


@router.post('/shuffle')
def get_random_country():
return services.get_random_country()
def get_random_country(
payload: schemas.SearchRequestBody,
db: Session = Depends(get_db)
) -> schemas.SearchResultResponseBody:

country = services.get_random_country()
print(f'Randomly selected country: {country}')

@router.get('/fetch')
def fetch() -> Response:
return services.load_google_map()
return cruds.get_destination(db=db, req=payload)


@router.post('/translate')
Expand Down
36 changes: 36 additions & 0 deletions app/api/v1/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,48 @@ class TranslateReqBody(BaseModel):
country: str


class SearchRequestBody(BaseModel):
time_limit: int
expense_limit: int
current_lat: float
current_lng: float


class SearchResultResponseBody(BaseModel):
dest_country: str
dest_city: str
dest_iata: str
dest_airport: str
dest_lat: float
dest_lng: float
tran_country: str
tran_city: str
tran_iata: str
tran_airport: str
tran_lat: float
tran_lng: float


# Database Model
class AirportBase(BaseModel):
pass


class Airport(AirportBase):
id: int
name: str
city: str
country: str
IATA: str
ICAO: str
latitude: float
longitude: float
altitude: int
tz_offset: float
DST: str
tz_dbtime: str
types: str
datasource: str

class Config:
orm_mode = True
5 changes: 1 addition & 4 deletions app/api/v1/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def translate_county_name(txt: TranslateReqBody) -> str:
return resp.get('data').get('translations')[0].get('translatedText')


def get_random_country():
# import data
def get_random_country() -> str:
try:
url = 'https://restcountries.com/v3.1/all?fields=region,name'
data = httpx.get(url).json()
Expand All @@ -60,7 +59,6 @@ def get_random_country():
region.append(data[x]['region'])

region_result = random.choice(list(set(region)))
print(f"Region selected: {region_result}")

# Select country randomly
country = []
Expand All @@ -69,6 +67,5 @@ def get_random_country():
country.append(data[x]['name']['official'])

country_result = random.choice(country)
print(f"Country selected: {country_result}")

return country_result
Loading

0 comments on commit 3f8f62b

Please sign in to comment.