add.go
1 package executor 2 3 import ( 4 "fmt" 5 "net/rpc" 6 7 "codeflow.dananglin.me.uk/apollo/enbas/internal/gtsclient" 8 "codeflow.dananglin.me.uk/apollo/enbas/internal/model" 9 "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" 10 "codeflow.dananglin.me.uk/apollo/enbas/internal/server" 11 ) 12 13 func (a *AddExecutor) Execute() error { 14 if a.toResourceType == "" { 15 return FlagNotSetError{flagText: flagTo} 16 } 17 18 funcMap := map[string]func(*rpc.Client) error{ 19 resourceList: a.addToList, 20 resourceAccount: a.addToAccount, 21 resourceBookmarks: a.addToBookmarks, 22 resourceStatus: a.addToStatus, 23 } 24 25 doFunc, ok := funcMap[a.toResourceType] 26 if !ok { 27 return UnsupportedTypeError{resourceType: a.toResourceType} 28 } 29 30 client, err := server.Connect(a.config.Server, a.configDir) 31 if err != nil { 32 return fmt.Errorf("error creating the client for the daemon process: %w", err) 33 } 34 defer client.Close() 35 36 return doFunc(client) 37 } 38 39 func (a *AddExecutor) addToList(client *rpc.Client) error { 40 if a.listID == "" { 41 return MissingIDError{ 42 resource: resourceList, 43 action: "add to", 44 } 45 } 46 47 funcMap := map[string]func(*rpc.Client) error{ 48 resourceAccount: a.addAccountsToList, 49 } 50 51 doFunc, ok := funcMap[a.resourceType] 52 if !ok { 53 return UnsupportedAddOperationError{ 54 resourceType: a.resourceType, 55 addToResourceType: a.toResourceType, 56 } 57 } 58 59 return doFunc(client) 60 } 61 62 func (a *AddExecutor) addAccountsToList(client *rpc.Client) error { 63 if a.accountNames.Empty() { 64 return NoAccountSpecifiedError{} 65 } 66 67 accounts, err := getOtherAccounts(client, a.accountNames) 68 if err != nil { 69 return fmt.Errorf("unable to get the accounts: %w", err) 70 } 71 72 accountIDs := make([]string, len(accounts)) 73 74 for ind := range accounts { 75 var relationship model.AccountRelationship 76 if err := client.Call("GTSClient.GetAccountRelationship", accounts[ind].ID, &relationship); err != nil { 77 return fmt.Errorf("unable to get your relationship to %s: %w", accounts[ind].Acct, err) 78 } 79 80 if !relationship.Following { 81 return NotFollowingError{account: accounts[ind].Acct} 82 } 83 84 accountIDs[ind] = accounts[ind].ID 85 } 86 87 if err := client.Call( 88 "GTSClient.AddAccountsToList", 89 gtsclient.AddAccountsToListArgs{ 90 ListID: a.listID, 91 AccountIDs: accountIDs, 92 }, 93 nil, 94 ); err != nil { 95 return fmt.Errorf("unable to add the accounts to the list: %w", err) 96 } 97 98 printer.PrintSuccess(a.printSettings, "Successfully added the account(s) to the list.") 99 100 return nil 101 } 102 103 func (a *AddExecutor) addToAccount(client *rpc.Client) error { 104 funcMap := map[string]func(*rpc.Client) error{ 105 resourceNote: a.addNoteToAccount, 106 } 107 108 doFunc, ok := funcMap[a.resourceType] 109 if !ok { 110 return UnsupportedAddOperationError{ 111 resourceType: a.resourceType, 112 addToResourceType: a.toResourceType, 113 } 114 } 115 116 return doFunc(client) 117 } 118 119 func (a *AddExecutor) addNoteToAccount(client *rpc.Client) error { 120 accountID, err := getAccountID(client, false, a.accountNames) 121 if err != nil { 122 return fmt.Errorf("received an error while getting the account ID: %w", err) 123 } 124 125 if a.content == "" { 126 return Error{"please add content to the note you want to add"} 127 } 128 129 if err := client.Call( 130 "GTSClient.SetPrivateNote", 131 gtsclient.SetPrivateNoteArgs{ 132 AccountID: accountID, 133 Note: a.content, 134 }, 135 nil, 136 ); err != nil { 137 return fmt.Errorf("unable to add the private note to the account: %w", err) 138 } 139 140 printer.PrintSuccess(a.printSettings, "Successfully added the private note to the account.") 141 142 return nil 143 } 144 145 func (a *AddExecutor) addToBookmarks(client *rpc.Client) error { 146 funcMap := map[string]func(*rpc.Client) error{ 147 resourceStatus: a.addStatusToBookmarks, 148 } 149 150 doFunc, ok := funcMap[a.resourceType] 151 if !ok { 152 return UnsupportedAddOperationError{ 153 resourceType: a.resourceType, 154 addToResourceType: a.toResourceType, 155 } 156 } 157 158 return doFunc(client) 159 } 160 161 func (a *AddExecutor) addStatusToBookmarks(client *rpc.Client) error { 162 if a.statusID == "" { 163 return MissingIDError{ 164 resource: resourceStatus, 165 action: "add to your bookmarks", 166 } 167 } 168 169 if err := client.Call("GTSClient.AddStatusToBookmarks", a.statusID, nil); err != nil { 170 return fmt.Errorf("unable to add the status to your bookmarks: %w", err) 171 } 172 173 printer.PrintSuccess(a.printSettings, "Successfully added the status to your bookmarks.") 174 175 return nil 176 } 177 178 func (a *AddExecutor) addToStatus(client *rpc.Client) error { 179 if a.statusID == "" { 180 return MissingIDError{ 181 resource: resourceStatus, 182 action: "add to", 183 } 184 } 185 186 funcMap := map[string]func(*rpc.Client) error{ 187 resourceStar: a.addStarToStatus, 188 resourceLike: a.addStarToStatus, 189 resourceBoost: a.addBoostToStatus, 190 resourceVote: a.addVoteToStatus, 191 } 192 193 doFunc, ok := funcMap[a.resourceType] 194 if !ok { 195 return UnsupportedAddOperationError{ 196 resourceType: a.resourceType, 197 addToResourceType: a.toResourceType, 198 } 199 } 200 201 return doFunc(client) 202 } 203 204 func (a *AddExecutor) addStarToStatus(client *rpc.Client) error { 205 if err := client.Call("GTSClient.LikeStatus", a.statusID, nil); err != nil { 206 return fmt.Errorf("error adding the %s to the status: %w", a.resourceType, err) 207 } 208 209 printer.PrintSuccess(a.printSettings, "Successfully added a "+a.resourceType+" to the status.") 210 211 return nil 212 } 213 214 func (a *AddExecutor) addBoostToStatus(client *rpc.Client) error { 215 if err := client.Call("GTSClient.ReblogStatus", a.statusID, nil); err != nil { 216 return fmt.Errorf("unable to add the boost to the status: %w", err) 217 } 218 219 printer.PrintSuccess(a.printSettings, "Successfully added the boost to the status.") 220 221 return nil 222 } 223 224 func (a *AddExecutor) addVoteToStatus(client *rpc.Client) error { 225 if a.votes.Empty() { 226 return Error{"please add your vote(s) to the poll"} 227 } 228 229 var status model.Status 230 if err := client.Call("GTSClient.GetStatus", a.statusID, &status); err != nil { 231 return fmt.Errorf("unable to get the status: %w", err) 232 } 233 234 if status.Poll == nil { 235 return Error{"this status does not have a poll"} 236 } 237 238 if status.Poll.Expired { 239 return Error{"this poll is closed"} 240 } 241 242 if !status.Poll.Multiple && !a.votes.ExpectedLength(1) { 243 return Error{"this poll does not allow multiple choices"} 244 } 245 246 myAccountID, err := getAccountID(client, true, nil) 247 if err != nil { 248 return fmt.Errorf("unable to get your account ID: %w", err) 249 } 250 251 if status.Account.ID == myAccountID { 252 return Error{"you cannot vote in your own poll"} 253 } 254 255 pollID := status.Poll.ID 256 257 if err := client.Call( 258 "GTSClient.VoteInPoll", 259 gtsclient.VoteInPollArgs{ 260 PollID: pollID, 261 Choices: a.votes, 262 }, 263 nil, 264 ); err != nil { 265 return fmt.Errorf("unable to add your vote(s) to the poll: %w", err) 266 } 267 268 printer.PrintSuccess(a.printSettings, "Successfully added your vote(s) to the poll.") 269 270 return nil 271 }