rosetta

package
v0.0.0-...-99e36ab Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 14, 2021 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package rosetta is iridaceae internal command parser. Greatly inspired by luis/dgc and zekroTJA/sireikan with some modification.

Index

Constants

View Source
const (
	GroupGlobalAdmin = "GLOBAL ADMIN"
	GroupGuildAdmin  = "GUILD ADMIN"
	GroupModeration  = "MODERATION"
	GroupFun         = "FUN"
	GroupChat        = "CHAT"
	GroupEtc         = "ETC"
	GroupGeneral     = "GENERAL"
	GroupGuildConfig = "GUILD CONFIG"
)
View Source
const (
	ObjectMapKeyRouter = "rosetta_router"
)

Variables

View Source
var (

	// ArgumentsRegex defines regex arguments should match.
	ArgumentsRegex = regexp.MustCompile("(\"[^\"]+\"|[^\\s]+)")

	// UserMentionRegex defines regex user mention should match.
	UserMentionRegex = regexp.MustCompile(`<@!?(\d+)>`)

	// RoleMentionRegex defines regex role mention should match.
	RoleMentionRegex = regexp.MustCompile(`<@&(\d+)>`)

	// ChannelMentionRegex defines regex channel mention should match.
	ChannelMentionRegex = regexp.MustCompile(`<#(\d+)>`)

	// CodeblockRegex defines regex for codeblock to match.
	CodeblockRegex = regexp.MustCompile("(?s)\\n*```(?:([\\w.\\-]*)\\n)?(.*)```")

	// InlineCodeRegex defines regex for inline code to match.
	InlineCodeRegex = regexp.MustCompile("(?s)\\n*`(.*)`")

	// ProgrammingLanguage defines valid language for codeblock.
	ProgrammingLanguage = []string{
		"go",
		"golang",
		"docker",
		"dockerfile",
		"python",
		"java",
		"c",
		"js",
		"jsx",
		"ts",
		"tsx",
		"lua",
		"makefile",
		"json",
	}
)
View Source
var (
	// ErrRateLimited is thrown when users spam commands =).
	ErrRateLimited = errors.New("rate limited")

	// ErrInvokeDoesNotExists is thrown when given command invoker doesn't exists.
	ErrInvokeDoesNotExists = errors.New("given invoke doesn't exists")

	// ErrGuildPrefixGetter is thrown GuildPrefixGetter failed.
	ErrGuildPrefixGetter = errors.New("error while getting guild prefix")

	// ErrGetChannel is thrown while getting channel.
	ErrGetChannel = errors.New("error while getting channel")

	// ErrGetGuild is thrown while getting guild.
	ErrGetGuild = errors.New("error while getting guild")

	// ErrCommandNotFound is thrown when command is not found.
	ErrCommandNotFound = errors.New("command not found")

	// ErrNotExecutableInDMs is thrown when command is not allowed to run in DMs.
	ErrNotExecutableInDMs = errors.New("command is not executable in DMs")

	// ErrMiddleware is thrown when middleware failed unexpectedly.
	ErrMiddleware = errors.New("middleware error")

	// ErrCommandExec is thrown when command exec failed.
	ErrCommandExec = errors.New("command failed to execute")

	// ErrDeleteCommandMessage is thrown when error occurred when deleting message.
	ErrDeleteCommandMessage = errors.New("failed while deleting command message")

	EmbedColorDefault = 0x6A5ACD
	EmbedColorError   = 0xE53935
)
View Source
var SpliceRegex = regexp.MustCompile(`\\s+`)

SpliceRegex represents the regex to split arguments.

Functions

This section is empty.

Types

type Argument

type Argument string

Argument extends string.

func (Argument) AsBool

func (a Argument) AsBool() (bool, error)

AsBool returns given argument as boolean. Since we are using strconv.ParseBool, it will accept 1, t, T, TRUE, true, True, 0, f, F, FALSE, False, false.

func (Argument) AsChannelMentionID

func (a Argument) AsChannelMentionID() string

AsChannelMentionID returns id of mentioned channel or an empty string if there isn't one.

func (Argument) AsDuration

func (a Argument) AsDuration() (time.Duration, error)

AsDuration parses given argument into a duration.

func (Argument) AsInt

func (a Argument) AsInt() (int, error)

AsInt returns given argument as int.

func (Argument) AsInt64

func (a Argument) AsInt64() (int64, error)

AsInt64 parses given argument into int64.

func (Argument) AsRoleMentionID

func (a Argument) AsRoleMentionID() string

AsRoleMentionID returns id of mentioned role or an empty string if there isn't one.

func (Argument) AsUserMentionID

func (a Argument) AsUserMentionID() string

AsUserMentionID returns id of mentioned user or an empty string if there isn't one.

func (Argument) String

func (a Argument) String() string

String returns raw string value of given argument.

type Arguments

type Arguments struct {
	// contains filtered or unexported fields
}

