diff --git a/cmd/enbas-cli-generators/main.go b/cmd/enbas-cli-generators/main.go index 35f39f4..3ac170e 100644 --- a/cmd/enbas-cli-generators/main.go +++ b/cmd/enbas-cli-generators/main.go @@ -36,10 +36,11 @@ func main() { func generateExecutors(schema enbasCLISchema, output string) error { funcMap := template.FuncMap{ - "capitalise": capitalise, - "flagFieldName": flagFieldName, - "getFlagType": schema.Flags.getType, - "getFlagDescription": schema.Flags.getDescription, + "capitalise": capitalise, + "flagFieldName": flagFieldName, + "getFlagType": schema.Flags.getType, + "getFlagDescription": schema.Flags.getDescription, + "customFlagValueType": customFlagValueType, } tmpl := template.Must(template.New("executor-template").Funcs(funcMap).Parse(executorsFileTemplate)) @@ -107,3 +108,15 @@ func convertFlagToMixedCaps(value string) string { return builder.String() } + +func customFlagValueType(flagType string) bool { + customFlagValueTypes := map[string]struct{}{ + "MultiStringFlagValue": {}, + "MultiIntFlagValue": {}, + "TimeDurationFlagValue": {}, + } + + _, exists := customFlagValueTypes[flagType] + + return exists +} diff --git a/cmd/enbas-cli-generators/templates.go b/cmd/enbas-cli-generators/templates.go index 71d99e4..9f825b7 100644 --- a/cmd/enbas-cli-generators/templates.go +++ b/cmd/enbas-cli-generators/templates.go @@ -51,6 +51,13 @@ func {{ $new_executor_function_name }}( {{- if $command.UseConfig }} config: config, {{- end }} + {{- range $flag := $command.Flags -}} + {{- $flag_type := getFlagType $flag.Flag -}} + {{- if customFlagValueType $flag_type -}} + {{ print "" }} + {{ flagFieldName $flag }}: New{{ $flag_type }}(), + {{- end -}} + {{- end -}} {{- range $field := $command.AdditionalFields -}} {{ print "" }} {{ $field.Name }}: {{ $field.Name }}, @@ -61,12 +68,16 @@ func {{ $new_executor_function_name }}( exe.Usage = commandUsageFunc({{ printf "%q" $name }}, {{ printf "%q" $command.Summary }}, exe.FlagSet) {{ print "" }} {{- range $flag := $command.Flags -}} - {{- if eq (getFlagType $flag.Flag) "string" -}} + {{- $flag_type := getFlagType $flag.Flag -}} + {{- if eq $flag_type "string" -}} {{ print "" }} 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 $flag_type "bool" -}} {{ print "" }} exe.BoolVar(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ $flag.Default }}, {{ getFlagDescription $flag.Flag | printf "%q" }}) + {{- else if customFlagValueType $flag_type -}} + {{ print "" }} + exe.Var(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ getFlagDescription $flag.Flag | printf "%q" }}) {{- end -}} {{- end -}} {{ print "" }} diff --git a/cmd/enbas/main.go b/cmd/enbas/main.go index b3ea309..1c8e4d3 100644 --- a/cmd/enbas/main.go +++ b/cmd/enbas/main.go @@ -129,11 +129,9 @@ func run() error { enbasPrinter, enbasConfig, ), - executor.CommandMute: executor.NewMuteOrUnmuteExecutor( + executor.CommandMute: executor.NewMuteExecutor( enbasPrinter, enbasConfig, - executor.CommandMute, - executor.CommandSummaryLookup(executor.CommandMute), ), executor.CommandReject: executor.NewRejectExecutor( enbasPrinter, @@ -153,11 +151,9 @@ func run() error { enbasPrinter, enbasConfig, ), - executor.CommandUnmute: executor.NewMuteOrUnmuteExecutor( + executor.CommandUnmute: executor.NewUnmuteExecutor( enbasPrinter, enbasConfig, - executor.CommandUnmute, - executor.CommandSummaryLookup(executor.CommandUnmute), ), executor.CommandUnblock: executor.NewUnblockExecutor( enbasPrinter, diff --git a/internal/executor/executors.go b/internal/executor/executors.go index 9e111fa..9c314f9 100644 --- a/internal/executor/executors.go +++ b/internal/executor/executors.go @@ -196,6 +196,37 @@ func NewLoginExecutor( return &exe } +// MuteExecutor is the executor for the mute command. +type MuteExecutor struct { + *flag.FlagSet + printer *printer.Printer + config *config.Config + accountName string + muteDuration TimeDurationFlagValue + muteNotifications bool + resourceType string +} + +func NewMuteExecutor( + printer *printer.Printer, + config *config.Config, +) *MuteExecutor { + exe := MuteExecutor{ + FlagSet: flag.NewFlagSet("mute", flag.ExitOnError), + printer: printer, + config: config, + muteDuration: NewTimeDurationFlagValue(), + } + + exe.Usage = commandUsageFunc("mute", "Mutes a specific resource (e.g. an account)", exe.FlagSet) + + exe.StringVar(&exe.accountName, "account-name", "", "The name of the account") + exe.Var(&exe.muteDuration, "mute-duration", "Specify how long the mute should last for. To mute indefinitely, set this to 0s") + exe.BoolVar(&exe.muteNotifications, "mute-notifications", false, "Set to true to mute notifications as well as posts") + exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)") + return &exe +} + // RejectExecutor is the executor for the reject command. type RejectExecutor struct { *flag.FlagSet @@ -300,6 +331,32 @@ func NewUnfollowExecutor( return &exe } +// UnmuteExecutor is the executor for the unmute command. +type UnmuteExecutor struct { + *flag.FlagSet + printer *printer.Printer + config *config.Config + accountName string + resourceType string +} + +func NewUnmuteExecutor( + printer *printer.Printer, + config *config.Config, +) *UnmuteExecutor { + exe := UnmuteExecutor{ + FlagSet: flag.NewFlagSet("unmute", flag.ExitOnError), + printer: printer, + config: config, + } + + exe.Usage = commandUsageFunc("unmute", "Umutes a specific 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. type VersionExecutor struct { *flag.FlagSet diff --git a/internal/executor/flags.go b/internal/executor/flags.go index 556470e..e27d974 100644 --- a/internal/executor/flags.go +++ b/internal/executor/flags.go @@ -101,8 +101,14 @@ type TimeDurationFlagValue struct { Duration time.Duration } +func NewTimeDurationFlagValue() TimeDurationFlagValue { + return TimeDurationFlagValue{ + Duration: 0 * time.Second, + } +} + func (v TimeDurationFlagValue) String() string { - return "" + return "Time duration: " + v.Duration.String() } func (v *TimeDurationFlagValue) Set(text string) error { diff --git a/internal/executor/mute.go b/internal/executor/mute.go new file mode 100644 index 0000000..468a01c --- /dev/null +++ b/internal/executor/mute.go @@ -0,0 +1,49 @@ +package executor + +import ( + "fmt" + + "codeflow.dananglin.me.uk/apollo/enbas/internal/client" +) + +func (m *MuteExecutor) Execute() error { + funcMap := map[string]func(*client.Client) error{ + resourceAccount: m.muteAccount, + } + + doFunc, ok := funcMap[m.resourceType] + if !ok { + return UnsupportedTypeError{resourceType: m.resourceType} + } + + gtsClient, err := client.NewClientFromFile(m.config.CredentialsFile) + if err != nil { + return fmt.Errorf("unable to create the GoToSocial client: %w", err) + } + + return doFunc(gtsClient) +} + +func (m *MuteExecutor) muteAccount(gtsClient *client.Client) error { + if m.accountName == "" { + return FlagNotSetError{flagText: flagAccountName} + } + + accountID, err := getAccountID(gtsClient, false, m.accountName, m.config.CredentialsFile) + if err != nil { + return fmt.Errorf("received an error while getting the account ID: %w", err) + } + + form := client.MuteAccountForm{ + Notifications: m.muteNotifications, + Duration: int(m.muteDuration.Duration.Seconds()), + } + + if err := gtsClient.MuteAccount(accountID, form); err != nil { + return fmt.Errorf("unable to mute the account: %w", err) + } + + m.printer.PrintSuccess("Successfully muted the account.") + + return nil +} diff --git a/internal/executor/mute_or_unmute.go b/internal/executor/mute_or_unmute.go deleted file mode 100644 index 790f04d..0000000 --- a/internal/executor/mute_or_unmute.go +++ /dev/null @@ -1,108 +0,0 @@ -package executor - -import ( - "flag" - "fmt" - "time" - - "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 MuteOrUnmuteExecutor struct { - *flag.FlagSet - - printer *printer.Printer - config *config.Config - accountName string - command string - resourceType string - muteDuration TimeDurationFlagValue - muteNotifications bool -} - -func NewMuteOrUnmuteExecutor(printer *printer.Printer, config *config.Config, name, summary string) *MuteOrUnmuteExecutor { - muteDuration := TimeDurationFlagValue{time.Duration(0 * time.Second)} - - exe := MuteOrUnmuteExecutor{ - FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - - printer: printer, - config: config, - command: name, - muteDuration: muteDuration, - } - - exe.StringVar(&exe.accountName, flagAccountName, "", "Specify the account name in full (username@domain)") - exe.StringVar(&exe.resourceType, flagType, "", "Specify the type of resource to mute or unmute") - exe.BoolVar(&exe.muteNotifications, flagMuteNotifications, false, "Mute notifications as well as posts") - exe.Var(&exe.muteDuration, flagMuteDuration, "Specify how long the mute should last for. To mute indefinitely, set this to 0s") - - exe.Usage = commandUsageFunc(name, summary, exe.FlagSet) - - return &exe -} - -func (m *MuteOrUnmuteExecutor) Execute() error { - funcMap := map[string]func(*client.Client) error{ - resourceAccount: m.muteOrUnmuteAccount, - } - - doFunc, ok := funcMap[m.resourceType] - if !ok { - return UnsupportedTypeError{resourceType: m.resourceType} - } - - gtsClient, err := client.NewClientFromFile(m.config.CredentialsFile) - if err != nil { - return fmt.Errorf("unable to create the GoToSocial client: %w", err) - } - - return doFunc(gtsClient) -} - -func (m *MuteOrUnmuteExecutor) muteOrUnmuteAccount(gtsClient *client.Client) error { - if m.accountName == "" { - return FlagNotSetError{flagText: flagAccountName} - } - - accountID, err := getAccountID(gtsClient, false, m.accountName, m.config.CredentialsFile) - if err != nil { - return fmt.Errorf("received an error while getting the account ID: %w", err) - } - - switch m.command { - case CommandMute: - return m.muteAccount(gtsClient, accountID) - case CommandUnmute: - return m.unmuteAccount(gtsClient, accountID) - default: - return nil - } -} - -func (m *MuteOrUnmuteExecutor) muteAccount(gtsClient *client.Client, accountID string) error { - form := client.MuteAccountForm{ - Notifications: m.muteNotifications, - Duration: int(m.muteDuration.Duration.Seconds()), - } - - if err := gtsClient.MuteAccount(accountID, form); err != nil { - return fmt.Errorf("unable to mute the account: %w", err) - } - - m.printer.PrintSuccess("Successfully muted the account.") - - return nil -} - -func (m *MuteOrUnmuteExecutor) unmuteAccount(gtsClient *client.Client, accountID string) error { - if err := gtsClient.UnmuteAccount(accountID); err != nil { - return fmt.Errorf("unable to unmute the account: %w", err) - } - - m.printer.PrintSuccess("Successfully unmuted the account.") - - return nil -} diff --git a/internal/executor/unmute.go b/internal/executor/unmute.go new file mode 100644 index 0000000..b05435b --- /dev/null +++ b/internal/executor/unmute.go @@ -0,0 +1,44 @@ +package executor + +import ( + "fmt" + + "codeflow.dananglin.me.uk/apollo/enbas/internal/client" +) + +func (m *UnmuteExecutor) Execute() error { + funcMap := map[string]func(*client.Client) error{ + resourceAccount: m.unmuteAccount, + } + + doFunc, ok := funcMap[m.resourceType] + if !ok { + return UnsupportedTypeError{resourceType: m.resourceType} + } + + gtsClient, err := client.NewClientFromFile(m.config.CredentialsFile) + if err != nil { + return fmt.Errorf("unable to create the GoToSocial client: %w", err) + } + + return doFunc(gtsClient) +} + +func (m *UnmuteExecutor) unmuteAccount(gtsClient *client.Client) error { + if m.accountName == "" { + return FlagNotSetError{flagText: flagAccountName} + } + + accountID, err := getAccountID(gtsClient, false, m.accountName, m.config.CredentialsFile) + if err != nil { + return fmt.Errorf("received an error while getting the account ID: %w", err) + } + + if err := gtsClient.UnmuteAccount(accountID); err != nil { + return fmt.Errorf("unable to unmute the account: %w", err) + } + + m.printer.PrintSuccess("Successfully unmuted the account.") + + return nil +} diff --git a/schema/enbas_cli_schema.json b/schema/enbas_cli_schema.json index 5cd41fd..33081eb 100644 --- a/schema/enbas_cli_schema.json +++ b/schema/enbas_cli_schema.json @@ -17,12 +17,20 @@ "description": "The ID of the list in question" }, "list-title": { - "type": "string", - "description": "The title of the list" + "type": "string", + "description": "The title of the list" }, "list-replies-policy": { - "type": "string", - "description": "The replies policy of the list" + "type": "string", + "description": "The replies policy of the list" + }, + "mute-duration": { + "type": "TimeDurationFlagValue", + "description": "Specify how long the mute should last for. To mute indefinitely, set this to 0s" + }, + "mute-notifications": { + "type": "bool", + "description": "Set to true to mute notifications as well as posts" }, "notify": { "type": "bool", @@ -115,6 +123,18 @@ "useConfig": true, "usePrinter": true }, + "mute": { + "additionalFields": [], + "flags": [ + { "flag": "account-name", "default": "" }, + { "flag": "mute-duration" }, + { "flag": "mute-notifications", "default": "false" }, + { "flag": "type", "fieldName": "resourceType", "default": "" } + ], + "summary": "Mutes a specific resource (e.g. an account)", + "useConfig": true, + "usePrinter": true + }, "reject": { "additionalFields": [], "flags": [ @@ -155,6 +175,16 @@ "useConfig": true, "usePrinter": true }, + "unmute": { + "additionalFields": [], + "flags": [ + { "flag": "account-name", "default": "" }, + { "flag": "type", "fieldName": "resourceType", "default": "" } + ], + "summary": "Umutes a specific resource (e.g. an account)", + "useConfig": true, + "usePrinter": true + }, "version": { "additionalFields": [ { "name": "binaryVersion", "type": "string"},