Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/auth/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var loginCmd = &cobra.Command{
ctx := cmd.Context()
api := keys.GetAPIInstance(ctx)

resume := terminal.Blocked("auth", "Log in to Unsplash in your browser")
fmt.Println("Please visit the following URL to login:")
authenticationURL := api.BuildAuthenticationUrl(
"read_user",
Expand All @@ -53,6 +54,7 @@ var loginCmd = &cobra.Command{
sp.Suffix = " Authenticating..."

code := <-codeChan
resume()
res, err := api.Authenticate(code)
if err != nil {
sp.FinalMSG = "An error occured while authenticating\n"
Expand All @@ -68,8 +70,6 @@ var loginCmd = &cobra.Command{
tokens.SetRefreshToken(res.RefreshToken)

logrus.Debug("writing config")
cobra.CheckErr(viper.WriteConfig())

if err := viper.WriteConfig(); err != nil {
logrus.WithField("error", err).Error("Error while saving config")

Expand Down
18 changes: 14 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"context"
"errors"
"fmt"
"os"
"time"
Expand Down Expand Up @@ -119,7 +120,10 @@ var rootCmd = &cobra.Command{
}

confirm := true
if err := survey.AskOne(prompt, &confirm); err != nil {
resume := terminal.Blocked("permission", prompt.Message)
err := survey.AskOne(prompt, &confirm)
resume()
if err != nil {
return
}

Expand Down Expand Up @@ -201,9 +205,6 @@ var rootCmd = &cobra.Command{
cobra.CheckErr(err)
}

if err = viper.WriteConfig(); err != nil {
handleSpinnerError(err, connectionSpinner, cmd, ConnectionSpinnerSuffix[2])
}
}

handleSpinnerError(err, connectionSpinner, cmd, ConnectionSpinnerSuffix[1])
Expand Down Expand Up @@ -236,6 +237,11 @@ var rootCmd = &cobra.Command{
}
}

if photo == nil {
connectionSpinner.Stop()
cobra.CheckErr(errors.New("no photos found"))
}

connectionSpinner.FinalMSG = ConnectionSpinnerSuffix[2]
connectionSpinner.Stop()

Expand Down Expand Up @@ -290,7 +296,9 @@ var rootCmd = &cobra.Command{
fmt.Println("")

var key keyboard.Key
resume := terminal.Blocked("permission", "Download failed. Set wallpaper from the URL?")
_, key, err = keyboard.GetSingleKey()
resume()
if err != nil {
eventID := sentry.CaptureException(err)
log.Fatal().Any("event_id", eventID).Err(err).Send()
Expand Down Expand Up @@ -372,10 +380,12 @@ var rootCmd = &cobra.Command{

shouldLike := false

resume := terminal.Blocked("question", "Do you like this photo?")
err := survey.AskOne(&survey.Confirm{
Default: false,
Message: "Do you like this photo?",
}, &shouldLike)
resume()
cobra.CheckErr(err)

if shouldLike {
Expand Down
48 changes: 48 additions & 0 deletions lib/terminal/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package terminal

import (
"encoding/base64"
"fmt"
"os"
)

// Blocked reports (OSC 7501, Program Status Protocol) that the program is
// waiting for user input. The returned func reports it is working again.
//
// Reports are best-effort and only sent to interactive terminals; terminals
// that don't support the protocol ignore the sequence.
//
// defer terminal.Blocked("question", "Do you like this photo?")()
func Blocked(kind, message string) (resume func()) {
report("blocked", kind, message)
return func() { report("working", "", "") }
}

func report(state, kind, message string) {
if !isInteractive() {
return
}

body := "state=" + state + ":app=splash-cli"
if kind != "" {
body += ":kind=" + kind
}
if message != "" {
body += ":msg=" + base64.StdEncoding.EncodeToString([]byte(truncate(message)))
}

fmt.Fprint(os.Stdout, "\x1b]7501;"+body+"\x1b\\")
}

func isInteractive() bool {
info, err := os.Stdout.Stat()
return err == nil && info.Mode()&os.ModeCharDevice != 0 && os.Getenv("TERM") != "dumb"
Comment on lines +38 to +39
}

// messages are limited to 2048 bytes
func truncate(s string) string {
if len(s) <= 2048 {
return s
}
return s[:2048]
}
23 changes: 23 additions & 0 deletions lib/terminal/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package terminal

import (
"encoding/base64"
"strings"
"testing"
)

func TestTruncate(t *testing.T) {
if got := truncate(strings.Repeat("a", 3000)); len(got) != 2048 {
t.Fatalf("len = %d, want 2048", len(got))
}
if got := truncate("hi"); got != "hi" {
t.Fatalf("got %q", got)
}
}

func TestMessageEncoding(t *testing.T) {
enc := base64.StdEncoding.EncodeToString([]byte("Do you like this photo?"))
if enc != "RG8geW91IGxpa2UgdGhpcyBwaG90bz8=" {
t.Fatalf("unexpected encoding %s", enc)
}
}
Loading