Arguments wraps around Arguments.

func FromArguments

func FromArguments(args []Argument) *Arguments

FromArguments create a new arguments from given list.

func ParseArguments

func ParseArguments(msg string) *Arguments

ParseArguments parses raw input message into several arguments.

func (Arguments) Args

func (a Arguments) Args() []Argument

Args returns list of args.

func (Arguments) AsCodeblock

func (a Arguments) AsCodeblock() *Codeblock

AsCodeblock parses given arguments as codeblock.

func (Arguments) AsSingle

func (a Arguments) AsSingle() *Arguments

AsSingle returns a singleton of arguments with raw content without args.

func (*Arguments) Get

func (a *Arguments) Get(n int) Argument

Get returns the nth arguments.

func (Arguments) IndexOf

func (a Arguments) IndexOf(arg string) int

IndexOf returns the index of a argument in arguments.

func (Arguments) Len

func (a Arguments) Len() int

Len returns length of given arguments.

func (Arguments) Raw

func (a Arguments) Raw() string

Raw returns raw string of the arguments.

func (*Arguments) Remove

func (a *Arguments) Remove(n int)

Remove removes the nth arguments.

type Codeblock

type Codeblock struct {
	Language string
	Content  string
}

Codeblock represents a discord codeblock.

type Command

type Command interface {
	// GetInvokers defines a unique string defines command invokers. First will be the primary
	// commands, following with aliases.
	GetInvokers() []string

	// GetDescription describes how the function will work.
	GetDescription() string

	// GetUsage returns how one can use the command with its subcommands.
	GetUsage() string

	// GetGroup returns the groups command belongs to.
	// admin - user - bot - helpers - etc.
	GetGroup() string

	// GetDomain returns the commands domain name.
	// TODO: have a regex to check if it follows the correct domain definition.
	// Domain definition as follow: rs.group.main.etc ...
	GetDomain() string

	// GetSubPermissionRules returns optional sub permissions of command.
	GetSubPermissionRules() []SubPermission

	// IsExecutableInDM returns true when command can be used when user dms the bot.
	// I saw this in yagpdb and I would like for rosetta to have something similar.
	IsExecutableInDM() bool

	// Exec is called when command is executed and getting passed CommandArgs.
	// Returns nil when successfully executed, otherwise errors encountered will be returned.
	Exec(ctx Context) error
}

Command defines a functionality of a command struct that will be registered under router.

type Config

type Config struct {
	GeneralPrefix         string `json:"general_prefix"`
	IgnoreCase            bool   `json:"ignore_case"`
	AllowDM               bool   `json:"allow_dm"`
	AllowBots             bool   `json:"allow_bots"`
	ExecuteOnEdit         bool   `json:"execute_on_edit"`
	UseDefaultHelpCommand bool   `json:"user_default_help_command"`
	DeleteMessageAfter    bool   `json:"delete_message_after"`

	// ObjectContainer can be passed by user to obtain instances from context.
	ObjectContainer di.Container `json:"-"`

	// OnError will be called when router failed to execute the command.
	// OnError will be passed when context failed to run, and return an ErrorType and error objects.
	OnError func(ctx Context, errType ErrorType, err error)

	// GuildPrefixGetter is called to get guild prefix.
	// Function will have guild id passed and return
	// the guild prefix if specified, else it will return
	// default prefix.
	// An error will be returned when the retrieving of the guild prefix failed unexpectedly.
	GuildPrefixGetter func(gid string) (string, error)
}

Config setup configs value for our router.

var C *Config

C can also be used out of a box, as a master config for iris.

func NewDefaultConfig

func NewDefaultConfig() *Config

type Context

type Context interface {
	ObjectMap

	// GetSession returns our instance of discordgo.Session.
	GetSession() *discordgo.Session

	// GetArguments returns our Arguments list and parsed Command Arguments.
	GetArguments() *Arguments

	// GetChannel returns the channel where message is sent.
	GetChannel() *discordgo.Channel

	// GetMessage returns the content of sent message.
	GetMessage() *discordgo.Message

	// GetGuild returns guild objects where command was sent.
	// We can use this later for logging purposes, update databases, etc.
	GetGuild() *discordgo.Guild

	// GetUser returns said user who invokes the command.
	GetUser() *discordgo.User

	// GetMember returns the member object of the author of the message.
	GetMember() *discordgo.Member

	// IsDM returns true if context is sent in a dms or group dms, false otherwise
	IsDM() bool

	// IsEdit returns true if event is a *discordgo.MessageUpdate event.
	IsEdit() bool

	// RespondText wraps around responses of given text message.
	RespondText(content string) (*discordgo.Message, error)

	// RespondEmbed responds with the given embed message.
	RespondEmbed(embed *discordgo.MessageEmbed) (*discordgo.Message, error)

	// RespondEmbedError responds with the given error in a embed message.
	RespondEmbedError(title string, err error) (*discordgo.Message, error)
}

