Refactor everything

Well, practically it's a rewrite.
master
Luther Wen Xu 2020-05-12 18:18:19 +07:00
parent 1828615e94
commit 0bd76d9c7b
Signed by: chanbakjsd
GPG Key ID: B7D77E3E9D102B70
8 changed files with 154 additions and 82 deletions

@ -0,0 +1,37 @@
package commands
import (
"github.com/bwmarrin/discordgo"
"gitea.teamortix.com/chanbakjsd/Milen/db"
"gitea.teamortix.com/chanbakjsd/Milen/util"
)
func handleAutorole(dg *discordgo.Session, m *discordgo.MessageCreate, arguments []string) {
if !util.HasAdmin(dg, m.Author.ID, m.ChannelID) {
util.SendErrorEmbed(dg, m.ChannelID, util.ErrRequireAdmin)
return
}
parsedMessageLink, err := util.ParseMessageLink(arguments[0])
if err != nil {
util.SendErrorEmbed(dg, m.ChannelID, err)
return
}
emoji, err := util.ParseEmoji(arguments[1])
if err != nil {
util.SendErrorEmbed(dg, m.ChannelID, err)
return
}
role, err := util.ParseRole(arguments[2])
if err != nil {
util.SendErrorEmbed(dg, m.ChannelID, err)
return
}
db.CreateReactRole(parsedMessageLink.MessageID, emoji, role)
err = dg.MessageReactionAdd(parsedMessageLink.ChannelID, parsedMessageLink.MessageID, emoji)
if err != nil {
util.ReportError(dg, err)
return
}
util.SendSuccessEmbed(dg, m.ChannelID, "Autorole has been registered successfully.")
}

