src/globals/utils.go (view raw)
1package globals
2
3import (
4 "errors"
5 "fmt"
6 "io"
7 "net/http"
8 "net/url"
9 "regexp"
10 "strings"
11 "time"
12
13 "github.com/birabittoh/myks"
14 "github.com/birabittoh/rabbitpipe"
15 "github.com/bwmarrin/discordgo"
16)
17
18var (
19 searchPattern = regexp.MustCompile(`watch\?v\x3d([a-zA-Z0-9_-]{11})`)
20 searchKS = myks.New[string](12 * time.Hour)
21)
22
23func GetVoiceChannelID(s *discordgo.Session, m *discordgo.MessageCreate) (response string, g *discordgo.Guild, voiceChannelID string) {
24 if m.Member == nil {
25 response = "Please, use this inside a server."
26 return
27 }
28
29 g, err := s.State.Guild(m.GuildID)
30 if err != nil {
31 logger.Errorf("could not get guild: %s", err)
32 response = MsgError
33 return
34 }
35
36 for _, vs := range g.VoiceStates {
37 if vs.UserID == m.Author.ID {
38 voiceChannelID = vs.ChannelID
39 break
40 }
41 }
42
43 if voiceChannelID == "" {
44 response = "You need to be in a voice channel to use this command."
45 }
46 return
47}
48
49func (bc BotCommand) FormatHelp(command, guildID string) string {
50 var shortCodeStr string
51 if bc.ShortCode != "" {
52 shortCodeStr = fmt.Sprintf(" (%s)", FormatCommand(bc.ShortCode, guildID))
53 }
54 return fmt.Sprintf(MsgHelpFmt, FormatCommand(command, guildID)+shortCodeStr, bc.Help)
55}
56
57func FormatCommand(command, guildID string) string {
58 return fmt.Sprintf("`%s%s`", GetPrefix(guildID), command)
59}
60
61func FormatVideo(v *rabbitpipe.Video) string {
62 duration := time.Duration(v.LengthSeconds) * time.Second
63 return fmt.Sprintf("**%s** (`%s`)", v.Title, duration.String())
64}
65
66func ParseUserMessage(messageContent, guildID string) (command string, args []string, ok bool) {
67 after, found := strings.CutPrefix(messageContent, GetPrefix(guildID))
68 if !found {
69 return
70 }
71
72 userInput := strings.Split(after, " ")
73 command = strings.ToLower(userInput[0])
74 return command, userInput[1:], len(command) > 0
75}
76
77func GetPrefix(guildID string) string {
78 for _, prefix := range Config.Values.Prefixes {
79 if prefix.Name == guildID {
80 return prefix.Value
81 }
82 }
83
84 Config.Values.Prefixes = append(Config.Values.Prefixes, KeyValuePair{Name: guildID, Value: defaultPrefix})
85 err := Config.Save()
86 if err != nil {
87 logger.Errorf("could not save config: %s", err)
88 }
89 return defaultPrefix
90}
91
92func SetPrefix(guildID, prefixValue string) string {
93 var found bool
94 for i, prefix := range Config.Values.Prefixes {
95 if prefix.Name == guildID {
96 Config.Values.Prefixes[i].Value = prefixValue
97 found = true
98 break
99 }
100 }
101
102 if !found {
103 Config.Values.Prefixes = append(Config.Values.Prefixes, KeyValuePair{Name: guildID, Value: prefixValue})
104 }
105
106 err := Config.Save()
107 if err != nil {
108 logger.Errorf("could not save config: %s", err)
109 }
110 return defaultPrefix
111}
112
113func Search(query string) (videoID string, err error) {
114 escaped := url.QueryEscape(strings.ToLower(strings.TrimSpace(query)))
115
116 cached, err := searchKS.Get(escaped)
117 if err == nil && cached != nil {
118 return *cached, nil
119 }
120
121 resp, err := http.Get("https://www.youtube.com/results?search_query=" + escaped)
122 if err != nil {
123 return
124 }
125 defer resp.Body.Close()
126
127 pageContent, err := io.ReadAll(resp.Body)
128 if err != nil {
129 return
130 }
131
132 matches := searchPattern.FindAllStringSubmatch(string(pageContent), -1)
133 if len(matches) == 0 {
134 err = errors.New("no video found")
135 return
136 }
137
138 videoID = matches[0][1]
139 searchKS.Set(escaped, videoID, 11*time.Hour)
140
141 return matches[0][1], nil
142}