From c3955f213bee7157851be205238dc3314f563570 Mon Sep 17 00:00:00 2001 From: Siwoo Jeon Date: Fri, 16 May 2025 18:46:28 +0900 Subject: [PATCH] fix: pagination embed in chatInput, list query --- commands/learnedDataList.go | 129 +++++++++++++++++++++++------------- configs/version.go | 4 +- handler/messageCreate.go | 4 +- scripts/export.go | 2 +- utils/customIds.go | 6 +- utils/paginationEmbed.go | 16 +++-- utils/regexp.go | 15 +++-- 7 files changed, 108 insertions(+), 68 deletions(-) diff --git a/commands/learnedDataList.go b/commands/learnedDataList.go index 7099822..e925f81 100644 --- a/commands/learnedDataList.go +++ b/commands/learnedDataList.go @@ -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")) } diff --git a/configs/version.go b/configs/version.go index 3b04fbd..389ea8c 100644 --- a/configs/version.go +++ b/configs/version.go @@ -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]) diff --git a/handler/messageCreate.go b/handler/messageCreate.go index 1a25e92..99fda87 100644 --- a/handler/messageCreate.go +++ b/handler/messageCreate.go @@ -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, diff --git a/scripts/export.go b/scripts/export.go index 24c26b0..3fb2b33 100644 --- a/scripts/export.go +++ b/scripts/export.go @@ -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 } diff --git a/utils/customIds.go b/utils/customIds.go index 0c3f2ac..27b160c 100644 --- a/utils/customIds.go +++ b/utils/customIds.go @@ -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] } diff --git a/utils/paginationEmbed.go b/utils/paginationEmbed.go index cdab278..9231ae4 100644 --- a/utils/paginationEmbed.go +++ b/utils/paginationEmbed.go @@ -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), }) } diff --git a/utils/regexp.go b/utils/regexp.go index da7774c..a5c7e0f 100644 --- a/utils/regexp.go +++ b/utils/regexp.go @@ -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(``) - 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(``) + RegexpLearnQueryCommand = regexp.MustCompile(`단어:([^\n대답개수:]*)`) + RegexpLearnQueryResult = regexp.MustCompile(`대답:([^\n단어개수:]*)`) + RegexpLearnQueryLength = regexp.MustCompile(`개수:(\d+)`) + RegexpPaginationEmbedId = regexp.MustCompile(`^(\d+)/(\d+)$`) )