Context is an interface representing information about a message and environment where this message was created and passed to middleware and command router.

type DefaultHelpCommand

type DefaultHelpCommand struct{}

func (*DefaultHelpCommand) Exec

func (d *DefaultHelpCommand) Exec(ctx Context) error

func (*DefaultHelpCommand) GetDescription

func (d *DefaultHelpCommand) GetDescription() string

func (*DefaultHelpCommand) GetDomain

func (d *DefaultHelpCommand) GetDomain() string

func (*DefaultHelpCommand) GetGroup

func (d *DefaultHelpCommand) GetGroup() string

func (*DefaultHelpCommand) GetInvokers

func (d *DefaultHelpCommand) GetInvokers() []string

func (*DefaultHelpCommand) GetSubPermissionRules

func (d *DefaultHelpCommand) GetSubPermissionRules() []SubPermission

func (*DefaultHelpCommand) GetUsage

func (d *DefaultHelpCommand) GetUsage() string

func (*DefaultHelpCommand) IsExecutableInDM

func (d *DefaultHelpCommand) IsExecutableInDM() bool

type ErrorType

type ErrorType int

ErrorType is the type of error happened while parsing in router.

const (
	ErrTypeGuildPrefixGetter ErrorType = iota
	ErrTypeGetChannel
	ErrTypeGetGuild
	ErrTypeCommandNotFound
	ErrTypeNotExecutableInDM
	ErrTypeMiddleware
	ErrTypeCommandExec
	ErrTypeDeleteCommandMessage
)

type LimitedConfig

type LimitedConfig interface {

	// GetLimiterBurst returns max amount of tokens which can be available at time.
	GetLimiterBurst() int

	// GetLimiterRestoration returns duration between new token get generated.
	GetLimiterRestoration() time.Duration

	// IsLimiterGlobal return true if limit shall be handled globally across all guilds.
	// Otherwise it should be created independently.
	IsLimiterGlobal() bool
}

LimitedConfig defines command that is rate limit-able.

type Middleware

type Middleware interface {

	// Handle is called before execution of a command handler
	// and will be passed context instance.
	//
	// if return bool is false then command handler shall not execute.
	//
	// An error should only be returned when middleware handler failed unexpectedly.
	Handle(cmd Command, ctx Context, layer MiddlewareLayer) (bool, error)

	// GetLayer returns the layer in which the middleware live.
	//
	// can be defined as bitmask, thus one can combine multiple layers to execute
	// the middleware at different point.
	GetLayer() MiddlewareLayer
}

type MiddlewareLayer

type MiddlewareLayer int

MiddlewareLayer defines layer in which middleware should live and executed during command parsing and handling.

const (
	LayerBeforeCommand MiddlewareLayer = 1 << iota
	LayerAfterCommand
)

type ObjectMap

type ObjectMap interface {
	ReadOnlyObjectMap
}

ObjectMap wraps around ReadOnlyObjectMap to provide a way to set value to and get value back.

type ReadOnlyObjectMap

type ReadOnlyObjectMap interface {

	// GetObject returns a value from its key.
	// Returns nil if no object is stored.
	GetObject(key string) (value interface{})

	// SetObject sets a value to the object.
	// This is used to workaround di.Container to get
	// our router instance inside our router context.
	SetObject(key string, value interface{})
}

ReadOnlyObjectMap provides a thread-safe key-value map to get previous set items from.

type Router

type Router interface {
	ReadOnlyObjectMap

	// Register is shortened for RegisterMiddleware and RegisterCommand
	// and automatically chooses depending on implementation.
	//
	// panics if an instance is passed which neither implements Command and Middleware.
	Register(v interface{})

	// RegisterCommand registers the passed Command interface.
	RegisterCommand(cmd Command)

	// RegisterMiddleware registers Middleware interface.
	RegisterMiddleware(m Middleware)

	// Setup registers given handlers to the passed discordgo.Session which are
	// used to handle and parse command.
	Setup(session *discordgo.Session)

	// GetConfig returns the specified config object which was specified on initialization.
	GetConfig() *Config

	// GetCommandMap returns internal command map.
	GetCommandMap() map[string]Command

	// GetCommandInstances returns an array of all registered command instance.
	GetCommandInstances() []Command

	// GetCommand returns a command instance from the registry by invoker. If command could
	// not be found, false is returned.
	GetCommand(invoke string) (Command, bool)
}

Router defines a command register and muxer.

var R Router

R can be used out of the box, acts as a master router for iris.

func NewRouter

func NewRouter(c *Config) Router

type SubPermission

type SubPermission struct {
	Term        string `json:"term"`
	Explicit    bool   `json:"explicit"`
	Description string `json:"description"`
}

SubPermission wraps information about a command sub permission.

Directories

Path Synopsis
Package ratelimit provides a basic token-bucket limiter for rosetta router.
Package ratelimit provides a basic token-bucket limiter for rosetta router.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL