diff --git a/go.mod b/go.mod index 7aaa61d..9271423 100644 --- a/go.mod +++ b/go.mod @@ -10,10 +10,10 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/klauspost/compress v1.17.9 github.com/lucasb-eyer/go-colorful v1.2.0 - github.com/mattn/go-runewidth v0.0.15 + github.com/mattn/go-runewidth v0.0.16 github.com/ncruces/zenity v0.10.13 github.com/stretchr/testify v1.8.4 - github.com/trzsz/go-arg v1.5.3 + github.com/trzsz/go-arg v1.5.4 github.com/trzsz/promptui v0.10.7 golang.org/x/sys v0.22.0 golang.org/x/term v0.22.0 diff --git a/go.sum b/go.sum index b40a835..3378c8d 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,9 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/ncruces/zenity v0.10.13 h1:0Gd/EdjjEQIhrFaJ05Q5ZvyjlcjnorlZpdzgUzqQIH0= @@ -54,8 +55,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/trzsz/go-arg v1.5.3 h1:eIDwDEmvSahtr5HpQOLrSa+YMqWQQ0H20xx60XgXQJw= -github.com/trzsz/go-arg v1.5.3/go.mod h1:IC6Z/FiVH7uYvcbp1/gJhDYCFPS/GkL0APYakVvgY4I= +github.com/trzsz/go-arg v1.5.4 h1:8cuwV8F1UvlKRXJcdLG1cSZNGXkRped+U1rz17M7Kac= +github.com/trzsz/go-arg v1.5.4/go.mod h1:IC6Z/FiVH7uYvcbp1/gJhDYCFPS/GkL0APYakVvgY4I= github.com/trzsz/promptui v0.10.7 h1:77uBrmsIPYYJS/9n+zwFRhwOz82EKXkkdjOiWSEUPpk= github.com/trzsz/promptui v0.10.7/go.mod h1:9dp59ixe32qBV9GjDxQ1PDWwbzHjTzveZenQwEoVHbg= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= diff --git a/trzsz/filter.go b/trzsz/filter.go index c7188b1..cf42844 100644 --- a/trzsz/filter.go +++ b/trzsz/filter.go @@ -90,6 +90,9 @@ type TrzszFilter struct { tunnelConnector atomic.Pointer[func(int) net.Conn] osc52Sequence *bytes.Buffer progressColorPair atomic.Pointer[string] + oneTimeUploadFiles []string + oneTimeUploadResult chan error + hidingCursor bool } // NewTrzszFilter create a TrzszFilter to support trzsz ( trz / tsz ). @@ -166,6 +169,40 @@ func (filter *TrzszFilter) UploadFiles(filePaths []string) error { return nil } +// OneTimeUpload upload one time while the server is already running trz / rz. +func (filter *TrzszFilter) OneTimeUpload(filePaths []string) (<-chan error, error) { + if len(filePaths) == 0 { + return nil, fmt.Errorf("nothing to upload") + } + for _, path := range filePaths { + info, err := os.Stat(path) + if err != nil { + return nil, err + } + if _, err := checkPathsReadable([]string{path}, info.IsDir()); err != nil { + return nil, err + } + } + filter.oneTimeUploadFiles = filePaths + filter.oneTimeUploadResult = make(chan error, 1) + go func() { + time.Sleep(10 * time.Second) + if filter.oneTimeUploadFiles != nil { + filter.oneTimeUploadResult <- fmt.Errorf( + "The upload did not start, possibly because trzsz is not installed or trz is not found on the server") + } + }() + return filter.oneTimeUploadResult, nil +} + +// ResetTerminal reset the terminal settings. +func (filter *TrzszFilter) ResetTerminal() { + if filter.hidingCursor { + showCursor(filter.clientOut) + filter.hidingCursor = false + } +} + // SetDefaultUploadPath set the default open path while choosing upload files. func (filter *TrzszFilter) SetDefaultUploadPath(path string) { if path == "" { @@ -315,6 +352,11 @@ func (filter *TrzszFilter) chooseDownloadPath() (string, error) { } func (filter *TrzszFilter) chooseUploadPaths(directory bool) ([]string, error) { + if len(filter.oneTimeUploadFiles) > 0 { + files := filter.oneTimeUploadFiles + filter.oneTimeUploadFiles = nil + return files, nil + } if filter.dragging.Load() { files := filter.resetDragFiles() return files, nil @@ -465,8 +507,10 @@ func (filter *TrzszFilter) handleTrzsz() { err = filter.downloadFiles(transfer) case 'R': err = filter.uploadFiles(transfer, false) + filter.setOneTimeUploadResult(err) case 'D': err = filter.uploadFiles(transfer, true) + filter.setOneTimeUploadResult(err) } if err != nil { transfer.clientError(err) @@ -481,6 +525,15 @@ func (filter *TrzszFilter) handleTrzsz() { } } +func (filter *TrzszFilter) setOneTimeUploadResult(err error) { + if filter.oneTimeUploadResult == nil { + return + } + filter.oneTimeUploadResult <- err + close(filter.oneTimeUploadResult) + filter.oneTimeUploadResult = nil +} + func (filter *TrzszFilter) resetDragFiles() []string { if !filter.dragging.Load() { return nil @@ -742,6 +795,7 @@ func (filter *TrzszFilter) wrapOutput() { continue } else { showCursor(filter.clientOut) + filter.hidingCursor = false filter.zmodem.CompareAndSwap(zmodem, nil) } } @@ -775,11 +829,20 @@ func (filter *TrzszFilter) wrapOutput() { _ = writeAll(filter.clientOut, buf) if filter.zmodem.CompareAndSwap(nil, zmodem) { hideCursor(filter.clientOut) + filter.hidingCursor = true go zmodem.handleZmodemEvent(filter.logger, filter.serverIn, filter.clientOut, func() ([]string, error) { return filter.chooseUploadPaths(false) }, filter.chooseDownloadPath) + if filter.oneTimeUploadResult != nil { + go func() { + for zmodem.isTransferringFiles() { + time.Sleep(100 * time.Millisecond) + } + filter.setOneTimeUploadResult(nil) + }() + } continue } } @@ -788,6 +851,7 @@ func (filter *TrzszFilter) wrapOutput() { _ = writeAll(filter.clientOut, buf) } if err == io.EOF { + time.Sleep(100 * time.Millisecond) continue // ignore output EOF } }