diff options
author | Martin Polden <mpolden@mpolden.no> | 2021-08-11 23:29:29 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2021-08-11 23:55:03 +0200 |
commit | 8a87fe4bfc70b6aad19e7b2a5fbe9ffe2425cddc (patch) | |
tree | f49f6fa66e861ff62b3531561c110e2215ee1eb0 | |
parent | 62a480d81d5e4bdb66594b0aef2b82b0e8ee11a3 (diff) |
http: Add support for specifying direction
-rw-r--r-- | http/http.go | 21 | ||||
-rw-r--r-- | http/http_test.go | 31 | ||||
-rw-r--r-- | http/types.go | 20 | ||||
-rw-r--r-- | http/types_test.go | 13 |
4 files changed, 60 insertions, 25 deletions
diff --git a/http/http.go b/http/http.go index 0af0146..f8ecbe0 100644 --- a/http/http.go +++ b/http/http.go @@ -15,6 +15,11 @@ import ( "github.com/mpolden/atb/entur" ) +const ( + inbound = "inbound" + outbound = "outbound" +) + // Server represents an Server server. type Server struct { ATB *atb.Client @@ -92,8 +97,13 @@ func (s *Server) atbDepartures(urlPrefix string, nodeID int) (Departures, bool, return departures, hit, nil } -func (s *Server) enturDepartures(urlPrefix string, stopID int) (Departures, bool, error) { - cacheKey := strconv.Itoa(stopID) +func (s *Server) enturDepartures(urlPrefix string, stopID int, direction string) (Departures, bool, error) { + var cacheKey string + if direction == inbound || direction == outbound { + cacheKey = fmt.Sprintf("%d-%s", stopID, direction) + } else { + cacheKey = fmt.Sprintf("%d", stopID) + } cached, hit := s.cache.Get(cacheKey) if hit { return cached.(Departures), hit, nil @@ -102,7 +112,7 @@ func (s *Server) enturDepartures(urlPrefix string, stopID int) (Departures, bool if err != nil { return Departures{}, hit, err } - departures := convertDepartures(enturDepartures) + departures := convertDepartures(enturDepartures, direction) departures.URL = fmt.Sprintf("%s/api/v2/departures/%d", urlPrefix, stopID) s.cache.Set(cacheKey, departures, s.ttl.departures) return departures, hit, nil @@ -214,12 +224,13 @@ func (s *Server) DepartureHandlerV2(w http.ResponseWriter, r *http.Request) (int Message: "Invalid stop ID. Use https://stoppested.entur.org/ to find stop IDs.", } } - departures, hit, err := s.enturDepartures(urlPrefix(r), stopID) + direction := r.URL.Query().Get("direction") + departures, hit, err := s.enturDepartures(urlPrefix(r), stopID, direction) if err != nil { return nil, &Error{ err: err, Status: http.StatusInternalServerError, - Message: "Failed to get departures from AtB", + Message: "Failed to get departures from Entur", } } s.setCacheHeader(w, hit) diff --git a/http/http_test.go b/http/http_test.go index ed7486b..0304828 100644 --- a/http/http_test.go +++ b/http/http_test.go @@ -96,7 +96,8 @@ func TestAPI(t *testing.T) { // Show specific departure (v2) {"/api/v2/departures", `{"status":400,"message":"Invalid stop ID. Use https://stoppested.entur.org/ to find stop IDs."}`, 400}, {"/api/v2/departures/", `{"status":400,"message":"Invalid stop ID. Use https://stoppested.entur.org/ to find stop IDs."}`, 400}, - {"/api/v2/departures/42098", fmt.Sprintf(`{"url":"%s/api/v2/departures/42098","isGoingTowardsCentrum":false,"departures":[{"line":"21","scheduledDepartureTime":"2021-08-11T21:19:00.000","destination":"Pirbadet via sentrum","isRealtimeData":false}]}`, httpSrv.URL), 200}, + {"/api/v2/departures/60890", fmt.Sprintf(`{"url":"%s/api/v2/departures/60890","departures":[{"line":"11","scheduledDepartureTime":"2021-08-11T23:33:09.000","destination":"Risvollan via sentrum","isRealtimeData":true,"isGoingTowardsCentrum":false},{"line":"3","scheduledDepartureTime":"2021-08-11T23:38:01.000","destination":"Hallset","isRealtimeData":true,"isGoingTowardsCentrum":true}]}`, httpSrv.URL), 200}, + {"/api/v2/departures/60890?direction=inbound", fmt.Sprintf(`{"url":"%s/api/v2/departures/60890","departures":[{"line":"3","scheduledDepartureTime":"2021-08-11T23:38:01.000","destination":"Hallset","isRealtimeData":true,"isGoingTowardsCentrum":true}]}`, httpSrv.URL), 200}, } for _, tt := range tests { data, contentType, status, err := httpGet(httpSrv.URL + tt.url) @@ -282,21 +283,37 @@ const forecastResponse = `<?xml version="1.0" encoding="utf-8"?> const enturResponse = `{ "data": { "stopPlace": { - "id": "NSR:StopPlace:42098", - "name": "Ilsvika", + "id": "NSR:StopPlace:60890", + "name": "Ila", "estimatedCalls": [ { - "realtime": false, - "expectedDepartureTime": "2021-08-11T21:19:00+0200", + "realtime": true, + "expectedDepartureTime": "2021-08-11T23:33:09+0200", "actualDepartureTime": null, "destinationDisplay": { - "frontText": "Pirbadet via sentrum" + "frontText": "Risvollan via sentrum" }, "serviceJourney": { "journeyPattern": { "directionType": "outbound", "line": { - "publicCode": "21" + "publicCode": "11" + } + } + } + }, + { + "realtime": true, + "expectedDepartureTime": "2021-08-11T23:38:01+0200", + "actualDepartureTime": null, + "destinationDisplay": { + "frontText": "Hallset" + }, + "serviceJourney": { + "journeyPattern": { + "directionType": "inbound", + "line": { + "publicCode": "3" } } } diff --git a/http/types.go b/http/types.go index d08f969..56855b0 100644 --- a/http/types.go +++ b/http/types.go @@ -50,7 +50,7 @@ type GeoJSONCollection struct { // Departures represents a list of departures, from a given bus stop. type Departures struct { URL string `json:"url"` - TowardsCentrum bool `json:"isGoingTowardsCentrum"` + TowardsCentrum *bool `json:"isGoingTowardsCentrum,omitempty"` Departures []Departure `json:"departures"` } @@ -61,6 +61,7 @@ type Departure struct { ScheduledDepartureTime string `json:"scheduledDepartureTime"` Destination string `json:"destination"` IsRealtimeData bool `json:"isRealtimeData"` + TowardsCentrum *bool `json:"isGoingTowardsCentrum,omitempty"` } // Error represents an error in the API, which is returned to the user. @@ -179,34 +180,39 @@ func convertForecasts(f atb.Forecasts) (Departures, error) { departures = append(departures, departure) } return Departures{ - TowardsCentrum: towardsCentrum, + TowardsCentrum: &towardsCentrum, Departures: departures, }, nil } -func convertDepartures(enturDepartures []entur.Departure) Departures { +func convertDepartures(enturDepartures []entur.Departure, direction string) Departures { departures := make([]Departure, 0, len(enturDepartures)) - inbound := false const timeLayout = "2006-01-02T15:04:05.000" for _, d := range enturDepartures { + if direction == inbound && !d.Inbound { + continue + } + if direction == outbound && d.Inbound { + continue + } scheduledDepartureTime := d.ScheduledDepartureTime.Format(timeLayout) registeredDepartureTime := "" if !d.RegisteredDepartureTime.IsZero() { registeredDepartureTime = d.RegisteredDepartureTime.Format(timeLayout) } + towardsCentrum := d.Inbound departure := Departure{ LineID: d.Line, ScheduledDepartureTime: scheduledDepartureTime, RegisteredDepartureTime: registeredDepartureTime, Destination: d.Destination, IsRealtimeData: d.IsRealtime, + TowardsCentrum: &towardsCentrum, } - inbound = d.Inbound departures = append(departures, departure) } return Departures{ - TowardsCentrum: inbound, - Departures: departures, + Departures: departures, } } diff --git a/http/types_test.go b/http/types_test.go index eac8b53..9550001 100644 --- a/http/types_test.go +++ b/http/types_test.go @@ -37,13 +37,13 @@ func TestConvertBusStop(t *testing.T) { func TestConvertBusStops(t *testing.T) { stops := atb.BusStops{ - Stops: []atb.BusStop{atb.BusStop{ + Stops: []atb.BusStop{{ NodeID: "16011376", Longitude: "1157514", Latitude: 9202874, }}} expected := BusStops{ - Stops: []BusStop{BusStop{ + Stops: []BusStop{{ NodeID: 16011376, Longitude: 10.398126, Latitude: 63.415535, @@ -116,13 +116,14 @@ func TestIsTowardsCentrum(t *testing.T) { func TestConvertForecasts(t *testing.T) { forecasts := atb.Forecasts{ - Nodes: []atb.NodeInfo{atb.NodeInfo{NodeID: "16011376"}}, - Forecasts: []atb.Forecast{atb.Forecast{ + Nodes: []atb.NodeInfo{{NodeID: "16011376"}}, + Forecasts: []atb.Forecast{{ RegisteredDepartureTime: "26.02.2015 18:38", ScheduledDepartureTime: "26.02.2015 18:01", }}} - expected := Departures{TowardsCentrum: true, - Departures: []Departure{Departure{ + b := true + expected := Departures{TowardsCentrum: &b, + Departures: []Departure{{ RegisteredDepartureTime: "2015-02-26T18:38:00.000", ScheduledDepartureTime: "2015-02-26T18:01:00.000", IsRealtimeData: false, |