mirror of https://github.com/Bios-Marcel/cordless
373 lines
10 KiB
Go
373 lines
10 KiB
Go
package commandimpls
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/Bios-Marcel/discordemojimap"
|
|
"github.com/Bios-Marcel/discordgo"
|
|
|
|
"github.com/Bios-Marcel/cordless/config"
|
|
"github.com/Bios-Marcel/cordless/ui/tviewutil"
|
|
)
|
|
|
|
const (
|
|
statusHelpPage = `[::b]NAME
|
|
status - view your or others status or update your own
|
|
|
|
[::b]SYNOPSIS
|
|
[::b]status [subcommand]
|
|
|
|
[::b]DESCRIPTION
|
|
This command allows to either update your status or view a users status.
|
|
For more information check the help pages of the subcommands.
|
|
|
|
[::b]SUBCOMMANDS
|
|
[::b]status-get (default)
|
|
prints the status of the given user or yourself
|
|
[::b]status-set
|
|
updates your current status
|
|
[::b]status-set-custom
|
|
set your status to a custom text`
|
|
|
|
statusSetHelpPage = `[::b]NAME
|
|
status-set - allows updating your own status
|
|
|
|
[::b]SYNOPSIS
|
|
[::b]status-set[::-] <online|idle|dnd|invisible>
|
|
|
|
[::b]DESCRIPTION
|
|
This command can be used to set your current online status to the
|
|
value passed as the first parameter. Other users will immediately
|
|
see your status update.
|
|
|
|
[::b]EXAMPLES
|
|
[gray]$ status-set invisible`
|
|
|
|
statusGetHelpPage = `[::b]NAME
|
|
status-get - prints your current status or the status of the given user
|
|
|
|
[::b]SYNOPSIS
|
|
[::b]status-get[::-] [Username|Username#NNNN|UserID[]
|
|
|
|
[::b]DESCRIPTION
|
|
This command prints either your current status of no value was passed
|
|
or the status of the passed user, if the presence for that user could
|
|
be found. Due to a problem with the presences, this command might randomly
|
|
fail when trying to query specific users.
|
|
|
|
[::b]EXAMPLES
|
|
[gray]$ status-get
|
|
[yellow]idle
|
|
|
|
[gray]$ status-get Marcel#7299
|
|
[red]Do not disturb`
|
|
|
|
statusSetCustomHelpPage = `[::b]NAME
|
|
status-set-custom - set a custom status text
|
|
|
|
[::b]SYNOPSIS
|
|
[::b]status-set-custom[::-] [OPTION[]...
|
|
|
|
[::b]DESCRIPTION
|
|
This command allows you to set a custom status.
|
|
|
|
[::b]OPTIONS
|
|
[::b]-s, --status
|
|
status message
|
|
[::b]-e, --emoji
|
|
emoji in your status
|
|
[::b]-i, --expire, --expiry <s|m|h>
|
|
time that the status expires after
|
|
|
|
[::b]EXAMPLES
|
|
[gray]$ status-set-custom -s "shining bright" -e :sun:
|
|
[gray]$ status-set-custom -s "shining bright" -e 🌞
|
|
[gray]$ status-set-custom -s test -i 1h`
|
|
)
|
|
|
|
type StatusCmd struct {
|
|
statusGetCmd *StatusGetCmd
|
|
statusSetCmd *StatusSetCmd
|
|
statusSetCustomCmd *StatusSetCustomCmd
|
|
}
|
|
|
|
type StatusGetCmd struct {
|
|
session *discordgo.Session
|
|
}
|
|
|
|
type StatusSetCmd struct {
|
|
session *discordgo.Session
|
|
}
|
|
|
|
type StatusSetCustomCmd struct {
|
|
session *discordgo.Session
|
|
}
|
|
|
|
func NewStatusCommand(statusGetCmd *StatusGetCmd, statusSetCmd *StatusSetCmd, statusSetCustomCmd *StatusSetCustomCmd) *StatusCmd {
|
|
return &StatusCmd{
|
|
statusGetCmd: statusGetCmd,
|
|
statusSetCmd: statusSetCmd,
|
|
statusSetCustomCmd: statusSetCustomCmd,
|
|
}
|
|
}
|
|
|
|
func NewStatusGetCommand(session *discordgo.Session) *StatusGetCmd {
|
|
return &StatusGetCmd{session}
|
|
}
|
|
|
|
func NewStatusSetCommand(session *discordgo.Session) *StatusSetCmd {
|
|
return &StatusSetCmd{session}
|
|
}
|
|
|
|
func NewStatusSetCustomCommand(session *discordgo.Session) *StatusSetCustomCmd {
|
|
return &StatusSetCustomCmd{session}
|
|
}
|
|
|
|
func statusColor(status discordgo.Status) string {
|
|
switch status {
|
|
case discordgo.StatusOnline:
|
|
return "green"
|
|
case discordgo.StatusDoNotDisturb:
|
|
return "red"
|
|
case discordgo.StatusIdle:
|
|
return "yellow"
|
|
case discordgo.StatusInvisible, discordgo.StatusOffline:
|
|
return "gray"
|
|
default:
|
|
return "gray"
|
|
}
|
|
}
|
|
|
|
func statusToString(status discordgo.Status) string {
|
|
statusString := "[" + statusColor(status) + "]"
|
|
switch status {
|
|
case discordgo.StatusOnline:
|
|
statusString += "Online"
|
|
case discordgo.StatusDoNotDisturb:
|
|
statusString += "Do not disturb"
|
|
case discordgo.StatusIdle:
|
|
statusString += "Idle"
|
|
case discordgo.StatusInvisible:
|
|
statusString += "Invisible"
|
|
case discordgo.StatusOffline:
|
|
statusString += "Offline"
|
|
default:
|
|
statusString += "Unknown status"
|
|
}
|
|
return statusString
|
|
}
|
|
|
|
func (cmd *StatusGetCmd) Execute(writer io.Writer, parameters []string) {
|
|
if len(parameters) > 1 {
|
|
fmt.Fprintln(writer, "["+tviewutil.ColorToHex(config.GetTheme().ErrorColor)+"]Invalid parameters")
|
|
cmd.PrintHelp(writer)
|
|
return
|
|
}
|
|
|
|
if len(parameters) == 0 {
|
|
fmt.Fprintf(writer, statusToString(cmd.session.State.Settings.Status))
|
|
|
|
customStatus := cmd.session.State.Settings.CustomStatus
|
|
if len(customStatus.Text) > 0 || len(customStatus.EmojiName) > 0 {
|
|
fmt.Fprintf(writer, ": %s %s", customStatus.EmojiName, customStatus.Text)
|
|
}
|
|
fmt.Fprintf(writer, "[white]\n")
|
|
return
|
|
}
|
|
|
|
input := parameters[0]
|
|
var matches []*discordgo.Presence
|
|
for _, presence := range cmd.session.State.Presences {
|
|
user := presence.User
|
|
if user.ID == input || user.Username == input || user.String() == input {
|
|
matches = append(matches, presence)
|
|
}
|
|
}
|
|
|
|
if len(matches) == 0 {
|
|
fmt.Fprintf(writer, "["+tviewutil.ColorToHex(config.GetTheme().ErrorColor)+"]No match for '%s'.\n", input)
|
|
} else if len(matches) > 1 {
|
|
fmt.Fprintf(writer, "Multiple matches were found for '%s'. Please be more precise.\n", input)
|
|
fmt.Fprintln(writer, "The following matches were found:")
|
|
for _, match := range matches {
|
|
fmt.Fprintf(writer, "\t%s\n", match.User.String())
|
|
}
|
|
} else {
|
|
fmt.Fprintln(writer, statusToString(matches[0].Status))
|
|
}
|
|
}
|
|
|
|
func (cmd *StatusSetCmd) Execute(writer io.Writer, parameters []string) {
|
|
if cmd.session.State.User.Bot {
|
|
fmt.Fprintln(writer, "[red]This command can't be used by bots due to Discord API restrictions.")
|
|
return
|
|
}
|
|
|
|
if len(parameters) == 0 || len(parameters) > 1 {
|
|
fmt.Fprintln(writer, "["+tviewutil.ColorToHex(config.GetTheme().ErrorColor)+"]Invalid parameters")
|
|
cmd.PrintHelp(writer)
|
|
return
|
|
}
|
|
|
|
var settingStatusError error
|
|
var updatedSettings *discordgo.Settings
|
|
|
|
switch strings.ToLower(parameters[0]) {
|
|
case "online", "available":
|
|
updatedSettings, settingStatusError = cmd.session.UserUpdateStatus(discordgo.StatusOnline)
|
|
case "dnd", "donotdisturb", "busy":
|
|
updatedSettings, settingStatusError = cmd.session.UserUpdateStatus(discordgo.StatusDoNotDisturb)
|
|
case "idle":
|
|
updatedSettings, settingStatusError = cmd.session.UserUpdateStatus(discordgo.StatusIdle)
|
|
case "invisible":
|
|
updatedSettings, settingStatusError = cmd.session.UserUpdateStatus(discordgo.StatusInvisible)
|
|
default:
|
|
fmt.Fprintf(writer, "["+tviewutil.ColorToHex(config.GetTheme().ErrorColor)+"]Invalid status: '%s'\n", strings.ToLower(parameters[0]))
|
|
cmd.PrintHelp(writer)
|
|
}
|
|
|
|
if settingStatusError != nil {
|
|
fmt.Fprintf(writer, "["+tviewutil.ColorToHex(config.GetTheme().ErrorColor)+"]Error setting status:\n\t["+tviewutil.ColorToHex(config.GetTheme().ErrorColor)+"]'%s'\n", settingStatusError.Error())
|
|
} else if updatedSettings != nil {
|
|
cmd.session.State.Settings = updatedSettings
|
|
}
|
|
}
|
|
|
|
func (cmd *StatusCmd) Execute(writer io.Writer, parameters []string) {
|
|
if len(parameters) >= 1 {
|
|
if parameters[0] == "set" || parameters[0] == "update" {
|
|
cmd.statusSetCmd.Execute(writer, parameters[1:])
|
|
} else if parameters[0] == "get" {
|
|
cmd.statusGetCmd.Execute(writer, parameters[1:])
|
|
} else if parameters[0] == "set-custom" || parameters[0] == "custom-set" {
|
|
cmd.statusSetCustomCmd.Execute(writer, parameters[1:])
|
|
} else {
|
|
cmd.statusGetCmd.Execute(writer, parameters)
|
|
}
|
|
} else {
|
|
cmd.statusGetCmd.Execute(writer, parameters)
|
|
}
|
|
}
|
|
|
|
func (cmd *StatusSetCustomCmd) Execute(writer io.Writer, parameters []string) {
|
|
if cmd.session.State.User.Bot {
|
|
fmt.Fprintln(writer, "[red]This command can't be used by bots due to Discord API restrictions.")
|
|
return
|
|
}
|
|
|
|
if len(parameters) == 0 {
|
|
fmt.Fprintln(writer, "["+tviewutil.ColorToHex(config.GetTheme().ErrorColor)+"]Invalid parameters")
|
|
cmd.PrintHelp(writer)
|
|
return
|
|
}
|
|
|
|
errorColor := tviewutil.ColorToHex(config.GetTheme().ErrorColor)
|
|
var customStatus discordgo.CustomStatus
|
|
for index, param := range parameters {
|
|
switch param {
|
|
case "-s", "--status":
|
|
if index != len(parameters)-1 {
|
|
customStatus.Text = parameters[index+1]
|
|
} else {
|
|
fmt.Fprintf(writer, "[%s]Error, you didn't supply a status\n", errorColor)
|
|
return
|
|
}
|
|
case "-e", "--emoji":
|
|
if index != len(parameters)-1 {
|
|
if discordemojimap.ContainsEmoji(parameters[index+1]) {
|
|
customStatus.EmojiName = parameters[index+1]
|
|
} else if emoji := discordemojimap.Replace(parameters[index+1]); emoji != parameters[index+1] {
|
|
customStatus.EmojiName = emoji
|
|
} else {
|
|
fmt.Fprintf(writer, "[%s]Invalid emoji\n", errorColor)
|
|
return
|
|
}
|
|
}
|
|
case "-i", "--expire", "--expiry":
|
|
if m, _ := regexp.MatchString(`\d+(s|m|h)`, parameters[index+1]); m {
|
|
lastIndex := len(parameters[index+1]) - 1
|
|
num, err := strconv.Atoi(parameters[index+1][:lastIndex])
|
|
if err != nil {
|
|
fmt.Fprintf(writer, "[%s]Invalid expiry\n", errorColor)
|
|
return
|
|
}
|
|
|
|
now := time.Now().UTC()
|
|
switch parameters[index+1][lastIndex] {
|
|
case 's':
|
|
now = now.Add(time.Second * time.Duration(num))
|
|
case 'm':
|
|
now = now.Add(time.Minute * time.Duration(num))
|
|
case 'h':
|
|
now = now.Add(time.Hour * time.Duration(num))
|
|
default:
|
|
fmt.Fprintf(writer, "[%s]Invalid time character: %c != <s|m|h>\n", errorColor, parameters[index+1][lastIndex])
|
|
return
|
|
}
|
|
customStatus.ExpiresAt = now.Format(time.RFC3339Nano)
|
|
}
|
|
}
|
|
}
|
|
|
|
settings, err := cmd.session.UserUpdateStatusCustom(customStatus)
|
|
if err != nil {
|
|
fmt.Fprintf(writer, "[%s]Error updating custom status:\n\t[%s]'%s'\n", errorColor, errorColor, err.Error())
|
|
return
|
|
} else if settings != nil {
|
|
cmd.session.State.Settings = settings
|
|
}
|
|
}
|
|
|
|
func (cmd *StatusCmd) PrintHelp(writer io.Writer) {
|
|
fmt.Fprintln(writer, statusHelpPage)
|
|
}
|
|
|
|
func (cmd *StatusSetCmd) PrintHelp(writer io.Writer) {
|
|
fmt.Fprintln(writer, statusSetHelpPage)
|
|
}
|
|
|
|
func (cmd *StatusGetCmd) PrintHelp(writer io.Writer) {
|
|
fmt.Fprintln(writer, statusGetHelpPage)
|
|
}
|
|
|
|
func (cmd *StatusSetCustomCmd) PrintHelp(writer io.Writer) {
|
|
fmt.Fprintln(writer, statusSetCustomHelpPage)
|
|
}
|
|
|
|
func (cmd *StatusSetCustomCmd) Name() string {
|
|
return "status-set-custom"
|
|
}
|
|
|
|
func (cmd *StatusSetCmd) Name() string {
|
|
return "status-set"
|
|
}
|
|
|
|
func (cmd *StatusGetCmd) Name() string {
|
|
return "status-get"
|
|
}
|
|
|
|
func (cmd *StatusCmd) Name() string {
|
|
return "status"
|
|
}
|
|
|
|
func (cmd *StatusSetCustomCmd) Aliases() []string {
|
|
return []string{"status-custom"}
|
|
}
|
|
|
|
func (cmd *StatusSetCmd) Aliases() []string {
|
|
return []string{"status-update"}
|
|
}
|
|
|
|
func (cmd *StatusGetCmd) Aliases() []string {
|
|
return nil
|
|
}
|
|
|
|
func (cmd *StatusCmd) Aliases() []string {
|
|
return nil
|
|
}
|