Author: Adam Evyčędo <git@apiote.xyz>
lua update scripts in Brussels STIB-MIVB
config/config.go | 7 +++ traffic/berlin_vbb.go | 3 + traffic/brussels_stib_mivb.go | 62 +++++++++++++++++++++++++++++++++++++ traffic/convert.go | 21 ++++++++++++ traffic/feeds.go | 1 traffic/gzm_ztm.go | 5 ++ traffic/krakow_ztp.go | 5 ++ traffic/poznan_ztm.go | 5 ++ traffic/realtime.go | 2 traffic/realtime_lua.go | 7 +++
diff --git a/config/config.go b/config/config.go index dc8b66368a0d2cb0c57bef89f4dc70dfe5c58ae7..ef2135954b60161a45530ed7b40a2f3be84e8ca8 100644 --- a/config/config.go +++ b/config/config.go @@ -8,12 +8,17 @@ "notabug.org/apiote/gott" ) -// todo change to dirty +// TODO change to dirty + +type BrusselsConfig struct { + ApiKey string +} type Config struct { FeedsPath string EnabledFeeds []string ListenAddress string + Brussels BrusselsConfig } type result struct { diff --git a/traffic/berlin_vbb.go b/traffic/berlin_vbb.go index eff340c7c8ba2cda450ff41b352b27d5cecbd3be..8f9ca0f1609b1393a3e6e9bb09e3ad50428a9ebe 100644 --- a/traffic/berlin_vbb.go +++ b/traffic/berlin_vbb.go @@ -1,6 +1,7 @@ package traffic import ( + "apiote.xyz/p/szczanieckiej/config" "apiote.xyz/p/szczanieckiej/transformers" "bufio" @@ -53,7 +54,7 @@ func (z VbbBerlin) RealtimeFeeds() map[RealtimeFeedType]string { return map[RealtimeFeedType]string{} } -func (z VbbBerlin) LuaUpdatesScript() string { +func (z VbbBerlin) LuaUpdatesScript(cfg config.Config) string { return ` function getUpdates(tripID, sequence) local http = require("http") diff --git a/traffic/brussels_stib_mivb.go b/traffic/brussels_stib_mivb.go index c13f79be2eb874750f2a161e9df7c61e96bf5a15..f5323fd048e2d2ad47bf70ab3a8cb1a8f1dd1c2f 100644 --- a/traffic/brussels_stib_mivb.go +++ b/traffic/brussels_stib_mivb.go @@ -1,6 +1,7 @@ package traffic import ( + "apiote.xyz/p/szczanieckiej/config" "apiote.xyz/p/szczanieckiej/transformers" "encoding/csv" @@ -61,6 +62,67 @@ } func (z StibMivbBrussels) RealtimeFeeds() map[RealtimeFeedType]string { return map[RealtimeFeedType]string{} +} + +func (z StibMivbBrussels) LuaUpdatesScript(cfg config.Config) string { + return ` + function getUpdates(tripID, sequence, stopID) + local http = require("http") + local json = require("json") + + response, error_message = http.get("https://stibmivb.opendatasoft.com/api/explore/v2.1/catalog/datasets/waiting-time-rt-production/records", { + query="apikey=` + cfg.Brussels.ApiKey + `&where=pointid%20%3D%20%22" .. stopID .. "%22&limit=20", + timeout="30s" + }) + + if response == nil then + return "", "while getting updates: " .. error_message + end + + if response.status_code != 200 then + return "", "api returned code " .. response.status_code .. "; " .. response.body + end + + struct, error_message = json.decode(response.body) + + if struct == nil then + return "", "while decoding updates: " .. error_message + end + + updates = { + areTripsInTimetable=false, + updates={} + } + + for i,entry in ipairs(struct.results) do + times, error_message = json.decode(entry.passingtimes) + if times == nil then + return "", "while decoding times for stop " .. entry.pointid .. ", line " .. entry.lineid .. ": " .. error_message + end + + for i, time_entry in ipairs(times) do + updates[time_entry.expectedArrivalTime] = { + time=string.sub(time_entry.expectedArrivalTime, 12, 13) .. string.sub(time_entry.expectedArrivalTime, 15, 16) .. string.sub(time_entry.expectedArrivalTime, 18, 19), + stopID=stopID, + delay=0, + timetableRelationship=1, + vehicleStatus={ + lineName=entry.lineid, + headsign=time_entry.destination.fr, // TODO translations + } + } + end + end + + result, error_message = json.encode(updates) + + if result == nil then + return "", "while encoding result: " .. error_message + end + + return result, "" + end + ` } func (z StibMivbBrussels) Transformer() transform.Transformer { diff --git a/traffic/convert.go b/traffic/convert.go index 5cff248b5bec7260e0d6b21c4223812793c25dbe..a515e4ca2fd4a9c20be70088f0942c98e89c85a4 100644 --- a/traffic/convert.go +++ b/traffic/convert.go @@ -74,6 +74,7 @@ GtfsFilename string Feed Feed HomeFeedPath string feedTranslations embed.FS + config config.Config Timezone *time.Location TrafficCalendarFile *os.File @@ -1355,6 +1356,24 @@ return c, err } +func convertLuaScripts(c feedConverter) error { // O(1) ; ( -- >> updates.lua ) + path := c.TmpFeedPath + updatesFile, err := os.Create(filepath.Join(path, "updates.lua")) + if err != nil { + return fmt.Errorf("while creating file: %w", err) + } + defer updatesFile.Close() + + script := c.Feed.LuaUpdatesScript(c.config) + if script == "" { + return nil + } + + updatesFile.Write([]byte(script)) + + return nil +} + func getAttrDesc(feedID string, feedTranslations embed.FS) (map[string]string, map[string]string, error) { attributions := map[string]string{} descriptions := map[string]string{} @@ -1612,6 +1631,7 @@ GtfsFilename: gtfsFile, Feed: args.feed, HomeFeedPath: args.homeFeedPath, feedTranslations: args.feedTranslations, + config: args.config, }, LogLevel: gott2.Debug, } @@ -1621,6 +1641,7 @@ Tee(prepareFeedGtfs). Tee(convertVehicles). Bind(convertAgencies). Bind(convertFeedInfo). + Tee(convertLuaScripts). Bind(readTranslations). Recover(recoverTranslations). Bind(createTrafficCalendarFile). diff --git a/traffic/feeds.go b/traffic/feeds.go index 11fc0a9d5b1d6b6e403a7242c68d32ed15496404..ebbcc1b52dcd6fd98db8a78b4eb7720ce1691441 100644 --- a/traffic/feeds.go +++ b/traffic/feeds.go @@ -18,6 +18,7 @@ fmt.Stringer ConvertVehicles(string) error // TODO return []Vehicle -> save to file in convert() GetVersions(time.Time, *time.Location) ([]Version, error) RealtimeFeeds() map[RealtimeFeedType]string + LuaUpdatesScript(config.Config) string Transformer() transform.Transformer Name() string Flags() FeedFlags diff --git a/traffic/gzm_ztm.go b/traffic/gzm_ztm.go index e0de76636826a474e05123b398895e5c46a6e0ed..91f920af734f1e2a5300daad4e0905e0c24714b9 100644 --- a/traffic/gzm_ztm.go +++ b/traffic/gzm_ztm.go @@ -1,6 +1,7 @@ package traffic import ( + "apiote.xyz/p/szczanieckiej/config" "apiote.xyz/p/szczanieckiej/transformers" "bufio" @@ -70,6 +71,10 @@ TRIP_UPDATES: "http://gtfsrt.metropoliagzm.pl:1111/gtfsrt/gzm/all", VEHICLE_POSITIONS: "http://gtfsrt.metropoliagzm.pl:1111/gtfsrt/gzm/all", } // return map[RealtimeFeedType]string{} +} + +func (z GzmZtm) LuaUpdatesScript(c config.Config) string { + return "" } func (z GzmZtm) Transformer() transform.Transformer { diff --git a/traffic/krakow_ztp.go b/traffic/krakow_ztp.go index 21c3e36ea0bec7b4acb3ebc01c4d6b550069a29b..9aef66d39fab5e9feaca3db25309c529a3221c73 100644 --- a/traffic/krakow_ztp.go +++ b/traffic/krakow_ztp.go @@ -1,6 +1,7 @@ package traffic import ( + "apiote.xyz/p/szczanieckiej/config" "apiote.xyz/p/szczanieckiej/transformers" "fmt" @@ -49,6 +50,10 @@ //"https://gtfs.ztp.krakow.pl/TripUpdates_T.pb", VEHICLE_POSITIONS: "https://gtfs.ztp.krakow.pl/VehiclePositions_A.pb", //"https://gtfs.ztp.krakow.pl/VehiclePositions_T.pb", } +} + +func (ZtpKrakow) LuaUpdatesScript(c config.Config) string { + return "" } func (ZtpKrakow) String() string { diff --git a/traffic/poznan_ztm.go b/traffic/poznan_ztm.go index e5458c99c4f50534fe1a53df7b6f70ec415399d9..f6138a05d8b146dd61f2e1b10d48bc424fe1e64c 100644 --- a/traffic/poznan_ztm.go +++ b/traffic/poznan_ztm.go @@ -1,6 +1,7 @@ package traffic import ( + "apiote.xyz/p/szczanieckiej/config" "apiote.xyz/p/szczanieckiej/transformers" "encoding/csv" @@ -154,6 +155,10 @@ return map[RealtimeFeedType]string{ TRIP_UPDATES: "https://ztm.poznan.pl/en/dla-deweloperow/getGtfsRtFile/?file=feeds.pb", VEHICLE_POSITIONS: "https://ztm.poznan.pl/en/dla-deweloperow/getGtfsRtFile/?file=feeds.pb", } +} + +func (z ZtmPoznan) LuaUpdatesScript(c config.Config) string { + return "" } func (z ZtmPoznan) Transformer() transform.Transformer { diff --git a/traffic/realtime.go b/traffic/realtime.go index 0414e3bc88a8e8075948a193a6e945b66732cf6f..7ab01c3152090cf710b5c8ff2582bbe211fae4ed 100644 --- a/traffic/realtime.go +++ b/traffic/realtime.go @@ -139,8 +139,8 @@ }, Headsign: update.VehicleStatus.Headsign, LineName: update.VehicleStatus.LineName, Order: StopOrder{ + uint(departureTime.Unix()), 0, - int(time.Now().Unix()), }, Update: update, // NOTE delay must be 0 } diff --git a/traffic/realtime_lua.go b/traffic/realtime_lua.go index bd8279414edc89014b6bf631202e69c38f881ed7..53b936cf1abb09735c845fb29a9910b52d30e764 100644 --- a/traffic/realtime_lua.go +++ b/traffic/realtime_lua.go @@ -64,13 +64,18 @@ } if err := l.CallByParam(lua.P{ Fn: l.GetGlobal("getUpdates"), - NRet: 1, + NRet: 2, Protect: true, }, lua.LString(stopID)); err != nil { return map[string]Update{}, false, fmt.Errorf("while executing updates function: %w", err) } result := l.Get(-1) l.Pop(1) + luaErr := l.Get(-1) + l.Pop(1) + if luaErr.(lua.LString) != "" { + return map[string]Update{}, false, fmt.Errorf("while executing updates function: %s", luaErr.(lua.LString)) + } json.Unmarshal([]byte(result.(lua.LString)), &luaUpdates) vehicleStatuses, err := getLuaRealtimeVehiclesMap(ctx)