Author: Adam Evyčędo <git@apiote.xyz>
add example feed with instructions
traffic/feed_example.go | 177 +++++++++++++++++++++++++++++++++++++++++++
diff --git a/traffic/feed_example.go b/traffic/feed_example.go new file mode 100644 index 0000000000000000000000000000000000000000..ffdc052715413c182ebd7e4ec1c54a3d78f17810 --- /dev/null +++ b/traffic/feed_example.go @@ -0,0 +1,177 @@ +// SPDX-FileCopyrightText: Adam Evyčędo +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +/* + TODO(1) + First choose an ID and struct name for the network You add. + As a guideline, the ID should be in format {locality}_{operator} and structure should be named {locality}{operator}. + In this example, we’ll be using a hipotetical network in Gravity Falls operated by Cipher Bus Transport, so the ID will be gravityfalls_cbt and thr structure will be named GravityFallsCbt. + Finally copy this file to a new one named {ID}.go, i.e. gravityfalls_cbt.go +*/ + +package traffic + +import ( + "net/http" + "time" + + "apiote.xyz/p/szczanieckiej/config" + "golang.org/x/text/transform" +) + +/* +TODO(2) +Define the scructure with http.Client and other fields as needed +*/ +type GravityFallsCbt struct { + client http.Client +} + +/* +TODO(3) +Fill in the IANA time zone for the operator. +It is only used to determine validity of published timetables. +For Gravity Falls, Oregon, the time zone will be that of Los_Angeles +*/ +func (GravityFallsCbt) getTimezone() *time.Location { + l, _ := time.LoadLocation("America/Los_Angeles") + return l +} + +/* +TODO(4) +If the operator publishes a file with description of vehicles used, then download, parse and convert it to list of Vehicle structures. +Otherwise, leave this empty return. +*/ +func (g GravityFallsCbt) ConvertVehicles() ([]Vehicle, error) { + return []Vehicle{}, nil +} + +/* +TODO(5) +Here, return list of available timetables. +Use the given timezone to create full valid-since and valid-till date-times. +If it’s not known since when the timetable is valid, use zero time; similarly, if end of validity is not known, use 9999-12-31. +As an example, there may exist an operator that publishes timetable under one address that is guaranteed to be valid at the time of donwloading; such timetable would be valid here from year 0 to 9999. +*/ +func (z GravityFallsCbt) GetVersions(_ time.Time, timezone *time.Location) ([]Version, error) { + return []Version{}, nil +} + +/* +TODO(6) +Return the chosen ID of the network. +*/ +func (GravityFallsCbt) String() string { + return "gravityfalls_cbt" +} + +/* +TODO(7) +If the operator publishes GTFS-RT feeds for the timetables, fill the returned map with respective feeds, or with the same one if it contains multiple types of updates. +*/ +func (GravityFallsCbt) RealtimeFeeds() map[RealtimeFeedType]string { + return map[RealtimeFeedType]string{ + TRIP_UPDATES: "https://cipherbustransport.oregon.co.us/gtfsrt/all.pb", + VEHICLE_POSITIONS: "https://cipherbustransport.oregon.co.us/gtfsrt/all.pb", + ALERTS: "https://cipherbustransport.oregon.co.us/gtfsrt/alerts.pb", + } +} + +/* +TODO(8) +If the operator uses a custom API for updates and not GTFS-RT, return a Lua script, which can serve as a client of that API. +Do not fill this function if GTFS-RT feed for this type of update is available. +More information can be found in TRAFFIC documentation. +*/ +func (GravityFallsCbt) LuaUpdatesScript(config.Auth) string { + return ` + function getUpdates(tripID, sequence, stopID) + local http = require("http") + local json = require("json") + + error_struct = { + httpResponseCode=0, + message="", + willNextRequestFail=false + } + error, error_message = json.encode(error_struct) + + updates = { + areTripsInTimetable=false, + updates={} + } + updates.updates[''] = { + time="000000", + stopID=stopID, + delay=0, + timetableRelationship=1, + vehicleStatus={ + lineName="", + headsign="" + } + } + result, error_message = json.encode(updates) + + return result, "" + end + ` +} + +/* +TODO(9) +Return a Transformer or a chain of them, which can replace non-ASCII letters in lines’ and stops’ names with their ASCII counterpart; e.g. for Norwegian å -> aa, for German ä -> ae, for French á -> a. +If such Transformer is not available, add a new one in transformer package. +*/ +func (GravityFallsCbt) Transformer() transform.Transformer { + return transform.Nop +} + +/* +TODO(10) +Return full, public-facing name of the network. +*/ +func (GravityFallsCbt) Name() string { + return "Gravity Falls CBT" +} + +/* +TODO(11) +Return flags which setup converter behaviour: +* Headsigns are taken from trips or from last stop, +* Which field in GTFS stops.txt file is stable across versions, +* How to unambiguously format a stop name, +* How to unambiguously format a line name. +*/ +func (GravityFallsCbt) Flags() FeedFlags { + return FeedFlags{ + Headsign: HeadsignTripHeadsing, + StopIdFormat: "{{stop_code}}", + StopName: "{{stop_name}} [{{stop_code}}]", + LineName: "{{route_short_name}}", + } +} + +/* +TODO(11) +Correct all errors in GTFS file. +Everything that is not correct acording to the GTFS documentation is considered an error. +This function has access to unzipped GTFS file and can operate on files at `path/specific_file.txt` +*/ +func (GravityFallsCbt) FeedPrepareZip(path string) error { + return nil +} + +/* +TODO(12) +If QR codes are available on stops with address that leads to realtime departures, return host, location of stop identifier and query param or regex to extract the identifier. +*/ +func (GravityFallsCbt) QRInfo() (string, QRLocation, string) { + return "", QRLocationNone, "" +} + +/* +TODO(13) +Add the structure in RegisterFeeds function in traffic/feeds.go +*/