szczanieckiej.git

commit ebc0ef113838fed8637ef0499672a5855398d008

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)