dashboard of nationalrail train times
1package main
2
3import (
4 "fmt"
5 "io"
6 "net/http"
7 "time"
8)
9
10const BaseURL = "https://www.nationalrail.co.uk/live-trains/departures/"
11
12// FetchStationDepartures fetches the HTML content for a station's departures
13func FetchStationDepartures(stationCode string) (string, error) {
14 client := &http.Client{
15 Timeout: 30 * time.Second,
16 }
17
18 url := BaseURL + stationCode + "/"
19 req, err := http.NewRequest("GET", url, nil)
20 if err != nil {
21 return "", fmt.Errorf("failed to create request: %w", err)
22 }
23
24 // Add headers to mimic a browser request
25 req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
26 req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
27
28 resp, err := client.Do(req)
29 if err != nil {
30 return "", fmt.Errorf("failed to fetch data: %w", err)
31 }
32 defer resp.Body.Close()
33
34 if resp.StatusCode != http.StatusOK {
35 return "", fmt.Errorf("unexpected status code: %d", resp.StatusCode)
36 }
37
38 body, err := io.ReadAll(resp.Body)
39 if err != nil {
40 return "", fmt.Errorf("failed to read response body: %w", err)
41 }
42
43 return string(body), nil
44}
45
46type StationData struct {
47 Station Station `json:"station"`
48 Departures []Departure `json:"departures"`
49 LastUpdate time.Time `json:"last_update"`
50 Error string `json:"error,omitempty"`
51}
52
53// FetchAllStationsData fetches departure data for all configured stations
54func FetchAllStationsData(stations []Station) []StationData {
55 results := make([]StationData, len(stations))
56
57 for i, station := range stations {
58 results[i] = StationData{
59 Station: station,
60 LastUpdate: time.Now(),
61 }
62
63 htmlContent, err := FetchStationDepartures(station.Code)
64 if err != nil {
65 results[i].Error = err.Error()
66 continue
67 }
68
69 departures, err := ParseDeparturesFromHTML(htmlContent)
70 if err != nil {
71 results[i].Error = err.Error()
72 continue
73 }
74
75 results[i].Departures = departures
76 }
77
78 return results
79}