// SPDX-FileCopyrightText: 2024 Dan Anglin // // SPDX-License-Identifier: GPL-3.0-or-later package executor import ( "flag" "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" ) type AddExecutor struct { *flag.FlagSet topLevelFlags TopLevelFlags resourceType string toResourceType string listID string statusID string accountNames AccountNames content string } func NewAddExecutor(tlf TopLevelFlags, name, summary string) *AddExecutor { emptyArr := make([]string, 0, 3) addExe := AddExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), accountNames: AccountNames(emptyArr), topLevelFlags: tlf, } addExe.StringVar(&addExe.resourceType, flagType, "", "Specify the resource type to add (e.g. account, note)") addExe.StringVar(&addExe.toResourceType, flagTo, "", "Specify the target resource type to add to (e.g. list, account, etc)") addExe.StringVar(&addExe.listID, flagListID, "", "The ID of the list to add to") addExe.StringVar(&addExe.statusID, flagStatusID, "", "The ID of the status") addExe.Var(&addExe.accountNames, flagAccountName, "The name of the account") addExe.StringVar(&addExe.content, flagContent, "", "The content of the resource") addExe.Usage = commandUsageFunc(name, summary, addExe.FlagSet) return &addExe } func (a *AddExecutor) Execute() error { if a.toResourceType == "" { return FlagNotSetError{flagText: flagTo} } funcMap := map[string]func(*client.Client) error{ resourceList: a.addToList, resourceAccount: a.addToAccount, resourceBookmarks: a.addToBookmarks, resourceStatus: a.addToStatus, } doFunc, ok := funcMap[a.toResourceType] if !ok { return UnsupportedTypeError{resourceType: a.toResourceType} } gtsClient, err := client.NewClientFromConfig(a.topLevelFlags.ConfigDir) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } return doFunc(gtsClient) } func (a *AddExecutor) addToList(gtsClient *client.Client) error { funcMap := map[string]func(*client.Client) error{ resourceAccount: a.addAccountsToList, } doFunc, ok := funcMap[a.resourceType] if !ok { return UnsupportedAddOperationError{ ResourceType: a.resourceType, AddToResourceType: a.toResourceType, } } return doFunc(gtsClient) } func (a *AddExecutor) addAccountsToList(gtsClient *client.Client) error { if a.listID == "" { return FlagNotSetError{flagText: flagListID} } if len(a.accountNames) == 0 { return NoAccountSpecifiedError{} } accountIDs := make([]string, len(a.accountNames)) for ind := range a.accountNames { accountID, err := getTheirAccountID(gtsClient, a.accountNames[ind]) if err != nil { return fmt.Errorf("unable to get the account ID for %s, %w", a.accountNames[ind], err) } accountIDs[ind] = accountID } if err := gtsClient.AddAccountsToList(a.listID, accountIDs); err != nil { return fmt.Errorf("unable to add the accounts to the list: %w", err) } fmt.Println("Successfully added the account(s) to the list.") return nil } func (a *AddExecutor) addToAccount(gtsClient *client.Client) error { funcMap := map[string]func(*client.Client) error{ resourceNote: a.addNoteToAccount, } doFunc, ok := funcMap[a.resourceType] if !ok { return UnsupportedAddOperationError{ ResourceType: a.resourceType, AddToResourceType: a.toResourceType, } } return doFunc(gtsClient) } func (a *AddExecutor) addNoteToAccount(gtsClient *client.Client) error { if len(a.accountNames) != 1 { return fmt.Errorf("unexpected number of accounts specified: want 1, got %d", len(a.accountNames)) } accountID, err := getAccountID(gtsClient, false, a.accountNames[0], a.topLevelFlags.ConfigDir) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } if a.content == "" { return EmptyContentError{ ResourceType: resourceNote, Hint: "please use --" + flagContent, } } if err := gtsClient.SetPrivateNote(accountID, a.content); err != nil { return fmt.Errorf("unable to add the private note to the account: %w", err) } fmt.Println("Successfully added the private note to the account.") return nil } func (a *AddExecutor) addToBookmarks(gtsClient *client.Client) error { funcMap := map[string]func(*client.Client) error{ resourceStatus: a.addStatusToBookmarks, } doFunc, ok := funcMap[a.resourceType] if !ok { return UnsupportedAddOperationError{ ResourceType: a.resourceType, AddToResourceType: a.toResourceType, } } return doFunc(gtsClient) } func (a *AddExecutor) addStatusToBookmarks(gtsClient *client.Client) error { if a.statusID == "" { return FlagNotSetError{flagText: flagStatusID} } if err := gtsClient.AddStatusToBookmarks(a.statusID); err != nil { return fmt.Errorf("unable to add the status to your bookmarks: %w", err) } fmt.Println("Successfully added the status to your bookmarks.") return nil } func (a *AddExecutor) addToStatus(gtsClient *client.Client) error { if a.statusID == "" { return FlagNotSetError{flagText: flagStatusID} } funcMap := map[string]func(*client.Client) error{ resourceStar: a.addStarToStatus, resourceLike: a.addStarToStatus, resourceBoost: a.addBoostToStatus, } doFunc, ok := funcMap[a.resourceType] if !ok { return UnsupportedAddOperationError{ ResourceType: a.resourceType, AddToResourceType: a.toResourceType, } } return doFunc(gtsClient) } func (a *AddExecutor) addStarToStatus(gtsClient *client.Client) error { if err := gtsClient.LikeStatus(a.statusID); err != nil { return fmt.Errorf("unable to add the %s to the status: %w", a.resourceType, err) } fmt.Printf("Successfully added a %s to the status.\n", a.resourceType) return nil } func (a *AddExecutor) addBoostToStatus(gtsClient *client.Client) error { if err := gtsClient.ReblogStatus(a.statusID); err != nil { return fmt.Errorf("unable to add the boost to the status: %w", err) } fmt.Println("Successfully added the boost to the status.") return nil }