func init() {
accountCmd.AddCommand(getFollowersCmd)
+ accountCmd.AddCommand(getFollowingCmd)
rootCmd.AddCommand(accountCmd)
}
Use: "account",
Short: "Account commands",
Long: "Commands related to the logged in Mastodon account.",
- Run: func(cmd *cobra.Command, args []string) {
- },
}
var getFollowersCmd = &cobra.Command{
}
},
}
+
+var getFollowingCmd = &cobra.Command{
+ Use: "following",
+ Short: "Get accounts followed",
+ Long: "Get a list of followed accounts for the current account.",
+
+ PreRun: func(cmd *cobra.Command, args []string) {
+ err := account.VerifyCredentials(host, token)
+ if err != nil {
+ panic(err.Error())
+ }
+ },
+
+ Run: func(cmd *cobra.Command, args []string) {
+ following, err := account.GetFollowing(host, token)
+ if err != nil {
+ panic(err.Error())
+ }
+ for _, value := range following {
+ fmt.Printf("%s\t%s\n", value.ID, value.Acct)
+ }
+ },
+}
return
}
+
+// GetFollowing returns a list of all accounts followed by the logged in user
+func (a *Account) GetFollowing(
+ host string, token Token) (following []Account, err error) {
+
+ client := &http.Client{}
+
+ id := url.PathEscape(a.ID)
+ path, err := url.JoinPath("api/v1/accounts", id, "following")
+ if err != nil {
+ return
+ }
+
+ u := url.URL{
+ Host: host,
+ Path: path,
+ }
+ 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)
+ if err != nil {
+ return
+ }
+
+ err = json.Unmarshal(body, &following)
+ if err != nil {
+ return
+ }
+
+ return
+}
"net/http"
"net/url"
"os"
+ "path/filepath"
)
-const ConfigDir = "foodir/"
+// ConfigDir points to the default location of serialized files,
+// such as application info and tokens
+const ConfigDir = ".dead-tooter"
// RedirectUris when passed to the redirect_uris parameter, will
// show return the authorization code instead of redirecting the client.
// Load will hydrate an Application instance based upon data stored in
// a file.
func Load(name string) (app Application, err error) {
- data, err := os.ReadFile(ConfigDir + name)
+ configdir, err := os.UserConfigDir()
+ if err != nil {
+ return
+ }
+ configfile := filepath.Join(configdir, "dead-tooter", name)
+
+ data, err := os.ReadFile(configfile)
if err != nil && os.IsNotExist(err) {
return
}
// Save will store a serialized version of the Application struct to a file.
func (a *Application) Save() (err error) {
+ configdir, err := os.UserConfigDir()
+ if err != nil {
+ return
+ }
+ configdir = filepath.Join(configdir, "dead-tooter")
+
err = os.Mkdir(ConfigDir, 0750)
if err != nil && !os.IsExist(err) {
return
return
}
- err = os.WriteFile(ConfigDir+a.Name, data, 0666)
+ err = os.WriteFile(
+ filepath.Join(configdir, "dead-tooter", a.Name), data, 0666)
if err != nil {
return
}
import (
"encoding/json"
"os"
+ "path/filepath"
)
// Token struct contains the data returned by the Application login request.
// LoadToken deserializes the application authentication token from disc, if it
// exists.
func LoadToken() (token Token, err error) {
- data, err := os.ReadFile(ConfigDir + "/token")
+ configdir, err := os.UserConfigDir()
+ if err != nil {
+ return
+ }
+ tokenfile := filepath.Join(configdir, "dead-tooter", "token")
+
+ data, err := os.ReadFile(tokenfile)
if err != nil && os.IsNotExist(err) {
return
}
return
}
- err = os.WriteFile(ConfigDir+"/token", data, 0666)
+ configdir, err := os.UserConfigDir()
+ if err != nil {
+ return
+ }
+
+ tokenfile := filepath.Join(configdir, "dead-tooter", "token")
+ err = os.WriteFile(tokenfile, data, 0666)
if err != nil {
return
}