forked from Elara6331/itd
		
	Add navigation support via PureMaps
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -15,7 +15,7 @@ require ( | |||||||
| 	github.com/mozillazg/go-pinyin v0.19.0 | 	github.com/mozillazg/go-pinyin v0.19.0 | ||||||
| 	github.com/rs/zerolog v1.26.1 | 	github.com/rs/zerolog v1.26.1 | ||||||
| 	github.com/urfave/cli/v2 v2.3.0 | 	github.com/urfave/cli/v2 v2.3.0 | ||||||
| 	go.arsenm.dev/infinitime v0.0.0-20221025193634-0ad671d3f550 | 	go.arsenm.dev/infinitime v0.0.0-20221107042015-72b558707ee3 | ||||||
| 	go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 | 	go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 | ||||||
| 	golang.org/x/text v0.3.7 | 	golang.org/x/text v0.3.7 | ||||||
| 	modernc.org/sqlite v1.17.2 | 	modernc.org/sqlite v1.17.2 | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							| @@ -397,8 +397,8 @@ github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 | |||||||
| github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | ||||||
| github.com/yuin/goldmark v1.4.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs= | github.com/yuin/goldmark v1.4.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs= | ||||||
| github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= | github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= | ||||||
| go.arsenm.dev/infinitime v0.0.0-20221025193634-0ad671d3f550 h1:GScKSLy9KI83+au3mV9w6koiYRap/uYNarRoUleou4k= | go.arsenm.dev/infinitime v0.0.0-20221107042015-72b558707ee3 h1:BfZkb41Gq6h9gy5Cg5jDd5hEk9kI27/h+EX0KN3qZv8= | ||||||
| go.arsenm.dev/infinitime v0.0.0-20221025193634-0ad671d3f550/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc= | go.arsenm.dev/infinitime v0.0.0-20221107042015-72b558707ee3/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc= | ||||||
| go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 h1:1K96g1eww+77GeGchwMhd0NTrs7Mk/Hc3M3ItW5NbG4= | go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 h1:1K96g1eww+77GeGchwMhd0NTrs7Mk/Hc3M3ItW5NbG4= | ||||||
| go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w= | go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w= | ||||||
| go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= | go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								main.go
									
									
									
									
									
								
							| @@ -178,6 +178,12 @@ func main() { | |||||||
| 		log.Error().Err(err).Msg("Error intializing metrics collection") | 		log.Error().Err(err).Msg("Error intializing metrics collection") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// Initialize metrics collection | ||||||
|  | 	err = initPureMaps(ctx, dev) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Error().Err(err).Msg("Error intializing puremaps integration") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Start control socket | 	// Start control socket | ||||||
| 	err = startSocket(ctx, dev) | 	err = startSocket(ctx, dev) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
							
								
								
									
										210
									
								
								maps.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								maps.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | |||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/godbus/dbus/v5" | ||||||
|  | 	"github.com/rs/zerolog/log" | ||||||
|  | 	"go.arsenm.dev/infinitime" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	interfaceName     = "io.github.rinigus.PureMaps.navigator" | ||||||
|  | 	iconProperty      = interfaceName + ".icon" | ||||||
|  | 	narrativeProperty = interfaceName + ".narrative" | ||||||
|  | 	manDistProperty   = interfaceName + ".manDist" | ||||||
|  | 	progressProperty  = interfaceName + ".progress" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func initPureMaps(ctx context.Context, dev *infinitime.Device) error { | ||||||
|  | 	// Connect to session bus. This connection is for method calls. | ||||||
|  | 	conn, err := newSessionBusConn(ctx) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	exists, err := pureMapsExists(ctx, conn) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Connect to session bus. This connection is for method calls. | ||||||
|  | 	monitorConn, err := newSessionBusConn(ctx) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Define rules to listen for | ||||||
|  | 	var rules = []string{ | ||||||
|  | 		"type='signal',interface='io.github.rinigus.PureMaps.navigator'", | ||||||
|  | 	} | ||||||
|  | 	var flag uint = 0 | ||||||
|  | 	// Becode monitor for notifications | ||||||
|  | 	call := monitorConn.BusObject().CallWithContext( | ||||||
|  | 		ctx, "org.freedesktop.DBus.Monitoring.BecomeMonitor", 0, rules, flag, | ||||||
|  | 	) | ||||||
|  | 	if call.Err != nil { | ||||||
|  | 		return call.Err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var navigator dbus.BusObject | ||||||
|  |  | ||||||
|  | 	if exists { | ||||||
|  | 		navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator") | ||||||
|  | 		err = setAll(navigator, dev) | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Error().Err(err).Msg("Error setting all navigation fields") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	go func() { | ||||||
|  | 		signalCh := make(chan *dbus.Message, 10) | ||||||
|  | 		monitorConn.Eavesdrop(signalCh) | ||||||
|  |  | ||||||
|  | 		for { | ||||||
|  | 			select { | ||||||
|  | 			case sig := <-signalCh: | ||||||
|  | 				if sig.Type != dbus.TypeSignal { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				var member string | ||||||
|  | 				err = sig.Headers[dbus.FieldMember].Store(&member) | ||||||
|  | 				if err != nil { | ||||||
|  | 					log.Error().Err(err).Msg("Error getting dbus member field") | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if !strings.HasSuffix(member, "Changed") { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				log.Debug().Str("member", member).Msg("Signal received from PureMaps navigator") | ||||||
|  |  | ||||||
|  | 				// The object must be retrieved in this loop in case PureMaps was not | ||||||
|  | 				// open at the time ITD was started. | ||||||
|  | 				navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator") | ||||||
|  | 				member = strings.TrimSuffix(member, "Changed") | ||||||
|  |  | ||||||
|  | 				switch member { | ||||||
|  | 				case "icon": | ||||||
|  | 					var icon string | ||||||
|  | 					err = navigator.StoreProperty(iconProperty, &icon) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error getting property") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					err = dev.Navigation.SetFlag(infinitime.NavFlag(icon)) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error setting flag") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  | 				case "narrative": | ||||||
|  | 					var narrative string | ||||||
|  | 					err = navigator.StoreProperty(narrativeProperty, &narrative) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error getting property") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					err = dev.Navigation.SetNarrative(narrative) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error setting flag") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  | 				case "manDist": | ||||||
|  | 					var manDist string | ||||||
|  | 					err = navigator.StoreProperty(manDistProperty, &manDist) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error getting property") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					err = dev.Navigation.SetManDist(manDist) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error setting flag") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  | 				case "progress": | ||||||
|  | 					var progress int32 | ||||||
|  | 					err = navigator.StoreProperty(progressProperty, &progress) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error getting property") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					err = dev.Navigation.SetProgress(uint8(progress)) | ||||||
|  | 					if err != nil { | ||||||
|  | 						log.Error().Err(err).Str("property", member).Msg("Error setting flag") | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			case <-ctx.Done(): | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	if exists { | ||||||
|  | 		log.Info().Msg("Sending PureMaps data to InfiniTime") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func setAll(navigator dbus.BusObject, dev *infinitime.Device) error { | ||||||
|  | 	var icon string | ||||||
|  | 	err := navigator.StoreProperty(iconProperty, &icon) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = dev.Navigation.SetFlag(infinitime.NavFlag(icon)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var narrative string | ||||||
|  | 	err = navigator.StoreProperty(narrativeProperty, &narrative) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = dev.Navigation.SetNarrative(narrative) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var manDist string | ||||||
|  | 	err = navigator.StoreProperty(manDistProperty, &manDist) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = dev.Navigation.SetManDist(manDist) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var progress int32 | ||||||
|  | 	err = navigator.StoreProperty(progressProperty, &progress) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return dev.Navigation.SetProgress(uint8(progress)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // pureMapsExists checks to make sure the PureMaps service exists on the bus | ||||||
|  | func pureMapsExists(ctx context.Context, conn *dbus.Conn) (bool, error) { | ||||||
|  | 	var names []string | ||||||
|  | 	err := conn.BusObject().CallWithContext( | ||||||
|  | 		ctx, "org.freedesktop.DBus.ListNames", 0, | ||||||
|  | 	).Store(&names) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, err | ||||||
|  | 	} | ||||||
|  | 	return strSlcContains(names, "io.github.rinigus.PureMaps"), nil | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user