busdepartures/bus.go

146 lines
3.2 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"time"
)
type Departure struct {
TripID int
RealtimeTripId string
StopHeadsign string
ArrivalTime time.Time
DepartureTime time.Time
RealtimeArrivalTime time.Time
RealtimeDepartureTime time.Time
RouteShortName string
}
func (d Departure) HasRealtimeDepartureTime() bool {
return !d.RealtimeDepartureTime.IsZero()
}
func (d Departure) IsDelayed() bool {
if !d.HasRealtimeDepartureTime() {
return false
}
return d.RealtimeDepartureTime.After(d.DepartureTime)
}
type ResponseDeparture struct {
TripID int `json:"trip_id"`
RealtimeTripId string `json:"realtime_trip_id"`
StopHeadsign string `json:"stop_headsign"`
ArrivalTime string `json:"arrival_time"`
DepartureTime string `json:"departure_time"`
RealtimeArrivalTime int `json:"realtime_arrival_time"`
RealtimeDepartureTime int `json:"realtime_departure_time"`
Tripdata struct {
Route struct {
RouteShortName string `json:"route_short_name"`
} `json:"route"`
} `json:"tripdata"`
}
// ToDeparture transforms the ResponseDeparture struct to a Departure.
func (rd ResponseDeparture) ToDeparture() (Departure, error) {
var departure Departure
departure.TripID = rd.TripID
departure.RealtimeTripId = rd.RealtimeTripId
departure.StopHeadsign = rd.StopHeadsign
departure.RouteShortName = rd.Tripdata.Route.RouteShortName
_time, err := parseUnixTimestamp(rd.ArrivalTime)
if err != nil {
return departure, err
}
departure.ArrivalTime = _time
_time, err = parseUnixTimestamp(rd.DepartureTime)
if err != nil {
return departure, err
}
departure.DepartureTime = _time
if rd.RealtimeArrivalTime != 0 {
_time, err = parseUnixTimestamp(strconv.Itoa(rd.RealtimeArrivalTime))
if err == nil {
departure.RealtimeArrivalTime = _time
}
}
if rd.RealtimeDepartureTime != 0 {
_time, err = parseUnixTimestamp(strconv.Itoa(rd.RealtimeDepartureTime))
if err == nil {
departure.RealtimeDepartureTime = _time
}
}
return departure, nil
}
type QueryResponse struct {
Results []struct {
Departures []ResponseDeparture `json:"departures"`
} `json:"results"`
}
func getDepartures(quay Quay) ([]Departure, error) {
var stop string
var uri string
var data QueryResponse
var departures []Departure
q, err := json.Marshal(quay)
if err != nil {
return departures, err
}
stop = string(q)
uri = fmt.Sprintf("https://www.breng.nl/api/travelplanner/quays/departures?stop=%s", url.QueryEscape(stop))
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return departures, err
}
resp, err := BusClient.Do(req)
if err != nil {
return departures, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return departures, err
}
err = json.Unmarshal(body, &data)
if err != nil {
return departures, err
}
for _, r := range data.Results {
for _, rd := range r.Departures {
d, err := rd.ToDeparture()
if err != nil {
return departures, err
}
if quay.IsInterestingDeparture(d) {
departures = append(departures, d)
}
}
}
return departures, nil
}