Gracefully shut down each component before exiting
This commit is contained in:
parent
947ab7fbcb
commit
6113ac019e
88
calls.go
88
calls.go
@ -10,7 +10,7 @@ import (
|
|||||||
"go.arsenm.dev/logger/log"
|
"go.arsenm.dev/logger/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initCallNotifs(ctx context.Context, dev *infinitime.Device) error {
|
func initCallNotifs(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
// Connect to system bus. This connection is for method calls.
|
// Connect to system bus. This connection is for method calls.
|
||||||
conn, err := utils.NewSystemBusConn(ctx)
|
conn, err := utils.NewSystemBusConn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -53,49 +53,55 @@ func initCallNotifs(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
var respHandlerOnce sync.Once
|
var respHandlerOnce sync.Once
|
||||||
var callObj dbus.BusObject
|
var callObj dbus.BusObject
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
// For every message received
|
defer wg.Done("callNotifs")
|
||||||
for event := range callCh {
|
for {
|
||||||
// Get path to call object
|
select {
|
||||||
callPath := event.Body[0].(dbus.ObjectPath)
|
case event := <-callCh:
|
||||||
// Get call object
|
// Get path to call object
|
||||||
callObj = conn.Object("org.freedesktop.ModemManager1", callPath)
|
callPath := event.Body[0].(dbus.ObjectPath)
|
||||||
|
// Get call object
|
||||||
|
callObj = conn.Object("org.freedesktop.ModemManager1", callPath)
|
||||||
|
|
||||||
// Get phone number from call object using method call connection
|
// Get phone number from call object using method call connection
|
||||||
phoneNum, err := getPhoneNum(conn, callObj)
|
phoneNum, err := getPhoneNum(conn, callObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error getting phone number").Err(err).Send()
|
log.Error("Error getting phone number").Err(err).Send()
|
||||||
continue
|
continue
|
||||||
}
|
|
||||||
|
|
||||||
// Send call notification to InfiniTime
|
|
||||||
resCh, err := dev.NotifyCall(phoneNum)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go respHandlerOnce.Do(func() {
|
|
||||||
// Wait for PineTime response
|
|
||||||
for res := range resCh {
|
|
||||||
switch res {
|
|
||||||
case infinitime.CallStatusAccepted:
|
|
||||||
// Attempt to accept call
|
|
||||||
err = acceptCall(ctx, conn, callObj)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("Error accepting call").Err(err).Send()
|
|
||||||
}
|
|
||||||
case infinitime.CallStatusDeclined:
|
|
||||||
// Attempt to decline call
|
|
||||||
err = declineCall(ctx, conn, callObj)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("Error declining call").Err(err).Send()
|
|
||||||
}
|
|
||||||
case infinitime.CallStatusMuted:
|
|
||||||
// Warn about unimplemented muting
|
|
||||||
log.Warn("Muting calls is not implemented").Send()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
// Send call notification to InfiniTime
|
||||||
|
resCh, err := dev.NotifyCall(phoneNum)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
go respHandlerOnce.Do(func() {
|
||||||
|
// Wait for PineTime response
|
||||||
|
for res := range resCh {
|
||||||
|
switch res {
|
||||||
|
case infinitime.CallStatusAccepted:
|
||||||
|
// Attempt to accept call
|
||||||
|
err = acceptCall(ctx, conn, callObj)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error accepting call").Err(err).Send()
|
||||||
|
}
|
||||||
|
case infinitime.CallStatusDeclined:
|
||||||
|
// Attempt to decline call
|
||||||
|
err = declineCall(ctx, conn, callObj)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error declining call").Err(err).Send()
|
||||||
|
}
|
||||||
|
case infinitime.CallStatusMuted:
|
||||||
|
// Warn about unimplemented muting
|
||||||
|
log.Warn("Muting calls is not implemented").Send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
11
fuse.go
11
fuse.go
@ -11,7 +11,7 @@ import (
|
|||||||
"go.arsenm.dev/logger/log"
|
"go.arsenm.dev/logger/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startFUSE(ctx context.Context, dev *infinitime.Device) error {
|
func startFUSE(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
// This is where we'll mount the FS
|
// This is where we'll mount the FS
|
||||||
err := os.MkdirAll(k.String("fuse.mountpoint"), 0o755)
|
err := os.MkdirAll(k.String("fuse.mountpoint"), 0o755)
|
||||||
if err != nil && !os.IsExist(err) {
|
if err != nil && !os.IsExist(err) {
|
||||||
@ -55,7 +55,12 @@ func startFUSE(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until unmount before exiting
|
wg.Add(1)
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
defer wg.Done("fuse")
|
||||||
|
<-ctx.Done()
|
||||||
|
server.Unmount()
|
||||||
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
4
go.mod
4
go.mod
@ -4,6 +4,8 @@ go 1.18
|
|||||||
|
|
||||||
replace fyne.io/x/fyne => github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb
|
replace fyne.io/x/fyne => github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb
|
||||||
|
|
||||||
|
replace go.arsenm.dev/drpc => /home/elara/Code/drpc
|
||||||
|
|
||||||
require (
|
require (
|
||||||
fyne.io/fyne/v2 v2.3.0
|
fyne.io/fyne/v2 v2.3.0
|
||||||
fyne.io/x/fyne v0.0.0-20220107050838-c4a1de51d4ce
|
fyne.io/x/fyne v0.0.0-20220107050838-c4a1de51d4ce
|
||||||
@ -74,7 +76,7 @@ require (
|
|||||||
golang.org/x/mobile v0.0.0-20221110043201-43a038452099 // indirect
|
golang.org/x/mobile v0.0.0-20221110043201-43a038452099 // indirect
|
||||||
golang.org/x/mod v0.7.0 // indirect
|
golang.org/x/mod v0.7.0 // indirect
|
||||||
golang.org/x/net v0.4.0 // indirect
|
golang.org/x/net v0.4.0 // indirect
|
||||||
golang.org/x/sys v0.3.0 // indirect
|
golang.org/x/sys v0.6.0 // indirect
|
||||||
golang.org/x/tools v0.4.0 // indirect
|
golang.org/x/tools v0.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70 // indirect
|
honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70 // indirect
|
||||||
|
3
go.sum
3
go.sum
@ -341,6 +341,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
|
|||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||||
github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc=
|
github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc=
|
||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
@ -756,6 +757,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
71
main.go
71
main.go
@ -26,6 +26,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -74,21 +76,7 @@ func main() {
|
|||||||
LogLevel: level,
|
LogLevel: level,
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx := context.Background()
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
sigCh := make(chan os.Signal, 1)
|
|
||||||
go func() {
|
|
||||||
<-sigCh
|
|
||||||
cancel()
|
|
||||||
time.Sleep(200 * time.Millisecond)
|
|
||||||
os.Exit(0)
|
|
||||||
}()
|
|
||||||
signal.Notify(
|
|
||||||
sigCh,
|
|
||||||
syscall.SIGINT,
|
|
||||||
syscall.SIGTERM,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Connect to InfiniTime with default options
|
// Connect to InfiniTime with default options
|
||||||
dev, err := infinitime.Connect(ctx, opts)
|
dev, err := infinitime.Connect(ctx, opts)
|
||||||
@ -145,57 +133,88 @@ func main() {
|
|||||||
log.Error("Error setting current time on connected InfiniTime").Err(err).Send()
|
log.Error("Error setting current time on connected InfiniTime").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigCh := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
sig := <-sigCh
|
||||||
|
log.Warn("Signal received, shutting down").Stringer("signal", sig).Send()
|
||||||
|
cancel()
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg := WaitGroup{&sync.WaitGroup{}}
|
||||||
|
|
||||||
// Initialize music controls
|
// Initialize music controls
|
||||||
err = initMusicCtrl(ctx, dev)
|
err = initMusicCtrl(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error initializing music control").Err(err).Send()
|
log.Error("Error initializing music control").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start control socket
|
// Start control socket
|
||||||
err = initCallNotifs(ctx, dev)
|
err = initCallNotifs(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error initializing call notifications").Err(err).Send()
|
log.Error("Error initializing call notifications").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize notification relay
|
// Initialize notification relay
|
||||||
err = initNotifRelay(ctx, dev)
|
err = initNotifRelay(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error initializing notification relay").Err(err).Send()
|
log.Error("Error initializing notification relay").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializa weather
|
// Initializa weather
|
||||||
err = initWeather(ctx, dev)
|
err = initWeather(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error initializing weather").Err(err).Send()
|
log.Error("Error initializing weather").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize metrics collection
|
// Initialize metrics collection
|
||||||
err = initMetrics(ctx, dev)
|
err = initMetrics(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error intializing metrics collection").Err(err).Send()
|
log.Error("Error intializing metrics collection").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize metrics collection
|
// Initialize puremaps integration
|
||||||
err = initPureMaps(ctx, dev)
|
err = initPureMaps(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error intializing puremaps integration").Err(err).Send()
|
log.Error("Error intializing puremaps integration").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start fuse socket
|
// Start fuse socket
|
||||||
if k.Bool("fuse.enabled") {
|
if k.Bool("fuse.enabled") {
|
||||||
err = startFUSE(ctx, dev)
|
err = startFUSE(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error starting fuse socket").Err(err).Send()
|
log.Error("Error starting fuse socket").Err(err).Send()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start control socket
|
// Start control socket
|
||||||
err = startSocket(ctx, dev)
|
err = startSocket(ctx, wg, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error starting socket").Err(err).Send()
|
log.Error("Error starting socket").Err(err).Send()
|
||||||
}
|
}
|
||||||
// Block forever
|
|
||||||
select {}
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
type x struct {
|
||||||
|
n int
|
||||||
|
*sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (xy *x) Add(i int) {
|
||||||
|
xy.n += i
|
||||||
|
xy.WaitGroup.Add(i)
|
||||||
|
fmt.Println("add: counter:", xy.n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (xy *x) Done() {
|
||||||
|
xy.n -= 1
|
||||||
|
xy.WaitGroup.Done()
|
||||||
|
fmt.Println("done: counter:", xy.n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func onReqPasskey() (uint32, error) {
|
func onReqPasskey() (uint32, error) {
|
||||||
|
5
maps.go
5
maps.go
@ -18,7 +18,7 @@ const (
|
|||||||
progressProperty = interfaceName + ".progress"
|
progressProperty = interfaceName + ".progress"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initPureMaps(ctx context.Context, dev *infinitime.Device) error {
|
func initPureMaps(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
// Connect to session bus. This connection is for method calls.
|
// Connect to session bus. This connection is for method calls.
|
||||||
conn, err := utils.NewSessionBusConn(ctx)
|
conn, err := utils.NewSessionBusConn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,7 +59,10 @@ func initPureMaps(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer wg.Done("pureMaps")
|
||||||
|
|
||||||
signalCh := make(chan *dbus.Message, 10)
|
signalCh := make(chan *dbus.Message, 10)
|
||||||
monitorConn.Eavesdrop(signalCh)
|
monitorConn.Eavesdrop(signalCh)
|
||||||
|
|
||||||
|
10
metrics.go
10
metrics.go
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.arsenm.dev/infinitime"
|
"go.arsenm.dev/infinitime"
|
||||||
@ -11,7 +12,7 @@ import (
|
|||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initMetrics(ctx context.Context, dev *infinitime.Device) error {
|
func initMetrics(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
// If metrics disabled, return nil
|
// If metrics disabled, return nil
|
||||||
if !k.Bool("metrics.enabled") {
|
if !k.Bool("metrics.enabled") {
|
||||||
return nil
|
return nil
|
||||||
@ -125,6 +126,13 @@ func initMetrics(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done("metrics")
|
||||||
|
<-ctx.Done()
|
||||||
|
db.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
log.Info("Initialized metrics collection").Send()
|
log.Info("Initialized metrics collection").Send()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
41
music.go
41
music.go
@ -20,6 +20,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
|
||||||
"go.arsenm.dev/infinitime"
|
"go.arsenm.dev/infinitime"
|
||||||
"go.arsenm.dev/itd/mpris"
|
"go.arsenm.dev/itd/mpris"
|
||||||
@ -27,7 +28,7 @@ import (
|
|||||||
"go.arsenm.dev/logger/log"
|
"go.arsenm.dev/logger/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initMusicCtrl(ctx context.Context, dev *infinitime.Device) error {
|
func initMusicCtrl(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
mpris.Init(ctx)
|
mpris.Init(ctx)
|
||||||
|
|
||||||
maps := k.Strings("notifs.translit.use")
|
maps := k.Strings("notifs.translit.use")
|
||||||
@ -54,23 +55,31 @@ func initMusicCtrl(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer wg.Done("musicCtrl")
|
||||||
// For every music event received
|
// For every music event received
|
||||||
for musicEvt := range musicEvtCh {
|
for {
|
||||||
// Perform appropriate action based on event
|
select {
|
||||||
switch musicEvt {
|
case musicEvt := <-musicEvtCh:
|
||||||
case infinitime.MusicEventPlay:
|
// Perform appropriate action based on event
|
||||||
mpris.Play()
|
switch musicEvt {
|
||||||
case infinitime.MusicEventPause:
|
case infinitime.MusicEventPlay:
|
||||||
mpris.Pause()
|
mpris.Play()
|
||||||
case infinitime.MusicEventNext:
|
case infinitime.MusicEventPause:
|
||||||
mpris.Next()
|
mpris.Pause()
|
||||||
case infinitime.MusicEventPrev:
|
case infinitime.MusicEventNext:
|
||||||
mpris.Prev()
|
mpris.Next()
|
||||||
case infinitime.MusicEventVolUp:
|
case infinitime.MusicEventPrev:
|
||||||
mpris.VolUp(uint(k.Int("music.vol.interval")))
|
mpris.Prev()
|
||||||
case infinitime.MusicEventVolDown:
|
case infinitime.MusicEventVolUp:
|
||||||
mpris.VolDown(uint(k.Int("music.vol.interval")))
|
mpris.VolUp(uint(k.Int("music.vol.interval")))
|
||||||
|
case infinitime.MusicEventVolDown:
|
||||||
|
mpris.VolDown(uint(k.Int("music.vol.interval")))
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
78
notifs.go
78
notifs.go
@ -29,7 +29,7 @@ import (
|
|||||||
"go.arsenm.dev/logger/log"
|
"go.arsenm.dev/logger/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initNotifRelay(ctx context.Context, dev *infinitime.Device) error {
|
func initNotifRelay(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
// Connect to dbus session bus
|
// Connect to dbus session bus
|
||||||
bus, err := utils.NewSessionBusConn(ctx)
|
bus, err := utils.NewSessionBusConn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -54,43 +54,51 @@ func initNotifRelay(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
// Send events to channel
|
// Send events to channel
|
||||||
bus.Eavesdrop(notifCh)
|
bus.Eavesdrop(notifCh)
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer wg.Done("notifRelay")
|
||||||
// For every event sent to channel
|
// For every event sent to channel
|
||||||
for v := range notifCh {
|
for {
|
||||||
// If firmware is updating, skip
|
select {
|
||||||
if firmwareUpdating {
|
case v := <-notifCh:
|
||||||
continue
|
// If firmware is updating, skip
|
||||||
|
if firmwareUpdating {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If body does not contain 5 elements, skip
|
||||||
|
if len(v.Body) < 5 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get requred fields
|
||||||
|
sender, summary, body := v.Body[0].(string), v.Body[3].(string), v.Body[4].(string)
|
||||||
|
|
||||||
|
// If fields are ignored in config, skip
|
||||||
|
if ignored(sender, summary, body) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
maps := k.Strings("notifs.translit.use")
|
||||||
|
translit.Transliterators["custom"] = translit.Map(k.Strings("notifs.translit.custom"))
|
||||||
|
sender = translit.Transliterate(sender, maps...)
|
||||||
|
summary = translit.Transliterate(summary, maps...)
|
||||||
|
body = translit.Transliterate(body, maps...)
|
||||||
|
|
||||||
|
var msg string
|
||||||
|
// If summary does not exist, set message to body.
|
||||||
|
// If it does, set message to summary, two newlines, and then body
|
||||||
|
if summary == "" {
|
||||||
|
msg = body
|
||||||
|
} else {
|
||||||
|
msg = fmt.Sprintf("%s\n\n%s", summary, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
dev.Notify(sender, msg)
|
||||||
|
case <-ctx.Done():
|
||||||
|
bus.Close()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If body does not contain 5 elements, skip
|
|
||||||
if len(v.Body) < 5 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get requred fields
|
|
||||||
sender, summary, body := v.Body[0].(string), v.Body[3].(string), v.Body[4].(string)
|
|
||||||
|
|
||||||
// If fields are ignored in config, skip
|
|
||||||
if ignored(sender, summary, body) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
maps := k.Strings("notifs.translit.use")
|
|
||||||
translit.Transliterators["custom"] = translit.Map(k.Strings("notifs.translit.custom"))
|
|
||||||
sender = translit.Transliterate(sender, maps...)
|
|
||||||
summary = translit.Transliterate(summary, maps...)
|
|
||||||
body = translit.Transliterate(body, maps...)
|
|
||||||
|
|
||||||
var msg string
|
|
||||||
// If summary does not exist, set message to body.
|
|
||||||
// If it does, set message to summary, two newlines, and then body
|
|
||||||
if summary == "" {
|
|
||||||
msg = body
|
|
||||||
} else {
|
|
||||||
msg = fmt.Sprintf("%s\n\n%s", summary, body)
|
|
||||||
}
|
|
||||||
|
|
||||||
dev.Notify(sender, msg)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
12
socket.go
12
socket.go
@ -25,6 +25,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.arsenm.dev/drpc/muxserver"
|
"go.arsenm.dev/drpc/muxserver"
|
||||||
@ -41,7 +42,7 @@ var (
|
|||||||
ErrDFUInvalidUpgType = errors.New("invalid upgrade type")
|
ErrDFUInvalidUpgType = errors.New("invalid upgrade type")
|
||||||
)
|
)
|
||||||
|
|
||||||
func startSocket(ctx context.Context, dev *infinitime.Device) error {
|
func startSocket(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
// Make socket directory if non-existant
|
// Make socket directory if non-existant
|
||||||
err := os.MkdirAll(filepath.Dir(k.String("socket.path")), 0o755)
|
err := os.MkdirAll(filepath.Dir(k.String("socket.path")), 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -77,10 +78,13 @@ func startSocket(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go muxserver.New(mux).Serve(ctx, ln)
|
log.Info("Starting control socket").Str("path", k.String("socket.path")).Send()
|
||||||
|
|
||||||
// Log socket start
|
wg.Add(1)
|
||||||
log.Info("Started control socket").Str("path", k.String("socket.path")).Send()
|
go func() {
|
||||||
|
defer wg.Done("socket")
|
||||||
|
muxserver.New(mux).Serve(ctx, ln)
|
||||||
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
16
waitgroup.go
Normal file
16
waitgroup.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"go.arsenm.dev/logger/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WaitGroup struct {
|
||||||
|
*sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wg WaitGroup) Done(c string) {
|
||||||
|
log.Info("Component stopped").Str("name", c).Send()
|
||||||
|
wg.WaitGroup.Done()
|
||||||
|
}
|
21
weather.go
21
weather.go
@ -9,6 +9,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.arsenm.dev/infinitime"
|
"go.arsenm.dev/infinitime"
|
||||||
@ -61,7 +62,14 @@ type OSMData []struct {
|
|||||||
|
|
||||||
var sendWeatherCh = make(chan struct{}, 1)
|
var sendWeatherCh = make(chan struct{}, 1)
|
||||||
|
|
||||||
func initWeather(ctx context.Context, dev *infinitime.Device) error {
|
func sleepCtx(ctx context.Context, d time.Duration) {
|
||||||
|
select {
|
||||||
|
case <-time.After(d):
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initWeather(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error {
|
||||||
if !k.Bool("weather.enabled") {
|
if !k.Bool("weather.enabled") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -74,14 +82,21 @@ func initWeather(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
|
|
||||||
timer := time.NewTimer(time.Hour)
|
timer := time.NewTimer(time.Hour)
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer wg.Done("weather")
|
||||||
for {
|
for {
|
||||||
|
_, ok := <-ctx.Done()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Attempt to get weather
|
// Attempt to get weather
|
||||||
data, err := getWeather(ctx, lat, lon)
|
data, err := getWeather(ctx, lat, lon)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Error getting weather data").Err(err).Send()
|
log.Warn("Error getting weather data").Err(err).Send()
|
||||||
// Wait 15 minutes before retrying
|
// Wait 15 minutes before retrying
|
||||||
time.Sleep(15 * time.Minute)
|
sleepCtx(ctx, 15*time.Minute)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +189,8 @@ func initWeather(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
select {
|
select {
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
case <-sendWeatherCh:
|
case <-sendWeatherCh:
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
Loading…
Reference in New Issue
Block a user