From 851f1975d651a776bfe341e48b2c118ba55c9f0d Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Tue, 30 Aug 2022 12:13:22 -0700 Subject: [PATCH 1/5] Add LoadResources() to API --- api/resources.go | 26 ++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- socket.go | 25 +++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 api/resources.go diff --git a/api/resources.go b/api/resources.go new file mode 100644 index 0000000..8690ddc --- /dev/null +++ b/api/resources.go @@ -0,0 +1,26 @@ +package api + +import ( + "context" + + "go.arsenm.dev/infinitime" +) + +// LoadResources loads resources onto the watch from the given +// file path to the resources zip +func (c *Client) LoadResources(ctx context.Context, path string) (<-chan infinitime.ResourceLoadProgress, error) { + progCh := make(chan infinitime.ResourceLoadProgress) + + err := c.client.Call( + ctx, + "FS", + "LoadResources", + path, + progCh, + ) + if err != nil { + return nil, err + } + + return progCh, nil +} diff --git a/go.mod b/go.mod index b99795e..d7eb013 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/mozillazg/go-pinyin v0.19.0 github.com/rs/zerolog v1.26.1 github.com/urfave/cli/v2 v2.3.0 - go.arsenm.dev/infinitime v0.0.0-20220819210252-d199fba93c2f + go.arsenm.dev/infinitime v0.0.0-20220829214316-3e9957d41961 go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 golang.org/x/text v0.3.7 modernc.org/sqlite v1.17.2 diff --git a/go.sum b/go.sum index 76bdf4a..98aeb44 100644 --- a/go.sum +++ b/go.sum @@ -396,8 +396,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.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs= github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= -go.arsenm.dev/infinitime v0.0.0-20220819210252-d199fba93c2f h1:Np0ZNlgVC5D9NOilN14HJ1mSXM8vl2LYGfK0fZOYUbY= -go.arsenm.dev/infinitime v0.0.0-20220819210252-d199fba93c2f/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc= +go.arsenm.dev/infinitime v0.0.0-20220829214316-3e9957d41961 h1:UcggI2jru69nHLcj8uDRLhaeUecaokeTjUItvifX4jM= +go.arsenm.dev/infinitime v0.0.0-20220829214316-3e9957d41961/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/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= diff --git a/socket.go b/socket.go index 5dba567..1e85aa6 100644 --- a/socket.go +++ b/socket.go @@ -424,6 +424,31 @@ func (fs *FS) Download(ctx *server.Context, paths [2]string) error { return nil } +func (fs *FS) LoadResources(ctx *server.Context, path string) error { + resFl, err := os.Open(path) + if err != nil { + return err + } + + progCh, err := infinitime.LoadResources(resFl, fs.fs) + if err != nil { + return err + } + + ch, err := ctx.MakeChannel() + if err != nil { + return err + } + + go func() { + for evt := range progCh { + ch <- evt + } + }() + + return nil +} + func (fs *FS) updateFS() { if fs.fs == nil || updateFS { // Get new FS From 6f87980d4b70ab3eb7fa11c9457c32af2eabbab6 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Tue, 30 Aug 2022 13:01:36 -0700 Subject: [PATCH 2/5] Add resource loading to itctl --- cmd/itctl/main.go | 29 ++++++++++++++++++------- cmd/itctl/resources.go | 48 ++++++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 3 ++- 4 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 cmd/itctl/resources.go diff --git a/cmd/itctl/main.go b/cmd/itctl/main.go index b548126..0de3d53 100644 --- a/cmd/itctl/main.go +++ b/cmd/itctl/main.go @@ -1,11 +1,11 @@ package main import ( - "time" "context" "os" "os/signal" "syscall" + "time" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -24,17 +24,17 @@ func main() { syscall.SIGINT, syscall.SIGTERM, ) - + // This goroutine ensures that itctl will exit // at most 200ms after the user sends SIGINT/SIGTERM. go func() { <-ctx.Done() - time.Sleep(200*time.Millisecond) + time.Sleep(200 * time.Millisecond) os.Exit(0) }() app := cli.App{ - Name: "itctl", + Name: "itctl", HideHelpCommand: true, Flags: []cli.Flag{ &cli.StringFlag{ @@ -46,10 +46,23 @@ func main() { }, Commands: []*cli.Command{ { - Name: "help", + Name: "help", ArgsUsage: "", - Usage: "Display help screen for a command", - Action: helpCmd, + Usage: "Display help screen for a command", + Action: helpCmd, + }, + { + Name: "resources", + Aliases: []string{"res"}, + Usage: "Handle InfiniTime resource loading", + Subcommands: []*cli.Command{ + { + Name: "load", + ArgsUsage: "", + Usage: "Load an InifiniTime resources package", + Action: resourcesLoad, + }, + }, }, { Name: "filesystem", @@ -284,4 +297,4 @@ func isHelpCmd() bool { } } return false -} \ No newline at end of file +} diff --git a/cmd/itctl/resources.go b/cmd/itctl/resources.go new file mode 100644 index 0000000..6bbca0e --- /dev/null +++ b/cmd/itctl/resources.go @@ -0,0 +1,48 @@ +package main + +import ( + "path/filepath" + + "github.com/cheggaaa/pb/v3" + "github.com/urfave/cli/v2" + "go.arsenm.dev/infinitime" +) + +func resourcesLoad(c *cli.Context) error { + if c.Args().Len() == 0 { + return cli.Exit("Command load requires one argument.", 1) + } + + // Create progress bar templates + rmTmpl := `Removing {{string . "filename"}}` + upTmpl := `Uploading {{string . "filename"}} {{counters . }} B {{bar . "|" "-" (cycle .) " " "|"}} {{percent . }} {{rtime . "%s"}}` + // Start full bar at 0 total + bar := pb.ProgressBarTemplate(rmTmpl).Start(0) + + path, err := filepath.Abs(c.Args().Get(0)) + if err != nil { + return err + } + + progCh, err := client.LoadResources(c.Context, path) + if err != nil { + return err + } + + for evt := range progCh { + if evt.Operation == infinitime.ResourceOperationRemoveObsolete { + bar.SetTemplateString(rmTmpl) + bar.Set("filename", evt.Name) + } else { + bar.SetTemplateString(upTmpl) + bar.Set("filename", evt.Name) + + bar.SetTotal(evt.Total) + bar.SetCurrent(evt.Sent) + } + } + + bar.Finish() + + return nil +} diff --git a/go.mod b/go.mod index d7eb013..793fb3c 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.8 // indirect - github.com/mattn/go-runewidth v0.0.12 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect diff --git a/go.sum b/go.sum index 98aeb44..1812906 100644 --- a/go.sum +++ b/go.sum @@ -270,8 +270,9 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb h1:+fP6ENsbd+BUOmD/kSjNtrOmi2vgJ/JfWDSWjTKmTVY= From 4efa4380c491398e0703b1532ed8442ce89d3d79 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sat, 3 Sep 2022 16:28:25 -0700 Subject: [PATCH 3/5] Add -r for rm and -p for mkdir --- api/fs.go | 20 ++++++++++++++++++++ cmd/itctl/fs.go | 14 ++++++++++++-- cmd/itctl/main.go | 14 ++++++++++++++ socket.go | 22 ++++++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/api/fs.go b/api/fs.go index ae41b9e..7b05b51 100644 --- a/api/fs.go +++ b/api/fs.go @@ -2,6 +2,16 @@ package api import "context" +func (c *Client) RemoveAll(ctx context.Context, paths ...string) error { + return c.client.Call( + ctx, + "FS", + "RemoveAll", + paths, + nil, + ) +} + func (c *Client) Remove(ctx context.Context, paths ...string) error { return c.client.Call( ctx, @@ -22,6 +32,16 @@ func (c *Client) Rename(ctx context.Context, old, new string) error { ) } +func (c *Client) MkdirAll(ctx context.Context, paths ...string) error { + return c.client.Call( + ctx, + "FS", + "MkdirAll", + paths, + nil, + ) +} + func (c *Client) Mkdir(ctx context.Context, paths ...string) error { return c.client.Call( ctx, diff --git a/cmd/itctl/fs.go b/cmd/itctl/fs.go index 38ac25d..fc2ec0a 100644 --- a/cmd/itctl/fs.go +++ b/cmd/itctl/fs.go @@ -34,7 +34,12 @@ func fsMkdir(c *cli.Context) error { return cli.Exit("Command mkdir requires one or more arguments", 1) } - err := client.Mkdir(c.Context, c.Args().Slice()...) + var err error + if c.Bool("parents") { + err = client.MkdirAll(c.Context, c.Args().Slice()...) + } else { + err = client.Mkdir(c.Context, c.Args().Slice()...) + } if err != nil { return err } @@ -109,7 +114,12 @@ func fsRemove(c *cli.Context) error { return cli.Exit("Command remove requires one or more arguments", 1) } - err := client.Remove(c.Context, c.Args().Slice()...) + var err error + if c.Bool("recursive") { + err = client.RemoveAll(c.Context, c.Args().Slice()...) + } else { + err = client.Remove(c.Context, c.Args().Slice()...) + } if err != nil { return err } diff --git a/cmd/itctl/main.go b/cmd/itctl/main.go index 0de3d53..dbc8112 100644 --- a/cmd/itctl/main.go +++ b/cmd/itctl/main.go @@ -77,6 +77,13 @@ func main() { Action: fsList, }, { + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "parents", + Aliases: []string{"p"}, + Usage: "Make parent directories if needed, no error if already existing", + }, + }, Name: "mkdir", ArgsUsage: "", Usage: "Create new directories", @@ -97,6 +104,13 @@ func main() { Action: fsRead, }, { + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "recursive", + Aliases: []string{"r", "R"}, + Usage: "Remove directories and their contents recursively", + }, + }, Name: "remove", ArgsUsage: "", Aliases: []string{"rm"}, diff --git a/socket.go b/socket.go index 1e85aa6..93d9287 100644 --- a/socket.go +++ b/socket.go @@ -293,6 +293,17 @@ type FS struct { fs *blefs.FS } +func (fs *FS) RemoveAll(_ *server.Context, paths []string) error { + fs.updateFS() + for _, path := range paths { + err := fs.fs.RemoveAll(path) + if err != nil { + return err + } + } + return nil +} + func (fs *FS) Remove(_ *server.Context, paths []string) error { fs.updateFS() for _, path := range paths { @@ -309,6 +320,17 @@ func (fs *FS) Rename(_ *server.Context, paths [2]string) error { return fs.fs.Rename(paths[0], paths[1]) } +func (fs *FS) MkdirAll(_ *server.Context, paths []string) error { + fs.updateFS() + for _, path := range paths { + err := fs.fs.MkdirAll(path) + if err != nil { + return err + } + } + return nil +} + func (fs *FS) Mkdir(_ *server.Context, paths []string) error { fs.updateFS() for _, path := range paths { From 2d0db1dcf15304a2f75d332e03d213cf42871976 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sun, 16 Oct 2022 12:42:59 -0700 Subject: [PATCH 4/5] Close channel once resource uploading complete --- go.mod | 2 +- go.sum | 4 ++-- socket.go | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 793fb3c..7ec585f 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/mozillazg/go-pinyin v0.19.0 github.com/rs/zerolog v1.26.1 github.com/urfave/cli/v2 v2.3.0 - go.arsenm.dev/infinitime v0.0.0-20220829214316-3e9957d41961 + go.arsenm.dev/infinitime v0.0.0-20221016193942-01970b2bb770 go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 golang.org/x/text v0.3.7 modernc.org/sqlite v1.17.2 diff --git a/go.sum b/go.sum index 1812906..e7130cf 100644 --- a/go.sum +++ b/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.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs= github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= -go.arsenm.dev/infinitime v0.0.0-20220829214316-3e9957d41961 h1:UcggI2jru69nHLcj8uDRLhaeUecaokeTjUItvifX4jM= -go.arsenm.dev/infinitime v0.0.0-20220829214316-3e9957d41961/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc= +go.arsenm.dev/infinitime v0.0.0-20221016193942-01970b2bb770 h1:OZ8kYFHCXt+7nxz9G0BTnSyJKnIpQnQ5m7kyIssG81Y= +go.arsenm.dev/infinitime v0.0.0-20221016193942-01970b2bb770/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/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= diff --git a/socket.go b/socket.go index 93d9287..6fcba5c 100644 --- a/socket.go +++ b/socket.go @@ -466,6 +466,7 @@ func (fs *FS) LoadResources(ctx *server.Context, path string) error { for evt := range progCh { ch <- evt } + close(ch) }() return nil From f639fef9922a4773cf26e92b7351458d3a1b792e Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sun, 16 Oct 2022 13:17:12 -0700 Subject: [PATCH 5/5] Add resource loading as part of DFU --- cmd/itctl/firmware.go | 13 +++++++++++++ cmd/itctl/main.go | 5 +++++ cmd/itctl/resources.go | 11 ++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cmd/itctl/firmware.go b/cmd/itctl/firmware.go index cc11df8..bcf41fb 100644 --- a/cmd/itctl/firmware.go +++ b/cmd/itctl/firmware.go @@ -11,6 +11,19 @@ import ( ) func fwUpgrade(c *cli.Context) error { + resources := c.String("resources") + if resources != "" { + absRes, err := filepath.Abs(resources) + if err != nil { + return err + } + + err = resLoad(c.Context, []string{absRes}) + if err != nil { + return err + } + } + start := time.Now() var upgType api.UpgradeType diff --git a/cmd/itctl/main.go b/cmd/itctl/main.go index dbc8112..c4f865d 100644 --- a/cmd/itctl/main.go +++ b/cmd/itctl/main.go @@ -143,6 +143,11 @@ func main() { Aliases: []string{"f"}, Usage: "Path to firmware image (.bin file)", }, + &cli.PathFlag{ + Name: "resources", + Aliases: []string{"r"}, + Usage: "Path to resources file (.zip file)", + }, &cli.PathFlag{ Name: "archive", Aliases: []string{"a"}, diff --git a/cmd/itctl/resources.go b/cmd/itctl/resources.go index 6bbca0e..2e5338e 100644 --- a/cmd/itctl/resources.go +++ b/cmd/itctl/resources.go @@ -1,6 +1,7 @@ package main import ( + "context" "path/filepath" "github.com/cheggaaa/pb/v3" @@ -9,7 +10,11 @@ import ( ) func resourcesLoad(c *cli.Context) error { - if c.Args().Len() == 0 { + return resLoad(c.Context, c.Args().Slice()) +} + +func resLoad(ctx context.Context, args []string) error { + if len(args) == 0 { return cli.Exit("Command load requires one argument.", 1) } @@ -19,12 +24,12 @@ func resourcesLoad(c *cli.Context) error { // Start full bar at 0 total bar := pb.ProgressBarTemplate(rmTmpl).Start(0) - path, err := filepath.Abs(c.Args().Get(0)) + path, err := filepath.Abs(args[0]) if err != nil { return err } - progCh, err := client.LoadResources(c.Context, path) + progCh, err := client.LoadResources(ctx, path) if err != nil { return err }