Compare commits

..

3 commits

5 changed files with 237 additions and 6 deletions

72
cmd/enbas/add.go Normal file
View file

@ -0,0 +1,72 @@
package main
import (
"errors"
"flag"
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
type addCommand struct {
*flag.FlagSet
toResourceType string
listID string
accountIDs accountIDs
}
func newAddCommand(name, summary string) *addCommand {
emptyArr := make([]string, 0, 3)
command := addCommand{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
accountIDs: accountIDs(emptyArr),
}
command.StringVar(&command.toResourceType, "add-to", "", "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, "account-id", "the ID of the account to add to the list")
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
return &command
}
func (c *addCommand) Execute() error {
if c.toResourceType == "" {
return flagNotSetError{flagText: "add-to"}
}
funcMap := map[string]func(*client.Client) error{
listResource: c.addAccountsToList,
}
doFunc, ok := funcMap[c.toResourceType]
if !ok {
return unsupportedResourceTypeError{resourceType: c.toResourceType}
}
gtsClient, err := client.NewClientFromConfig()
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
}
return doFunc(gtsClient)
}
func (c *addCommand) addAccountsToList(gtsClient *client.Client) error {
if c.listID == "" {
return flagNotSetError{flagText: listIDFlag}
}
if len(c.accountIDs) == 0 {
return errors.New("no account IDs has been specified")
}
if err := gtsClient.AddAccountsToList(c.listID, []string(c.accountIDs)); err != nil {
return fmt.Errorf("unable to add the accounts to the list; %w", err)
}
return nil
}

17
cmd/enbas/flags.go Normal file
View file

@ -0,0 +1,17 @@
package main
import "strings"
type accountIDs []string
func (a *accountIDs) String() string {
return strings.Join(*a, ", ")
}
func (a *accountIDs) Set(value string) error {
if len(value) > 0 {
*a = append(*a, value)
}
return nil
}

View file

@ -52,6 +52,7 @@ func run() error {
deleteResource string = "delete" deleteResource string = "delete"
updateResource string = "update" updateResource string = "update"
whoami string = "whoami" whoami string = "whoami"
add string = "add"
) )
summaries := map[string]string{ summaries := map[string]string{
@ -63,6 +64,7 @@ func run() error {
deleteResource: "delete a specific resource", deleteResource: "delete a specific resource",
updateResource: "update a specific resource", updateResource: "update a specific resource",
whoami: "print the account that you are currently logged in to", whoami: "print the account that you are currently logged in to",
add: "add a resource to another resource",
} }
flag.Usage = enbasUsageFunc(summaries) flag.Usage = enbasUsageFunc(summaries)
@ -97,6 +99,8 @@ func run() error {
executor = newUpdateCommand(updateResource, summaries[updateResource]) executor = newUpdateCommand(updateResource, summaries[updateResource])
case whoami: case whoami:
executor = newWhoAmICommand(whoami, summaries[whoami]) executor = newWhoAmICommand(whoami, summaries[whoami])
case add:
executor = newAddCommand(add, summaries[add])
default: default:
flag.Usage() flag.Usage()
return fmt.Errorf("unknown subcommand %q", subcommand) return fmt.Errorf("unknown subcommand %q", subcommand)

72
cmd/enbas/remove.go Normal file
View file

@ -0,0 +1,72 @@
package main
import (
"errors"
"flag"
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
type removeCommand struct {
*flag.FlagSet
fromResourceType string
listID string
accountIDs accountIDs
}
func newRemoveCommand(name, summary string) *removeCommand {
emptyArr := make([]string, 0, 3)
command := removeCommand{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
accountIDs: accountIDs(emptyArr),
}
command.StringVar(&command.fromResourceType, "remove-from", "", "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, "account-id", "the ID of the account to remove from the list")
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
return &command
}
func (c *removeCommand) Execute() error {
if c.fromResourceType == "" {
return flagNotSetError{flagText: "remove-from"}
}
funcMap := map[string]func(*client.Client) error{
listResource: c.removeAccountsFromList,
}
doFunc, ok := funcMap[c.fromResourceType]
if !ok {
return unsupportedResourceTypeError{resourceType: c.fromResourceType}
}
gtsClient, err := client.NewClientFromConfig()
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
}
return doFunc(gtsClient)
}
func (c *removeCommand) removeAccountsFromList(gtsClient *client.Client) error {
if c.listID == "" {
return flagNotSetError{flagText: listIDFlag}
}
if len(c.accountIDs) == 0 {
return errors.New("no account IDs has been specified")
}
if err := gtsClient.RemoveAccountsFromList(c.listID, []string(c.accountIDs)); err != nil {
return fmt.Errorf("unable to remove the accounts from the list; %w", err)
}
return nil
}

View file

@ -44,7 +44,7 @@ func (g *Client) GetList(listID string) (model.List, error) {
} }
func (g *Client) CreateList(title string, repliesPolicy model.ListRepliesPolicy) (model.List, error) { func (g *Client) CreateList(title string, repliesPolicy model.ListRepliesPolicy) (model.List, error) {
params := struct { form := struct {
Title string `json:"title"` Title string `json:"title"`
RepliesPolicy model.ListRepliesPolicy `json:"replies_policy"` RepliesPolicy model.ListRepliesPolicy `json:"replies_policy"`
}{ }{
@ -52,9 +52,9 @@ func (g *Client) CreateList(title string, repliesPolicy model.ListRepliesPolicy)
RepliesPolicy: repliesPolicy, RepliesPolicy: repliesPolicy,
} }
data, err := json.Marshal(params) data, err := json.Marshal(form)
if err != nil { if err != nil {
return model.List{}, fmt.Errorf("unable to marshal the request body; %w", err) return model.List{}, fmt.Errorf("unable to marshal the form; %w", err)
} }
requestBody := bytes.NewBuffer(data) requestBody := bytes.NewBuffer(data)
@ -73,7 +73,7 @@ func (g *Client) CreateList(title string, repliesPolicy model.ListRepliesPolicy)
} }
func (g *Client) UpdateList(listToUpdate model.List) (model.List, error) { func (g *Client) UpdateList(listToUpdate model.List) (model.List, error) {
params := struct { form := struct {
Title string `json:"title"` Title string `json:"title"`
RepliesPolicy model.ListRepliesPolicy `json:"replies_policy"` RepliesPolicy model.ListRepliesPolicy `json:"replies_policy"`
}{ }{
@ -81,9 +81,9 @@ func (g *Client) UpdateList(listToUpdate model.List) (model.List, error) {
RepliesPolicy: listToUpdate.RepliesPolicy, RepliesPolicy: listToUpdate.RepliesPolicy,
} }
data, err := json.Marshal(params) data, err := json.Marshal(form)
if err != nil { if err != nil {
return model.List{}, fmt.Errorf("unable to marshal the request body; %w", err) return model.List{}, fmt.Errorf("unable to marshal the form; %w", err)
} }
requestBody := bytes.NewBuffer(data) requestBody := bytes.NewBuffer(data)
@ -106,3 +106,69 @@ func (g *Client) DeleteList(listID string) error {
return g.sendRequest(http.MethodDelete, url, nil, nil) return g.sendRequest(http.MethodDelete, url, nil, nil)
} }
func (g *Client) AddAccountsToList(listID string, accountIDs []string) error {
form := struct {
AccountIDs []string `json:"account_ids"`
}{
AccountIDs: accountIDs,
}
data, err := json.Marshal(form)
if err != nil {
return fmt.Errorf("unable to marshal the form; %w", err)
}
requestBody := bytes.NewBuffer(data)
url := g.Authentication.Instance + listPath + "/" + listID + "/accounts"
if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil {
return fmt.Errorf(
"received an error after sending the request to add the accounts to the list; %w",
err,
)
}
return nil
}
func (g *Client) RemoveAccountsFromList(listID string, accountIDs []string) error {
form := struct {
AccountIDs []string `json:"account_ids"`
}{
AccountIDs: accountIDs,
}
data, err := json.Marshal(form)
if err != nil {
return fmt.Errorf("unable to marshal the form; %w", err)
}
requestBody := bytes.NewBuffer(data)
url := g.Authentication.Instance + listPath + "/" + listID + "/accounts"
if err := g.sendRequest(http.MethodDelete, url, requestBody, nil); err != nil {
return fmt.Errorf(
"received an error after sending the request to remove the accounts from the list; %w",
err,
)
}
return nil
}
func (g *Client) GetAccountsFromList(listID string, limit int) ([]model.Account, error) {
path := fmt.Sprintf("%s/%s/accounts?limit=%d", listPath, listID, limit)
url := g.Authentication.Instance + path
var accounts []model.Account
if err := g.sendRequest(http.MethodGet, url, nil, &accounts); err != nil {
return nil, fmt.Errorf(
"received an error after sending the request to get the accounts from the list; %w",
err,
)
}
return accounts, nil
}