fix: pagination embed in chatInput, list query

This commit is contained in:
Siwoo Jeon 2025-05-16 18:46:28 +09:00
parent e9f6929ee5
commit c3955f213b
Signed by: migan
GPG key ID: 036E9A8C5E8E48DA
7 changed files with 108 additions and 68 deletions

View file

@ -3,6 +3,7 @@ package commands
import (
"context"
"fmt"
"strconv"
"strings"
"git.wh64.net/muffin/goMuffin/configs"
@ -13,9 +14,9 @@ import (
"go.mongodb.org/mongo-driver/v2/mongo"
)
const (
learnArgsCommand = "단어:"
learnArgsResult = "대답:"
var (
LIST_MIN_VALUE float64 = 10.0
LIST_MAX_VALUE float64 = 100.0
)
var LearnedDataListCommand *Command = &Command{
@ -25,10 +26,25 @@ var LearnedDataListCommand *Command = &Command{
Description: "당신이 가ㄹ르쳐준 지식을 나열해요.",
Options: []*discordgo.ApplicationCommandOption{
{
Name: "쿼리",
Type: discordgo.ApplicationCommandOptionString,
Name: "단어",
Description: "해당 단어가 포함된 결과만 찾아요.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: "대답",
Description: "해당 대답이 포함된 결과만 찾아요.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "개수",
Description: "한 페이지당 보여줄 지식의 데이터 양을 정해요.",
MinValue: &LIST_MIN_VALUE,
MaxValue: LIST_MAX_VALUE,
Required: false,
},
},
},
Aliases: []string{"list", "목록", "지식목록"},
@ -49,9 +65,13 @@ var LearnedDataListCommand *Command = &Command{
},
}
func getDescriptions(data *[]databases.Learn) (descriptions []string) {
func getDescriptions(data *[]databases.Learn, length int) (descriptions []string) {
var builder strings.Builder
MAX_LENGTH := 100
MAX_ITEM_LENGTH := 25
if length == 0 {
length = 25
}
tempDesc := []string{}
@ -70,12 +90,10 @@ func getDescriptions(data *[]databases.Learn) (descriptions []string) {
tempDesc = append(tempDesc, fmt.Sprintf("- %s: %s\n", command, result))
}
var builder strings.Builder
for i, s := range tempDesc {
builder.WriteString(s)
if (i+1)%MAX_ITEM_LENGTH == 0 {
if (i+1)%length == 0 {
descriptions = append(descriptions, builder.String())
builder.Reset()
}
@ -88,65 +106,84 @@ func getDescriptions(data *[]databases.Learn) (descriptions []string) {
}
func learnedDataListRun(s *discordgo.Session, m any, args *[]string) {
var userId, globalName, avatarUrl string
var globalName, avatarUrl string
var data []databases.Learn
var filter bson.E
var filter bson.D
var length int
switch m := m.(type) {
case *discordgo.MessageCreate:
userId = m.Author.ID
filter = bson.D{{Key: "user_id", Value: m.Author.ID}}
globalName = m.Author.GlobalName
avatarUrl = m.Author.AvatarURL("512")
query := strings.Join(*args, " ")
if strings.HasPrefix(query, learnArgsResult) {
query, _ = strings.CutPrefix(query, learnArgsResult)
filter = bson.E{
Key: "result",
Value: bson.M{
"$regex": query,
},
}
} else {
query, _ = strings.CutPrefix(query, learnArgsCommand)
filter = bson.E{
if match := utils.RegexpLearnQueryCommand.FindStringSubmatch(query); match != nil {
filter = append(filter, bson.E{
Key: "command",
Value: bson.M{
"$regex": query,
"$regex": match[1],
},
})
}
if match := utils.RegexpLearnQueryResult.FindStringSubmatch(query); match != nil {
fmt.Println(match[1])
filter = append(filter, bson.E{
Key: "result",
Value: bson.M{
"$regex": match[1],
},
})
}
if match := utils.RegexpLearnQueryLength.FindStringSubmatch(query); match != nil {
fmt.Println(1)
var err error
length, err = strconv.Atoi(match[1])
fmt.Printf("err: %v\n", err)
if err != nil {
s.ChannelMessageSendEmbedReply(m.ChannelID, &discordgo.MessageEmbed{
Title: "❌ 오류",
Description: "개수의 값은 숫자여야해요.",
Color: utils.EmbedFail,
}, m.Reference())
return
}
}
case *utils.InteractionCreate:
m.DeferReply(true)
userId = m.Member.User.ID
filter = bson.D{{Key: "user_id", Value: m.Member.User.ID}}
globalName = m.Member.User.GlobalName
avatarUrl = m.Member.User.AvatarURL("512")
if opt, ok := m.Options["쿼리"]; ok {
query := opt.StringValue()
if opt, ok := m.Options["단어"]; ok {
filter = append(filter, bson.E{
Key: "command",
Value: bson.M{
"$regex": opt.StringValue(),
},
})
}
if strings.HasPrefix(query, learnArgsResult) {
query, _ = strings.CutPrefix(query, learnArgsResult)
filter = bson.E{
Key: "result",
Value: bson.M{
"$regex": query,
},
}
} else {
query, _ = strings.CutPrefix(query, learnArgsCommand)
filter = bson.E{
Key: "command",
Value: bson.M{
"$regex": query,
},
}
}
if opt, ok := m.Options["대답"]; ok {
filter = append(filter, bson.E{
Key: "result",
Value: bson.M{
"$regex": opt.StringValue(),
},
})
}
if opt, ok := m.Options["개수"]; ok {
length = int(opt.IntValue())
}
}
cur, err := databases.Database.Learns.Find(context.TODO(), bson.D{{Key: "user_id", Value: userId}, filter})
cur, err := databases.Database.Learns.Find(context.TODO(), filter)
if err != nil {
if err == mongo.ErrNoDocuments {
embed := &discordgo.MessageEmbed{
@ -196,5 +233,5 @@ func learnedDataListRun(s *discordgo.Session, m any, args *[]string) {
},
}
utils.StartPaginationEmbed(s, m, embed, getDescriptions(&data), utils.CodeBlock("md", fmt.Sprintf("# 총 %d개에요.\n", len(data))+"%s"))
utils.StartPaginationEmbed(s, m, embed, getDescriptions(&data, length), utils.CodeBlock("md", fmt.Sprintf("# 총 %d개에요.\n", len(data))+"%s"))
}

View file

@ -7,9 +7,9 @@ import (
"git.wh64.net/muffin/goMuffin/utils"
)
const MUFFIN_VERSION = "5.1.0-gopher_dev.250514b"
const MUFFIN_VERSION = "5.1.0-gopher_dev.250516a"
var updatedString string = utils.Decimals.FindAllStringSubmatch(MUFFIN_VERSION, -1)[3][0]
var updatedString string = utils.RegexpDecimals.FindAllStringSubmatch(MUFFIN_VERSION, -1)[3][0]
var UpdatedAt *time.Time = func() *time.Time {
year, _ := strconv.Atoi("20" + updatedString[0:2])

View file

@ -18,7 +18,7 @@ import (
)
func argParser(content string) (args []string) {
for _, arg := range utils.FlexibleStringParser.FindAllStringSubmatch(content, -1) {
for _, arg := range utils.RegexpFlexibleString.FindAllStringSubmatch(content, -1) {
if arg[1] != "" {
args = append(args, arg[1])
} else {
@ -131,7 +131,6 @@ func MessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
user, _ := s.User(data.UserId)
result := resultParser(data.Result, s, m)
// s.ChannelMessageSendReply(m.ChannelID, fmt.Sprintf("%s\n%s", result, utils.InlineCode(fmt.Sprintf("%s님이 알려주셨어요.", user.Username))), m.Reference())
s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{
Reference: m.Reference(),
Content: fmt.Sprintf("%s\n%s", result, utils.InlineCode(fmt.Sprintf("%s님이 알려주셨어요.", user.Username))),
@ -144,7 +143,6 @@ func MessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
return
}
// s.ChannelMessageSendReply(m.ChannelID, data[rand.Intn(len(data))].Text, m.Reference())
s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{
Reference: m.Reference(),
Content: data[rand.Intn(len(data))].Text,

View file

@ -186,7 +186,7 @@ func ExportData(n *commando.Node) error {
if refined {
for i, text := range data {
if utils.EmojiRegexp.Match([]byte(text.Text)) {
if utils.RegexpEmoji.Match([]byte(text.Text)) {
data = append(data[:i], data[i+1:]...)
return
}

View file

@ -31,8 +31,8 @@ func MakeDeleteLearnedDataCancel(id string) string {
}
func GetDeleteLearnedDataId(customId string) (id bson.ObjectID, itemId int) {
id, _ = bson.ObjectIDFromHex(strings.ReplaceAll(ItemIdRegexp.ReplaceAllString(customId[len(DeleteLearnedData):], ""), "&", ""))
stringItemId := strings.ReplaceAll(ItemIdRegexp.FindAllString(customId, 1)[0], "No.", "")
id, _ = bson.ObjectIDFromHex(strings.ReplaceAll(RegexpItemId.ReplaceAllString(customId[len(DeleteLearnedData):], ""), "&", ""))
stringItemId := strings.ReplaceAll(RegexpItemId.FindAllString(customId, 1)[0], "No.", "")
itemId, _ = strconv.Atoi(stringItemId)
return
}
@ -68,5 +68,5 @@ func GetPaginationEmbedId(customId string) string {
}
func GetPaginationEmbedUserId(id string) string {
return PaginationEmbedId.FindAllStringSubmatch(id, 1)[0][1]
return RegexpPaginationEmbedId.FindAllStringSubmatch(id, 1)[0][1]
}

View file

@ -21,7 +21,6 @@ type PaginationEmbed struct {
var PaginationEmbeds = make(map[string]*PaginationEmbed)
func makeComponents(id string, current, total int) *[]discordgo.MessageComponent {
return &[]discordgo.MessageComponent{
discordgo.ActionsRow{
Components: []discordgo.MessageComponent{
@ -81,19 +80,24 @@ func StartPaginationEmbed(s *discordgo.Session, m any, e *discordgo.MessageEmbed
desc: defaultDesc,
}
p.Embed.Description = makeDesc(p.desc, data[0])
if len(data) <= 0 {
p.Embed.Description = makeDesc(p.desc, "없음")
p.Total = 1
} else {
p.Embed.Description = makeDesc(p.desc, data[0])
}
switch m := m.(type) {
case *discordgo.MessageCreate:
s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{
Reference: m.Reference(),
Embeds: []*discordgo.MessageEmbed{p.Embed},
Components: *makeComponents(id, 1, len(data)),
Components: *makeComponents(id, p.Current, p.Total),
})
case *InteractionCreate:
m.Reply(&discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{p.Embed},
Components: *makeComponents(id, 1, len(data)),
m.EditReply(&discordgo.WebhookEdit{
Embeds: &[]*discordgo.MessageEmbed{p.Embed},
Components: makeComponents(id, p.Current, p.Total),
})
}

View file

@ -3,11 +3,12 @@ package utils
import "regexp"
var (
FlexibleStringParser = regexp.MustCompile(`[^\s"'「」«»]+|"([^"]*)"|'([^']*)'|「([^」]*)」|«([^»]*)»`)
Decimals = regexp.MustCompile(`\d+`)
ItemIdRegexp = regexp.MustCompile(`No.\d+`)
EmojiRegexp = regexp.MustCompile(`<a?:\w+:\d+>`)
LearnQueryCommand = regexp.MustCompile(`^단어:`)
LearnQueryResult = regexp.MustCompile(`^대답:`)
PaginationEmbedId = regexp.MustCompile(`^(\d+)/(\d+)$`)
RegexpFlexibleString = regexp.MustCompile(`[^\s"'「」«»]+|"([^"]*)"|'([^']*)'|「([^」]*)」|«([^»]*)»`)
RegexpDecimals = regexp.MustCompile(`\d+`)
RegexpItemId = regexp.MustCompile(`No.\d+`)
RegexpEmoji = regexp.MustCompile(`<a?:\w+:\d+>`)
RegexpLearnQueryCommand = regexp.MustCompile(`단어:([^\n대답개수:]*)`)
RegexpLearnQueryResult = regexp.MustCompile(`대답:([^\n단어개수:]*)`)
RegexpLearnQueryLength = regexp.MustCompile(`개수:(\d+)`)
RegexpPaginationEmbedId = regexp.MustCompile(`^(\d+)/(\d+)$`)
)