mastotool/main.go

141 lines
3.2 KiB
Go

package main
import (
"bufio"
"context"
"fmt"
"os"
"strings"
mastodon "github.com/mattn/go-mastodon"
"github.com/spf13/cobra"
)
var (
client *mastodon.Client
self *mastodon.Account
configFile string
// RootCmd is the core command used for cli-arg parsing.
RootCmd = &cobra.Command{
Use: "mastotool",
Short: "mastotool offers a collection of tools to work with your Mastodon account",
SilenceErrors: true,
SilenceUsage: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := initClient(); err != nil {
return err
}
var err error
self, err = client.GetAccountCurrentUser(context.Background())
if err != nil {
return fmt.Errorf("Can't retrieve user: %s", err)
}
return nil
},
}
)
const (
progressBarWidth = 40
)
func registerApp(config *Config) (string, error) {
app, err := mastodon.RegisterApp(context.Background(), &mastodon.AppConfig{
Server: config.Value("instance").(string),
ClientName: "mastotool",
Scopes: "read",
Website: "",
})
if err != nil {
return "", err
}
config.Set("id", app.ClientID)
config.Set("secret", app.ClientSecret)
config.Set("redirectURI", app.RedirectURI)
return app.AuthURI, nil
}
func initClient() error {
var err error
var instance, token, redirectURI, authURI, id, secret string
config, err := LoadConfig(configFile)
if err == nil {
instance = config.Value("instance").(string)
id = config.Value("id").(string)
secret = config.Value("secret").(string)
token = config.Value("token").(string)
redirectURI = config.Value("redirectURI").(string)
}
scanner := bufio.NewScanner(os.Stdin)
if len(instance) == 0 {
fmt.Print("Which instance to connect to (e.g. https://mastodon.social): ")
scanner.Scan()
if scanner.Err() != nil {
return fmt.Errorf("Can't open input: %s", err)
}
instance = scanner.Text()
if !strings.HasPrefix(instance, "http") {
instance = "https://" + instance
}
config.Set("instance", instance)
}
if len(id) == 0 {
authURI, err = registerApp(&config)
if err != nil {
return fmt.Errorf("Can't register app: %s", err)
}
id = config.Value("id").(string)
secret = config.Value("secret").(string)
redirectURI = config.Value("redirectURI").(string)
}
mConfig := &mastodon.Config{
AccessToken: token,
Server: instance,
ClientID: id,
ClientSecret: secret,
}
client = mastodon.NewClient(mConfig)
if len(mConfig.AccessToken) == 0 {
fmt.Printf("Please visit %s and enter the generated token: ", authURI)
scanner.Scan()
if scanner.Err() != nil {
return fmt.Errorf("Can't open input: %s", err)
}
code := scanner.Text()
err = client.AuthenticateToken(context.Background(), code, redirectURI)
if err != nil {
return fmt.Errorf("Can't retrieve authentication token: %s", err)
}
config.Set("token", mConfig.AccessToken)
err = config.Save(configFile)
if err != nil {
return fmt.Errorf("Can't save config: %s", err)
}
}
return nil
}
func main() {
RootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "mastodon.json", "uses the specified config file")
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}