Compare commits

...

3 commits

Author SHA1 Message Date
9d509af0df
checkpoint: add edit and delete to schema 2024-08-10 12:06:35 +01:00
93bc7a93f8
checkpoint: added block and unblock to schema 2024-08-10 10:27:45 +01:00
b06fdc2960
checkpoint: add more commands to the schema
- Added accept and reject
- Added follow and unfollow
- Add ability to use a define a different field name for each flag
  reference.
2024-08-10 08:51:53 +01:00
18 changed files with 616 additions and 384 deletions

View file

@ -37,7 +37,7 @@ func main() {
func generateExecutors(schema enbasCLISchema, output string) error { func generateExecutors(schema enbasCLISchema, output string) error {
funcMap := template.FuncMap{ funcMap := template.FuncMap{
"capitalise": capitalise, "capitalise": capitalise,
"convertFlagToMixedCaps": convertFlagToMixedCaps, "flagFieldName": flagFieldName,
"getFlagType": schema.Flags.getType, "getFlagType": schema.Flags.getType,
"getFlagDescription": schema.Flags.getDescription, "getFlagDescription": schema.Flags.getDescription,
} }
@ -75,6 +75,14 @@ func capitalise(str string) string {
return string(runes) return string(runes)
} }
func flagFieldName(flagRef enbasCLISchemaFlagReference) string {
if flagRef.FieldName != "" {
return flagRef.FieldName
}
return convertFlagToMixedCaps(flagRef.Flag)
}
func convertFlagToMixedCaps(value string) string { func convertFlagToMixedCaps(value string) string {
var builder strings.Builder var builder strings.Builder

View file

@ -62,6 +62,7 @@ type enbasCLISchemaCommand struct {
type enbasCLISchemaFlagReference struct { type enbasCLISchemaFlagReference struct {
Flag string `json:"flag"` Flag string `json:"flag"`
FieldName string `json:"fieldName"`
Default string `json:"default"` Default string `json:"default"`
} }

View file

@ -1,6 +1,11 @@
package main package main
var executorsFileTemplate = `package executor var executorsFileTemplate = `package executor
{{ print "" }}
/*
This file is generated by ./cmd/enbas-cli-generators
DO NOT EDIT.
*/
{{ range $name, $command := . }} {{ range $name, $command := . }}
{{- $struct_name := capitalise $name | printf "%sExecutor" -}} {{- $struct_name := capitalise $name | printf "%sExecutor" -}}
{{- $new_executor_function_name := capitalise $name | printf "New%sExecutor" -}} {{- $new_executor_function_name := capitalise $name | printf "New%sExecutor" -}}
@ -16,7 +21,7 @@ type {{ $struct_name }} struct {
{{- end }} {{- end }}
{{- range $flag := $command.Flags -}} {{- range $flag := $command.Flags -}}
{{ print "" }} {{ print "" }}
{{ convertFlagToMixedCaps $flag.Flag }} {{ getFlagType $flag.Flag }} {{ flagFieldName $flag }} {{ getFlagType $flag.Flag }}
{{- end -}} {{- end -}}
{{- range $field := $command.AdditionalFields -}} {{- range $field := $command.AdditionalFields -}}
{{ print "" }} {{ print "" }}
@ -58,10 +63,10 @@ func {{ $new_executor_function_name }}(
{{- range $flag := $command.Flags -}} {{- range $flag := $command.Flags -}}
{{- if eq (getFlagType $flag.Flag) "string" -}} {{- if eq (getFlagType $flag.Flag) "string" -}}
{{ print "" }} {{ print "" }}
exe.StringVar(&exe.{{ convertFlagToMixedCaps $flag.Flag }}, {{ printf "%q" $flag.Flag }}, {{ printf "%q" $flag.Default }}, {{ getFlagDescription $flag.Flag | printf "%q" }}) exe.StringVar(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ printf "%q" $flag.Default }}, {{ getFlagDescription $flag.Flag | printf "%q" }})
{{- else if eq (getFlagType $flag.Flag) "bool" -}} {{- else if eq (getFlagType $flag.Flag) "bool" -}}
{{ print "" }} {{ print "" }}
exe.BoolVar(&exe.{{ convertFlagToMixedCaps $flag.Flag }}, {{ printf "%q" $flag.Flag }}, {{ $flag.Default }}, {{ getFlagDescription $flag.Flag | printf "%q" }}) exe.BoolVar(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ $flag.Default }}, {{ getFlagDescription $flag.Flag | printf "%q" }})
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{ print "" }} {{ print "" }}

View file

@ -89,11 +89,9 @@ func run() error {
} }
executorMap := map[string]executor.Executor{ executorMap := map[string]executor.Executor{
executor.CommandAccept: executor.NewAcceptOrRejectExecutor( executor.CommandAccept: executor.NewAcceptExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandAccept,
executor.CommandSummaryLookup(executor.CommandAccept),
), ),
executor.CommandAdd: executor.NewAddExecutor( executor.CommandAdd: executor.NewAddExecutor(
enbasPrinter, enbasPrinter,
@ -101,11 +99,9 @@ func run() error {
executor.CommandAdd, executor.CommandAdd,
executor.CommandSummaryLookup(executor.CommandAdd), executor.CommandSummaryLookup(executor.CommandAdd),
), ),
executor.CommandBlock: executor.NewBlockOrUnblockExecutor( executor.CommandBlock: executor.NewBlockExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandBlock,
executor.CommandSummaryLookup(executor.CommandBlock),
), ),
executor.CommandCreate: executor.NewCreateExecutor( executor.CommandCreate: executor.NewCreateExecutor(
enbasPrinter, enbasPrinter,
@ -116,26 +112,18 @@ func run() error {
executor.CommandDelete: executor.NewDeleteExecutor( executor.CommandDelete: executor.NewDeleteExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandDelete,
executor.CommandSummaryLookup(executor.CommandDelete),
), ),
executor.CommandEdit: executor.NewEditExecutor( executor.CommandEdit: executor.NewEditExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandEdit,
executor.CommandSummaryLookup(executor.CommandEdit),
), ),
executor.CommandFollow: executor.NewFollowOrUnfollowExecutor( executor.CommandFollow: executor.NewFollowExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandFollow,
executor.CommandSummaryLookup(executor.CommandFollow),
), ),
executor.CommandInit: executor.NewInitExecutor( executor.CommandInit: executor.NewInitExecutor(
enbasPrinter, enbasPrinter,
configDir, configDir,
executor.CommandInit,
executor.CommandSummaryLookup(executor.CommandInit),
), ),
executor.CommandLogin: executor.NewLoginExecutor( executor.CommandLogin: executor.NewLoginExecutor(
enbasPrinter, enbasPrinter,
@ -147,11 +135,9 @@ func run() error {
executor.CommandMute, executor.CommandMute,
executor.CommandSummaryLookup(executor.CommandMute), executor.CommandSummaryLookup(executor.CommandMute),
), ),
executor.CommandReject: executor.NewAcceptOrRejectExecutor( executor.CommandReject: executor.NewRejectExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandReject,
executor.CommandSummaryLookup(executor.CommandReject),
), ),
executor.CommandRemove: executor.NewRemoveExecutor( executor.CommandRemove: executor.NewRemoveExecutor(
enbasPrinter, enbasPrinter,
@ -163,11 +149,9 @@ func run() error {
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
executor.CommandUnfollow: executor.NewFollowOrUnfollowExecutor( executor.CommandUnfollow: executor.NewUnfollowExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandUnfollow,
executor.CommandSummaryLookup(executor.CommandUnfollow),
), ),
executor.CommandUnmute: executor.NewMuteOrUnmuteExecutor( executor.CommandUnmute: executor.NewMuteOrUnmuteExecutor(
enbasPrinter, enbasPrinter,
@ -175,11 +159,9 @@ func run() error {
executor.CommandUnmute, executor.CommandUnmute,
executor.CommandSummaryLookup(executor.CommandUnmute), executor.CommandSummaryLookup(executor.CommandUnmute),
), ),
executor.CommandUnblock: executor.NewBlockOrUnblockExecutor( executor.CommandUnblock: executor.NewUnblockExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
executor.CommandUnblock,
executor.CommandSummaryLookup(executor.CommandUnblock),
), ),
executor.CommandShow: executor.NewShowExecutor( executor.CommandShow: executor.NewShowExecutor(
enbasPrinter, enbasPrinter,

View file

@ -0,0 +1,40 @@
package executor
import (
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
func (a *AcceptExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceFollowRequest: a.acceptFollowRequest,
}
doFunc, ok := funcMap[a.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: a.resourceType}
}
gtsClient, err := client.NewClientFromFile(a.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (a *AcceptExecutor) acceptFollowRequest(gtsClient *client.Client) error {
accountID, err := getAccountID(gtsClient, false, a.accountName, a.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
if err := gtsClient.AcceptFollowRequest(accountID); err != nil {
return fmt.Errorf("unable to accept the follow request: %w", err)
}
a.printer.PrintSuccess("Successfully accepted the follow request.")
return nil
}

View file

@ -1,91 +0,0 @@
package executor
import (
"flag"
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
)
type AcceptOrRejectExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
resourceType string
accountName string
command string
}
func NewAcceptOrRejectExecutor(enbasPrinter *printer.Printer, config *config.Config, name, summary string) *AcceptOrRejectExecutor {
acceptExe := AcceptOrRejectExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: enbasPrinter,
config: config,
command: name,
}
acceptExe.StringVar(&acceptExe.resourceType, flagType, "", "Specify the type of resource to accept or reject")
acceptExe.StringVar(&acceptExe.accountName, flagAccountName, "", "Specify the account name in full (username@domain)")
acceptExe.Usage = commandUsageFunc(name, summary, acceptExe.FlagSet)
return &acceptExe
}
func (a *AcceptOrRejectExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceFollowRequest: a.acceptOrRejectFollowRequest,
}
doFunc, ok := funcMap[a.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: a.resourceType}
}
gtsClient, err := client.NewClientFromFile(a.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (a *AcceptOrRejectExecutor) acceptOrRejectFollowRequest(gtsClient *client.Client) error {
accountID, err := getAccountID(gtsClient, false, a.accountName, a.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
switch a.command {
case CommandAccept:
return a.acceptFollowRequest(gtsClient, accountID)
case CommandReject:
return a.rejectFollowRequest(gtsClient, accountID)
default:
return nil
}
}
func (a *AcceptOrRejectExecutor) acceptFollowRequest(gtsClient *client.Client, accountID string) error {
if err := gtsClient.AcceptFollowRequest(accountID); err != nil {
return fmt.Errorf("unable to accept the follow request: %w", err)
}
a.printer.PrintSuccess("Successfully accepted the follow request.")
return nil
}
func (a *AcceptOrRejectExecutor) rejectFollowRequest(gtsClient *client.Client, accountID string) error {
if err := gtsClient.RejectFollowRequest(accountID); err != nil {
return fmt.Errorf("unable to reject the follow request: %w", err)
}
a.printer.PrintSuccess("Successfully rejected the follow request.")
return nil
}

View file

@ -0,0 +1,44 @@
package executor
import (
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
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.NewClientFromFile(b.config.CredentialsFile)
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 {
if b.accountName == "" {
return FlagNotSetError{flagText: flagAccountName}
}
accountID, err := getAccountID(gtsClient, false, b.accountName, b.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
if err := gtsClient.BlockAccount(accountID); err != nil {
return fmt.Errorf("unable to block the account: %w", err)
}
b.printer.PrintSuccess("Successfully blocked the account.")
return nil
}

View file

@ -1,95 +0,0 @@
package executor
import (
"flag"
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
)
type BlockOrUnblockExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
resourceType string
accountName string
command string
}
func NewBlockOrUnblockExecutor(printer *printer.Printer, config *config.Config, name, summary string) *BlockOrUnblockExecutor {
blockExe := BlockOrUnblockExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: printer,
config: config,
command: name,
}
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 *BlockOrUnblockExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceAccount: b.blockOrUnblockAccount,
}
doFunc, ok := funcMap[b.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: b.resourceType}
}
gtsClient, err := client.NewClientFromFile(b.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (b *BlockOrUnblockExecutor) blockOrUnblockAccount(gtsClient *client.Client) error {
if b.accountName == "" {
return FlagNotSetError{flagText: flagAccountName}
}
accountID, err := getAccountID(gtsClient, false, b.accountName, b.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
switch b.command {
case CommandBlock:
return b.blockAccount(gtsClient, accountID)
case CommandUnblock:
return b.unblockAccount(gtsClient, accountID)
default:
return nil
}
}
func (b *BlockOrUnblockExecutor) blockAccount(gtsClient *client.Client, accountID string) error {
if err := gtsClient.BlockAccount(accountID); err != nil {
return fmt.Errorf("unable to block the account: %w", err)
}
b.printer.PrintSuccess("Successfully blocked the account.")
return nil
}
func (b *BlockOrUnblockExecutor) unblockAccount(gtsClient *client.Client, accountID string) error {
if err := gtsClient.UnblockAccount(accountID); err != nil {
return fmt.Errorf("unable to unblock the account: %w", err)
}
b.printer.PrintSuccess("Successfully unblocked the account.")
return nil
}

View file

@ -1,39 +1,11 @@
package executor package executor
import ( import (
"flag"
"fmt" "fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client" "codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
type DeleteExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
resourceType string
listID string
}
func NewDeleteExecutor(printer *printer.Printer, config *config.Config, name, summary string) *DeleteExecutor {
deleteExe := DeleteExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: printer,
config: config,
}
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 { func (d *DeleteExecutor) Execute() error {
if d.resourceType == "" { if d.resourceType == "" {
return FlagNotSetError{flagText: flagType} return FlagNotSetError{flagText: flagType}

View file

@ -1,44 +1,12 @@
package executor package executor
import ( import (
"flag"
"fmt" "fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client" "codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/model" "codeflow.dananglin.me.uk/apollo/enbas/internal/model"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
type EditExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
resourceType string
listID string
listTitle string
listRepliesPolicy string
}
func NewEditExecutor(printer *printer.Printer, config *config.Config, name, summary string) *EditExecutor {
editExe := EditExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: printer,
config: config,
}
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 { func (e *EditExecutor) Execute() error {
if e.resourceType == "" { if e.resourceType == "" {
return FlagNotSetError{flagText: flagType} return FlagNotSetError{flagText: flagType}

View file

@ -7,6 +7,149 @@ import (
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
/*
This file is generated by ./cmd/enbas-cli-generators
DO NOT EDIT.
*/
// AcceptExecutor is the executor for the accept command.
type AcceptExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
accountName string
resourceType string
}
func NewAcceptExecutor(
printer *printer.Printer,
config *config.Config,
) *AcceptExecutor {
exe := AcceptExecutor{
FlagSet: flag.NewFlagSet("accept", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("accept", "Accepts a request (e.g. a follow request)", exe.FlagSet)
exe.StringVar(&exe.accountName, "account-name", "", "The name of the account")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// BlockExecutor is the executor for the block command.
type BlockExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
accountName string
resourceType string
}
func NewBlockExecutor(
printer *printer.Printer,
config *config.Config,
) *BlockExecutor {
exe := BlockExecutor{
FlagSet: flag.NewFlagSet("block", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("block", "Blocks a resource (e.g. an account)", exe.FlagSet)
exe.StringVar(&exe.accountName, "account-name", "", "The name of the account")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// DeleteExecutor is the executor for the delete command.
type DeleteExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
listID string
resourceType string
}
func NewDeleteExecutor(
printer *printer.Printer,
config *config.Config,
) *DeleteExecutor {
exe := DeleteExecutor{
FlagSet: flag.NewFlagSet("delete", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("delete", "Delete a specific resource", exe.FlagSet)
exe.StringVar(&exe.listID, "list-id", "", "The ID of the list in question")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// EditExecutor is the executor for the edit command.
type EditExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
listID string
listTitle string
listRepliesPolicy string
resourceType string
}
func NewEditExecutor(
printer *printer.Printer,
config *config.Config,
) *EditExecutor {
exe := EditExecutor{
FlagSet: flag.NewFlagSet("edit", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("edit", "Edit a specific resource", exe.FlagSet)
exe.StringVar(&exe.listID, "list-id", "", "The ID of the list in question")
exe.StringVar(&exe.listTitle, "list-title", "", "The title of the list")
exe.StringVar(&exe.listRepliesPolicy, "list-replies-policy", "", "The replies policy of the list")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// FollowExecutor is the executor for the follow command.
type FollowExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
accountName string
notify bool
showReposts bool
resourceType string
}
func NewFollowExecutor(
printer *printer.Printer,
config *config.Config,
) *FollowExecutor {
exe := FollowExecutor{
FlagSet: flag.NewFlagSet("follow", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("follow", "Follow a resource (e.g. an account)", exe.FlagSet)
exe.StringVar(&exe.accountName, "account-name", "", "The name of the account")
exe.BoolVar(&exe.notify, "notify", false, "Get notifications from statuses from the account you want to follow")
exe.BoolVar(&exe.showReposts, "show-reposts", true, "Show reposts from the account you want to follow")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// InitExecutor is the executor for the init command. // InitExecutor is the executor for the init command.
type InitExecutor struct { type InitExecutor struct {
*flag.FlagSet *flag.FlagSet
@ -53,6 +196,32 @@ func NewLoginExecutor(
return &exe return &exe
} }
// RejectExecutor is the executor for the reject command.
type RejectExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
accountName string
resourceType string
}
func NewRejectExecutor(
printer *printer.Printer,
config *config.Config,
) *RejectExecutor {
exe := RejectExecutor{
FlagSet: flag.NewFlagSet("reject", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("reject", "Rejects a request (e.g. a follow request)", exe.FlagSet)
exe.StringVar(&exe.accountName, "account-name", "", "The name of the account")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// SwitchExecutor is the executor for the switch command. // SwitchExecutor is the executor for the switch command.
type SwitchExecutor struct { type SwitchExecutor struct {
*flag.FlagSet *flag.FlagSet
@ -79,6 +248,58 @@ func NewSwitchExecutor(
return &exe return &exe
} }
// UnblockExecutor is the executor for the unblock command.
type UnblockExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
accountName string
resourceType string
}
func NewUnblockExecutor(
printer *printer.Printer,
config *config.Config,
) *UnblockExecutor {
exe := UnblockExecutor{
FlagSet: flag.NewFlagSet("unblock", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("unblock", "Unblocks a resource (e.g. an account)", exe.FlagSet)
exe.StringVar(&exe.accountName, "account-name", "", "The name of the account")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// UnfollowExecutor is the executor for the unfollow command.
type UnfollowExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
accountName string
resourceType string
}
func NewUnfollowExecutor(
printer *printer.Printer,
config *config.Config,
) *UnfollowExecutor {
exe := UnfollowExecutor{
FlagSet: flag.NewFlagSet("unfollow", flag.ExitOnError),
printer: printer,
config: config,
}
exe.Usage = commandUsageFunc("unfollow", "Unfollow a resource (e.g. an account)", exe.FlagSet)
exe.StringVar(&exe.accountName, "account-name", "", "The name of the account")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
return &exe
}
// VersionExecutor is the executor for the version command. // VersionExecutor is the executor for the version command.
type VersionExecutor struct { type VersionExecutor struct {
*flag.FlagSet *flag.FlagSet

View file

@ -34,7 +34,6 @@ const (
flagMyAccount = "my-account" flagMyAccount = "my-account"
flagMuteDuration = "mute-duration" flagMuteDuration = "mute-duration"
flagMuteNotifications = "mute-notifications" flagMuteNotifications = "mute-notifications"
flagNotify = "notify"
flagOnlyMedia = "only-media" flagOnlyMedia = "only-media"
flagOnlyPinned = "only-pinned" flagOnlyPinned = "only-pinned"
flagOnlyPublic = "only-public" flagOnlyPublic = "only-public"
@ -46,7 +45,6 @@ const (
flagSensitive = "sensitive" flagSensitive = "sensitive"
flagSkipRelationship = "skip-relationship" flagSkipRelationship = "skip-relationship"
flagShowPreferences = "show-preferences" flagShowPreferences = "show-preferences"
flagShowReposts = "show-reposts"
flagShowStatuses = "show-statuses" flagShowStatuses = "show-statuses"
flagSpoilerText = "spoiler-text" flagSpoilerText = "spoiler-text"
flagStatusID = "status-id" flagStatusID = "status-id"

View file

@ -0,0 +1,46 @@
package executor
import (
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
func (f *FollowExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceAccount: f.followAccount,
}
doFunc, ok := funcMap[f.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: f.resourceType}
}
gtsClient, err := client.NewClientFromFile(f.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (f *FollowExecutor) followAccount(gtsClient *client.Client) error {
accountID, err := getAccountID(gtsClient, false, f.accountName, f.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
form := client.FollowAccountForm{
AccountID: accountID,
ShowReposts: f.showReposts,
Notify: f.notify,
}
if err := gtsClient.FollowAccount(form); err != nil {
return fmt.Errorf("unable to follow the account: %w", err)
}
f.printer.PrintSuccess("Successfully sent the follow request.")
return nil
}

View file

@ -1,101 +0,0 @@
package executor
import (
"flag"
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
)
type FollowOrUnfollowExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
resourceType string
accountName string
showReposts bool
notify bool
action string
}
func NewFollowOrUnfollowExecutor(printer *printer.Printer, config *config.Config, name, summary string) *FollowOrUnfollowExecutor {
command := FollowOrUnfollowExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: printer,
config: config,
action: name,
}
command.StringVar(&command.resourceType, flagType, "", "Specify the type of resource to follow")
command.StringVar(&command.accountName, flagAccountName, "", "Specify the account name in full (username@domain)")
command.BoolVar(&command.showReposts, flagShowReposts, true, "Show reposts from the account you want to follow")
command.BoolVar(&command.notify, flagNotify, false, "Get notifications when the account you want to follow posts a status")
command.Usage = commandUsageFunc(name, summary, command.FlagSet)
return &command
}
func (f *FollowOrUnfollowExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceAccount: f.followOrUnfollowAccount,
}
doFunc, ok := funcMap[f.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: f.resourceType}
}
gtsClient, err := client.NewClientFromFile(f.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (f *FollowOrUnfollowExecutor) followOrUnfollowAccount(gtsClient *client.Client) error {
accountID, err := getAccountID(gtsClient, false, f.accountName, f.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
switch f.action {
case CommandFollow:
return f.followAccount(gtsClient, accountID)
case CommandUnfollow:
return f.unfollowAccount(gtsClient, accountID)
default:
return nil
}
}
func (f *FollowOrUnfollowExecutor) followAccount(gtsClient *client.Client, accountID string) error {
form := client.FollowAccountForm{
AccountID: accountID,
ShowReposts: f.showReposts,
Notify: f.notify,
}
if err := gtsClient.FollowAccount(form); err != nil {
return fmt.Errorf("unable to follow the account: %w", err)
}
f.printer.PrintSuccess("Successfully sent the follow request.")
return nil
}
func (f *FollowOrUnfollowExecutor) unfollowAccount(gtsClient *client.Client, accountID string) error {
if err := gtsClient.UnfollowAccount(accountID); err != nil {
return fmt.Errorf("unable to unfollow the account: %w", err)
}
f.printer.PrintSuccess("Successfully unfollowed the account.")
return nil
}

View file

@ -0,0 +1,40 @@
package executor
import (
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
func (r *RejectExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceFollowRequest: r.rejectFollowRequest,
}
doFunc, ok := funcMap[r.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: r.resourceType}
}
gtsClient, err := client.NewClientFromFile(r.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (r *RejectExecutor) rejectFollowRequest(gtsClient *client.Client) error {
accountID, err := getAccountID(gtsClient, false, r.accountName, r.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
if err := gtsClient.RejectFollowRequest(accountID); err != nil {
return fmt.Errorf("unable to reject the follow request: %w", err)
}
r.printer.PrintSuccess("Successfully rejected the follow request.")
return nil
}

View file

@ -0,0 +1,44 @@
package executor
import (
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
func (b *UnblockExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceAccount: b.unblockAccount,
}
doFunc, ok := funcMap[b.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: b.resourceType}
}
gtsClient, err := client.NewClientFromFile(b.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (b *UnblockExecutor) unblockAccount(gtsClient *client.Client) error {
if b.accountName == "" {
return FlagNotSetError{flagText: flagAccountName}
}
accountID, err := getAccountID(gtsClient, false, b.accountName, b.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
if err := gtsClient.UnblockAccount(accountID); err != nil {
return fmt.Errorf("unable to unblock the account: %w", err)
}
b.printer.PrintSuccess("Successfully unblocked the account.")
return nil
}

View file

@ -0,0 +1,40 @@
package executor
import (
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
)
func (f *UnfollowExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
resourceAccount: f.unfollowAccount,
}
doFunc, ok := funcMap[f.resourceType]
if !ok {
return UnsupportedTypeError{resourceType: f.resourceType}
}
gtsClient, err := client.NewClientFromFile(f.config.CredentialsFile)
if err != nil {
return fmt.Errorf("unable to create the GoToSocial client: %w", err)
}
return doFunc(gtsClient)
}
func (f *UnfollowExecutor) unfollowAccount(gtsClient *client.Client) error {
accountID, err := getAccountID(gtsClient, false, f.accountName, f.config.CredentialsFile)
if err != nil {
return fmt.Errorf("received an error while getting the account ID: %w", err)
}
if err := gtsClient.UnfollowAccount(accountID); err != nil {
return fmt.Errorf("unable to unfollow the account: %w", err)
}
f.printer.PrintSuccess("Successfully unfollowed the account.")
return nil
}

View file

@ -12,6 +12,30 @@
"type": "string", "type": "string",
"description": "The instance that you want to log into" "description": "The instance that you want to log into"
}, },
"list-id": {
"type": "string",
"description": "The ID of the list in question"
},
"list-title": {
"type": "string",
"description": "The title of the list"
},
"list-replies-policy": {
"type": "string",
"description": "The replies policy of the list"
},
"notify": {
"type": "bool",
"description": "Get notifications from statuses from the account you want to follow"
},
"show-reposts": {
"type": "bool",
"description": "Show reposts from the account you want to follow"
},
"type": {
"type": "string",
"description": "The type of resource you want to action on (e.g. account, status)"
},
"to": { "to": {
"type": "string", "type": "string",
"description": "TBC" "description": "TBC"
@ -19,6 +43,60 @@
}, },
"commands": { "commands": {
"accept": {
"additionalFields": [],
"flags": [
{ "flag": "account-name", "default": "" },
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Accepts a request (e.g. a follow request)",
"useConfig": true,
"usePrinter": true
},
"block": {
"additionalFields": [],
"flags": [
{ "flag": "account-name", "default": "" },
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Blocks a resource (e.g. an account)",
"useConfig": true,
"usePrinter": true
},
"delete": {
"additionalFields": [],
"flags": [
{ "flag": "list-id", "fieldName": "listID", "default": ""},
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Delete a specific resource",
"useConfig": true,
"usePrinter": true
},
"edit": {
"additionalFields": [],
"flags": [
{ "flag": "list-id", "fieldName": "listID", "default": ""},
{ "flag": "list-title", "default": "" },
{ "flag": "list-replies-policy", "default": "" },
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Edit a specific resource",
"useConfig": true,
"usePrinter": true
},
"follow": {
"additionalFields": [],
"flags": [
{ "flag": "account-name", "default": "" },
{ "flag": "notify", "default": "false" },
{ "flag": "show-reposts", "default": "true" },
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Follow a resource (e.g. an account)",
"useConfig": true,
"usePrinter": true
},
"init": { "init": {
"additionalFields": [ "additionalFields": [
{ "name": "configDir", "type": "string"} { "name": "configDir", "type": "string"}
@ -29,6 +107,7 @@
"usePrinter": true "usePrinter": true
}, },
"login": { "login": {
"additionalFields": [],
"flags": [ "flags": [
{ "flag": "instance", "default": "" } { "flag": "instance", "default": "" }
], ],
@ -36,7 +115,18 @@
"useConfig": true, "useConfig": true,
"usePrinter": true "usePrinter": true
}, },
"reject": {
"additionalFields": [],
"flags": [
{ "flag": "account-name", "default": "" },
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Rejects a request (e.g. a follow request)",
"useConfig": true,
"usePrinter": true
},
"switch": { "switch": {
"additionalFields": [],
"flags": [ "flags": [
{ "flag": "account-name", "default": "" }, { "flag": "account-name", "default": "" },
{ "flag": "to", "default": "" } { "flag": "to", "default": "" }
@ -45,6 +135,26 @@
"useConfig": true, "useConfig": true,
"usePrinter": true "usePrinter": true
}, },
"unblock": {
"additionalFields": [],
"flags": [
{ "flag": "account-name", "default": "" },
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Unblocks a resource (e.g. an account)",
"useConfig": true,
"usePrinter": true
},
"unfollow": {
"additionalFields": [],
"flags": [
{ "flag": "account-name", "default": "" },
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Unfollow a resource (e.g. an account)",
"useConfig": true,
"usePrinter": true
},
"version": { "version": {
"additionalFields": [ "additionalFields": [
{ "name": "binaryVersion", "type": "string"}, { "name": "binaryVersion", "type": "string"},