-
Notifications
You must be signed in to change notification settings - Fork 0
/
feeds.go
121 lines (102 loc) · 2.97 KB
/
feeds.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package mta
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
gtfs "github.com/errornil/mta/v2/transit_realtime"
)
type Feed string
const (
Feed123456S Feed = "nyct/gtfs" // Red
FeedACEHS Feed = "nyct/gtfs-ace" // Blue, Franklin Ave. Shuttle
FeedNQRW Feed = "nyct/gtfs-nqrw" // Yellow
FeedBDFM Feed = "nyct/gtfs-bdfm" // Orange
FeedL Feed = "nyct/gtfs-l"
FeedSIR Feed = "nyct/gtfs-si" // StatenIslandRailway
FeedG Feed = "nyct/gtfs-g"
FeedJZ Feed = "nyct/gtfs-jz" // Brown
Feed7 Feed = "nyct/gtfs-7"
FeedLIRR Feed = "lirr/gtfs-lirr" // Long Island Rail Road
FeedMNR Feed = "mnr/gtfs-mnr" // Metro-North Railroad
AlertsAll Feed = "camsys/all-alerts" // All Service Alerts
AlertsSubway Feed = "camsys/subway-alerts" // Subway Alerts
AlertsBus Feed = "camsys/bus-alerts" // Bus Alerts
AlertsLIRR Feed = "camsys/lirr-alerts" // Long Island Rail Road Alerts
AlertsMNR Feed = "camsys/mnr-alerts" // Metro-North Railroad Alerts
FeedURL = "https://api-endpoint.mta.info/Dataservice/mtagtfsfeeds/"
)
var (
SubwayFeeds []Feed = []Feed{
Feed123456S,
FeedACEHS,
FeedNQRW,
FeedBDFM,
FeedL,
FeedSIR,
FeedG,
FeedJZ,
Feed7,
}
AllFeeds []Feed = append(SubwayFeeds, FeedLIRR, FeedMNR)
AllAlerts []Feed = []Feed{
AlertsAll,
AlertsSubway,
AlertsBus,
AlertsLIRR,
AlertsMNR,
}
)
type FeedsService interface {
GetFeedMessage(feedID Feed) (*gtfs.FeedMessage, error)
}
// FeedsClient provides MTA GTFS-Realtime data
// Implements FeedsService interface.
type FeedsClient struct {
client HTTPClient
apiKey string
userAgent string
}
// NewFeedsClient creates new FeedsClient
func NewFeedsClient(client HTTPClient, apiKey, userAgent string) (*FeedsClient, error) {
if client == nil {
return nil, ErrClientRequired
}
if apiKey == "" {
return nil, ErrAPIKeyRequired
}
return &FeedsClient{
client: client,
apiKey: apiKey,
userAgent: userAgent,
}, nil
}
// GetFeedMessage sends request to MTA server to get latest GTFS-Realtime data from specified feed
func (f *FeedsClient) GetFeedMessage(feedID Feed) (*gtfs.FeedMessage, error) {
u := fmt.Sprintf("%s%s", FeedURL, url.PathEscape(string(feedID)))
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
return nil, errors.Wrap(err, "failed to create new HTTP request")
}
req.Header.Add("x-api-key", f.apiKey)
resp, err := f.client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to send GET request")
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("non 200 response status: %v", resp.Status)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "failed to read response body")
}
feed := >fs.FeedMessage{}
err = proto.Unmarshal(body, feed)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshall GTFS Realtime Feed Message")
}
return feed, nil
}