From 34b7d2fa588868a82e38c75277e0a920fb96e463 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Thu, 30 Sep 2021 12:00:02 +0200 Subject: [PATCH 1/8] Update iot-clients-go version --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 260e1ebb..68e1a4f1 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/antihax/optional v1.0.0 github.com/arduino/arduino-cli v0.0.0-20210607095659-16f41352eac3 github.com/arduino/go-paths-helper v1.6.1 - github.com/arduino/iot-client-go v1.3.4-0.20210902151346-1cd63fb0c784 + github.com/arduino/iot-client-go v1.3.4-0.20210930122852-04551f4cb061 github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6 github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 github.com/sirupsen/logrus v1.8.1 diff --git a/go.sum b/go.sum index e8af50c8..2fdc7a11 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ github.com/arduino/go-properties-orderedmap v1.3.0/go.mod h1:DKjD2VXY/NZmlingh4l github.com/arduino/go-timeutils v0.0.0-20171220113728-d1dd9e313b1b/go.mod h1:uwGy5PpN4lqW97FiLnbcx+xx8jly5YuPMJWfVwwjJiQ= github.com/arduino/go-win32-utils v0.0.0-20180330194947-ed041402e83b h1:3PjgYG5gVPA7cipp7vIR2lF96KkEJIFBJ+ANnuv6J20= github.com/arduino/go-win32-utils v0.0.0-20180330194947-ed041402e83b/go.mod h1:iIPnclBMYm1g32Q5kXoqng4jLhMStReIP7ZxaoUC2y8= -github.com/arduino/iot-client-go v1.3.4-0.20210902151346-1cd63fb0c784 h1:Wo4g3vuu8Tv57GggLK1T2as/xEqG7CIDnOA49C6Ce7I= -github.com/arduino/iot-client-go v1.3.4-0.20210902151346-1cd63fb0c784/go.mod h1:gYvpMt7Qw+OSScTLyIlCnpbvy9y96ey/2zhB4w6FoK0= +github.com/arduino/iot-client-go v1.3.4-0.20210930122852-04551f4cb061 h1:uQeaIHzj0tOlqnHaRskSy6UwMgQ6LIOECySpaYBCt5M= +github.com/arduino/iot-client-go v1.3.4-0.20210930122852-04551f4cb061/go.mod h1:gYvpMt7Qw+OSScTLyIlCnpbvy9y96ey/2zhB4w6FoK0= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= From 862e1809a7b3f7ec394b4bb31b593bb1e3ee760b Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Thu, 30 Sep 2021 15:19:22 +0200 Subject: [PATCH 2/8] Add dashboard list command --- cli/cli.go | 2 + cli/dashboard/dashboard.go | 34 +++++++++++++ cli/dashboard/list.go | 90 ++++++++++++++++++++++++++++++++++ command/dashboard/dashboard.go | 51 +++++++++++++++++++ command/dashboard/list.go | 49 ++++++++++++++++++ internal/iot/client.go | 11 +++++ 6 files changed, 237 insertions(+) create mode 100644 cli/dashboard/dashboard.go create mode 100644 cli/dashboard/list.go create mode 100644 command/dashboard/dashboard.go create mode 100644 command/dashboard/list.go diff --git a/cli/cli.go b/cli/cli.go index 7f8ccc11..7b9a8267 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -26,6 +26,7 @@ import ( "github.com/arduino/arduino-cli/cli/errorcodes" "github.com/arduino/arduino-cli/cli/feedback" "github.com/arduino/arduino-cloud-cli/cli/config" + "github.com/arduino/arduino-cloud-cli/cli/dashboard" "github.com/arduino/arduino-cloud-cli/cli/device" "github.com/arduino/arduino-cloud-cli/cli/ota" "github.com/arduino/arduino-cloud-cli/cli/thing" @@ -51,6 +52,7 @@ func Execute() { cli.AddCommand(config.NewCommand()) cli.AddCommand(device.NewCommand()) cli.AddCommand(thing.NewCommand()) + cli.AddCommand(dashboard.NewCommand()) cli.AddCommand(ota.NewCommand()) cli.PersistentFlags().BoolVarP(&cliFlags.verbose, "verbose", "v", false, "Print the logs on the standard output.") diff --git a/cli/dashboard/dashboard.go b/cli/dashboard/dashboard.go new file mode 100644 index 00000000..4d79ac91 --- /dev/null +++ b/cli/dashboard/dashboard.go @@ -0,0 +1,34 @@ +// This file is part of arduino-cloud-cli. +// +// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dashboard + +import ( + "github.com/spf13/cobra" +) + +func NewCommand() *cobra.Command { + dashboardCommand := &cobra.Command{ + Use: "dashboard", + Short: "Dashboard commands.", + Long: "Dashboard commands.", + } + + dashboardCommand.AddCommand(initListCommand()) + + return dashboardCommand +} diff --git a/cli/dashboard/list.go b/cli/dashboard/list.go new file mode 100644 index 00000000..070b404c --- /dev/null +++ b/cli/dashboard/list.go @@ -0,0 +1,90 @@ +// This file is part of arduino-cloud-cli. +// +// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dashboard + +import ( + "os" + "strings" + + "github.com/arduino/arduino-cli/cli/errorcodes" + "github.com/arduino/arduino-cli/cli/feedback" + "github.com/arduino/arduino-cli/table" + "github.com/arduino/arduino-cloud-cli/command/dashboard" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var listFlags struct { + showSharing bool +} + +func initListCommand() *cobra.Command { + listCommand := &cobra.Command{ + Use: "list", + Short: "List dashboards", + Long: "List dashboards on Arduino IoT Cloud", + Run: runListCommand, + } + + listCommand.Flags().BoolVarP(&listFlags.showSharing, "show-sharing", "s", false, "Show dashboard sharing information") + return listCommand +} + +func runListCommand(cmd *cobra.Command, args []string) { + logrus.Info("Listing dashboards") + + dash, err := dashboard.List() + if err != nil { + feedback.Errorf("Error during dashboard list: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + + feedback.PrintResult(listResult{dash}) +} + +type listResult struct { + dashboards []dashboard.DashboardInfo +} + +func (r listResult) Data() interface{} { + return r.dashboards +} + +func (r listResult) String() string { + if len(r.dashboards) == 0 { + return "No dashboard found." + } + t := table.New() + + head := []interface{}{"Name", "ID", "Widgets", "UpdatedAt"} + if listFlags.showSharing { + head = append(head, "SharedBy", "SharedWith") + } + t.SetHeader(head...) + + for _, dash := range r.dashboards { + row := []interface{}{dash.Name, dash.ID} + row = append(row, strings.Join(dash.Widgets, ", ")) + if listFlags.showSharing { + row = append(row, dash.SharedBy) + row = append(row, strings.Join(dash.SharedWith, ", ")) + } + t.AddRow(row...) + } + return t.Render() +} diff --git a/command/dashboard/dashboard.go b/command/dashboard/dashboard.go new file mode 100644 index 00000000..a1a43687 --- /dev/null +++ b/command/dashboard/dashboard.go @@ -0,0 +1,51 @@ +// This file is part of arduino-cloud-cli. +// +// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dashboard + +import iotclient "github.com/arduino/iot-client-go" + +// DashboardInfo contains the most interesting +// information, in string format, of an Arduino IoT Cloud dashboard. +type DashboardInfo struct { + Name string `json:"name"` + ID string `json:"id"` + SharedBy string `json:"shared_by"` + SharedWith []string `json:"shared_with"` + UpdatedAt string `json:"updated_at"` + Widgets []string `json:"widgets"` +} + +func getDashboardInfo(dashboard *iotclient.ArduinoDashboardv2) *DashboardInfo { + var shares []string + for _, s := range dashboard.SharedWith { + shares = append(shares, s.Username) + } + var widgets []string + for _, w := range dashboard.Widgets { + widgets = append(widgets, w.Name) + } + info := &DashboardInfo{ + Name: dashboard.Name, + ID: dashboard.Id, + SharedBy: dashboard.SharedBy.Username, + SharedWith: shares, + UpdatedAt: dashboard.UpdatedAt.String(), + Widgets: widgets, + } + return info +} diff --git a/command/dashboard/list.go b/command/dashboard/list.go new file mode 100644 index 00000000..5e9aeb43 --- /dev/null +++ b/command/dashboard/list.go @@ -0,0 +1,49 @@ +// This file is part of arduino-cloud-cli. +// +// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dashboard + +import ( + "github.com/arduino/arduino-cloud-cli/internal/config" + "github.com/arduino/arduino-cloud-cli/internal/iot" +) + +// List command is used to list +// the dashboards of Arduino IoT Cloud. +func List() ([]DashboardInfo, error) { + conf, err := config.Retrieve() + if err != nil { + return nil, err + } + iotClient, err := iot.NewClient(conf.Client, conf.Secret) + if err != nil { + return nil, err + } + + foundDashboards, err := iotClient.DashboardList() + if err != nil { + return nil, err + } + + var dashboards []DashboardInfo + for _, found := range foundDashboards { + info := getDashboardInfo(&found) + dashboards = append(dashboards, *info) + } + + return dashboards, nil +} diff --git a/internal/iot/client.go b/internal/iot/client.go index 831feae6..e63808c5 100644 --- a/internal/iot/client.go +++ b/internal/iot/client.go @@ -39,6 +39,7 @@ type Client interface { ThingDelete(id string) error ThingShow(id string) (*iotclient.ArduinoThing, error) ThingList(ids []string, device *string, props bool) ([]iotclient.ArduinoThing, error) + DashboardList() ([]iotclient.ArduinoDashboardv2, error) } type client struct { @@ -202,6 +203,16 @@ func (cl *client) ThingList(ids []string, device *string, props bool) ([]iotclie return things, nil } +// DashboardList returns a list of dashboards on Arduino IoT Cloud. +func (cl *client) DashboardList() ([]iotclient.ArduinoDashboardv2, error) { + dashboards, _, err := cl.api.DashboardsV2Api.DashboardsV2List(cl.ctx, nil) + if err != nil { + err = fmt.Errorf("listing dashboards: %w", errorDetail(err)) + return nil, err + } + return dashboards, nil +} + func (cl *client) setup(client, secret string) error { // Get the access token in exchange of client_id and client_secret tok, err := token(client, secret) From 699fb258babe1ab42febab5149a2bdfdf7913545 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 11 Oct 2021 16:37:01 +0200 Subject: [PATCH 3/8] Update readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index c5177458..96a77c11 100644 --- a/README.md +++ b/README.md @@ -118,3 +118,9 @@ The default OTA upload should complete in 10 minutes. Use `--deferred` flag to e `$ arduino-cloud-cli ota upload --device-id --file ` `$ arduino-cloud-cli ota upload --device-id --file --deferred` + +## Dashboard commands + +Print a list of available dashboards and their share information by using this command: + +`$ arduino-cloud-cli dashboard list --show-sharing` \ No newline at end of file From b453e0b0d98500ffcaf173d9ab5246ad159dfae6 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 11 Oct 2021 16:45:37 +0200 Subject: [PATCH 4/8] Fix - print UpdatedAt string --- cli/dashboard/list.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/dashboard/list.go b/cli/dashboard/list.go index 070b404c..06b289d2 100644 --- a/cli/dashboard/list.go +++ b/cli/dashboard/list.go @@ -80,6 +80,7 @@ func (r listResult) String() string { for _, dash := range r.dashboards { row := []interface{}{dash.Name, dash.ID} row = append(row, strings.Join(dash.Widgets, ", ")) + row = append(row, dash.UpdatedAt) if listFlags.showSharing { row = append(row, dash.SharedBy) row = append(row, strings.Join(dash.SharedWith, ", ")) From 972676a0c9a8105a138d4c33765d6b37c8ed5a55 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 11 Oct 2021 18:58:32 +0200 Subject: [PATCH 5/8] Limit number of widgets per row --- cli/dashboard/list.go | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/cli/dashboard/list.go b/cli/dashboard/list.go index 06b289d2..20ce940d 100644 --- a/cli/dashboard/list.go +++ b/cli/dashboard/list.go @@ -18,6 +18,7 @@ package dashboard import ( + "math" "os" "strings" @@ -29,6 +30,10 @@ import ( "github.com/spf13/cobra" ) +const ( + widgetsPerRow = 3 +) + var listFlags struct { showSharing bool } @@ -72,20 +77,31 @@ func (r listResult) String() string { t := table.New() head := []interface{}{"Name", "ID", "Widgets", "UpdatedAt"} - if listFlags.showSharing { - head = append(head, "SharedBy", "SharedWith") - } t.SetHeader(head...) for _, dash := range r.dashboards { row := []interface{}{dash.Name, dash.ID} - row = append(row, strings.Join(dash.Widgets, ", ")) - row = append(row, dash.UpdatedAt) - if listFlags.showSharing { - row = append(row, dash.SharedBy) - row = append(row, strings.Join(dash.SharedWith, ", ")) + + // Limit number of widgets per row. + if len(dash.Widgets) > widgetsPerRow { + row = append(row, strings.Join(dash.Widgets[:widgetsPerRow], ", ")) + dash.Widgets = dash.Widgets[widgetsPerRow:] + } else { + row = append(row, strings.Join(dash.Widgets, ", ")) + dash.Widgets = nil } + row = append(row, dash.UpdatedAt) t.AddRow(row...) + + // Print remaining widgets in new rows + for len(dash.Widgets) > 0 { + row := []interface{}{"", ""} + l := int(math.Min(float64(len(dash.Widgets)), widgetsPerRow)) + row = append(row, strings.Join(dash.Widgets[:l], ", ")) + dash.Widgets = dash.Widgets[l:] + row = append(row, "") + t.AddRow(row...) + } } return t.Render() } From db1eebb0a5aecd187e158c0decc190be9c462ff8 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 11 Oct 2021 19:08:32 +0200 Subject: [PATCH 6/8] Add flag to show widgets --- cli/dashboard/list.go | 45 ++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/cli/dashboard/list.go b/cli/dashboard/list.go index 20ce940d..f68abae6 100644 --- a/cli/dashboard/list.go +++ b/cli/dashboard/list.go @@ -35,7 +35,7 @@ const ( ) var listFlags struct { - showSharing bool + showWidgets bool } func initListCommand() *cobra.Command { @@ -46,7 +46,7 @@ func initListCommand() *cobra.Command { Run: runListCommand, } - listCommand.Flags().BoolVarP(&listFlags.showSharing, "show-sharing", "s", false, "Show dashboard sharing information") + listCommand.Flags().BoolVarP(&listFlags.showWidgets, "show-widgets", "s", false, "Show names of dashboard widgets") return listCommand } @@ -76,31 +76,36 @@ func (r listResult) String() string { } t := table.New() - head := []interface{}{"Name", "ID", "Widgets", "UpdatedAt"} + head := []interface{}{"Name", "ID", "UpdatedAt"} + if listFlags.showWidgets { + head = append(head, "Widgets") + } t.SetHeader(head...) for _, dash := range r.dashboards { - row := []interface{}{dash.Name, dash.ID} - - // Limit number of widgets per row. - if len(dash.Widgets) > widgetsPerRow { - row = append(row, strings.Join(dash.Widgets[:widgetsPerRow], ", ")) - dash.Widgets = dash.Widgets[widgetsPerRow:] - } else { - row = append(row, strings.Join(dash.Widgets, ", ")) - dash.Widgets = nil + row := []interface{}{dash.Name, dash.ID, dash.UpdatedAt} + + if listFlags.showWidgets { + // Limit number of widgets per row. + if len(dash.Widgets) > widgetsPerRow { + row = append(row, strings.Join(dash.Widgets[:widgetsPerRow], ", ")) + dash.Widgets = dash.Widgets[widgetsPerRow:] + } else { + row = append(row, strings.Join(dash.Widgets, ", ")) + dash.Widgets = nil + } } - row = append(row, dash.UpdatedAt) t.AddRow(row...) // Print remaining widgets in new rows - for len(dash.Widgets) > 0 { - row := []interface{}{"", ""} - l := int(math.Min(float64(len(dash.Widgets)), widgetsPerRow)) - row = append(row, strings.Join(dash.Widgets[:l], ", ")) - dash.Widgets = dash.Widgets[l:] - row = append(row, "") - t.AddRow(row...) + if listFlags.showWidgets { + for len(dash.Widgets) > 0 { + row := []interface{}{"", "", ""} + l := int(math.Min(float64(len(dash.Widgets)), widgetsPerRow)) + row = append(row, strings.Join(dash.Widgets[:l], ", ")) + dash.Widgets = dash.Widgets[l:] + t.AddRow(row...) + } } } return t.Render() From 71113a22621d81f36d2cd52aaae7113b44bdc886 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Tue, 12 Oct 2021 09:58:25 +0200 Subject: [PATCH 7/8] Remove share details --- command/dashboard/dashboard.go | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/command/dashboard/dashboard.go b/command/dashboard/dashboard.go index a1a43687..b1da267b 100644 --- a/command/dashboard/dashboard.go +++ b/command/dashboard/dashboard.go @@ -17,35 +17,29 @@ package dashboard -import iotclient "github.com/arduino/iot-client-go" +import ( + iotclient "github.com/arduino/iot-client-go" +) // DashboardInfo contains the most interesting // information, in string format, of an Arduino IoT Cloud dashboard. type DashboardInfo struct { - Name string `json:"name"` - ID string `json:"id"` - SharedBy string `json:"shared_by"` - SharedWith []string `json:"shared_with"` - UpdatedAt string `json:"updated_at"` - Widgets []string `json:"widgets"` + Name string `json:"name"` + ID string `json:"id"` + UpdatedAt string `json:"updated_at"` + Widgets []string `json:"widgets"` } func getDashboardInfo(dashboard *iotclient.ArduinoDashboardv2) *DashboardInfo { - var shares []string - for _, s := range dashboard.SharedWith { - shares = append(shares, s.Username) - } var widgets []string for _, w := range dashboard.Widgets { widgets = append(widgets, w.Name) } info := &DashboardInfo{ - Name: dashboard.Name, - ID: dashboard.Id, - SharedBy: dashboard.SharedBy.Username, - SharedWith: shares, - UpdatedAt: dashboard.UpdatedAt.String(), - Widgets: widgets, + Name: dashboard.Name, + ID: dashboard.Id, + UpdatedAt: dashboard.UpdatedAt.String(), + Widgets: widgets, } return info } From cecf96ced3027711bae70094040238952916206a Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Tue, 12 Oct 2021 10:04:52 +0200 Subject: [PATCH 8/8] Update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 96a77c11..42f8598b 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,6 @@ The default OTA upload should complete in 10 minutes. Use `--deferred` flag to e ## Dashboard commands -Print a list of available dashboards and their share information by using this command: +Print a list of available dashboards and their widgets by using this command: -`$ arduino-cloud-cli dashboard list --show-sharing` \ No newline at end of file +`$ arduino-cloud-cli dashboard list --show-widgets` \ No newline at end of file