@ -5,36 +5,39 @@ import (
"github.com/bwmarrin/discordgo"
"gitea.teamortix.com/chanbakjsd/Milen/db"
"gitea.teamortix.com/chanbakjsd/Milen/humanify"
"gitea.teamortix.com/chanbakjsd/Milen/util"
)
type command struct {
Name string
Usage string
Processor func(*discordgo.Session, *discordgo.MessageCreate, []string)
MinimumArgument int
ExactArgument bool
}
var commands = []command{
command{"autorole", "<message link> <emoji> <role to assign>", handleAutorole, 3, true},
}
func Event(dg *discordgo.Session, m *discordgo.MessageCreate) {
if !strings.HasPrefix(m.Content, "milen ") {
return
}
split := strings.Split(m.Content, " ")
switch split[1] {
case "autorole":
util.RequireAdmin(dg, m.Author.ID, m.ChannelID, func() {
if len(split) < 6 {
util.SendCheckError(dg, m.ChannelID, humanify.Eng.Usage.Autorole)
return
}
role := util.ParseRole(split[2])
if role == "" {
util.SendCheckError(dg, m.ChannelID, humanify.Eng.Usage.Autorole)
return
}
emoji := util.ParseEmoji(split[5])
db.CreateReactRole(split[4], emoji, role)
err := dg.MessageReactionAdd(split[3], split[4], emoji)
if err != nil {
util.ReportError(dg, err)
return
}
util.SendCheckError(dg, m.ChannelID, humanify.Eng.Autorole.Success)
})
for _, v := range commands {
if split[1] != v.Name {
continue
}
if (v.ExactArgument && len(split) != v.MinimumArgument+2) || (!v.ExactArgument && len(split) < v.MinimumArgument+2) {
util.SendFailEmbed(dg, m.ChannelID, "Incorrect Usage", "Usage: `milen "+v.Name+" "+v.Usage+"`")
return
}
if len(split) == 2 {
v.Processor(dg, m, []string{})
return
}
v.Processor(dg, m, split[2:])
return
}
}

@ -1,35 +0,0 @@
package humanify
import (
"fmt"
"io/ioutil"
"github.com/BurntSushi/toml"
)
var Eng Locale
type Locale struct {
NoAdmin string `toml:"no_admin"`
Usage localeUsage
Autorole localeAutorole
}
type localeUsage struct {
Autorole string `toml:"autorole"`
}
type localeAutorole struct {
Success string `toml:"success"`
}
func init() {
data, err := ioutil.ReadFile("locale.toml")
if err != nil {
panic(err)
}
err = toml.Unmarshal(data, &Eng)
if err != nil {
panic(err)
}
}

@ -1,7 +0,0 @@
no_admin="❌ You do not have permission to use this command."
[usage]
autorole="❌ Incorrect usage. Usage: `milen autorole <role> <channel> <message> <emoji>`"
[autorole]
success="✅ Auto-role registered."

@ -0,0 +1,37 @@
package util
import (
"github.com/bwmarrin/discordgo"
)
func SendSuccessEmbed(dg *discordgo.Session, channelID string, message string) {
_, err := dg.ChannelMessageSendEmbed(
channelID,
&discordgo.MessageEmbed{
Title: "Success",
Description: message,
Color: 0x00D000,
},
)
if err != nil {
ReportError(dg, err)
}
}
func SendErrorEmbed(dg *discordgo.Session, channelID string, toSend error) {
SendFailEmbed(dg, channelID, "Error", toSend.Error())
}
func SendFailEmbed(dg *discordgo.Session, channelID string, title string, description string) {
_, err := dg.ChannelMessageSendEmbed(
channelID,
&discordgo.MessageEmbed{
Title: title,
Description: description,
Color: 0xD00000,
},
)
if err != nil {
ReportError(dg, err)
}
}

@ -1,12 +1,17 @@
package util
import (
"errors"
"fmt"
"runtime/debug"
"github.com/bwmarrin/discordgo"
)
var (
ErrRequireAdmin = errors.New("This command requires administrator.")
)
var ReportTarget string
func ReportError(dg *discordgo.Session, toReport error) {
@ -31,7 +36,7 @@ func ReportError(dg *discordgo.Session, toReport error) {
}
}
func SendCheckError(dg *discordgo.Session, channelID string, message string) {
func SendMessage(dg *discordgo.Session, channelID string, message string) {
_, err := dg.ChannelMessageSend(channelID, message)
if err != nil {
ReportError(dg, err)

@ -1,19 +1,57 @@
package util
import (
"errors"
"strings"
)
func ParseRole(roleString string) string {
var (
//Errors for ParseRole
ErrInvalidRole = errors.New("Invalid role has been provided.")
//Errors for ParseEmoji
ErrInvalidEmoji = errors.New("Invalid emoji has been provided.")
//Errors for ParseMessageLink
ErrNotValidURL = errors.New("Invalid URL has been provided (expecting message link).")
ErrNotDiscordURL = errors.New("Invalid Discord URL has been provided (expecting message link).")
ErrNotMessageURL = errors.New("Invalid Discord message link has been provided.")
)
type ParsedMessageLink struct {
GuildID string
ChannelID string
MessageID string
}
func ParseRole(roleString string) (string, error) {
if !strings.HasPrefix(roleString, "<@&") || !strings.HasSuffix(roleString, ">") {
return ""
return "", ErrInvalidRole
}
return roleString[3 : len(roleString)-1]
return roleString[3 : len(roleString)-1], nil
}
func ParseEmoji(emojiString string) string {
if !strings.HasPrefix(emojiString, "<:") || !strings.HasSuffix(emojiString, ">") {
return emojiString
func ParseEmoji(emojiString string) (string, error) {
if strings.HasPrefix(emojiString, "<:") && strings.HasSuffix(emojiString, ">") {
return emojiString[2 : len(emojiString)-1], nil
}
//TODO: We assume people aren't ill-intended and everything are actually emoji for now.
//The alternative would be to keep a list of all possible emoji which is overkill.
return emojiString, nil
}
func ParseMessageLink(messageLink string) (ParsedMessageLink, error) {
if !strings.HasPrefix(messageLink, "https://") {
return ParsedMessageLink{}, ErrNotValidURL
}
split := strings.Split(messageLink, "/")
if split[2] != "discordapp.com" && split[2] != "canary.discordapp.com" && split[2] != "ptb.discordapp.com" {
return ParsedMessageLink{}, ErrNotDiscordURL
}
if len(split) < 7 || split[3] != "channels" {
return ParsedMessageLink{}, ErrNotMessageURL
}
return emojiString[2 : len(emojiString)-1]
return ParsedMessageLink{
GuildID: split[4],
ChannelID: split[5],
MessageID: split[6],
}, nil
}

@ -2,19 +2,13 @@ package util
import (
"github.com/bwmarrin/discordgo"
"gitea.teamortix.com/chanbakjsd/Milen/humanify"
)
func RequireAdmin(dg *discordgo.Session, userID string, channelID string, hasAdmin func()) {
func HasAdmin(dg *discordgo.Session, userID string, channelID string) bool {
perm, err := dg.UserChannelPermissions(userID, channelID)
if err != nil {
ReportError(dg, err)
return
}
if perm&discordgo.PermissionAdministrator == 0 {
SendCheckError(dg, channelID, humanify.Eng.NoAdmin)
return
return false
}
hasAdmin()
return perm&discordgo.PermissionAdministrator != 0
}