checkpoint: moved all executors to internal package
This commit is contained in:
parent
3e9290897c
commit
8ae4085d84
28 changed files with 994 additions and 905 deletions
147
cmd/enbas/add.go
147
cmd/enbas/add.go
|
@ -1,147 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
type addCommand struct {
|
|
||||||
*flag.FlagSet
|
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
|
||||||
resourceType string
|
|
||||||
toResourceType string
|
|
||||||
listID string
|
|
||||||
accountNames accountNames
|
|
||||||
content string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAddCommand(tlf topLevelFlags, name, summary string) *addCommand {
|
|
||||||
emptyArr := make([]string, 0, 3)
|
|
||||||
|
|
||||||
command := addCommand{
|
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
|
||||||
accountNames: accountNames(emptyArr),
|
|
||||||
topLevelFlags: tlf,
|
|
||||||
}
|
|
||||||
|
|
||||||
command.StringVar(&command.resourceType, flagType, "", "specify the resource type to add (e.g. account, note)")
|
|
||||||
command.StringVar(&command.toResourceType, flagTo, "", "specify the target resource type to add to (e.g. list, account, etc)")
|
|
||||||
command.StringVar(&command.listID, flagListID, "", "the ID of the list to add to")
|
|
||||||
command.Var(&command.accountNames, flagAccountName, "the name of the account to add to the resource")
|
|
||||||
command.StringVar(&command.content, flagContent, "", "the content of the note")
|
|
||||||
|
|
||||||
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
|
|
||||||
|
|
||||||
return &command
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *addCommand) Execute() error {
|
|
||||||
if c.toResourceType == "" {
|
|
||||||
return flagNotSetError{flagText: flagTo}
|
|
||||||
}
|
|
||||||
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceList: c.addToList,
|
|
||||||
resourceAccount: c.addToAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.toResourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedResourceTypeError{resourceType: c.toResourceType}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *addCommand) addToList(gtsClient *client.Client) error {
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceAccount: c.addAccountsToList,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedAddOperationError{
|
|
||||||
ResourceType: c.resourceType,
|
|
||||||
AddToResourceType: c.toResourceType,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *addCommand) addAccountsToList(gtsClient *client.Client) error {
|
|
||||||
if c.listID == "" {
|
|
||||||
return flagNotSetError{flagText: flagListID}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(c.accountNames) == 0 {
|
|
||||||
return noAccountSpecifiedError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Successfully added the account(s) to the list.")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *addCommand) addToAccount(gtsClient *client.Client) error {
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceNote: c.addNoteToAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedAddOperationError{
|
|
||||||
ResourceType: c.resourceType,
|
|
||||||
AddToResourceType: c.toResourceType,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *addCommand) addNoteToAccount(gtsClient *client.Client) error {
|
|
||||||
if len(c.accountNames) != 1 {
|
|
||||||
return fmt.Errorf("unexpected number of accounts specified; want 1, got %d", len(c.accountNames))
|
|
||||||
}
|
|
||||||
|
|
||||||
accountID, err := getAccountID(gtsClient, false, c.accountNames[0], c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.content == "" {
|
|
||||||
return errors.New("the note content should not be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gtsClient.SetPrivateNote(accountID, c.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
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
type blockCommand struct {
|
|
||||||
*flag.FlagSet
|
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
|
||||||
resourceType string
|
|
||||||
accountName string
|
|
||||||
unblock bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBlockCommand(tlf topLevelFlags, name, summary string, unblock bool) *blockCommand {
|
|
||||||
command := blockCommand{
|
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
|
||||||
|
|
||||||
topLevelFlags: tlf,
|
|
||||||
unblock: unblock,
|
|
||||||
}
|
|
||||||
|
|
||||||
command.StringVar(&command.resourceType, flagType, "", "specify the type of resource to block or unblock")
|
|
||||||
command.StringVar(&command.accountName, flagAccountName, "", "specify the account name in full (username@domain)")
|
|
||||||
|
|
||||||
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
|
|
||||||
|
|
||||||
return &command
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *blockCommand) Execute() error {
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceAccount: c.blockAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedResourceTypeError{resourceType: c.resourceType}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *blockCommand) blockAccount(gtsClient *client.Client) error {
|
|
||||||
accountID, err := getAccountID(gtsClient, false, c.accountName, c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.unblock {
|
|
||||||
return c.unblockAccount(gtsClient, accountID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gtsClient.BlockAccount(accountID); err != nil {
|
|
||||||
return fmt.Errorf("unable to block the account; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Successfully blocked the account.")
|
|
||||||
|
|
||||||
return 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Successfully unblocked the account.")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
type deleteCommand struct {
|
|
||||||
*flag.FlagSet
|
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
|
||||||
resourceType string
|
|
||||||
listID string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDeleteCommand(tlf topLevelFlags, name, summary string) *deleteCommand {
|
|
||||||
command := deleteCommand{
|
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
|
||||||
|
|
||||||
topLevelFlags: tlf,
|
|
||||||
}
|
|
||||||
|
|
||||||
command.StringVar(&command.resourceType, flagType, "", "specify the type of resource to delete")
|
|
||||||
command.StringVar(&command.listID, flagListID, "", "specify the ID of the list to delete")
|
|
||||||
|
|
||||||
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
|
|
||||||
|
|
||||||
return &command
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *deleteCommand) Execute() error {
|
|
||||||
if c.resourceType == "" {
|
|
||||||
return flagNotSetError{flagText: flagType}
|
|
||||||
}
|
|
||||||
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceList: c.deleteList,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedResourceTypeError{resourceType: c.resourceType}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *deleteCommand) deleteList(gtsClient *client.Client) error {
|
|
||||||
if c.listID == "" {
|
|
||||||
return flagNotSetError{flagText: flagListID}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gtsClient.DeleteList(c.listID); err != nil {
|
|
||||||
return fmt.Errorf("unable to delete the list; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("The list was successfully deleted.")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,57 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type flagNotSetError struct {
|
type unknownCommandError struct {
|
||||||
flagText string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e flagNotSetError) Error() string {
|
|
||||||
return "the flag '" + e.flagText + "' is not set"
|
|
||||||
}
|
|
||||||
|
|
||||||
type unsupportedResourceTypeError struct {
|
|
||||||
resourceType string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e unsupportedResourceTypeError) Error() string {
|
|
||||||
return "unsupported resource type '" + e.resourceType + "'"
|
|
||||||
}
|
|
||||||
|
|
||||||
type invalidTimelineCategoryError struct {
|
|
||||||
category string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e invalidTimelineCategoryError) Error() string {
|
|
||||||
return "'" + e.category + "' is not a valid timeline category (please choose home, public, tag or list)"
|
|
||||||
}
|
|
||||||
|
|
||||||
type unknownSubcommandError struct {
|
|
||||||
subcommand string
|
subcommand string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e unknownSubcommandError) Error() string {
|
func (e unknownCommandError) Error() string {
|
||||||
return "unknown subcommand '" + e.subcommand + "'"
|
return "unknown command '" + e.subcommand + "'"
|
||||||
}
|
|
||||||
|
|
||||||
type noAccountSpecifiedError struct{}
|
|
||||||
|
|
||||||
func (e noAccountSpecifiedError) Error() string {
|
|
||||||
return "no account specified in this request"
|
|
||||||
}
|
|
||||||
|
|
||||||
type unsupportedAddOperationError struct {
|
|
||||||
ResourceType string
|
|
||||||
AddToResourceType string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e unsupportedAddOperationError) Error() string {
|
|
||||||
return "adding '" + e.ResourceType + "' to '" + e.AddToResourceType + "' is not supported"
|
|
||||||
}
|
|
||||||
|
|
||||||
type unsupportedRemoveOperationError struct {
|
|
||||||
ResourceType string
|
|
||||||
RemoveFromResourceType string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e unsupportedRemoveOperationError) Error() string {
|
|
||||||
return "removing '" + e.ResourceType + "' from '" + e.RemoveFromResourceType + "' is not supported"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
type accountNames []string
|
|
||||||
|
|
||||||
func (a *accountNames) String() string {
|
|
||||||
return strings.Join(*a, ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *accountNames) Set(value string) error {
|
|
||||||
if len(value) > 0 {
|
|
||||||
*a = append(*a, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type topLevelFlags struct {
|
|
||||||
configDir string
|
|
||||||
}
|
|
|
@ -4,47 +4,36 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/executor"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
flagAccountName = "account-name"
|
commandLogin string = "login"
|
||||||
flagTo = "to"
|
commandVersion string = "version"
|
||||||
flagContent = "content"
|
commandShow string = "show"
|
||||||
flagInstance = "instance"
|
commandSwitch string = "switch"
|
||||||
flagLimit = "limit"
|
commandCreate string = "create"
|
||||||
flagListID = "list-id"
|
commandDelete string = "delete"
|
||||||
flagListTitle = "list-title"
|
commandEdit string = "edit"
|
||||||
flagListRepliesPolicy = "list-replies-policy"
|
commandWhoami string = "whoami"
|
||||||
flagMyAccount = "my-account"
|
commandAdd string = "add"
|
||||||
flagNotify = "notify"
|
commandRemove string = "remove"
|
||||||
flagFrom = "from"
|
commandFollow string = "follow"
|
||||||
flagType = "type"
|
commandUnfollow string = "unfollow"
|
||||||
flagShowRelationship = "show-relationship"
|
commandBlock string = "block"
|
||||||
flagShowPreferences = "show-preferences"
|
commandUnblock string = "unblock"
|
||||||
flagShowReposts = "show-reposts"
|
|
||||||
flagStatusID = "status-id"
|
|
||||||
flagTag = "tag"
|
|
||||||
flagTimelineCategory = "timeline-category"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var (
|
||||||
resourceAccount = "account"
|
binaryVersion string
|
||||||
resourceBlocked = "blocked"
|
buildTime string
|
||||||
resourceFollowers = "followers"
|
goVersion string
|
||||||
resourceFollowing = "following"
|
gitCommit string
|
||||||
resourceInstance = "instance"
|
|
||||||
resourceList = "list"
|
|
||||||
resourceNote = "note"
|
|
||||||
resourceStatus = "status"
|
|
||||||
resourceTimeline = "timeline"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Executor interface {
|
|
||||||
Name() string
|
|
||||||
Parse(args []string) error
|
|
||||||
Execute() error
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := run(); err != nil {
|
if err := run(); err != nil {
|
||||||
fmt.Printf("ERROR: %v.\n", err)
|
fmt.Printf("ERROR: %v.\n", err)
|
||||||
|
@ -53,31 +42,14 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
func run() error {
|
||||||
const (
|
|
||||||
commandLogin string = "login"
|
|
||||||
commandVersion string = "version"
|
|
||||||
commandShow string = "show"
|
|
||||||
commandSwitchAccount string = "switch-account"
|
|
||||||
commandCreate string = "create"
|
|
||||||
commandDelete string = "delete"
|
|
||||||
commandUpdate string = "update"
|
|
||||||
commandWhoami string = "whoami"
|
|
||||||
commandAdd string = "add"
|
|
||||||
commandRemove string = "remove"
|
|
||||||
commandFollow string = "follow"
|
|
||||||
commandUnfollow string = "unfollow"
|
|
||||||
commandBlock string = "block"
|
|
||||||
commandUnblock string = "unblock"
|
|
||||||
)
|
|
||||||
|
|
||||||
commandSummaries := map[string]string{
|
commandSummaries := map[string]string{
|
||||||
commandLogin: "login to an account on GoToSocial",
|
commandLogin: "login to an account on GoToSocial",
|
||||||
commandVersion: "print the application's version and build information",
|
commandVersion: "print the application's version and build information",
|
||||||
commandShow: "print details about a specified resource",
|
commandShow: "print details about a specified resource",
|
||||||
commandSwitchAccount: "switch to a different account",
|
commandSwitch: "switch to a different account",
|
||||||
commandCreate: "create a specific resource",
|
commandCreate: "create a specific resource",
|
||||||
commandDelete: "delete a specific resource",
|
commandDelete: "delete a specific resource",
|
||||||
commandUpdate: "update a specific resource",
|
commandEdit: "edit a specific resource",
|
||||||
commandWhoami: "print the account that you are currently logged in to",
|
commandWhoami: "print the account that you are currently logged in to",
|
||||||
commandAdd: "add a resource to another resource",
|
commandAdd: "add a resource to another resource",
|
||||||
commandRemove: "remove a resource from another resource",
|
commandRemove: "remove a resource from another resource",
|
||||||
|
@ -87,11 +59,11 @@ func run() error {
|
||||||
commandUnblock: "unblock a resource (e.g. an account)",
|
commandUnblock: "unblock a resource (e.g. an account)",
|
||||||
}
|
}
|
||||||
|
|
||||||
tlf := topLevelFlags{}
|
topLevelFlags := executor.TopLevelFlags{}
|
||||||
|
|
||||||
flag.StringVar(&tlf.configDir, "config-dir", "", "specify your config directory")
|
flag.StringVar(&topLevelFlags.ConfigDir, "config-dir", "", "specify your config directory")
|
||||||
|
|
||||||
flag.Usage = enbasUsageFunc(commandSummaries)
|
flag.Usage = usageFunc(commandSummaries)
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
@ -104,54 +76,143 @@ func run() error {
|
||||||
command := flag.Arg(0)
|
command := flag.Arg(0)
|
||||||
args := flag.Args()[1:]
|
args := flag.Args()[1:]
|
||||||
|
|
||||||
// TODO: will not be needed anymore
|
var err error
|
||||||
var executor Executor
|
|
||||||
|
|
||||||
switch command {
|
switch command {
|
||||||
case commandLogin:
|
|
||||||
executor = newLoginCommand(tlf, commandLogin, commandSummaries[commandLogin])
|
|
||||||
case commandVersion:
|
|
||||||
executor = newVersionCommand(commandVersion, commandSummaries[commandVersion])
|
|
||||||
case commandShow:
|
|
||||||
executor = newShowCommand(tlf, commandShow, commandSummaries[commandShow])
|
|
||||||
case commandSwitchAccount:
|
|
||||||
executor = newSwitchCommand(tlf, commandSwitchAccount, commandSummaries[commandSwitchAccount])
|
|
||||||
case commandCreate:
|
|
||||||
executor = newCreateCommand(tlf, commandCreate, commandSummaries[commandCreate])
|
|
||||||
case commandDelete:
|
|
||||||
executor = newDeleteCommand(tlf, commandDelete, commandSummaries[commandDelete])
|
|
||||||
case commandUpdate:
|
|
||||||
executor = newUpdateCommand(tlf, commandUpdate, commandSummaries[commandUpdate])
|
|
||||||
case commandWhoami:
|
|
||||||
executor = newWhoAmICommand(tlf, commandWhoami, commandSummaries[commandWhoami])
|
|
||||||
case commandAdd:
|
case commandAdd:
|
||||||
executor = newAddCommand(tlf, commandAdd, commandSummaries[commandAdd])
|
exe := executor.NewAddExecutor(
|
||||||
case commandRemove:
|
topLevelFlags,
|
||||||
executor = newRemoveCommand(tlf, commandRemove, commandSummaries[commandRemove])
|
commandAdd,
|
||||||
case commandFollow:
|
commandSummaries[commandAdd],
|
||||||
executor = newFollowCommand(tlf, commandFollow, commandSummaries[commandFollow], false)
|
)
|
||||||
case commandUnfollow:
|
err = executor.Execute(exe, args)
|
||||||
executor = newFollowCommand(tlf, commandUnfollow, commandSummaries[commandUnfollow], true)
|
|
||||||
case commandBlock:
|
case commandBlock:
|
||||||
executor = newBlockCommand(tlf, commandBlock, commandSummaries[commandBlock], false)
|
exe := executor.NewBlockExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandBlock,
|
||||||
|
commandSummaries[commandBlock],
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandCreate:
|
||||||
|
exe := executor.NewCreateExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandCreate,
|
||||||
|
commandSummaries[commandCreate],
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandDelete:
|
||||||
|
exe := executor.NewDeleteExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandDelete,
|
||||||
|
commandSummaries[commandDelete],
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandEdit:
|
||||||
|
exe := executor.NewEditExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandEdit,
|
||||||
|
commandSummaries[commandEdit],
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandFollow:
|
||||||
|
exe := executor.NewFollowExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandFollow,
|
||||||
|
commandSummaries[commandFollow],
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandLogin:
|
||||||
|
exe := executor.NewLoginExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandLogin,
|
||||||
|
commandSummaries[commandLogin],
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandRemove:
|
||||||
|
exe := executor.NewRemoveExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandRemove,
|
||||||
|
commandSummaries[commandRemove],
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandSwitch:
|
||||||
|
exe := executor.NewSwitchExecutor(
|
||||||
|
topLevelFlags,
|
||||||
|
commandSwitch,
|
||||||
|
commandSummaries[commandSwitch],
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandUnfollow:
|
||||||
|
exe := executor.NewFollowExecutor(topLevelFlags, commandUnfollow, commandSummaries[commandUnfollow], true)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
case commandUnblock:
|
case commandUnblock:
|
||||||
executor = newBlockCommand(tlf, commandUnblock, commandSummaries[commandUnblock], true)
|
exe := executor.NewBlockExecutor(topLevelFlags, commandUnblock, commandSummaries[commandUnblock], true)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandShow:
|
||||||
|
exe := executor.NewShowExecutor(topLevelFlags, commandShow, commandSummaries[commandShow])
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandVersion:
|
||||||
|
exe := executor.NewVersionExecutor(
|
||||||
|
commandVersion,
|
||||||
|
commandSummaries[commandVersion],
|
||||||
|
binaryVersion,
|
||||||
|
buildTime,
|
||||||
|
goVersion,
|
||||||
|
gitCommit,
|
||||||
|
)
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
|
case commandWhoami:
|
||||||
|
exe := executor.NewWhoAmIExecutor(topLevelFlags, commandWhoami, commandSummaries[commandWhoami])
|
||||||
|
err = executor.Execute(exe, args)
|
||||||
default:
|
default:
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
|
|
||||||
return unknownSubcommandError{command}
|
return unknownCommandError{command}
|
||||||
}
|
}
|
||||||
|
|
||||||
// To Do: create a function in executor package that will take in concrete type
|
if err != nil {
|
||||||
// as interface and run the parse and execute command.
|
return fmt.Errorf("received an error executing the command; %w", err)
|
||||||
|
|
||||||
if err := executor.Parse(args); err != nil {
|
|
||||||
return fmt.Errorf("unable to parse the command line flags; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := executor.Execute(); err != nil {
|
|
||||||
return fmt.Errorf("received an error after executing %q; %w", executor.Name(), err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func usageFunc(summaries map[string]string) func() {
|
||||||
|
cmds := make([]string, len(summaries))
|
||||||
|
ind := 0
|
||||||
|
|
||||||
|
for k := range summaries {
|
||||||
|
cmds[ind] = k
|
||||||
|
ind++
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.Sort(cmds)
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
var builder strings.Builder
|
||||||
|
|
||||||
|
builder.WriteString("SUMMARY:\n enbas - A GoToSocial client for the terminal.\n\n")
|
||||||
|
|
||||||
|
if binaryVersion != "" {
|
||||||
|
builder.WriteString("VERSION:\n " + binaryVersion + "\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("USAGE:\n enbas [flags]\n enbas [command]\n\nCOMMANDS:")
|
||||||
|
|
||||||
|
for _, cmd := range cmds {
|
||||||
|
fmt.Fprintf(&builder, "\n %s\t%s", cmd, summaries[cmd])
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n\nFLAGS:\n --help\n print the help message\n")
|
||||||
|
flag.VisitAll(func(f *flag.Flag) {
|
||||||
|
fmt.Fprintf(&builder, "\n --%s\n %s\n", f.Name, f.Usage)
|
||||||
|
})
|
||||||
|
|
||||||
|
builder.WriteString("\nUse \"enbas [command] --help\" for more information about a command.\n")
|
||||||
|
|
||||||
|
w := flag.CommandLine.Output()
|
||||||
|
fmt.Fprint(w, builder.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
type removeCommand struct {
|
|
||||||
*flag.FlagSet
|
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
|
||||||
resourceType string
|
|
||||||
fromResourceType string
|
|
||||||
listID string
|
|
||||||
accountNames accountNames
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRemoveCommand(tlf topLevelFlags, name, summary string) *removeCommand {
|
|
||||||
emptyArr := make([]string, 0, 3)
|
|
||||||
|
|
||||||
command := removeCommand{
|
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
|
||||||
accountNames: accountNames(emptyArr),
|
|
||||||
topLevelFlags: tlf,
|
|
||||||
}
|
|
||||||
|
|
||||||
command.StringVar(&command.resourceType, flagType, "", "specify the resource type to remove (e.g. account, note)")
|
|
||||||
command.StringVar(&command.fromResourceType, flagFrom, "", "specify the resource type to remove from (e.g. list, account, etc)")
|
|
||||||
command.StringVar(&command.listID, flagListID, "", "the ID of the list to remove from")
|
|
||||||
command.Var(&command.accountNames, flagAccountName, "the name of the account to remove from the resource")
|
|
||||||
|
|
||||||
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
|
|
||||||
|
|
||||||
return &command
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *removeCommand) Execute() error {
|
|
||||||
if c.fromResourceType == "" {
|
|
||||||
return flagNotSetError{flagText: flagFrom}
|
|
||||||
}
|
|
||||||
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceList: c.removeFromList,
|
|
||||||
resourceAccount: c.removeFromAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.fromResourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedResourceTypeError{resourceType: c.fromResourceType}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *removeCommand) removeFromList(gtsClient *client.Client) error {
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceAccount: c.removeAccountsFromList,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedRemoveOperationError{
|
|
||||||
ResourceType: c.resourceType,
|
|
||||||
RemoveFromResourceType: c.fromResourceType,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *removeCommand) removeAccountsFromList(gtsClient *client.Client) error {
|
|
||||||
if c.listID == "" {
|
|
||||||
return flagNotSetError{flagText: flagListID}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(c.accountNames) == 0 {
|
|
||||||
return noAccountSpecifiedError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Successfully removed the account(s) from the list.")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *removeCommand) removeFromAccount(gtsClient *client.Client) error {
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceNote: c.removeNoteFromAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedRemoveOperationError{
|
|
||||||
ResourceType: c.resourceType,
|
|
||||||
RemoveFromResourceType: c.fromResourceType,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *removeCommand) removeNoteFromAccount(gtsClient *client.Client) error {
|
|
||||||
if len(c.accountNames) != 1 {
|
|
||||||
return fmt.Errorf("unexpected number of accounts specified; want 1, got %d", len(c.accountNames))
|
|
||||||
}
|
|
||||||
|
|
||||||
accountID, err := getAccountID(gtsClient, false, c.accountNames[0], c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gtsClient.SetPrivateNote(accountID, ""); err != nil {
|
|
||||||
return fmt.Errorf("unable to remove the private note from the account; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Successfully removed the private note from the account.")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
type switchCommand struct {
|
|
||||||
*flag.FlagSet
|
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
|
||||||
toAccount string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSwitchCommand(tlf topLevelFlags, name, summary string) *switchCommand {
|
|
||||||
command := switchCommand{
|
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
|
||||||
topLevelFlags: tlf,
|
|
||||||
}
|
|
||||||
|
|
||||||
command.StringVar(&command.toAccount, flagTo, "", "the account to switch to")
|
|
||||||
|
|
||||||
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
|
|
||||||
|
|
||||||
return &command
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *switchCommand) Execute() error {
|
|
||||||
if c.toAccount == "" {
|
|
||||||
return flagNotSetError{flagText: flagTo}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := config.UpdateCurrentAccount(c.toAccount, c.topLevelFlags.configDir); err != nil {
|
|
||||||
return fmt.Errorf("unable to switch accounts; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("The current account is now set to %q.\n", c.toAccount)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type updateCommand struct {
|
|
||||||
*flag.FlagSet
|
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
|
||||||
resourceType string
|
|
||||||
listID string
|
|
||||||
listTitle string
|
|
||||||
listRepliesPolicy string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newUpdateCommand(tlf topLevelFlags, name, summary string) *updateCommand {
|
|
||||||
command := updateCommand{
|
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
|
||||||
topLevelFlags: tlf,
|
|
||||||
}
|
|
||||||
|
|
||||||
command.StringVar(&command.resourceType, flagType, "", "specify the type of resource to update")
|
|
||||||
command.StringVar(&command.listID, flagListID, "", "specify the ID of the list to update")
|
|
||||||
command.StringVar(&command.listTitle, flagListTitle, "", "specify the title of the list")
|
|
||||||
command.StringVar(&command.listRepliesPolicy, flagListRepliesPolicy, "", "specify the policy of the replies for this list (valid values are followed, list and none)")
|
|
||||||
|
|
||||||
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
|
|
||||||
|
|
||||||
return &command
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *updateCommand) Execute() error {
|
|
||||||
if c.resourceType == "" {
|
|
||||||
return flagNotSetError{flagText: flagType}
|
|
||||||
}
|
|
||||||
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
|
||||||
resourceList: c.updateList,
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
|
||||||
if !ok {
|
|
||||||
return unsupportedResourceTypeError{resourceType: c.resourceType}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *updateCommand) updateList(gtsClient *client.Client) error {
|
|
||||||
if c.listID == "" {
|
|
||||||
return flagNotSetError{flagText: flagListID}
|
|
||||||
}
|
|
||||||
|
|
||||||
list, err := gtsClient.GetList(c.listID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to get the list; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.listTitle != "" {
|
|
||||||
list.Title = c.listTitle
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.listRepliesPolicy != "" {
|
|
||||||
repliesPolicy, err := model.ParseListRepliesPolicy(c.listRepliesPolicy)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to parse the list replies policy; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
list.RepliesPolicy = repliesPolicy
|
|
||||||
}
|
|
||||||
|
|
||||||
updatedList, err := gtsClient.UpdateList(list)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to update the list; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Successfully updated the list.")
|
|
||||||
fmt.Println(updatedList)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"slices"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func commandUsageFunc(name, summary string, flagset *flag.FlagSet) func() {
|
|
||||||
return func() {
|
|
||||||
var builder strings.Builder
|
|
||||||
|
|
||||||
fmt.Fprintf(
|
|
||||||
&builder,
|
|
||||||
"SUMMARY:\n %s - %s\n\nUSAGE:\n enbas %s [flags]\n\nFLAGS:",
|
|
||||||
name,
|
|
||||||
summary,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
|
|
||||||
flagset.VisitAll(func(f *flag.Flag) {
|
|
||||||
fmt.Fprintf(
|
|
||||||
&builder,
|
|
||||||
"\n --%s\n %s",
|
|
||||||
f.Name,
|
|
||||||
f.Usage,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
builder.WriteString("\n")
|
|
||||||
|
|
||||||
w := flag.CommandLine.Output()
|
|
||||||
|
|
||||||
fmt.Fprint(w, builder.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func enbasUsageFunc(summaries map[string]string) func() {
|
|
||||||
cmds := make([]string, len(summaries))
|
|
||||||
ind := 0
|
|
||||||
|
|
||||||
for k := range summaries {
|
|
||||||
cmds[ind] = k
|
|
||||||
ind++
|
|
||||||
}
|
|
||||||
|
|
||||||
slices.Sort(cmds)
|
|
||||||
|
|
||||||
return func() {
|
|
||||||
var builder strings.Builder
|
|
||||||
|
|
||||||
builder.WriteString("SUMMARY:\n enbas - A GoToSocial client for the terminal.\n\n")
|
|
||||||
|
|
||||||
if binaryVersion != "" {
|
|
||||||
builder.WriteString("VERSION:\n " + binaryVersion + "\n\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("USAGE:\n enbas [flags]\n enbas [command]\n\nCOMMANDS:")
|
|
||||||
|
|
||||||
for _, cmd := range cmds {
|
|
||||||
fmt.Fprintf(&builder, "\n %s\t%s", cmd, summaries[cmd])
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("\n\nFLAGS:\n --help\n print the help message\n")
|
|
||||||
flag.VisitAll(func(f *flag.Flag) {
|
|
||||||
fmt.Fprintf(&builder, "\n --%s\n %s\n", f.Name, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
builder.WriteString("\nUse \"enbas [command] --help\" for more information about a command.\n")
|
|
||||||
|
|
||||||
w := flag.CommandLine.Output()
|
|
||||||
fmt.Fprint(w, builder.String())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -26,7 +26,7 @@ func getAccountID(gtsClient *client.Client, myAccount bool, accountName, configD
|
||||||
return "", fmt.Errorf("unable to get their account ID; %w", err)
|
return "", fmt.Errorf("unable to get their account ID; %w", err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return "", noAccountSpecifiedError{}
|
return "", NoAccountSpecifiedError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return accountID, nil
|
return accountID, nil
|
146
internal/executor/add.go
Normal file
146
internal/executor/add.go
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
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
|
||||||
|
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.Var(&addExe.accountNames, flagAccountName, "the name of the account to add to the resource")
|
||||||
|
addExe.StringVar(&addExe.content, flagContent, "", "the content of the note")
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
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{}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
80
internal/executor/block.go
Normal file
80
internal/executor/block.go
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BlockExecutor struct {
|
||||||
|
*flag.FlagSet
|
||||||
|
|
||||||
|
topLevelFlags TopLevelFlags
|
||||||
|
resourceType string
|
||||||
|
accountName string
|
||||||
|
unblock bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBlockExecutor(tlf TopLevelFlags, name, summary string, unblock bool) *BlockExecutor {
|
||||||
|
blockExe := BlockExecutor{
|
||||||
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
|
|
||||||
|
topLevelFlags: tlf,
|
||||||
|
unblock: unblock,
|
||||||
|
}
|
||||||
|
|
||||||
|
blockExe.StringVar(&blockExe.resourceType, flagType, "", "specify the type of resource to block or unblock")
|
||||||
|
blockExe.StringVar(&blockExe.accountName, flagAccountName, "", "specify the account name in full (username@domain)")
|
||||||
|
|
||||||
|
blockExe.Usage = commandUsageFunc(name, summary, blockExe.FlagSet)
|
||||||
|
|
||||||
|
return &blockExe
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BlockExecutor) Execute() error {
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceAccount: b.blockAccount,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[b.resourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedTypeError{resourceType: b.resourceType}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtsClient, err := client.NewClientFromConfig(b.topLevelFlags.ConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BlockExecutor) blockAccount(gtsClient *client.Client) error {
|
||||||
|
accountID, err := getAccountID(gtsClient, false, b.accountName, b.topLevelFlags.ConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.unblock {
|
||||||
|
return b.unblockAccount(gtsClient, accountID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gtsClient.BlockAccount(accountID); err != nil {
|
||||||
|
return fmt.Errorf("unable to block the account; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Successfully blocked the account.")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BlockExecutor) unblockAccount(gtsClient *client.Client, accountID string) error {
|
||||||
|
if err := gtsClient.UnblockAccount(accountID); err != nil {
|
||||||
|
return fmt.Errorf("unable to unblock the account; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Successfully unblocked the account.")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
32
internal/executor/const.go
Normal file
32
internal/executor/const.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
const (
|
||||||
|
flagAccountName = "account-name"
|
||||||
|
flagContent = "content"
|
||||||
|
flagInstance = "instance"
|
||||||
|
flagLimit = "limit"
|
||||||
|
flagListID = "list-id"
|
||||||
|
flagListTitle = "list-title"
|
||||||
|
flagListRepliesPolicy = "list-replies-policy"
|
||||||
|
flagMyAccount = "my-account"
|
||||||
|
flagNotify = "notify"
|
||||||
|
flagFrom = "from"
|
||||||
|
flagType = "type"
|
||||||
|
flagShowRelationship = "show-relationship"
|
||||||
|
flagShowPreferences = "show-preferences"
|
||||||
|
flagShowReposts = "show-reposts"
|
||||||
|
flagStatusID = "status-id"
|
||||||
|
flagTag = "tag"
|
||||||
|
flagTimelineCategory = "timeline-category"
|
||||||
|
flagTo = "to"
|
||||||
|
|
||||||
|
resourceAccount = "account"
|
||||||
|
resourceBlocked = "blocked"
|
||||||
|
resourceFollowers = "followers"
|
||||||
|
resourceFollowing = "following"
|
||||||
|
resourceInstance = "instance"
|
||||||
|
resourceList = "list"
|
||||||
|
resourceNote = "note"
|
||||||
|
resourceStatus = "status"
|
||||||
|
resourceTimeline = "timeline"
|
||||||
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -8,37 +8,37 @@ import (
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type createCommand struct {
|
type CreateExecutor struct {
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
topLevelFlags TopLevelFlags
|
||||||
resourceType string
|
resourceType string
|
||||||
listTitle string
|
listTitle string
|
||||||
listRepliesPolicy string
|
listRepliesPolicy string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCreateCommand(tlf topLevelFlags, name, summary string) *createCommand {
|
func NewCreateExecutor(tlf TopLevelFlags, name, summary string) *CreateExecutor {
|
||||||
command := createCommand{
|
createExe := CreateExecutor{
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
|
|
||||||
topLevelFlags: tlf,
|
topLevelFlags: tlf,
|
||||||
}
|
}
|
||||||
|
|
||||||
command.StringVar(&command.resourceType, flagType, "", "specify the type of resource to create")
|
createExe.StringVar(&createExe.resourceType, flagType, "", "specify the type of resource to create")
|
||||||
command.StringVar(&command.listTitle, flagListTitle, "", "specify the title of the list")
|
createExe.StringVar(&createExe.listTitle, flagListTitle, "", "specify the title of the list")
|
||||||
command.StringVar(&command.listRepliesPolicy, flagListRepliesPolicy, "list", "specify the policy of the replies for this list (valid values are followed, list and none)")
|
createExe.StringVar(&createExe.listRepliesPolicy, flagListRepliesPolicy, "list", "specify the policy of the replies for this list (valid values are followed, list and none)")
|
||||||
|
|
||||||
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
|
createExe.Usage = commandUsageFunc(name, summary, createExe.FlagSet)
|
||||||
|
|
||||||
return &command
|
return &createExe
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *createCommand) Execute() error {
|
func (c *CreateExecutor) Execute() error {
|
||||||
if c.resourceType == "" {
|
if c.resourceType == "" {
|
||||||
return flagNotSetError{flagText: flagType}
|
return FlagNotSetError{flagText: flagType}
|
||||||
}
|
}
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||||
}
|
}
|
||||||
|
@ -49,15 +49,15 @@ func (c *createCommand) Execute() error {
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
doFunc, ok := funcMap[c.resourceType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return unsupportedResourceTypeError{resourceType: c.resourceType}
|
return UnsupportedTypeError{resourceType: c.resourceType}
|
||||||
}
|
}
|
||||||
|
|
||||||
return doFunc(gtsClient)
|
return doFunc(gtsClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *createCommand) createList(gtsClient *client.Client) error {
|
func (c *CreateExecutor) createList(gtsClient *client.Client) error {
|
||||||
if c.listTitle == "" {
|
if c.listTitle == "" {
|
||||||
return flagNotSetError{flagText: flagListTitle}
|
return FlagNotSetError{flagText: flagListTitle}
|
||||||
}
|
}
|
||||||
|
|
||||||
repliesPolicy, err := model.ParseListRepliesPolicy(c.listRepliesPolicy)
|
repliesPolicy, err := model.ParseListRepliesPolicy(c.listRepliesPolicy)
|
66
internal/executor/delete.go
Normal file
66
internal/executor/delete.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteExecutor struct {
|
||||||
|
*flag.FlagSet
|
||||||
|
|
||||||
|
topLevelFlags TopLevelFlags
|
||||||
|
resourceType string
|
||||||
|
listID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDeleteExecutor(tlf TopLevelFlags, name, summary string) *DeleteExecutor {
|
||||||
|
deleteExe := DeleteExecutor{
|
||||||
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
|
topLevelFlags: tlf,
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteExe.StringVar(&deleteExe.resourceType, flagType, "", "specify the type of resource to delete")
|
||||||
|
deleteExe.StringVar(&deleteExe.listID, flagListID, "", "specify the ID of the list to delete")
|
||||||
|
|
||||||
|
deleteExe.Usage = commandUsageFunc(name, summary, deleteExe.FlagSet)
|
||||||
|
|
||||||
|
return &deleteExe
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DeleteExecutor) Execute() error {
|
||||||
|
if d.resourceType == "" {
|
||||||
|
return FlagNotSetError{flagText: flagType}
|
||||||
|
}
|
||||||
|
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceList: d.deleteList,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[d.resourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedTypeError{resourceType: d.resourceType}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtsClient, err := client.NewClientFromConfig(d.topLevelFlags.ConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DeleteExecutor) deleteList(gtsClient *client.Client) error {
|
||||||
|
if d.listID == "" {
|
||||||
|
return FlagNotSetError{flagText: flagListID}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gtsClient.DeleteList(d.listID); err != nil {
|
||||||
|
return fmt.Errorf("unable to delete the list; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("The list was successfully deleted.")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
55
internal/executor/errors.go
Normal file
55
internal/executor/errors.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
type FlagNotSetError struct {
|
||||||
|
flagText string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e FlagNotSetError) Error() string {
|
||||||
|
return "the flag '" + e.flagText + "' is not set"
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnsupportedTypeError struct {
|
||||||
|
resourceType string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UnsupportedTypeError) Error() string {
|
||||||
|
return "unsupported resource type '" + e.resourceType + "'"
|
||||||
|
}
|
||||||
|
|
||||||
|
type InvalidTimelineCategoryError struct {
|
||||||
|
category string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e InvalidTimelineCategoryError) Error() string {
|
||||||
|
return "'" + e.category + "' is not a valid timeline category (please choose home, public, tag or list)"
|
||||||
|
}
|
||||||
|
|
||||||
|
type NoAccountSpecifiedError struct{}
|
||||||
|
|
||||||
|
func (e NoAccountSpecifiedError) Error() string {
|
||||||
|
return "no account specified in this request"
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnsupportedAddOperationError struct {
|
||||||
|
ResourceType string
|
||||||
|
AddToResourceType string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UnsupportedAddOperationError) Error() string {
|
||||||
|
return "adding '" + e.ResourceType + "' to '" + e.AddToResourceType + "' is not supported"
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnsupportedRemoveOperationError struct {
|
||||||
|
ResourceType string
|
||||||
|
RemoveFromResourceType string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UnsupportedRemoveOperationError) Error() string {
|
||||||
|
return "removing '" + e.ResourceType + "' from '" + e.RemoveFromResourceType + "' is not supported"
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmptyContentError struct{}
|
||||||
|
|
||||||
|
func (e EmptyContentError) Error() string {
|
||||||
|
return "content should not be empty"
|
||||||
|
}
|
21
internal/executor/executor.go
Normal file
21
internal/executor/executor.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Executor interface {
|
||||||
|
Name() string
|
||||||
|
Parse(args []string) error
|
||||||
|
Execute() error
|
||||||
|
}
|
||||||
|
|
||||||
|
func Execute(executor Executor, args []string) error {
|
||||||
|
if err := executor.Parse(args); err != nil {
|
||||||
|
return fmt.Errorf("unable to parse the command line flags; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := executor.Execute(); err != nil {
|
||||||
|
return fmt.Errorf("unable to execute the command %q; %w", executor.Name(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
21
internal/executor/flags.go
Normal file
21
internal/executor/flags.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
type AccountNames []string
|
||||||
|
|
||||||
|
func (a *AccountNames) String() string {
|
||||||
|
return strings.Join(*a, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AccountNames) Set(value string) error {
|
||||||
|
if len(value) > 0 {
|
||||||
|
*a = append(*a, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TopLevelFlags struct {
|
||||||
|
ConfigDir string
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -7,10 +7,10 @@ import (
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
type followCommand struct {
|
type FollowExecutor struct {
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
topLevelFlags TopLevelFlags
|
||||||
resourceType string
|
resourceType string
|
||||||
accountName string
|
accountName string
|
||||||
showReposts bool
|
showReposts bool
|
||||||
|
@ -18,8 +18,8 @@ type followCommand struct {
|
||||||
unfollow bool
|
unfollow bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFollowCommand(tlf topLevelFlags, name, summary string, unfollow bool) *followCommand {
|
func NewFollowExecutor(tlf TopLevelFlags, name, summary string, unfollow bool) *FollowExecutor {
|
||||||
command := followCommand{
|
command := FollowExecutor{
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
unfollow: unfollow,
|
unfollow: unfollow,
|
||||||
topLevelFlags: tlf,
|
topLevelFlags: tlf,
|
||||||
|
@ -35,17 +35,17 @@ func newFollowCommand(tlf topLevelFlags, name, summary string, unfollow bool) *f
|
||||||
return &command
|
return &command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *followCommand) Execute() error {
|
func (c *FollowExecutor) Execute() error {
|
||||||
funcMap := map[string]func(*client.Client) error{
|
funcMap := map[string]func(*client.Client) error{
|
||||||
resourceAccount: c.followAccount,
|
resourceAccount: c.followAccount,
|
||||||
}
|
}
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
doFunc, ok := funcMap[c.resourceType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return unsupportedResourceTypeError{resourceType: c.resourceType}
|
return UnsupportedTypeError{resourceType: c.resourceType}
|
||||||
}
|
}
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@ func (c *followCommand) Execute() error {
|
||||||
return doFunc(gtsClient)
|
return doFunc(gtsClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *followCommand) followAccount(gtsClient *client.Client) error {
|
func (c *FollowExecutor) followAccount(gtsClient *client.Client) error {
|
||||||
accountID, err := getAccountID(gtsClient, false, c.accountName, c.topLevelFlags.configDir)
|
accountID, err := getAccountID(gtsClient, false, c.accountName, c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ func (c *followCommand) followAccount(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *followCommand) unfollowAccount(gtsClient *client.Client, accountID string) error {
|
func (c *FollowExecutor) unfollowAccount(gtsClient *client.Client, accountID string) error {
|
||||||
if err := gtsClient.UnfollowAccount(accountID); err != nil {
|
if err := gtsClient.UnfollowAccount(accountID); err != nil {
|
||||||
return fmt.Errorf("unable to unfollow the account; %w", err)
|
return fmt.Errorf("unable to unfollow the account; %w", err)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -10,15 +10,15 @@ import (
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
|
||||||
)
|
)
|
||||||
|
|
||||||
type loginCommand struct {
|
type LoginExecutor struct {
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
topLevelFlags TopLevelFlags
|
||||||
instance string
|
instance string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLoginCommand(tlf topLevelFlags, name, summary string) *loginCommand {
|
func NewLoginExecutor(tlf TopLevelFlags, name, summary string) *LoginExecutor {
|
||||||
command := loginCommand{
|
command := LoginExecutor{
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
topLevelFlags: tlf,
|
topLevelFlags: tlf,
|
||||||
instance: "",
|
instance: "",
|
||||||
|
@ -31,11 +31,11 @@ func newLoginCommand(tlf topLevelFlags, name, summary string) *loginCommand {
|
||||||
return &command
|
return &command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *loginCommand) Execute() error {
|
func (c *LoginExecutor) Execute() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if c.instance == "" {
|
if c.instance == "" {
|
||||||
return flagNotSetError{flagText: flagInstance}
|
return FlagNotSetError{flagText: flagInstance}
|
||||||
}
|
}
|
||||||
|
|
||||||
instance := c.instance
|
instance := c.instance
|
||||||
|
@ -91,7 +91,7 @@ Once you have the code please copy and paste it below.
|
||||||
return fmt.Errorf("unable to verify the credentials; %w", err)
|
return fmt.Errorf("unable to verify the credentials; %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
loginName, err := config.SaveCredentials(c.topLevelFlags.configDir, account.Username, gtsClient.Authentication)
|
loginName, err := config.SaveCredentials(c.topLevelFlags.ConfigDir, account.Username, gtsClient.Authentication)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to save the authentication details; %w", err)
|
return fmt.Errorf("unable to save the authentication details; %w", err)
|
||||||
}
|
}
|
140
internal/executor/remove.go
Normal file
140
internal/executor/remove.go
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoveExecutor struct {
|
||||||
|
*flag.FlagSet
|
||||||
|
|
||||||
|
topLevelFlags TopLevelFlags
|
||||||
|
resourceType string
|
||||||
|
fromResourceType string
|
||||||
|
listID string
|
||||||
|
accountNames AccountNames
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRemoveExecutor(tlf TopLevelFlags, name, summary string) *RemoveExecutor {
|
||||||
|
emptyArr := make([]string, 0, 3)
|
||||||
|
|
||||||
|
removeExe := RemoveExecutor{
|
||||||
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
|
accountNames: AccountNames(emptyArr),
|
||||||
|
topLevelFlags: tlf,
|
||||||
|
}
|
||||||
|
|
||||||
|
removeExe.StringVar(&removeExe.resourceType, flagType, "", "specify the resource type to remove (e.g. account, note)")
|
||||||
|
removeExe.StringVar(&removeExe.fromResourceType, flagFrom, "", "specify the resource type to remove from (e.g. list, account, etc)")
|
||||||
|
removeExe.StringVar(&removeExe.listID, flagListID, "", "the ID of the list to remove from")
|
||||||
|
removeExe.Var(&removeExe.accountNames, flagAccountName, "the name of the account to remove from the resource")
|
||||||
|
|
||||||
|
removeExe.Usage = commandUsageFunc(name, summary, removeExe.FlagSet)
|
||||||
|
|
||||||
|
return &removeExe
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoveExecutor) Execute() error {
|
||||||
|
if r.fromResourceType == "" {
|
||||||
|
return FlagNotSetError{flagText: flagFrom}
|
||||||
|
}
|
||||||
|
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceList: r.removeFromList,
|
||||||
|
resourceAccount: r.removeFromAccount,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[r.fromResourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedTypeError{resourceType: r.fromResourceType}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtsClient, err := client.NewClientFromConfig(r.topLevelFlags.ConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoveExecutor) removeFromList(gtsClient *client.Client) error {
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceAccount: r.removeAccountsFromList,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[r.resourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedRemoveOperationError{
|
||||||
|
ResourceType: r.resourceType,
|
||||||
|
RemoveFromResourceType: r.fromResourceType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoveExecutor) removeAccountsFromList(gtsClient *client.Client) error {
|
||||||
|
if r.listID == "" {
|
||||||
|
return FlagNotSetError{flagText: flagListID}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(r.accountNames) == 0 {
|
||||||
|
return NoAccountSpecifiedError{}
|
||||||
|
}
|
||||||
|
|
||||||
|
accountIDs := make([]string, len(r.accountNames))
|
||||||
|
|
||||||
|
for i := range r.accountNames {
|
||||||
|
accountID, err := getTheirAccountID(gtsClient, r.accountNames[i])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get the account ID for %s, %w", r.accountNames[i], err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountIDs[i] = accountID
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gtsClient.RemoveAccountsFromList(r.listID, accountIDs); err != nil {
|
||||||
|
return fmt.Errorf("unable to remove the accounts from the list; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Successfully removed the account(s) from the list.")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoveExecutor) removeFromAccount(gtsClient *client.Client) error {
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceNote: r.removeNoteFromAccount,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[r.resourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedRemoveOperationError{
|
||||||
|
ResourceType: r.resourceType,
|
||||||
|
RemoveFromResourceType: r.fromResourceType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoveExecutor) removeNoteFromAccount(gtsClient *client.Client) error {
|
||||||
|
if len(r.accountNames) != 1 {
|
||||||
|
return fmt.Errorf("unexpected number of accounts specified; want 1, got %d", len(r.accountNames))
|
||||||
|
}
|
||||||
|
|
||||||
|
accountID, err := getAccountID(gtsClient, false, r.accountNames[0], r.topLevelFlags.ConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gtsClient.SetPrivateNote(accountID, ""); err != nil {
|
||||||
|
return fmt.Errorf("unable to remove the private note from the account; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Successfully removed the private note from the account.")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -9,9 +9,9 @@ import (
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
|
||||||
)
|
)
|
||||||
|
|
||||||
type showCommand struct {
|
type ShowExecutor struct {
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
topLevelFlags topLevelFlags
|
topLevelFlags TopLevelFlags
|
||||||
myAccount bool
|
myAccount bool
|
||||||
showAccountRelationship bool
|
showAccountRelationship bool
|
||||||
showUserPreferences bool
|
showUserPreferences bool
|
||||||
|
@ -24,8 +24,8 @@ type showCommand struct {
|
||||||
limit int
|
limit int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newShowCommand(tlf topLevelFlags, name, summary string) *showCommand {
|
func NewShowExecutor(tlf TopLevelFlags, name, summary string) *ShowExecutor {
|
||||||
command := showCommand{
|
command := ShowExecutor{
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
topLevelFlags: tlf,
|
topLevelFlags: tlf,
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,9 @@ func newShowCommand(tlf topLevelFlags, name, summary string) *showCommand {
|
||||||
return &command
|
return &command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) Execute() error {
|
func (c *ShowExecutor) Execute() error {
|
||||||
if c.resourceType == "" {
|
if c.resourceType == "" {
|
||||||
return flagNotSetError{flagText: flagType}
|
return FlagNotSetError{flagText: flagType}
|
||||||
}
|
}
|
||||||
|
|
||||||
funcMap := map[string]func(*client.Client) error{
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
@ -64,10 +64,10 @@ func (c *showCommand) Execute() error {
|
||||||
|
|
||||||
doFunc, ok := funcMap[c.resourceType]
|
doFunc, ok := funcMap[c.resourceType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return unsupportedResourceTypeError{resourceType: c.resourceType}
|
return UnsupportedTypeError{resourceType: c.resourceType}
|
||||||
}
|
}
|
||||||
|
|
||||||
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.configDir)
|
gtsClient, err := client.NewClientFromConfig(c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ func (c *showCommand) Execute() error {
|
||||||
return doFunc(gtsClient)
|
return doFunc(gtsClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showInstance(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showInstance(gtsClient *client.Client) error {
|
||||||
instance, err := gtsClient.GetInstance()
|
instance, err := gtsClient.GetInstance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve the instance details; %w", err)
|
return fmt.Errorf("unable to retrieve the instance details; %w", err)
|
||||||
|
@ -86,20 +86,20 @@ func (c *showCommand) showInstance(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showAccount(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showAccount(gtsClient *client.Client) error {
|
||||||
var (
|
var (
|
||||||
account model.Account
|
account model.Account
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if c.myAccount {
|
if c.myAccount {
|
||||||
account, err = getMyAccount(gtsClient, c.topLevelFlags.configDir)
|
account, err = getMyAccount(gtsClient, c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("received an error while getting the account details; %w", err)
|
return fmt.Errorf("received an error while getting the account details; %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if c.accountName == "" {
|
if c.accountName == "" {
|
||||||
return flagNotSetError{flagText: flagAccountName}
|
return FlagNotSetError{flagText: flagAccountName}
|
||||||
}
|
}
|
||||||
|
|
||||||
account, err = getAccount(gtsClient, c.accountName)
|
account, err = getAccount(gtsClient, c.accountName)
|
||||||
|
@ -131,9 +131,9 @@ func (c *showCommand) showAccount(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showStatus(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showStatus(gtsClient *client.Client) error {
|
||||||
if c.statusID == "" {
|
if c.statusID == "" {
|
||||||
return flagNotSetError{flagText: flagStatusID}
|
return FlagNotSetError{flagText: flagStatusID}
|
||||||
}
|
}
|
||||||
|
|
||||||
status, err := gtsClient.GetStatus(c.statusID)
|
status, err := gtsClient.GetStatus(c.statusID)
|
||||||
|
@ -146,7 +146,7 @@ func (c *showCommand) showStatus(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showTimeline(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showTimeline(gtsClient *client.Client) error {
|
||||||
var (
|
var (
|
||||||
timeline model.Timeline
|
timeline model.Timeline
|
||||||
err error
|
err error
|
||||||
|
@ -159,18 +159,18 @@ func (c *showCommand) showTimeline(gtsClient *client.Client) error {
|
||||||
timeline, err = gtsClient.GetPublicTimeline(c.limit)
|
timeline, err = gtsClient.GetPublicTimeline(c.limit)
|
||||||
case "list":
|
case "list":
|
||||||
if c.listID == "" {
|
if c.listID == "" {
|
||||||
return flagNotSetError{flagText: flagListID}
|
return FlagNotSetError{flagText: flagListID}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeline, err = gtsClient.GetListTimeline(c.listID, c.limit)
|
timeline, err = gtsClient.GetListTimeline(c.listID, c.limit)
|
||||||
case "tag":
|
case "tag":
|
||||||
if c.tag == "" {
|
if c.tag == "" {
|
||||||
return flagNotSetError{flagText: flagTag}
|
return FlagNotSetError{flagText: flagTag}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeline, err = gtsClient.GetTagTimeline(c.tag, c.limit)
|
timeline, err = gtsClient.GetTagTimeline(c.tag, c.limit)
|
||||||
default:
|
default:
|
||||||
return invalidTimelineCategoryError{category: c.timelineCategory}
|
return InvalidTimelineCategoryError{category: c.timelineCategory}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -188,7 +188,7 @@ func (c *showCommand) showTimeline(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showList(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showList(gtsClient *client.Client) error {
|
||||||
if c.listID == "" {
|
if c.listID == "" {
|
||||||
return c.showLists(gtsClient)
|
return c.showLists(gtsClient)
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ func (c *showCommand) showList(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showLists(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showLists(gtsClient *client.Client) error {
|
||||||
lists, err := gtsClient.GetAllLists()
|
lists, err := gtsClient.GetAllLists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve the lists; %w", err)
|
return fmt.Errorf("unable to retrieve the lists; %w", err)
|
||||||
|
@ -235,8 +235,8 @@ func (c *showCommand) showLists(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showFollowers(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showFollowers(gtsClient *client.Client) error {
|
||||||
accountID, err := getAccountID(gtsClient, c.myAccount, c.accountName, c.topLevelFlags.configDir)
|
accountID, err := getAccountID(gtsClient, c.myAccount, c.accountName, c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,8 @@ func (c *showCommand) showFollowers(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showFollowing(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showFollowing(gtsClient *client.Client) error {
|
||||||
accountID, err := getAccountID(gtsClient, c.myAccount, c.accountName, c.topLevelFlags.configDir)
|
accountID, err := getAccountID(gtsClient, c.myAccount, c.accountName, c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
return fmt.Errorf("received an error while getting the account ID; %w", err)
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ func (c *showCommand) showFollowing(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *showCommand) showBlocked(gtsClient *client.Client) error {
|
func (c *ShowExecutor) showBlocked(gtsClient *client.Client) error {
|
||||||
blocked, err := gtsClient.GetBlockedAccounts(c.limit)
|
blocked, err := gtsClient.GetBlockedAccounts(c.limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve the list of blocked accounts; %w", err)
|
return fmt.Errorf("unable to retrieve the list of blocked accounts; %w", err)
|
57
internal/executor/switch.go
Normal file
57
internal/executor/switch.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SwitchExecutor struct {
|
||||||
|
*flag.FlagSet
|
||||||
|
|
||||||
|
topLevelFlags TopLevelFlags
|
||||||
|
toResourceType string
|
||||||
|
accountName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSwitchExecutor(tlf TopLevelFlags, name, summary string) *SwitchExecutor {
|
||||||
|
switchExe := SwitchExecutor{
|
||||||
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
|
topLevelFlags: tlf,
|
||||||
|
}
|
||||||
|
|
||||||
|
switchExe.StringVar(&switchExe.toResourceType, flagTo, "", "the account to switch to")
|
||||||
|
switchExe.StringVar(&switchExe.accountName, flagAccountName, "", "the name of the account to switch to")
|
||||||
|
|
||||||
|
switchExe.Usage = commandUsageFunc(name, summary, switchExe.FlagSet)
|
||||||
|
|
||||||
|
return &switchExe
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SwitchExecutor) Execute() error {
|
||||||
|
funcMap := map[string]func() error{
|
||||||
|
resourceAccount: s.switchToAccount,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[s.toResourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedTypeError{resourceType: s.toResourceType}
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SwitchExecutor) switchToAccount() error {
|
||||||
|
if s.accountName == "" {
|
||||||
|
return NoAccountSpecifiedError{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := config.UpdateCurrentAccount(s.accountName, s.topLevelFlags.ConfigDir); err != nil {
|
||||||
|
return fmt.Errorf("unable to switch account to the account; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("The current account is now set to %q.\n", s.accountName)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
91
internal/executor/update.go
Normal file
91
internal/executor/update.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||||
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EditExecutor struct {
|
||||||
|
*flag.FlagSet
|
||||||
|
|
||||||
|
topLevelFlags TopLevelFlags
|
||||||
|
resourceType string
|
||||||
|
listID string
|
||||||
|
listTitle string
|
||||||
|
listRepliesPolicy string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEditExecutor(tlf TopLevelFlags, name, summary string) *EditExecutor {
|
||||||
|
editExe := EditExecutor{
|
||||||
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
|
topLevelFlags: tlf,
|
||||||
|
}
|
||||||
|
|
||||||
|
editExe.StringVar(&editExe.resourceType, flagType, "", "specify the type of resource to update")
|
||||||
|
editExe.StringVar(&editExe.listID, flagListID, "", "specify the ID of the list to update")
|
||||||
|
editExe.StringVar(&editExe.listTitle, flagListTitle, "", "specify the title of the list")
|
||||||
|
editExe.StringVar(&editExe.listRepliesPolicy, flagListRepliesPolicy, "", "specify the policy of the replies for this list (valid values are followed, list and none)")
|
||||||
|
|
||||||
|
editExe.Usage = commandUsageFunc(name, summary, editExe.FlagSet)
|
||||||
|
|
||||||
|
return &editExe
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EditExecutor) Execute() error {
|
||||||
|
if e.resourceType == "" {
|
||||||
|
return FlagNotSetError{flagText: flagType}
|
||||||
|
}
|
||||||
|
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceList: e.updateList,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[e.resourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedTypeError{resourceType: e.resourceType}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtsClient, err := client.NewClientFromConfig(e.topLevelFlags.ConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EditExecutor) updateList(gtsClient *client.Client) error {
|
||||||
|
if e.listID == "" {
|
||||||
|
return FlagNotSetError{flagText: flagListID}
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := gtsClient.GetList(e.listID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get the list; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.listTitle != "" {
|
||||||
|
list.Title = e.listTitle
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.listRepliesPolicy != "" {
|
||||||
|
repliesPolicy, err := model.ParseListRepliesPolicy(e.listRepliesPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to parse the list replies policy; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
list.RepliesPolicy = repliesPolicy
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedList, err := gtsClient.UpdateList(list)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to update the list; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Successfully updated the list.")
|
||||||
|
fmt.Println(updatedList)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
37
internal/executor/usage.go
Normal file
37
internal/executor/usage.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package executor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// commandUsageFunc returns the function used to print a command's help page.
|
||||||
|
func commandUsageFunc(name, summary string, flagset *flag.FlagSet) func() {
|
||||||
|
return func() {
|
||||||
|
var builder strings.Builder
|
||||||
|
|
||||||
|
fmt.Fprintf(
|
||||||
|
&builder,
|
||||||
|
"SUMMARY:\n %s - %s\n\nUSAGE:\n enbas %s [flags]\n\nFLAGS:",
|
||||||
|
name,
|
||||||
|
summary,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
|
||||||
|
flagset.VisitAll(func(f *flag.Flag) {
|
||||||
|
fmt.Fprintf(
|
||||||
|
&builder,
|
||||||
|
"\n --%s\n %s",
|
||||||
|
f.Name,
|
||||||
|
f.Usage,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
builder.WriteString("\n")
|
||||||
|
|
||||||
|
w := flag.CommandLine.Output()
|
||||||
|
|
||||||
|
fmt.Fprint(w, builder.String())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -7,14 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
type VersionExecutor struct {
|
||||||
binaryVersion string
|
|
||||||
buildTime string
|
|
||||||
goVersion string
|
|
||||||
gitCommit string
|
|
||||||
)
|
|
||||||
|
|
||||||
type versionCommand struct {
|
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
showFullVersion bool
|
showFullVersion bool
|
||||||
binaryVersion string
|
binaryVersion string
|
||||||
|
@ -23,8 +16,8 @@ type versionCommand struct {
|
||||||
gitCommit string
|
gitCommit string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVersionCommand(name, summary string) *versionCommand {
|
func NewVersionExecutor(name, summary, binaryVersion, buildTime, goVersion, gitCommit string) *VersionExecutor {
|
||||||
command := versionCommand{
|
command := VersionExecutor{
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
binaryVersion: binaryVersion,
|
binaryVersion: binaryVersion,
|
||||||
buildTime: buildTime,
|
buildTime: buildTime,
|
||||||
|
@ -40,7 +33,7 @@ func newVersionCommand(name, summary string) *versionCommand {
|
||||||
return &command
|
return &command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *versionCommand) Execute() error {
|
func (c *VersionExecutor) Execute() error {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
|
|
||||||
if c.showFullVersion {
|
if c.showFullVersion {
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -7,14 +7,14 @@ import (
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type whoAmICommand struct {
|
type WhoAmIExecutor struct {
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
|
|
||||||
topLevelFlags topLevelFlags
|
topLevelFlags TopLevelFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWhoAmICommand(tlf topLevelFlags, name, summary string) *whoAmICommand {
|
func NewWhoAmIExecutor(tlf TopLevelFlags, name, summary string) *WhoAmIExecutor {
|
||||||
command := whoAmICommand{
|
command := WhoAmIExecutor{
|
||||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||||
topLevelFlags: tlf,
|
topLevelFlags: tlf,
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ func newWhoAmICommand(tlf topLevelFlags, name, summary string) *whoAmICommand {
|
||||||
return &command
|
return &command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *whoAmICommand) Execute() error {
|
func (c *WhoAmIExecutor) Execute() error {
|
||||||
config, err := config.NewCredentialsConfigFromFile(c.topLevelFlags.configDir)
|
config, err := config.NewCredentialsConfigFromFile(c.topLevelFlags.ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to load the credential config; %w", err)
|
return fmt.Errorf("unable to load the credential config; %w", err)
|
||||||
}
|
}
|
Loading…
Reference in a new issue