Timeout after 10 seconds on FetchDepartures
Also apply gofmt
This commit is contained in:
parent
330e5923af
commit
3fe42e1ff0
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [ ] Use timeout for fetching departures
|
- [x] Use timeout for fetching departures
|
||||||
- [ ] Write ESP8266 client
|
- [ ] Write ESP8266 client
|
||||||
- [ ] Add basic auth
|
- [ ] Add basic auth
|
||||||
- [ ] Create Nix package
|
- [ ] Create Nix package
|
||||||
|
200
main.go
200
main.go
@ -7,134 +7,136 @@ import "net/http"
|
|||||||
import "net/url"
|
import "net/url"
|
||||||
import "slices"
|
import "slices"
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
import "time"
|
||||||
|
|
||||||
type DMResponse struct {
|
type DMResponse struct {
|
||||||
Departures []DMDeparture `json:"departureList"`
|
Departures []DMDeparture `json:"departureList"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DMDeparture struct {
|
type DMDeparture struct {
|
||||||
StopName string `json:"stopName"`
|
StopName string `json:"stopName"`
|
||||||
Platform string `json:"platform"`
|
Platform string `json:"platform"`
|
||||||
Countdown string `json:"countdown"`
|
Countdown string `json:"countdown"`
|
||||||
DateTime DMDateTime `json:"dateTime"`
|
DateTime DMDateTime `json:"dateTime"`
|
||||||
RealDateTime *DMDateTime `json:"realDateTime"`
|
RealDateTime *DMDateTime `json:"realDateTime"`
|
||||||
ServingLine DMServingLine `json:"servingLine"`
|
ServingLine DMServingLine `json:"servingLine"`
|
||||||
OnwardStopSeq []DMStop `json:"onwardStopSeq"`
|
OnwardStopSeq []DMStop `json:"onwardStopSeq"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DMServingLine struct {
|
type DMServingLine struct {
|
||||||
Symbol string `json:"symbol"`
|
Symbol string `json:"symbol"`
|
||||||
Direction string `json:"direction"`
|
Direction string `json:"direction"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DMStop struct {
|
type DMStop struct {
|
||||||
PlaceID string `json:"placeID"`
|
PlaceID string `json:"placeID"`
|
||||||
Place string `json:"place"`
|
Place string `json:"place"`
|
||||||
NameWO string `json:"nameWO"`
|
NameWO string `json:"nameWO"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DMDateTime struct {
|
type DMDateTime struct {
|
||||||
Hour string `json:"hour"`
|
Hour string `json:"hour"`
|
||||||
Minute string `json:"minute"`
|
Minute string `json:"minute"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use different client (with timeout)
|
|
||||||
func FetchDepartures(stopId string) (*DMResponse, error) {
|
func FetchDepartures(stopId string) (*DMResponse, error) {
|
||||||
// Create request object
|
// Create request object
|
||||||
req, err := http.NewRequest("GET", "https://www.vrn.de/mngvrn/XML_DM_REQUEST", nil)
|
req, err := http.NewRequest("GET", "https://www.vrn.de/mngvrn/XML_DM_REQUEST", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure our request
|
// Configure our request
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("coordOutputFormat", "EPSG:4326")
|
query.Set("coordOutputFormat", "EPSG:4326")
|
||||||
query.Set("depType", "stopEvents")
|
query.Set("depType", "stopEvents")
|
||||||
query.Set("includeCompleteStopSeq", "1")
|
query.Set("includeCompleteStopSeq", "1")
|
||||||
query.Set("limit", "10")
|
query.Set("limit", "10")
|
||||||
query.Set("locationServerActive", "0")
|
query.Set("locationServerActive", "0")
|
||||||
query.Set("mode", "direct")
|
query.Set("mode", "direct")
|
||||||
query.Set("name_dm", stopId)
|
query.Set("name_dm", stopId)
|
||||||
query.Set("outputFormat", "json")
|
query.Set("outputFormat", "json")
|
||||||
query.Set("type_dm", "stop")
|
query.Set("type_dm", "stop")
|
||||||
query.Set("useOnlyStops", "1")
|
query.Set("useOnlyStops", "1")
|
||||||
query.Set("useRealtime", "1")
|
query.Set("useRealtime", "1")
|
||||||
req.URL.RawQuery = query.Encode()
|
req.URL.RawQuery = query.Encode()
|
||||||
|
|
||||||
// Send the request
|
// Send the request, wait max 10 seconds
|
||||||
res, err := http.DefaultClient.Do(req)
|
client := http.Client{
|
||||||
if err != nil {
|
Timeout: 10 * time.Second,
|
||||||
return nil, err
|
}
|
||||||
}
|
res, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
var dmResponse DMResponse
|
var dmResponse DMResponse
|
||||||
err = json.NewDecoder(res.Body).Decode(&dmResponse)
|
err = json.NewDecoder(res.Body).Decode(&dmResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &dmResponse, nil
|
return &dmResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
http.HandleFunc("/departures", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/departures", func(w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
|
|
||||||
if query["stop_id"] == nil || len(query["stop_id"]) < 1 {
|
if query["stop_id"] == nil || len(query["stop_id"]) < 1 {
|
||||||
http.Error(w, "Missing query parameter: stop_id", http.StatusBadRequest)
|
http.Error(w, "Missing query parameter: stop_id", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
stopId := query["stop_id"][0]
|
stopId := query["stop_id"][0]
|
||||||
|
|
||||||
var platform *string = nil
|
var platform *string = nil
|
||||||
if query["platform"] != nil && len(query["platform"]) != 0 {
|
if query["platform"] != nil && len(query["platform"]) != 0 {
|
||||||
platform = &query["platform"][0]
|
platform = &query["platform"][0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds, err := FetchDepartures(stopId)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ds, err := FetchDepartures(stopId)
|
for _, d := range ds.Departures {
|
||||||
if err != nil {
|
if platform != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
if d.Platform != *platform {
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, d := range ds.Departures {
|
direction := d.ServingLine.Direction
|
||||||
if platform != nil {
|
if len(d.OnwardStopSeq) != 0 {
|
||||||
if d.Platform != *platform {
|
last := d.OnwardStopSeq[len(d.OnwardStopSeq)-1]
|
||||||
continue
|
if slices.Contains([]string{"5", "6"}, last.PlaceID) {
|
||||||
}
|
direction = last.NameWO
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
direction := d.ServingLine.Direction
|
leaving := fmt.Sprintf("%s min", d.Countdown)
|
||||||
if len(d.OnwardStopSeq) != 0 {
|
countdown, err := strconv.Atoi(d.Countdown)
|
||||||
last := d.OnwardStopSeq[len(d.OnwardStopSeq) - 1]
|
if err == nil {
|
||||||
if slices.Contains([]string{"5", "6"}, last.PlaceID) {
|
if countdown == 0 {
|
||||||
direction = last.NameWO
|
leaving = "sofort"
|
||||||
}
|
}
|
||||||
}
|
if countdown > 20 {
|
||||||
|
dt := d.DateTime
|
||||||
|
if d.RealDateTime != nil {
|
||||||
|
dt = *d.RealDateTime
|
||||||
|
}
|
||||||
|
leaving = fmt.Sprintf("%02s:%02s", dt.Hour, dt.Minute)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
leaving := fmt.Sprintf("%s min", d.Countdown)
|
fmt.Fprintf(w, "%2s %-22s %6s\n",
|
||||||
countdown, err := strconv.Atoi(d.Countdown)
|
d.ServingLine.Symbol,
|
||||||
if err == nil {
|
direction[:min(len(direction), 22)],
|
||||||
if countdown == 0 {
|
leaving,
|
||||||
leaving = "sofort"
|
)
|
||||||
}
|
}
|
||||||
if countdown > 20 {
|
})
|
||||||
dt := d.DateTime
|
log.Fatal(http.ListenAndServe(":8000", nil))
|
||||||
if d.RealDateTime != nil {
|
|
||||||
dt = *d.RealDateTime
|
|
||||||
}
|
|
||||||
leaving = fmt.Sprintf("%02s:%02s", dt.Hour, dt.Minute)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(w, "%2s %-22s %6s\n",
|
|
||||||
d.ServingLine.Symbol,
|
|
||||||
direction[:min(len(direction), 22)],
|
|
||||||
leaving,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
log.Fatal(http.ListenAndServe(":8000", nil))
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user