Skip to content

Commit

Permalink
added planefinder as a destination finder
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewl committed Oct 23, 2016
1 parent 82b5eae commit 87856bd
Show file tree
Hide file tree
Showing 4 changed files with 564 additions and 1 deletion.
4 changes: 3 additions & 1 deletion destinationfinder/destinationfinder.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ type DestinationFinder interface {
func GetDestinationFinder() DestinationFinder {
findername := os.Getenv("WATFT_FINDER")
switch findername {
case "planefinder":
return PlaneFinderDestinationFinder{}
case "holidayextras":
return HolidayExtrasDestinationFinder{}
default:
return HolidayExtrasDestinationFinder{}
return PlaneFinderDestinationFinder{}
}
return nil
}
89 changes: 89 additions & 0 deletions destinationfinder/destinationfinder_planefinder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Package destinationfinder provides functionality for
// determining where a flight with a given callsign is
// destined.
package destinationfinder

import (
"errors"
"io/ioutil"
"net/http"
"os"
"strings"
)

type PlaneFinderDestinationFinder struct {
}

/**
* Retrieves the lat long of the destination (as a simple string, we're not interested in doing
* any real processing with this, just using it as an index. Uses the flightaware website as
* a datasource, and parses some js embedded in the page. As such this is potentially
* brittle, but the function defintion should stand, even if we were to plugin a different
* data source.
**/
func (destination_finder PlaneFinderDestinationFinder) GetDestinationFromCallsign(callsign string) (lat_long string, err error) {
if callsign == "" {
return "", errors.New("Not going to get latlong from an empty callsign")
}
flight_url := "http://www.planefinder.net/data/flight/" + callsign

resp, err := http.Get(flight_url)
if err != nil {
return "", errors.New("Failed to retrieve flight details from " + flight_url)
}
defer resp.Body.Close()

planefinder_html, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", errors.New("Failed to retrieve flight details from " + flight_url)
}

return destination_finder.ExtractDestinationFromHTML(planefinder_html)
}

func (destination_finder *PlaneFinderDestinationFinder) ExtractDestinationFromHTML(html []byte) (lat_long string, err error) {
if strings.Index(string(html), "/data/airport") == -1 {
return "", errors.New("Failed to arrival airport in html ")
}

tmp_strings := strings.Split(string(html), "/data/airport/")
airport_code := strings.Split(tmp_strings[2], "\"")[0]
return destination_finder.getLatLongFromAirportCode(airport_code)
}

func (destination_finder *PlaneFinderDestinationFinder) getLatLongFromAirportCode(airport_code string) (lat_long string, err error) {
if airport_code == "" {
return "", errors.New("Not going to get latlong from an empty airport code")
}

airport_html, err := ioutil.ReadFile("./airport_" + airport_code + ".cache")
if err != nil {
airport_code_url := "http://www.planefinder.net/data/airport/" + airport_code

resp, err := http.Get(airport_code_url)
if err != nil {
return "", errors.New("Failed to retrieve airport details from " + airport_code_url)
}
defer resp.Body.Close()

airport_html, err = ioutil.ReadAll(resp.Body)
if err != nil {
return "", errors.New("Failed to retrieve airport details from " + airport_code_url)
}
cache_file, err := os.Create("./airport_" + airport_code + ".cache")
if err == nil {
cache_file.Write(airport_html)
cache_file.Sync()
cache_file.Close()
}
}

if strings.Index(string(airport_html), "location=") == -1 {
return "", errors.New("Failed to arrival airport in html ")
}

tmp_strings := strings.Split(string(airport_html), "location=")
airport_lat_lng := strings.Split(tmp_strings[1], ",13")[0]

return airport_lat_lng, nil
}
19 changes: 19 additions & 0 deletions destinationfinder/destinationfinder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,22 @@ func TestHolidayExtrasExtraction(t *testing.T) {
t.Fail()
}
}

func TestPlaneFinderExtraction(t *testing.T) {
var df PlaneFinderDestinationFinder
data, err := ioutil.ReadFile("./testdata/planefinder.html")
if err != nil {
fmt.Println(err)
t.Error("Failed to open planefinder.html")
return
}
latlong, err := df.ExtractDestinationFromHTML(data)
if err != nil {
fmt.Println("ExtractDestinationFromHTML errored with")
fmt.Println(err)
t.Fail()
} else if latlong != "63.985,-22.6056" {
fmt.Println("Failed to extract correct lat-long: " + latlong)
t.Fail()
}
}
Loading

0 comments on commit 87856bd

Please sign in to comment.