Skip to content

Commit

Permalink
Add ability to pass many locations to GetPriceGraph (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
krisukox authored Jul 23, 2023
1 parent 6a7e465 commit 5692d9a
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 125 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,21 @@ jobs:
- name: Run unit tests
run: |
go test ./... -v
examples:
name: Run examples
runs-on: ubuntu-22.04
steps:
- name: Set up toolchain
uses: actions/setup-go@v3
with:
go-version: 1.20.1
id: go

- name: Check out repository code
uses: actions/checkout@v3

- name: Run unit tests
run: |
go run ./examples/example1/main.go
go run ./examples/example2/main.go
6 changes: 5 additions & 1 deletion examples/example1/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ func getCheapOffers(rangeStartDate, rangeEndDate time.Time, tripLength int, srcC

for _, s := range srcCities {
for _, d := range dstCities {
offers, err := session.GetPriceGraph(rangeStartDate, rangeEndDate, tripLength, s, d, currency.PLN, lang)
offers, err := session.GetPriceGraph(
rangeStartDate, rangeEndDate,
[]string{s}, []string{}, []string{d}, []string{},
1, currency.PLN, flights.AnyStops, flights.Economy, flights.RoundTrip,
lang, tripLength)
if err != nil {
log.Fatal(err)
}
Expand Down
12 changes: 8 additions & 4 deletions examples/example2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import (
"golang.org/x/text/language"
)

func getBestOffer(rangeStartDate, rangeEndDate time.Time, tripLength int, srcCities, dstCities string, lang language.Tag) {
func getBestOffer(rangeStartDate, rangeEndDate time.Time, tripLength int, srcCity, dstCity string, lang language.Tag) {
session := flights.New()
var bestOffer flights.Offer

offers, err := session.GetPriceGraph(rangeStartDate, rangeEndDate, tripLength, srcCities, dstCities, currency.PLN, lang)
offers, err := session.GetPriceGraph(
rangeStartDate, rangeEndDate,
[]string{srcCity}, []string{}, []string{dstCity}, []string{},
1, currency.PLN, flights.AnyStops, flights.Economy, flights.RoundTrip,
lang, tripLength)
if err != nil {
log.Fatal(err)
}
Expand All @@ -30,9 +34,9 @@ func getBestOffer(rangeStartDate, rangeEndDate time.Time, tripLength int, srcCit
url, err := session.SerializeUrl(
bestOffer.StartDate,
bestOffer.ReturnDate,
[]string{srcCities},
[]string{srcCity},
[]string{},
[]string{dstCities},
[]string{dstCity},
[]string{},
1,
currency.PLN,
Expand Down
73 changes: 48 additions & 25 deletions flights/flight.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func serializeFlightClass(class Class) string {
return "4"
}

func (s *Session) getFlightRawData(
func (s *Session) getRawData(
date, returnDate time.Time,
srcCities, srcAirports, dstCities, dstAirports []string,
adults int,
Expand All @@ -92,10 +92,7 @@ func (s *Session) getFlightRawData(
serClass := serializeFlightClass(class)
serTripType := serializeTripType(tripType)

prefix := `[null,"[[],`
suffix := `],null,null,null,1,null,null,null,null,null,[]],1,0,0]"]`

rawData := prefix
rawData := ""

rawData += fmt.Sprintf(`[null,null,%d,null,[],%s,%s,null,null,null,null,null,null,[`,
serTripType, serClass, serAdults)
Expand All @@ -108,23 +105,48 @@ func (s *Session) getFlightRawData(
serDsts, serSrcs, serStops, serReturnDate)
}

rawData += suffix
return rawData, nil
}

func (s *Session) getFlightReqData(
date, returnDate time.Time,
srcCities, srcAirports, dstCities, dstAirports []string,
adults int,
stops Stops,
class Class,
tripType TripType,
lang language.Tag,
) (string, error) {
rawData, err := s.getRawData(
date, returnDate,
srcCities, srcAirports, dstCities, dstAirports,
adults, stops, class, tripType, lang)
if err != nil {
return "", nil
}

prefix := `[null,"[[],`
suffix := `],null,null,null,1,null,null,null,null,null,[]],1,0,0]"]`

reqData := prefix
reqData += rawData
reqData += suffix

return url.QueryEscape(rawData), nil
return url.QueryEscape(reqData), nil
}

func getPrice(tripObj []interface{}) (float64, error) {
priceObj1, ok := tripObj[1].([]interface{})
priceObj1, ok := getElement[[]interface{}](tripObj, 1)
if !ok {
return 0, fmt.Errorf("wrong price format stage 1: %v", priceObj1[1])
return 0, fmt.Errorf("wrong price format stage 1: %v", priceObj1)
}
priceObj2, ok := priceObj1[0].([]interface{})
priceObj2, ok := getElement[[]interface{}](priceObj1, 0)
if !ok {
return 0, fmt.Errorf("wrong price format stage 2: %v", priceObj2[0])
return 0, fmt.Errorf("wrong price format stage 2: %v", priceObj2)
}
price, ok := priceObj2[1].(float64)
price, ok := getElement[float64](priceObj2, 1)
if !ok {
return 0, fmt.Errorf("wrong price format stage 3: %v", priceObj2[1])
return 0, fmt.Errorf("wrong price format stage 3: %v", priceObj2)
}
return price, nil
}
Expand Down Expand Up @@ -182,7 +204,7 @@ func getTime(flightTime interface{}, flightDate interface{}) (time.Time, error)
}

func getDuration(duration []interface{}) (time.Duration, error) {
duration1 := getElement[float64](duration, 11)
duration1, _ := getElement[float64](duration, 11)
return time.ParseDuration(fmt.Sprintf("%dm", int(duration1)))
}

Expand All @@ -191,15 +213,15 @@ func getFlightNumberAirline(data interface{}) (string, interface{}, string, erro
if !ok || len(data1) != 4 {
return "", "", "", fmt.Errorf("wrong flight number of airline type: %v", data)
}
flightNumberPart1 := getElement[string](data1, 0)
flightNumberPart1, _ := getElement[string](data1, 0)
// if !ok {
// return "", "", "", fmt.Errorf("wrong flight number part 1 type: %v", data1[0])
// }
flightNumberPart2 := getElement[string](data1, 1)
flightNumberPart2, _ := getElement[string](data1, 1)
// if !ok {
// return "", "", "", fmt.Errorf("wrong flight number part 2 type: %v", data1[1])
// }
airline := getElement[string](data1, 3)
airline, _ := getElement[string](data1, 3)
// if !ok {
// return "", "", "", fmt.Errorf("wrong airline name type: %v", data1[3])
// }
Expand Down Expand Up @@ -237,19 +259,19 @@ func getFlight(flightObj interface{}) (flight, error) {
return flight{}, fmt.Errorf("wrong flight format: %v", flightObj)
}

departureAirportCode := getElement[string](flightObj1, 3)
departureAirportCode, _ := getElement[string](flightObj1, 3)
// if !ok {
// return flightV2{}, fmt.Errorf("wrong departure airport code type: %v", object1[3])
// }
departureAirportName := getElement[string](flightObj1, 4)
departureAirportName, _ := getElement[string](flightObj1, 4)
// if !ok {
// return flightV2{}, fmt.Errorf("wrong departure airport name type: %v", object1[4])
// }
arrivalAirportName := getElement[string](flightObj1, 5)
arrivalAirportName, _ := getElement[string](flightObj1, 5)
// if !ok {
// return flightV2{}, fmt.Errorf("wrong arrival airport name type: %v", object1[5])
// }
arrivalAirportCode := getElement[string](flightObj1, 6)
arrivalAirportCode, _ := getElement[string](flightObj1, 6)
// if !ok {
// return flightV2{}, fmt.Errorf("wrong arrival airport code type: %v", object1[6])
// }
Expand All @@ -270,11 +292,11 @@ func getFlight(flightObj interface{}) (flight, error) {
// if err != nil {
// return flightV2{}, err
// }
airplane := getElement[string](flightObj1, 17)
airplane, _ := getElement[string](flightObj1, 17)
// if !ok {
// return flightV2{}, fmt.Errorf("wrong airplane format: %v", object1[17])
// }
legroom := getElement[string](flightObj1, 30)
legroom, _ := getElement[string](flightObj1, 30)
us := getUnknowns(flightObj1)
unknowns = append(unknowns, us...)
return flight{
Expand Down Expand Up @@ -368,7 +390,7 @@ func (s *Session) doRequestFlights(
) (*http.Response, error) {
url := "https://www.google.com/_/TravelFrontendUi/data/travel.frontend.flights.FlightsFrontendService/GetShoppingResults?f.sid=-1300922759171628473&bl=boq_travel-frontend-ui_20230627.02_p1&hl=en&soc-app=162&soc-platform=1&soc-device=1&_reqid=52717&rt=c"

rawDate, err := s.getFlightRawData(
reqDate, err := s.getFlightReqData(
date, returnDate,
srcCities, srcAirports, dstCities, dstAirports,
adults, stops, class, tripType, lang)
Expand All @@ -377,7 +399,8 @@ func (s *Session) doRequestFlights(
return nil, err
}

jsonBody := []byte(`f.req=` + rawDate + `&at=AAuQa1qjMakasqKYcQeoFJjN7RZ3%3A1687955915303&`) // Add current unix timestamp instead of 1687955915303
jsonBody := []byte(`f.req=` + reqDate +
`&at=AAuQa1qjMakasqKYcQeoFJjN7RZ3%3A1687955915303&`) // Add current unix timestamp instead of 1687955915303
bodyReader := bytes.NewReader(jsonBody)

req, err := http.NewRequest(http.MethodPost, url, bodyReader)
Expand Down
22 changes: 11 additions & 11 deletions flights/flight_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,11 @@ func TestGetOffers(t *testing.T) {
}
}

func TestFlightRawData(t *testing.T) {
func TestFlightReqData(t *testing.T) {
session := New()

expectedUnescapedQuery1 := `[null,"[[],[null,null,1,null,[],1,[1,0,0,0],null,null,null,null,null,null,[[[[[\"SFO\",0],[\"/m/030qb3t\",5]]],[[[\"CDG\",0],[\"/m/04jpl\",5]]],null,0,[],[],\"2024-01-01\",null,[],[],[],null,null,[],3],[[[[\"CDG\",0],[\"/m/04jpl\",5]]],[[[\"SFO\",0],[\"/m/030qb3t\",5]]],null,0,[],[],\"2024-01-31\",null,[],[],[],null,null,[],3]],null,null,null,1,null,null,null,null,null,[]],1,0,0]"]`
expectedUnescapedQuery2 := `[null,"[[],[null,null,2,null,[],3,[2,0,0,0],null,null,null,null,null,null,[[[[[\"SFO\",0],[\"/m/030qb3t\",5]]],[[[\"CDG\",0],[\"/m/04jpl\",5]]],null,3,[],[],\"2024-01-01\",null,[],[],[],null,null,[],3]],null,null,null,1,null,null,null,null,null,[]],1,0,0]"]`
expectedReqData1 := `[null,"[[],[null,null,1,null,[],1,[1,0,0,0],null,null,null,null,null,null,[[[[[\"SFO\",0],[\"/m/030qb3t\",5]]],[[[\"CDG\",0],[\"/m/04jpl\",5]]],null,0,[],[],\"2024-01-01\",null,[],[],[],null,null,[],3],[[[[\"CDG\",0],[\"/m/04jpl\",5]]],[[[\"SFO\",0],[\"/m/030qb3t\",5]]],null,0,[],[],\"2024-01-31\",null,[],[],[],null,null,[],3]],null,null,null,1,null,null,null,null,null,[]],1,0,0]"]`
expectedReqData2 := `[null,"[[],[null,null,2,null,[],3,[2,0,0,0],null,null,null,null,null,null,[[[[[\"SFO\",0],[\"/m/030qb3t\",5]]],[[[\"CDG\",0],[\"/m/04jpl\",5]]],null,3,[],[],\"2024-01-01\",null,[],[],[],null,null,[],3]],null,null,null,1,null,null,null,null,null,[]],1,0,0]"]`

date, err := time.Parse("2006-01-02", "2024-01-01")
if err != nil {
Expand All @@ -192,7 +192,7 @@ func TestFlightRawData(t *testing.T) {
t.Fatalf("Error while creating return date: %v", err)
}

rawData1, err := session.getFlightRawData(
_reqData1, err := session.getFlightReqData(
date,
returnDate,
[]string{"Los Angeles"},
Expand All @@ -208,16 +208,16 @@ func TestFlightRawData(t *testing.T) {
t.Fatal(err)
}

unescapedQuery1, err := url.QueryUnescape(rawData1)
reqData1, err := url.QueryUnescape(_reqData1)
if err != nil {
t.Fatal(err)
}

if unescapedQuery1 != expectedUnescapedQuery1 {
t.Fatalf("wrong unescaped query, expected: %s received: %s", expectedUnescapedQuery1, unescapedQuery1)
if reqData1 != expectedReqData1 {
t.Fatalf("wrong unescaped query, expected: %s received: %s", expectedReqData1, reqData1)
}

rawData2, err := session.getFlightRawData(
_reqData2, err := session.getFlightReqData(
date,
returnDate,
[]string{"Los Angeles"},
Expand All @@ -233,12 +233,12 @@ func TestFlightRawData(t *testing.T) {
t.Fatal(err)
}

unescapedQuery2, err := url.QueryUnescape(rawData2)
reqData2, err := url.QueryUnescape(_reqData2)
if err != nil {
t.Fatal(err)
}

if unescapedQuery2 != expectedUnescapedQuery2 {
t.Fatalf("wrong unescaped query, expected: %s received: %s", expectedUnescapedQuery2, unescapedQuery2)
if reqData2 != expectedReqData2 {
t.Fatalf("wrong unescaped query, expected: %s received: %s", expectedReqData2, reqData2)
}
}
Loading

0 comments on commit 5692d9a

Please sign in to comment.