mirror of
https://github.com/diamondburned/arikawa.git
synced 2025-03-21 01:19:20 +00:00
Bot: Added Usager, improved help
This commit is contained in:
parent
be12849668
commit
3ee307b788
|
@ -17,6 +17,12 @@ type Parser interface {
|
|||
Parse(string) error
|
||||
}
|
||||
|
||||
// Usager is used in place of the automatically parsed struct name for Parser
|
||||
// and other interfaces.
|
||||
type Usager interface {
|
||||
Usage() string
|
||||
}
|
||||
|
||||
// ManualParser has a ParseContent(string) method. If the library sees
|
||||
// this for an argument, it will send all of the arguments (including the
|
||||
// command) into the method. If used, this should be the only argument followed
|
||||
|
@ -145,7 +151,7 @@ func getArgumentValueFn(t reflect.Type) (*Argument, error) {
|
|||
}
|
||||
|
||||
return &Argument{
|
||||
String: t.String(),
|
||||
String: fromUsager(typeI),
|
||||
Type: typeI,
|
||||
pointer: ptr,
|
||||
fn: avfn,
|
||||
|
@ -219,3 +225,16 @@ func quickRet(v interface{}, err error, t reflect.Type) (reflect.Value, error) {
|
|||
|
||||
return rv.Convert(t), nil
|
||||
}
|
||||
|
||||
func fromUsager(typeI reflect.Type) string {
|
||||
if typeI.Implements(typeIUsager) {
|
||||
mt, ok := typeI.MethodByName("Usage")
|
||||
if !ok {
|
||||
panic("BUG: type IUsager does not implement Usage")
|
||||
}
|
||||
vs := mt.Func.Call([]reflect.Value{reflect.New(typeI.Elem())})
|
||||
return vs[0].String()
|
||||
}
|
||||
s := strings.Split(typeI.String(), ".")
|
||||
return s[len(s)-1]
|
||||
}
|
||||
|
|
31
bot/ctx.go
31
bot/ctx.go
|
@ -361,38 +361,27 @@ func (ctx *Context) help(hideAdmin bool) string {
|
|||
help.WriteString("\n---\n")
|
||||
|
||||
// Generate all commands
|
||||
help.WriteString("__Commands__\n")
|
||||
|
||||
for _, cmd := range ctx.Commands {
|
||||
if cmd.Flag.Is(AdminOnly) && hideAdmin {
|
||||
continue
|
||||
}
|
||||
|
||||
help.WriteString(indent + cmd.Command)
|
||||
|
||||
switch {
|
||||
case len(cmd.Usage()) > 0:
|
||||
help.WriteString(" " + strings.Join(cmd.Usage(), " "))
|
||||
case cmd.Description != "":
|
||||
help.WriteString(": " + cmd.Description)
|
||||
}
|
||||
|
||||
help.WriteByte('\n')
|
||||
}
|
||||
help.WriteString("__Commands__")
|
||||
help.WriteString(ctx.Subcommand.Help(indent, hideAdmin))
|
||||
help.WriteByte('\n')
|
||||
|
||||
var subHelp = strings.Builder{}
|
||||
var subcommands = ctx.Subcommands()
|
||||
|
||||
for _, sub := range subcommands {
|
||||
if help := sub.Help(indent, hideAdmin); help != "" {
|
||||
subHelp.WriteString(help)
|
||||
for _, line := range strings.Split(help, "\n") {
|
||||
subHelp.WriteString(indent)
|
||||
subHelp.WriteString(line)
|
||||
subHelp.WriteByte('\n')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sub := subHelp.String(); sub != "" {
|
||||
if subHelp.Len() > 0 {
|
||||
help.WriteString("---\n")
|
||||
help.WriteString("__Subcommands__\n")
|
||||
help.WriteString(sub)
|
||||
help.WriteString(subHelp.String())
|
||||
}
|
||||
|
||||
return help.String()
|
||||
|
|
|
@ -55,6 +55,10 @@ func (e Emoji) URL() string {
|
|||
}
|
||||
}
|
||||
|
||||
func (e *Emoji) Usage() string {
|
||||
return "emoji"
|
||||
}
|
||||
|
||||
func (e *Emoji) Parse(arg string) error {
|
||||
// Check if Unicode emoji
|
||||
if rate.StringIsEmojiOnly(arg) {
|
||||
|
|
62
bot/extras/arguments/link.go
Normal file
62
bot/extras/arguments/link.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
package arguments
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
)
|
||||
|
||||
// (empty) so it matches standard links
|
||||
// | OR
|
||||
// canary. matches canary MessageURL
|
||||
// 3 `(\d+)` for guild ID, channel ID and message ID
|
||||
var Regex = regexp.MustCompile(
|
||||
`https://(|ptb\.|canary\.)discordapp\.com/channels/(\d+)/(\d+)/(\d+)`,
|
||||
)
|
||||
|
||||
// MessageURL contains info from a MessageURL
|
||||
type MessageURL struct {
|
||||
GuildID discord.Snowflake
|
||||
ChannelID discord.Snowflake
|
||||
MessageID discord.Snowflake
|
||||
}
|
||||
|
||||
func (url *MessageURL) Parse(arg string) error {
|
||||
u := ParseMessageURL(arg)
|
||||
if u == nil {
|
||||
return errors.New("Invalid MessageURL format.")
|
||||
}
|
||||
*url = *u
|
||||
return nil
|
||||
}
|
||||
|
||||
func (url *MessageURL) Usage() string {
|
||||
return "https\u200b://discordapp.com/channels/\\*/\\*/\\*"
|
||||
}
|
||||
|
||||
// ParseMessageURL parses the MessageURL into a smartlink
|
||||
func ParseMessageURL(url string) *MessageURL {
|
||||
ss := Regex.FindAllStringSubmatch(url, -1)
|
||||
if ss == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(ss) == 0 || len(ss[0]) != 5 {
|
||||
return nil
|
||||
}
|
||||
|
||||
gID, err1 := discord.ParseSnowflake(ss[0][2])
|
||||
cID, err2 := discord.ParseSnowflake(ss[0][3])
|
||||
mID, err3 := discord.ParseSnowflake(ss[0][4])
|
||||
|
||||
if err1 != nil || err2 != nil || err3 != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &MessageURL{
|
||||
GuildID: gID,
|
||||
ChannelID: cID,
|
||||
MessageID: mID,
|
||||
}
|
||||
}
|
|
@ -18,8 +18,7 @@ var (
|
|||
type ChannelMention discord.Snowflake
|
||||
|
||||
func (m *ChannelMention) Parse(arg string) error {
|
||||
return grabFirst(ChannelRegex, "channel mention",
|
||||
arg, (*discord.Snowflake)(m))
|
||||
return grabFirst(ChannelRegex, "channel mention", arg, (*discord.Snowflake)(m))
|
||||
}
|
||||
|
||||
func (m *ChannelMention) Usage() string {
|
||||
|
@ -39,8 +38,7 @@ func (m *ChannelMention) Mention() string {
|
|||
type UserMention discord.Snowflake
|
||||
|
||||
func (m *UserMention) Parse(arg string) error {
|
||||
return grabFirst(UserRegex, "user mention",
|
||||
arg, (*discord.Snowflake)(m))
|
||||
return grabFirst(UserRegex, "user mention", arg, (*discord.Snowflake)(m))
|
||||
}
|
||||
|
||||
func (m *UserMention) Usage() string {
|
||||
|
@ -60,8 +58,7 @@ func (m *UserMention) Mention() string {
|
|||
type RoleMention discord.Snowflake
|
||||
|
||||
func (m *RoleMention) Parse(arg string) error {
|
||||
return grabFirst(RoleRegex, "role mention",
|
||||
arg, (*discord.Snowflake)(m))
|
||||
return grabFirst(RoleRegex, "role mention", arg, (*discord.Snowflake)(m))
|
||||
}
|
||||
|
||||
func (m *RoleMention) Usage() string {
|
||||
|
@ -78,9 +75,7 @@ func (m *RoleMention) Mention() string {
|
|||
|
||||
//
|
||||
|
||||
func grabFirst(reg *regexp.Regexp,
|
||||
item, input string, output *discord.Snowflake) error {
|
||||
|
||||
func grabFirst(reg *regexp.Regexp, item, input string, output *discord.Snowflake) error {
|
||||
matches := reg.FindStringSubmatch(input)
|
||||
if len(matches) < 2 {
|
||||
return errors.New("Invalid " + item)
|
||||
|
|
|
@ -23,6 +23,7 @@ var (
|
|||
typeIManP = reflect.TypeOf((*ManualParser)(nil)).Elem()
|
||||
typeICusP = reflect.TypeOf((*CustomParser)(nil)).Elem()
|
||||
typeIParser = reflect.TypeOf((*Parser)(nil)).Elem()
|
||||
typeIUsager = reflect.TypeOf((*Usager)(nil)).Elem()
|
||||
typeSetupFn = func() reflect.Type {
|
||||
method, _ := reflect.TypeOf((*CanSetup)(nil)).
|
||||
Elem().
|
||||
|
@ -182,14 +183,12 @@ func (sub *Subcommand) Help(indent string, hideAdmin bool) string {
|
|||
var header string
|
||||
|
||||
if sub.Command != "" {
|
||||
header += indent + sub.Command
|
||||
header += sub.Command
|
||||
}
|
||||
|
||||
if sub.Description != "" {
|
||||
if header != "" {
|
||||
header += ": "
|
||||
} else {
|
||||
header += indent
|
||||
}
|
||||
|
||||
header += sub.Description
|
||||
|
@ -200,21 +199,27 @@ func (sub *Subcommand) Help(indent string, hideAdmin bool) string {
|
|||
// The commands part:
|
||||
var commands = ""
|
||||
|
||||
for _, cmd := range sub.Commands {
|
||||
for i, cmd := range sub.Commands {
|
||||
if cmd.Flag.Is(AdminOnly) && hideAdmin {
|
||||
continue
|
||||
}
|
||||
|
||||
commands += indent + indent + sub.Command + " " + cmd.Command
|
||||
if sub.Command != "" {
|
||||
commands += indent + sub.Command + " " + cmd.Command
|
||||
} else {
|
||||
commands += indent + cmd.Command
|
||||
}
|
||||
|
||||
switch {
|
||||
case len(cmd.Usage()) > 0:
|
||||
commands += " " + strings.Join(cmd.Usage(), " ")
|
||||
commands += " **" + strings.Join(cmd.Usage(), " ") + "**"
|
||||
case cmd.Description != "":
|
||||
commands += ": " + cmd.Description
|
||||
}
|
||||
|
||||
commands += "\n"
|
||||
if i != len(sub.Commands)-1 {
|
||||
commands += "\n"
|
||||
}
|
||||
}
|
||||
|
||||
if commands == "" {
|
||||
|
|
|
@ -148,9 +148,7 @@ func (s *State) MemberColor(guildID, userID discord.Snowflake) discord.Color {
|
|||
|
||||
////
|
||||
|
||||
func (s *State) Permissions(
|
||||
channelID, userID discord.Snowflake) (discord.Permissions, error) {
|
||||
|
||||
func (s *State) Permissions(channelID, userID discord.Snowflake) (discord.Permissions, error) {
|
||||
ch, err := s.Channel(channelID)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "Failed to get channel")
|
||||
|
|
Loading…
Reference in a new issue