From: Adam Shamblin Date: Tue, 27 Dec 2022 00:32:46 +0000 (-0700) Subject: cleanup X-Git-Url: https://git.vexinglabs.com/?a=commitdiff_plain;h=55e7f269c153242a56d0057ed9e34040f39a466b;p=dead-tooter.git cleanup --- diff --git a/cmd/account.go b/cmd/account.go index 963c8ee..538e1d6 100644 --- a/cmd/account.go +++ b/cmd/account.go @@ -2,6 +2,9 @@ package tooter import ( "fmt" + "os" + "strings" + "text/tabwriter" "git.vexingworkshop.com/signal9/dead-tooter/pkg/mastodon" "github.com/spf13/cobra" @@ -31,7 +34,8 @@ var getAccountCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := account.VerifyCredentials(host, token) if err != nil { - panic(err.Error()) + fmt.Printf("Error verifying credentials: %s", err.Error()) + return } if len(args) < 1 { @@ -65,9 +69,12 @@ var getFollowersCmd = &cobra.Command{ if err != nil { panic(err.Error()) } + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) for _, value := range followers { - fmt.Printf("%s\t%s\n", value.ID, value.Acct) + fmt.Fprintln(w, strings.Join([]string{value.ID, value.Acct}, "\t")) } + w.Flush() }, } @@ -88,8 +95,11 @@ var getFollowingCmd = &cobra.Command{ if err != nil { panic(err.Error()) } + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) for _, value := range following { - fmt.Printf("%s\t%s\n", value.ID, value.Acct) + fmt.Fprintln(w, strings.Join([]string{value.ID, value.Acct}, "\t")) } + w.Flush() }, } diff --git a/cmd/login.go b/cmd/login.go index 32f3078..2333c06 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -42,7 +42,11 @@ func login() { } var account mastodon.Account - code := account.Authorize(host, app) + code, err := account.Authorize(host, app) + if err != nil { + fmt.Printf("Failed to authorize account: %s\n", err.Error()) + } + token, err = account.RequestToken(host, app, code) if err != nil { fmt.Printf("Failed to acquire request token: %s\n", err.Error()) diff --git a/cmd/root.go b/cmd/root.go index 94b50b7..0eefac7 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,7 +14,7 @@ var token mastodon.Token func init() { rootCmd.PersistentFlags().StringVarP(&host, "host", "H", "", "Mastodon host where your account lives.") - rootCmd.MarkFlagRequired("host") + rootCmd.MarkPersistentFlagRequired("host") } @@ -28,7 +28,7 @@ be present in the Mastodon web UI.`, var err error token, err = mastodon.LoadToken() if err != nil { - fmt.Println("No authentication token found.\nYou must login before performing futher commands.") + fmt.Println("No authentication token found.") } }, diff --git a/pkg/mastodon/account.go b/pkg/mastodon/account.go index 75cbf9b..503c761 100644 --- a/pkg/mastodon/account.go +++ b/pkg/mastodon/account.go @@ -62,7 +62,7 @@ type Emoji struct { // Authorize opens the default browser to initiate the authorization flow // for the current user. -func (a *Account) Authorize(host string, app Application) (code string) { +func (a *Account) Authorize(host string, app Application) (code string, err error) { v := url.Values{} v.Set("client_id", app.ClientID) v.Set("response_type", "code") @@ -75,18 +75,18 @@ func (a *Account) Authorize(host string, app Application) (code string) { } u.Scheme = "https" - err := exec.Command("xdg-open", u.String()).Start() + err = exec.Command("xdg-open", u.String()).Start() if err != nil { - return + return code, err } fmt.Print("Enter returned code: ") _, err = fmt.Scanln(&code) if err != nil { - return + return code, err } - return + return code, err } // RequestToken takes the provided authorization code and returns a structure @@ -110,77 +110,57 @@ func (a *Account) RequestToken( resp, err := http.PostForm(u.String(), v) if err != nil { - return + return token, err } if resp.StatusCode != 200 { err = errors.New(resp.Status) - return + return token, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - return + return token, err } err = json.Unmarshal(body, &token) if err != nil { - return + return token, err } - return + return token, err } // VerifyCredentials hydrates the account object by validating the bearer token // against the Mastodon API func (a *Account) VerifyCredentials(host string, token Token) (err error) { - client := &http.Client{} - u := url.URL{ Host: host, Path: "api/v1/accounts/verify_credentials", } u.Scheme = "https" - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return - } - req.Header.Add("Authorization", "Bearer "+token.AccessToken) - - resp, err := client.Do(req) - if err != nil { - return - } - if resp.StatusCode != 200 { - err = errors.New(resp.Status) - return - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) + body, err := Get(u, host, token) if err != nil { - return + return err } err = json.Unmarshal(body, a) if err != nil { - return + return err } - return + return err } // Get returns the details of account specified by ID. func (a *Account) Get( ID string, host string, token Token) (account Account, err error) { - client := &http.Client{} - id := url.PathEscape(ID) path, err := url.JoinPath("api/v1/accounts", id) if err != nil { - return + return account, err } u := url.URL{ @@ -189,45 +169,27 @@ func (a *Account) Get( } u.Scheme = "https" - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return - } - req.Header.Add("Authorization", "Bearer "+token.AccessToken) - - resp, err := client.Do(req) - if err != nil { - return - } - if resp.StatusCode != 200 { - err = errors.New(resp.Status) - return - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) + body, err := Get(u, host, token) if err != nil { - return + return account, err } err = json.Unmarshal(body, &account) if err != nil { - return + return account, err } - return + return account, err } // GetFollowers returns a list of all accounts following the logged in user func (a *Account) GetFollowers( host string, token Token) (followers []Account, err error) { - client := &http.Client{} - id := url.PathEscape(a.ID) path, err := url.JoinPath("api/v1/accounts", id, "followers") if err != nil { - return + return followers, err } u := url.URL{ @@ -236,33 +198,17 @@ func (a *Account) GetFollowers( } u.Scheme = "https" - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return - } - req.Header.Add("Authorization", "Bearer "+token.AccessToken) - - resp, err := client.Do(req) - if err != nil { - return - } - if resp.StatusCode != 200 { - err = errors.New(resp.Status) - return - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) + body, err := Get(u, host, token) if err != nil { - return + return followers, err } err = json.Unmarshal(body, &followers) if err != nil { - return + return followers, err } - return + return followers, err } // GetFollowing returns a list of all accounts followed by the logged in user @@ -274,7 +220,7 @@ func (a *Account) GetFollowing( id := url.PathEscape(a.ID) path, err := url.JoinPath("api/v1/accounts", id, "following") if err != nil { - return + return following, err } u := url.URL{ @@ -285,29 +231,29 @@ func (a *Account) GetFollowing( req, err := http.NewRequest("GET", u.String(), nil) if err != nil { - return + return following, err } req.Header.Add("Authorization", "Bearer "+token.AccessToken) resp, err := client.Do(req) if err != nil { - return + return following, err } if resp.StatusCode != 200 { err = errors.New(resp.Status) - return + return following, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - return + return following, err } err = json.Unmarshal(body, &following) if err != nil { - return + return following, err } - return + return following, err } diff --git a/pkg/mastodon/api.go b/pkg/mastodon/api.go new file mode 100644 index 0000000..feb6d8c --- /dev/null +++ b/pkg/mastodon/api.go @@ -0,0 +1,36 @@ +package mastodon + +import ( + "errors" + "io" + "net/http" + "net/url" +) + +// Get provides a request +func Get(u url.URL, host string, token Token) (body []byte, err error) { + client := &http.Client{} + + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + return + } + req.Header.Add("Authorization", "Bearer "+token.AccessToken) + + resp, err := client.Do(req) + if err != nil { + return + } + if resp.StatusCode != 200 { + err = errors.New(resp.Status) + return + } + defer resp.Body.Close() + + body, err = io.ReadAll(resp.Body) + if err != nil { + return + } + + return +}