Author: Adam <git@apiote.xyz>
implement line endpoint
api/api.go | 67 +++++++++++++++++++++----------------- api/structs_gen.go | 48 ++++++++++++++++++++++++--- server/router.go | 13 +++++-- traffic/structs_gen.go | 76 ++++++++++++++++++++++----------------------
diff --git a/api/api.go b/api/api.go index 3ea43a208d1ce0e820e460493b588ea41922933e..8e1cdaf2a328558a96985f64b320160a72e618ee 100644 --- a/api/api.go +++ b/api/api.go @@ -77,42 +77,52 @@ return s } func convertTrafficLineGraphs(trafficLine traffic.Line, line LineV1, context traffic.Context, t *traffic.Traffic) (LineV1, error) { - line.Graphs = [2]LineGraphV1{ - { + if len(trafficLine.GraphThere.StopCodes) != 0 { + graph := LineGraphV1{ Stops: make([]StopStubV1, len(trafficLine.GraphThere.StopCodes)), NextNodes: trafficLine.GraphThere.NextNodes, - }, - { + } + for i, code := range trafficLine.GraphThere.StopCodes { + stopStub, err := traffic.GetStopStub(code, line.Name, context, t) + if err != nil { + return line, fmt.Errorf("while getting stopStub for %s: %w", code, err) + } + graph.Stops[i] = convertTrafficStopStub(stopStub) + } + line.Graphs = append(line.Graphs, graph) + } + if len(trafficLine.GraphBack.StopCodes) != 0 { + graph := LineGraphV1{ Stops: make([]StopStubV1, len(trafficLine.GraphBack.StopCodes)), NextNodes: trafficLine.GraphBack.NextNodes, - }, - } - - for i, code := range trafficLine.GraphThere.StopCodes { - stopStub, err := traffic.GetStopStub(code, line.Name, context, t) - if err != nil { - return line, fmt.Errorf("while getting stopStub for %s: %w", code, err) } - line.Graphs[0].Stops[i] = convertTrafficStopStub(stopStub) - } - for i, code := range trafficLine.GraphBack.StopCodes { - stopStub, err := traffic.GetStopStub(code, line.Name, context, t) - if err != nil { - return line, fmt.Errorf("while getting stopStub for %s: %w", code, err) + for i, code := range trafficLine.GraphBack.StopCodes { + stopStub, err := traffic.GetStopStub(code, line.Name, context, t) + if err != nil { + return line, fmt.Errorf("while getting stopStub for %s: %w", code, err) + } + graph.Stops[i] = convertTrafficStopStub(stopStub) } - line.Graphs[0].Stops[i] = convertTrafficStopStub(stopStub) + line.Graphs = append(line.Graphs, graph) } return line, nil } -func convertTrafficLine(line traffic.Line, feedID string, convertGraphs bool) LineV1 { +func convertTrafficLine(line traffic.Line, feedID string) LineV1 { l := LineV1{ Name: line.Name, Colour: fromColor(line.Colour), Kind: makeLineTypeV2(line), FeedID: feedID, - Headsigns: [2][]string{line.HeadsignsThere, line.HeadsignsBack}, + Headsigns: [][]string{}, + } + + if len(line.HeadsignsThere) != 0 { + l.Headsigns = append(l.Headsigns, line.HeadsignsThere) + } + if len(line.HeadsignsBack) != 0 { + l.Headsigns = append(l.Headsigns, line.HeadsignsBack) } return l } @@ -240,7 +250,7 @@ if stop, ok := item.(traffic.Stop); ok { s := convertTrafficStopV2(stop, context.FeedName) success.Queryables = append(success.Queryables, QueryableV2(s)) } else if line, ok := item.(traffic.Line); ok { - l := convertTrafficLine(line, context.FeedName, false) + l := convertTrafficLine(line, context.FeedName) success.Queryables = append(success.Queryables, QueryableV2(l)) } else { // todo error @@ -357,20 +367,17 @@ } return success, nil } -func CreateSuccessLine(line traffic.Line, context traffic.Context, t *traffic.Traffic) /*(LineResponse, error) */ { - /*l, err := convertTrafficLine(line, context, t) +func CreateSuccessLine(line traffic.Line, context traffic.Context, t *traffic.Traffic) (LineResponse, error) { + l := convertTrafficLine(line, context.FeedName) + l, err := convertTrafficLineGraphs(line, l, context, t) if err != nil { - return SuccessLine{}, fmt.Errorf("while converting line: %w", err) + return LineResponseV1{}, fmt.Errorf("while converting graph: %w", err) } - l, err = convertTrafficLineGraphs(line, l, context, t) - if err != nil { - return SuccessLine{}, fmt.Errorf("while converting graph: %w", err) - } - success := SuccessLine{ + success := LineResponseV1{ Line: l, } - return success, nil*/ + return success, nil } func convertVehicle(update gtfs_rt.Update, vehicles map[string]traffic.Vehicle, line traffic.Line, headsign string) VehicleV1 { diff --git a/api/structs_gen.go b/api/structs_gen.go index 3e02d4df9cdc61f7d6b5a404d635fd3364a5b097..622631161336d902a5888003da90270d2d73e90a 100644 --- a/api/structs_gen.go +++ b/api/structs_gen.go @@ -7,6 +7,30 @@ "errors" "git.sr.ht/~sircmpwn/go-bare" ) +type LineResponseV1 struct { + Line LineV1 `bare:"line"` +} + +func (t *LineResponseV1) Decode(data []byte) error { + return bare.Unmarshal(data, t) +} + +func (t *LineResponseV1) Encode() ([]byte, error) { + return bare.Marshal(t) +} + +type LineResponseDev struct { + Line LineV1 `bare:"line"` +} + +func (t *LineResponseDev) Decode(data []byte) error { + return bare.Unmarshal(data, t) +} + +func (t *LineResponseDev) Encode() ([]byte, error) { + return bare.Marshal(t) +} + type FeedsResponseDev struct { Feeds []FeedInfoV1 `bare:"feeds"` } @@ -106,12 +130,12 @@ return bare.Marshal(t) } type LineV1 struct { - Name string `bare:"name"` - Colour ColourV1 `bare:"colour"` - Kind LineTypeV2 `bare:"kind"` - FeedID string `bare:"feedID"` - Headsigns [2][]string `bare:"headsigns"` - Graphs [2]LineGraphV1 `bare:"graphs"` + Name string `bare:"name"` + Colour ColourV1 `bare:"colour"` + Kind LineTypeV2 `bare:"kind"` + FeedID string `bare:"feedID"` + Headsigns [][]string `bare:"headsigns"` + Graphs []LineGraphV1 `bare:"graphs"` } func (t *LineV1) Decode(data []byte) error { @@ -638,6 +662,14 @@ } panic(errors.New("Invalid BoardingV1 value")) } +type LineResponse interface { + bare.Union +} + +func (_ LineResponseDev) IsUnion() {} + +func (_ LineResponseV1) IsUnion() {} + type FeedsResponse interface { bare.Union } @@ -699,6 +731,10 @@ func (_ DeparturesResponseV1) IsUnion() {} func init() { + bare.RegisterUnion((*LineResponse)(nil)). + Member(*new(LineResponseDev), 0). + Member(*new(LineResponseV1), 1) + bare.RegisterUnion((*FeedsResponse)(nil)). Member(*new(FeedsResponseDev), 0). Member(*new(FeedsResponseV1), 1) diff --git a/server/router.go b/server/router.go index 261f79798b3b5e604f7459a99e5b818774d4df1e..a26d6000f65a0139d1ba98e80af025eca752c751 100644 --- a/server/router.go +++ b/server/router.go @@ -601,6 +601,11 @@ return nil } func handleLine(w http.ResponseWriter, r *http.Request, feedName string, cfg config.Config, t *traffic.Traffic, accept uint) error { + if accept > 1 { + return ServerError{ + code: http.StatusNotAcceptable, + } + } path := strings.Split(r.URL.Path[1:], "/") if len(path) == 3 { dateString := r.Form.Get("date") @@ -627,7 +632,7 @@ field: "line", value: name, } } - success, err := struct{}{}, nil //api.CreateSuccessLine(line, context, t) + success, err := api.CreateSuccessLine(line, context, t) if err != nil { return fmt.Errorf("while creating response: %w", err) } @@ -756,7 +761,7 @@ } break } err = handleDepartures(w, r, feedNames[0], cfg, traffic, accept) - /*case "lines": + case "lines": if len(feedNames) > 1 { err = ServerError{ code: http.StatusBadRequest, @@ -765,8 +770,8 @@ value: path[0], } break } - err = handleLine(w, r, feedNames[0], cfg, traffic) - case "trips": + err = handleLine(w, r, feedNames[0], cfg, traffic, accept) + /*case "trips": if len(feedNames) > 1 { err = ServerError{ code: http.StatusBadRequest, diff --git a/traffic/structs_gen.go b/traffic/structs_gen.go index 0f5522ba86e072f5146e242ea352b3faee51bf43..3985f8d578b6095845f5fb77ec7fc494f5fa4213 100644 --- a/traffic/structs_gen.go +++ b/traffic/structs_gen.go @@ -250,44 +250,6 @@ } panic(errors.New("Invalid Direction value")) } -type VehicleCapabilities uint - -const ( - RAMP VehicleCapabilities = 1 - LOW_FLOOR VehicleCapabilities = 2 - AIR_CONDITIONING VehicleCapabilities = 4 - BICYCLE VehicleCapabilities = 8 - VOICE_ANNOUNCEMENTS VehicleCapabilities = 16 - TICKET_MACHINE VehicleCapabilities = 32 - TICKET_SOLD_DRIVER VehicleCapabilities = 64 - USB_CHARGING VehicleCapabilities = 128 - LOW_FLOOR_PARTIAL VehicleCapabilities = 256 -) - -func (t VehicleCapabilities) String() string { - switch t { - case RAMP: - return "RAMP" - case LOW_FLOOR: - return "LOW_FLOOR" - case AIR_CONDITIONING: - return "AIR_CONDITIONING" - case BICYCLE: - return "BICYCLE" - case VOICE_ANNOUNCEMENTS: - return "VOICE_ANNOUNCEMENTS" - case TICKET_MACHINE: - return "TICKET_MACHINE" - case TICKET_SOLD_DRIVER: - return "TICKET_SOLD_DRIVER" - case USB_CHARGING: - return "USB_CHARGING" - case LOW_FLOOR_PARTIAL: - return "LOW_FLOOR_PARTIAL" - } - panic(errors.New("Invalid VehicleCapabilities value")) -} - type Boarding uint const ( @@ -351,3 +313,41 @@ return "MONORAIL" } panic(errors.New("Invalid LineType value")) } + +type VehicleCapabilities uint + +const ( + RAMP VehicleCapabilities = 1 + LOW_FLOOR VehicleCapabilities = 2 + AIR_CONDITIONING VehicleCapabilities = 4 + BICYCLE VehicleCapabilities = 8 + VOICE_ANNOUNCEMENTS VehicleCapabilities = 16 + TICKET_MACHINE VehicleCapabilities = 32 + TICKET_SOLD_DRIVER VehicleCapabilities = 64 + USB_CHARGING VehicleCapabilities = 128 + LOW_FLOOR_PARTIAL VehicleCapabilities = 256 +) + +func (t VehicleCapabilities) String() string { + switch t { + case RAMP: + return "RAMP" + case LOW_FLOOR: + return "LOW_FLOOR" + case AIR_CONDITIONING: + return "AIR_CONDITIONING" + case BICYCLE: + return "BICYCLE" + case VOICE_ANNOUNCEMENTS: + return "VOICE_ANNOUNCEMENTS" + case TICKET_MACHINE: + return "TICKET_MACHINE" + case TICKET_SOLD_DRIVER: + return "TICKET_SOLD_DRIVER" + case USB_CHARGING: + return "USB_CHARGING" + case LOW_FLOOR_PARTIAL: + return "LOW_FLOOR_PARTIAL" + } + panic(errors.New("Invalid VehicleCapabilities value")) +}