diff --git a/cmd/enbas/account.go b/cmd/enbas/account.go new file mode 100644 index 0000000..a7d6053 --- /dev/null +++ b/cmd/enbas/account.go @@ -0,0 +1,76 @@ +package main + +import ( + "fmt" + + "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" + "codeflow.dananglin.me.uk/apollo/enbas/internal/model" +) + +func getAccountID(gtsClient *client.Client, myAccount bool, accountName string) (string, error) { + var ( + accountID string + err error + ) + + switch { + case myAccount: + accountID, err = getMyAccountID(gtsClient) + if err != nil { + return "", fmt.Errorf("unable to get your account ID; %w", err) + } + case accountName != "": + accountID, err = getTheirAccountID(gtsClient, accountName) + if err != nil { + return "", fmt.Errorf("unable to get their account ID; %w", err) + } + default: + return "", noAccountSpecifiedError{} + } + + return accountID, nil +} + +func getTheirAccountID(gtsClient *client.Client, accountURI string) (string, error) { + account, err := getAccount(gtsClient, accountURI) + if err != nil { + return "", fmt.Errorf("unable to retrieve your account; %w", err) + } + + return account.ID, nil +} + +func getMyAccountID(gtsClient *client.Client) (string, error) { + account, err := getMyAccount(gtsClient) + if err != nil { + return "", fmt.Errorf("received an error while getting your account details; %w", err) + } + + return account.ID, nil +} + +func getMyAccount(gtsClient *client.Client) (model.Account, error) { + authConfig, err := config.NewAuthenticationConfigFromFile() + if err != nil { + return model.Account{}, fmt.Errorf("unable to retrieve the authentication configuration; %w", err) + } + + accountURI := authConfig.CurrentAccount + + account, err := getAccount(gtsClient, accountURI) + if err != nil { + return model.Account{}, fmt.Errorf("unable to retrieve your account; %w", err) + } + + return account, nil +} + +func getAccount(gtsClient *client.Client, accountURI string) (model.Account, error) { + account, err := gtsClient.GetAccount(accountURI) + if err != nil { + return model.Account{}, fmt.Errorf("unable to retrieve the account details; %w", err) + } + + return account, nil +} diff --git a/cmd/enbas/add.go b/cmd/enbas/add.go index a0612b7..b47c178 100644 --- a/cmd/enbas/add.go +++ b/cmd/enbas/add.go @@ -12,20 +12,20 @@ type addCommand struct { toResourceType string listID string - accountIDs accountIDs + accountNames accountNames } func newAddCommand(name, summary string) *addCommand { emptyArr := make([]string, 0, 3) command := addCommand{ - FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - accountIDs: accountIDs(emptyArr), + FlagSet: flag.NewFlagSet(name, flag.ExitOnError), + accountNames: accountNames(emptyArr), } command.StringVar(&command.toResourceType, addToFlag, "", "specify the type of resource to add to") command.StringVar(&command.listID, listIDFlag, "", "the ID of the list to add to") - command.Var(&command.accountIDs, accountIDFlag, "the ID of the account to add to the list") + command.Var(&command.accountNames, accountNameFlag, "the name of the account to add to the resource") command.Usage = commandUsageFunc(name, summary, command.FlagSet) @@ -34,7 +34,7 @@ func newAddCommand(name, summary string) *addCommand { func (c *addCommand) Execute() error { if c.toResourceType == "" { - return flagNotSetError{flagText: "add-to"} + return flagNotSetError{flagText: addToFlag} } funcMap := map[string]func(*client.Client) error{ @@ -59,11 +59,21 @@ func (c *addCommand) addAccountsToList(gtsClient *client.Client) error { return flagNotSetError{flagText: listIDFlag} } - if len(c.accountIDs) == 0 { - return noAccountIDsSpecifiedError{} + if len(c.accountNames) == 0 { + return noAccountSpecifiedError{} } - if err := gtsClient.AddAccountsToList(c.listID, []string(c.accountIDs)); err != nil { + accountIDs := make([]string, len(c.accountNames)) + + for i := range c.accountNames { + accountID, err := getTheirAccountID(gtsClient, c.accountNames[i]) + if err != nil { + return fmt.Errorf("unable to get the account ID for %s, %w", c.accountNames[i], err) + } + accountIDs[i] = accountID + } + + if err := gtsClient.AddAccountsToList(c.listID, accountIDs); err != nil { return fmt.Errorf("unable to add the accounts to the list; %w", err) } diff --git a/cmd/enbas/block.go b/cmd/enbas/block.go index 6eb6413..03a7069 100644 --- a/cmd/enbas/block.go +++ b/cmd/enbas/block.go @@ -11,7 +11,7 @@ type blockCommand struct { *flag.FlagSet resourceType string - accountID string + accountName string unblock bool } @@ -23,7 +23,7 @@ func newBlockCommand(name, summary string, unblock bool) *blockCommand { } command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to block or unblock") - command.StringVar(&command.accountID, accountIDFlag, "", "specify the ID of the account you want to block or unblock") + command.StringVar(&command.accountName, accountNameFlag, "", "specify the account name in full (username@domain)") command.Usage = commandUsageFunc(name, summary, command.FlagSet) @@ -48,16 +48,17 @@ func (c *blockCommand) Execute() error { return doFunc(gtsClient) } -func (c *blockCommand) blockAccount(gts *client.Client) error { - if c.accountID == "" { - return flagNotSetError{flagText: accountIDFlag} +func (c *blockCommand) blockAccount(gtsClient *client.Client) error { + accountID, err := getAccountID(gtsClient, false, c.accountName) + if err != nil { + return fmt.Errorf("received an error while getting the account ID; %w", err) } if c.unblock { - return c.unblockAccount(gts) + return c.unblockAccount(gtsClient, accountID) } - if err := gts.BlockAccount(c.accountID); err != nil { + if err := gtsClient.BlockAccount(accountID); err != nil { return fmt.Errorf("unable to block the account; %w", err) } @@ -66,8 +67,8 @@ func (c *blockCommand) blockAccount(gts *client.Client) error { return nil } -func (c *blockCommand) unblockAccount(gts *client.Client) error { - if err := gts.UnblockAccount(c.accountID); err != nil { +func (c *blockCommand) unblockAccount(gtsClient *client.Client, accountID string) error { + if err := gtsClient.UnblockAccount(accountID); err != nil { return fmt.Errorf("unable to unblock the account; %w", err) } diff --git a/cmd/enbas/errors.go b/cmd/enbas/errors.go index 8aa5dcc..e2be4f9 100644 --- a/cmd/enbas/errors.go +++ b/cmd/enbas/errors.go @@ -32,8 +32,8 @@ func (e unknownSubcommandError) Error() string { return "unknown subcommand '" + e.subcommand + "'" } -type noAccountIDsSpecifiedError struct{} +type noAccountSpecifiedError struct{} -func (e noAccountIDsSpecifiedError) Error() string { - return "no account IDs specified" +func (e noAccountSpecifiedError) Error() string { + return "no account specified in this request" } diff --git a/cmd/enbas/flags.go b/cmd/enbas/flags.go index 4856a45..df46ae5 100644 --- a/cmd/enbas/flags.go +++ b/cmd/enbas/flags.go @@ -2,13 +2,13 @@ package main import "strings" -type accountIDs []string +type accountNames []string -func (a *accountIDs) String() string { +func (a *accountNames) String() string { return strings.Join(*a, ", ") } -func (a *accountIDs) Set(value string) error { +func (a *accountNames) Set(value string) error { if len(value) > 0 { *a = append(*a, value) } diff --git a/cmd/enbas/follow.go b/cmd/enbas/follow.go index 20ff36d..ff0148e 100644 --- a/cmd/enbas/follow.go +++ b/cmd/enbas/follow.go @@ -11,7 +11,7 @@ type followCommand struct { *flag.FlagSet resourceType string - accountID string + accountName string showReposts bool notify bool unfollow bool @@ -25,7 +25,7 @@ func newFollowCommand(name, summary string, unfollow bool) *followCommand { } command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to follow") - command.StringVar(&command.accountID, accountIDFlag, "", "specify the ID of the account you want to follow") + command.StringVar(&command.accountName, accountNameFlag, "", "specify the account name in full (username@domain)") command.BoolVar(&command.showReposts, showRepostsFlag, true, "show reposts from the account you want to follow") command.BoolVar(&command.notify, notifyFlag, false, "get notifications when the account you want to follow posts a status") @@ -52,16 +52,17 @@ func (c *followCommand) Execute() error { return doFunc(gtsClient) } -func (c *followCommand) followAccount(gts *client.Client) error { - if c.accountID == "" { - return flagNotSetError{flagText: accountIDFlag} +func (c *followCommand) followAccount(gtsClient *client.Client) error { + accountID, err := getAccountID(gtsClient, false, c.accountName) + if err != nil { + return fmt.Errorf("received an error while getting the account ID; %w", err) } if c.unfollow { - return c.unfollowAccount(gts) + return c.unfollowAccount(gtsClient, accountID) } - if err := gts.FollowAccount(c.accountID, c.showReposts, c.notify); err != nil { + if err := gtsClient.FollowAccount(accountID, c.showReposts, c.notify); err != nil { return fmt.Errorf("unable to follow the account; %w", err) } @@ -70,8 +71,8 @@ func (c *followCommand) followAccount(gts *client.Client) error { return nil } -func (c *followCommand) unfollowAccount(gts *client.Client) error { - if err := gts.UnfollowAccount(c.accountID); err != nil { +func (c *followCommand) unfollowAccount(gtsClient *client.Client, accountID string) error { + if err := gtsClient.UnfollowAccount(accountID); err != nil { return fmt.Errorf("unable to unfollow the account; %w", err) } diff --git a/cmd/enbas/main.go b/cmd/enbas/main.go index 792e024..485f290 100644 --- a/cmd/enbas/main.go +++ b/cmd/enbas/main.go @@ -4,15 +4,10 @@ import ( "flag" "fmt" "os" - - "codeflow.dananglin.me.uk/apollo/enbas/internal/client" - "codeflow.dananglin.me.uk/apollo/enbas/internal/config" - "codeflow.dananglin.me.uk/apollo/enbas/internal/model" ) const ( - accountFlag = "account" - accountIDFlag = "account-id" + accountNameFlag = "account-name" addToFlag = "add-to" instanceFlag = "instance" listIDFlag = "list-id" @@ -151,19 +146,3 @@ func run() error { return nil } - -func getMyAccount(gts *client.Client) (model.Account, error) { - authConfig, err := config.NewAuthenticationConfigFromFile() - if err != nil { - return model.Account{}, fmt.Errorf("unable to retrieve the authentication configuration; %w", err) - } - - accountURI := authConfig.CurrentAccount - - account, err := gts.GetAccount(accountURI) - if err != nil { - return model.Account{}, fmt.Errorf("unable to retrieve the account details; %w", err) - } - - return account, nil -} diff --git a/cmd/enbas/remove.go b/cmd/enbas/remove.go index 0c79676..9d388b1 100644 --- a/cmd/enbas/remove.go +++ b/cmd/enbas/remove.go @@ -12,20 +12,20 @@ type removeCommand struct { fromResourceType string listID string - accountIDs accountIDs + accountNames accountNames } func newRemoveCommand(name, summary string) *removeCommand { emptyArr := make([]string, 0, 3) command := removeCommand{ - FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - accountIDs: accountIDs(emptyArr), + FlagSet: flag.NewFlagSet(name, flag.ExitOnError), + accountNames: accountNames(emptyArr), } command.StringVar(&command.fromResourceType, removeFromFlag, "", "specify the type of resource to remove from") command.StringVar(&command.listID, listIDFlag, "", "the ID of the list to remove from") - command.Var(&command.accountIDs, accountIDFlag, "the ID of the account to remove from the list") + command.Var(&command.accountNames, accountNameFlag, "the name of the account to remove from the resource") command.Usage = commandUsageFunc(name, summary, command.FlagSet) @@ -34,7 +34,7 @@ func newRemoveCommand(name, summary string) *removeCommand { func (c *removeCommand) Execute() error { if c.fromResourceType == "" { - return flagNotSetError{flagText: "remove-from"} + return flagNotSetError{flagText: removeFromFlag} } funcMap := map[string]func(*client.Client) error{ @@ -59,11 +59,21 @@ func (c *removeCommand) removeAccountsFromList(gtsClient *client.Client) error { return flagNotSetError{flagText: listIDFlag} } - if len(c.accountIDs) == 0 { - return noAccountIDsSpecifiedError{} + if len(c.accountNames) == 0 { + return noAccountSpecifiedError{} } - if err := gtsClient.RemoveAccountsFromList(c.listID, []string(c.accountIDs)); err != nil { + accountIDs := make([]string, len(c.accountNames)) + + for i := range c.accountNames { + accountID, err := getTheirAccountID(gtsClient, c.accountNames[i]) + if err != nil { + return fmt.Errorf("unable to get the account ID for %s, %w", c.accountNames[i], err) + } + accountIDs[i] = accountID + } + + if err := gtsClient.RemoveAccountsFromList(c.listID, accountIDs); err != nil { return fmt.Errorf("unable to remove the accounts from the list; %w", err) } diff --git a/cmd/enbas/show.go b/cmd/enbas/show.go index ad0939d..79014e4 100644 --- a/cmd/enbas/show.go +++ b/cmd/enbas/show.go @@ -15,8 +15,7 @@ type showCommand struct { showAccountRelationship bool showUserPreferences bool resourceType string - account string - accountID string + accountName string statusID string timelineCategory string listID string @@ -33,8 +32,7 @@ func newShowCommand(name, summary string) *showCommand { command.BoolVar(&command.showAccountRelationship, showAccountRelationshipFlag, false, "show your relationship to the specified account") command.BoolVar(&command.showUserPreferences, showUserPreferencesFlag, false, "show your preferences") command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to display") - command.StringVar(&command.account, accountFlag, "", "specify the account URI to lookup") - command.StringVar(&command.accountID, accountIDFlag, "", "specify the account ID") + command.StringVar(&command.accountName, accountNameFlag, "", "specify the account name in full (username@domain)") command.StringVar(&command.statusID, statusIDFlag, "", "specify the ID of the status to display") command.StringVar(&command.timelineCategory, timelineCategoryFlag, "home", "specify the type of timeline to display (valid values are home, public, list and tag)") command.StringVar(&command.listID, listIDFlag, "", "specify the ID of the list to display") @@ -75,8 +73,8 @@ func (c *showCommand) Execute() error { return doFunc(gtsClient) } -func (c *showCommand) showInstance(gts *client.Client) error { - instance, err := gts.GetInstance() +func (c *showCommand) showInstance(gtsClient *client.Client) error { + instance, err := gtsClient.GetInstance() if err != nil { return fmt.Errorf("unable to retrieve the instance details; %w", err) } @@ -86,34 +84,32 @@ func (c *showCommand) showInstance(gts *client.Client) error { return nil } -func (c *showCommand) showAccount(gts *client.Client) error { +func (c *showCommand) showAccount(gtsClient *client.Client) error { var ( account model.Account err error ) if c.myAccount { - account, err = getMyAccount(gts) + account, err = getMyAccount(gtsClient) if err != nil { - return fmt.Errorf("received an error while getting account details; %w", err) + return fmt.Errorf("received an error while getting the account details; %w", err) } } else { - if c.account == "" { - return flagNotSetError{flagText: accountFlag} + if c.accountName == "" { + return flagNotSetError{flagText: accountNameFlag} } - accountURI := c.account - - account, err = gts.GetAccount(accountURI) + account, err = getAccount(gtsClient, c.accountName) if err != nil { - return fmt.Errorf("unable to retrieve the account details; %w", err) + return fmt.Errorf("received an error while getting the account details; %w", err) } } fmt.Println(account) if !c.myAccount && c.showAccountRelationship { - relationship, err := gts.GetAccountRelationship(account.ID) + relationship, err := gtsClient.GetAccountRelationship(account.ID) if err != nil { return fmt.Errorf("unable to retrieve the relationship to this account; %w", err) } @@ -122,7 +118,7 @@ func (c *showCommand) showAccount(gts *client.Client) error { } if c.myAccount && c.showUserPreferences { - preferences, err := gts.GetUserPreferences() + preferences, err := gtsClient.GetUserPreferences() if err != nil { return fmt.Errorf("unable to retrieve the user preferences; %w", err) } @@ -133,12 +129,12 @@ func (c *showCommand) showAccount(gts *client.Client) error { return nil } -func (c *showCommand) showStatus(gts *client.Client) error { +func (c *showCommand) showStatus(gtsClient *client.Client) error { if c.statusID == "" { return flagNotSetError{flagText: statusIDFlag} } - status, err := gts.GetStatus(c.statusID) + status, err := gtsClient.GetStatus(c.statusID) if err != nil { return fmt.Errorf("unable to retrieve the status; %w", err) } @@ -148,7 +144,7 @@ func (c *showCommand) showStatus(gts *client.Client) error { return nil } -func (c *showCommand) showTimeline(gts *client.Client) error { +func (c *showCommand) showTimeline(gtsClient *client.Client) error { var ( timeline model.Timeline err error @@ -156,21 +152,21 @@ func (c *showCommand) showTimeline(gts *client.Client) error { switch c.timelineCategory { case "home": - timeline, err = gts.GetHomeTimeline(c.limit) + timeline, err = gtsClient.GetHomeTimeline(c.limit) case "public": - timeline, err = gts.GetPublicTimeline(c.limit) + timeline, err = gtsClient.GetPublicTimeline(c.limit) case "list": if c.listID == "" { return flagNotSetError{flagText: listIDFlag} } - timeline, err = gts.GetListTimeline(c.listID, c.limit) + timeline, err = gtsClient.GetListTimeline(c.listID, c.limit) case "tag": if c.tag == "" { return flagNotSetError{flagText: tagFlag} } - timeline, err = gts.GetTagTimeline(c.tag, c.limit) + timeline, err = gtsClient.GetTagTimeline(c.tag, c.limit) default: return invalidTimelineCategoryError{category: c.timelineCategory} } @@ -190,17 +186,17 @@ func (c *showCommand) showTimeline(gts *client.Client) error { return nil } -func (c *showCommand) showList(gts *client.Client) error { +func (c *showCommand) showList(gtsClient *client.Client) error { if c.listID == "" { - return c.showLists(gts) + return c.showLists(gtsClient) } - list, err := gts.GetList(c.listID) + list, err := gtsClient.GetList(c.listID) if err != nil { return fmt.Errorf("unable to retrieve the list; %w", err) } - accounts, err := gts.GetAccountsFromList(c.listID, 0) + accounts, err := gtsClient.GetAccountsFromList(c.listID, 0) if err != nil { return fmt.Errorf("unable to retrieve the accounts from the list; %w", err) } @@ -219,8 +215,8 @@ func (c *showCommand) showList(gts *client.Client) error { return nil } -func (c *showCommand) showLists(gts *client.Client) error { - lists, err := gts.GetAllLists() +func (c *showCommand) showLists(gtsClient *client.Client) error { + lists, err := gtsClient.GetAllLists() if err != nil { return fmt.Errorf("unable to retrieve the lists; %w", err) } @@ -237,25 +233,13 @@ func (c *showCommand) showLists(gts *client.Client) error { return nil } -func (c *showCommand) showFollowers(gts *client.Client) error { - var accountID string - - if c.myAccount { - account, err := getMyAccount(gts) - if err != nil { - return fmt.Errorf("received an error while getting account details; %w", err) - } - - accountID = account.ID - } else { - if c.accountID == "" { - return flagNotSetError{flagText: accountIDFlag} - } - - accountID = c.accountID +func (c *showCommand) showFollowers(gtsClient *client.Client) error { + accountID, err := getAccountID(gtsClient, c.myAccount, c.accountName) + if err != nil { + return fmt.Errorf("received an error while getting the account ID; %w", err) } - followers, err := gts.GetFollowers(accountID, c.limit) + followers, err := gtsClient.GetFollowers(accountID, c.limit) if err != nil { return fmt.Errorf("unable to retrieve the list of followers; %w", err) } @@ -269,25 +253,13 @@ func (c *showCommand) showFollowers(gts *client.Client) error { return nil } -func (c *showCommand) showFollowing(gts *client.Client) error { - var accountID string - - if c.myAccount { - account, err := getMyAccount(gts) - if err != nil { - return fmt.Errorf("received an error while getting account details; %w", err) - } - - accountID = account.ID - } else { - if c.accountID == "" { - return flagNotSetError{flagText: accountIDFlag} - } - - accountID = c.accountID +func (c *showCommand) showFollowing(gtsClient *client.Client) error { + accountID, err := getAccountID(gtsClient, c.myAccount, c.accountName) + if err != nil { + return fmt.Errorf("received an error while getting the account ID; %w", err) } - following, err := gts.GetFollowing(accountID, c.limit) + following, err := gtsClient.GetFollowing(accountID, c.limit) if err != nil { return fmt.Errorf("unable to retrieve the list of followed accounts; %w", err) } @@ -301,8 +273,8 @@ func (c *showCommand) showFollowing(gts *client.Client) error { return nil } -func (c *showCommand) showBlocked(gts *client.Client) error { - blocked, err := gts.GetBlockedAccounts(c.limit) +func (c *showCommand) showBlocked(gtsClient *client.Client) error { + blocked, err := gtsClient.GetBlockedAccounts(c.limit) if err != nil { return fmt.Errorf("unable to retrieve the list of blocked accounts; %w", err) }