diff --git a/cmd/test copy.go b/cmd/test copy.go index 06cbd0d..54a02bb 100644 --- a/cmd/test copy.go +++ b/cmd/test copy.go @@ -1,24 +1,18 @@ package cmd -import ( - "rioctl/internal/ui" +// var test2CMD = &cobra.Command{ +// Use: "test2", +// Short: "test operations", +// Args: cobra.ArbitraryArgs, +// RunE: func(cmd *cobra.Command, args []string) error { - "github.com/spf13/cobra" -) +// allFiles := []string{"asdf", "asdf"} +// _, err := ui.RunFilePicker(allFiles) +// return err +// }, +// } -var test2CMD = &cobra.Command{ - Use: "test2", - Short: "test operations", - Args: cobra.ArbitraryArgs, - RunE: func(cmd *cobra.Command, args []string) error { +// func init() { - allFiles := []string{"asdf", "asdf"} - _, err := ui.RunFilePicker(allFiles) - return err - }, -} - -func init() { - - rootCmd.AddCommand(test2CMD) -} +// rootCmd.AddCommand(test2CMD) +// } diff --git a/go.mod b/go.mod index 555a3ed..59e9868 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,18 @@ module rioctl go 1.26.1 require ( - charm.land/bubbles/v2 v2.1.0 // indirect - charm.land/bubbletea/v2 v2.0.2 // indirect - charm.land/lipgloss/v2 v2.0.2 // indirect + charm.land/bubbles/v2 v2.1.0 + charm.land/bubbletea/v2 v2.0.2 + charm.land/lipgloss/v2 v2.0.2 + github.com/charmbracelet/bubbles v1.0.0 + github.com/charmbracelet/bubbletea v1.3.10 + github.com/melbahja/goph v1.5.0 + github.com/spf13/cobra v1.10.2 +) + +require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/bubbles v1.0.0 // indirect - github.com/charmbracelet/bubbletea v1.3.10 // indirect github.com/charmbracelet/colorprofile v0.4.2 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect @@ -29,7 +34,6 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.21 // indirect - github.com/melbahja/goph v1.5.0 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect @@ -37,7 +41,6 @@ require ( github.com/pkg/sftp v1.13.10 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/sahilm/fuzzy v0.1.1 // indirect - github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.9 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/crypto v0.49.0 // indirect diff --git a/internal/sshclient/client.go b/internal/sshclient/client.go index c249ba7..bcdc974 100644 --- a/internal/sshclient/client.go +++ b/internal/sshclient/client.go @@ -2,6 +2,8 @@ package sshclient import ( "fmt" + "rioctl/internal/utils" + "slices" "strconv" "strings" @@ -36,22 +38,23 @@ func (c *Client) Close() error { return c.client.Close() } -func (c *Client) ListFiles(dir string) ([]string, error) { - out, err := c.Run(fmt.Sprintf("find %s -type f -name '*.wpilog'", dir)) +func (c *Client) ListFiles(dir string) ([]utils.File, error) { + out, err := c.Run(fmt.Sprintf("ls -lh %s | grep .wpilog | awk '{ print $5\",\"$9 }'", dir)) if err != nil { return nil, err } lines := strings.Split(out, "\n") - var files []string + var files []utils.File for _, l := range lines { if l == "" { continue } - files = append(files, strings.TrimPrefix(l, dir+"/")) + stringArr := strings.Split(l, ",") + files = append(files, utils.File{Name: stringArr[1], Size: stringArr[0]}) } - + slices.Reverse(files) return files, nil } diff --git a/internal/transfer/scp.go b/internal/transfer/scp.go index a8a4bc3..6137d7b 100644 --- a/internal/transfer/scp.go +++ b/internal/transfer/scp.go @@ -12,24 +12,24 @@ import ( func PullFiles(client *sshclient.Client, remoteBase, localBase string, files []string) error { finishedChan := make(chan int) - currentChan := make(chan utils.File) + currentChan := make(chan utils.FileUpload) go func() { for i, file := range files { - remotePath := filepath.Join(remoteBase, file) + remotePath := filepath.ToSlash(filepath.Join(remoteBase, file)) localPath := filepath.Join(localBase, file) if err := os.MkdirAll(filepath.Dir(localPath), 0755); err != nil { - // continue + // fmt.Print(err) } err := os.Remove(localPath) if err != nil { - // + // fmt.Print(err) } totalSize, err := client.FileSize(remotePath) if err != nil { - // + // fmt.Print(err) } file := utils.NewFile(totalSize, 0, file) currentChan <- file @@ -50,8 +50,7 @@ func PullFiles(client *sshclient.Client, remoteBase, localBase string, files []s // goph SCP download err = client.Raw().Download(remotePath, localPath) if err != nil { - // fmt.Printf("failed to download %s: %w", file, err) - // continue + // fmt.Print(err) } finishedChan <- i + 1 diff --git a/internal/ui/filepicker.go b/internal/ui/filepicker.go index f3a5a8a..adab305 100644 --- a/internal/ui/filepicker.go +++ b/internal/ui/filepicker.go @@ -3,6 +3,7 @@ package ui import ( "fmt" "os" + "rioctl/internal/utils" "charm.land/bubbles/v2/list" tea "charm.land/bubbletea/v2" @@ -15,6 +16,7 @@ var defaultDelegate = list.NewDefaultDelegate() type item struct { title string + size string selected bool } @@ -26,18 +28,14 @@ func (i item) Title() string { // return i.title } func (i item) Description() string { - // if i.selected { - // return "[x]" - // } - // return "[ ]" - return "" + return " " + i.size } func (i item) FilterValue() string { return i.title } type model struct { list list.Model - choices []item + choices []*item quitting bool } @@ -58,6 +56,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "ctrl+c", "q": m.quitting = true + m.choices = []*item{} return m, tea.Quit case "enter": @@ -68,18 +67,15 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, tea.Quit case "space": - i := m.list.Index() - m.choices[i].selected = !m.choices[i].selected + f, ok := m.list.SelectedItem().(*item) + if ok { + f.selected = !f.selected + } } case tea.WindowSizeMsg: h, v := docStyle.GetFrameSize() m.list.SetSize(msg.Width-h, msg.Height-v) } - interfaces := make([]list.Item, len(m.choices)) - for i, v := range m.choices { - interfaces[i] = v - } - m.list.SetItems(interfaces) var cmd tea.Cmd m.list, cmd = m.list.Update(msg) return m, cmd @@ -102,17 +98,17 @@ func (m model) Selected() []string { return out } -func NewFilePicker(files []string) model { +func NewFilePicker(files []utils.File) model { items := make([]list.Item, len(files)) - choices := make([]item, len(files)) + choices := make([]*item, len(files)) for i, f := range files { - it := item{title: f} + it := &item{title: f.Name, size: f.Size} items[i] = it choices[i] = it } - defaultDelegate.ShowDescription = false + // defaultDelegate.ShowDescription = false l := list.New(items, defaultDelegate, 0, 0) l.Title = "Select log files (space to toggle, enter to confirm)" @@ -122,7 +118,7 @@ func NewFilePicker(files []string) model { } } -func RunFilePicker(files []string) ([]string, error) { +func RunFilePicker(files []utils.File) ([]string, error) { m := NewFilePicker(files) p := tea.NewProgram(m) diff --git a/internal/ui/progress.go b/internal/ui/progress.go index c2b86e4..7e86df6 100644 --- a/internal/ui/progress.go +++ b/internal/ui/progress.go @@ -62,7 +62,7 @@ func (m progressModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.done = true return m, tea.Quit } - case utils.File: + case utils.FileUpload: m.currentFileBytes = msg.Current m.totalFileBytes = msg.Size m.currentFile = msg.Name @@ -94,7 +94,7 @@ func (m progressModel) View() tea.View { pad + helpStyle(fmt.Sprintf("%s / %s", humanize(m.currentFileBytes), humanize((m.totalFileBytes))))) } -func RunProgress(total int, current <-chan utils.File, finished <-chan int) { +func RunProgress(total int, current <-chan utils.FileUpload, finished <-chan int) { m := NewProgress(total) p := tea.NewProgram(m) diff --git a/internal/utils/file.go b/internal/utils/file.go index 13a3c63..6a3b133 100644 --- a/internal/utils/file.go +++ b/internal/utils/file.go @@ -1,20 +1,25 @@ package utils -type File struct { +type FileUpload struct { Size int64 Current int64 Name string } -func (m File) UpdateCurrent(current int64) File { +func (m FileUpload) UpdateCurrent(current int64) FileUpload { m.Current = current return m } -func NewFile(size int64, current int64, name string) File { - return File{ +func NewFile(size int64, current int64, name string) FileUpload { + return FileUpload{ Name: name, Current: current, Size: size, } } + +type File struct { + Size string + Name string +}