Compare commits

...

2 Commits

Author SHA1 Message Date
Cynthia Foxwell c1296d9822 history commands 2023-07-16 14:58:14 -06:00
Cynthia Foxwell 651b2a8e68 nullcheck msg.BeforeUpdate 2023-07-16 13:12:51 -06:00
4 changed files with 240 additions and 62 deletions

135
commands/history.go Normal file
View File

@ -0,0 +1,135 @@
package commands
import (
"fmt"
"math"
"strconv"
"strings"
"github.com/Cynosphere/comcord/lib"
"github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo"
)
func GetHistory(session *discordgo.Session, limit int, channel string) {
messages, err := session.ChannelMessages(channel, 100, "", "", "")
if err != nil {
fmt.Print("<failed to get messages: ", err.Error(), ">\n\r")
return
}
for i, j := 0, len(messages) - 1; i < j; i, j = i + 1, j - 1 {
messages[i], messages[j] = messages[j], messages[i]
}
fmt.Print("--Beginning-Review", strings.Repeat("-", 62), "\n\r")
lines := make([]string, 0)
for _, msg := range messages {
msgLines := lib.ProcessMessage(session, msg, lib.MessageOptions{NoColor: true, InHistory: true})
for _, line := range msgLines {
lines = append(lines, line)
}
}
length := len(lines)
startIndex := int(math.Max(float64(0), float64(length - limit)))
for _, line := range lines[startIndex:] {
fmt.Print(line)
}
fmt.Print("--Review-Complete", strings.Repeat("-", 63), "\n\r")
}
func HistoryCommand(session *discordgo.Session) {
currentChannel := state.GetCurrentChannel()
if currentChannel == "" {
fmt.Print("<not in a channel>\n\r")
return
}
GetHistory(session, 20, currentChannel)
}
func ExtendedHistoryCommand(session *discordgo.Session) {
currentChannel := state.GetCurrentChannel()
if currentChannel == "" {
fmt.Print("<not in a channel>\n\r")
return
}
lib.MakePrompt(session, ":lines> ", false, func(session *discordgo.Session, input string, interrupt bool) {
fmt.Print("\r")
limit, err := strconv.Atoi(input)
if err != nil {
fmt.Print("<not a number>\n\r")
} else {
GetHistory(session, limit, currentChannel)
}
})
}
func PeekHistory(session *discordgo.Session, guild, channel string) {
target := ""
channels := GetSortedChannels(session, guild, false, false)
for _, c := range channels {
if strings.Index(strings.ToLower(c.Name), strings.ToLower(channel)) > -1 {
target = c.ID
break
}
}
if target == "" {
fmt.Print("<channel not found>\n\r")
} else {
GetHistory(session, 20, target)
}
}
func PeekCommand(session *discordgo.Session) {
currentGuild := state.GetCurrentGuild()
if currentGuild == "" {
fmt.Print("<not in a guild>\n\r")
return
}
lib.MakePrompt(session, ":peek> ", false, func(session *discordgo.Session, input string, interrupt bool) {
fmt.Print("\r")
if input != "" {
PeekHistory(session, currentGuild, input)
}
})
}
func CrossPeekCommand(session *discordgo.Session) {
lib.MakePrompt(session, ":guild> ", false, func(session *discordgo.Session, input string, interrupt bool) {
fmt.Print("\r")
if input != "" {
targetGuild := ""
for _, guild := range session.State.Guilds {
if strings.Index(strings.ToLower(guild.Name), strings.ToLower(input)) > -1 {
targetGuild = guild.ID
break;
}
}
if targetGuild == "" {
fmt.Print("<guild not found>\n\r")
} else {
lib.MakePrompt(session, ":peek> ", false, func(session *discordgo.Session, input string, interrupt bool) {
fmt.Print("\r")
if input != "" {
PeekHistory(session, targetGuild, input)
}
})
}
}
})
}

View File

@ -56,6 +56,26 @@ func Setup() {
Run: ListUsersCommand, Run: ListUsersCommand,
Description: "who is in channel", Description: "who is in channel",
} }
commandMap["r"] = Command{
Run: HistoryCommand,
Description: "channel history",
}
commandMap["R"] = Command{
Run: ExtendedHistoryCommand,
Description: "extended history",
}
commandMap["p"] = Command{
Run: PeekCommand,
Description: "peek at channel",
}
commandMap["P"] = Command{
Run: CrossPeekCommand,
Description: "cross-guild peek",
}
} }
func GetCommand(key string) (Command, bool) { func GetCommand(key string) (Command, bool) {

View File

@ -1,6 +1,8 @@
package events package events
import ( import (
"fmt"
"github.com/Cynosphere/comcord/lib" "github.com/Cynosphere/comcord/lib"
"github.com/Cynosphere/comcord/state" "github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
@ -21,7 +23,10 @@ func MessageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) {
if state.IsInPrompt() { if state.IsInPrompt() {
state.AddMessageToQueue(msg.Message) state.AddMessageToQueue(msg.Message)
} else { } else {
lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()}) lines := lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()})
for _, line := range lines {
fmt.Print(line)
}
} }
if isDM { if isDM {
@ -38,7 +43,7 @@ func MessageUpdate(session *discordgo.Session, msg *discordgo.MessageUpdate) {
return return
} }
if msg.Content == msg.BeforeUpdate.Content { if msg.BeforeUpdate != nil && msg.Content == msg.BeforeUpdate.Content {
return return
} }
@ -52,7 +57,10 @@ func MessageUpdate(session *discordgo.Session, msg *discordgo.MessageUpdate) {
if state.IsInPrompt() { if state.IsInPrompt() {
state.AddMessageToQueue(msg.Message) state.AddMessageToQueue(msg.Message)
} else { } else {
lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()}) lines := lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()})
for _, line := range lines {
fmt.Print(line)
}
} }
if isDM { if isDM {

View File

@ -35,10 +35,10 @@ type MessageOptions struct {
InHistory bool InHistory bool
} }
func FormatMessage(session *discordgo.Session, options MessageOptions) { func FormatMessage(session *discordgo.Session, options MessageOptions) []string {
timestamp := options.Timestamp.Format("[15:04:05]") lines := make([]string, 0)
// TODO: history lines timestamp := options.Timestamp.Format("[15:04:05]")
nameLength := utf8.RuneCountInString(options.Name) + 2 nameLength := utf8.RuneCountInString(options.Name) + 2
stateNameLength := state.GetNameLength() stateNameLength := state.GetNameLength()
@ -102,12 +102,21 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
replyContent = replyContent[:79 - headerLength] + moreContent replyContent = replyContent[:79 - headerLength] + moreContent
} }
fmt.Print(replySymbol, name, replyContent, "\n\r") lines = append(lines, replySymbol, name, replyContent, "\n\r")
} }
if options.IsDump { if options.IsDump {
if options.InHistory { if options.InHistory {
// TODO headerLength := 80 - (utf8.RuneCountInString(options.Name) + 5)
dumpHeader := fmt.Sprintf("--- %s %s\n\r", options.Name, strings.Repeat("-", headerLength))
contentLines := strings.Split(options.Content, "\n")
lines = append(lines, dumpHeader)
for _, line := range contentLines {
lines = append(lines, line + "\n\r")
}
lines = append(lines, dumpHeader)
} else { } else {
wordCount := len(strings.Split(options.Content, " ")) wordCount := len(strings.Split(options.Content, " "))
lineCount := len(strings.Split(options.Content, "\n")) lineCount := len(strings.Split(options.Content, "\n"))
@ -127,7 +136,7 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
str = ansi.Color(str, "yellow+b") str = ansi.Color(str, "yellow+b")
} }
fmt.Print(str + "\n\r") lines = append(lines, str + "\n\r")
} }
} else { } else {
// TODO: markdown // TODO: markdown
@ -140,7 +149,7 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
name = ansi.Color(name, "red+b") name = ansi.Color(name, "red+b")
} }
fmt.Printf("%s %s\x07\n\r", name, content) lines = append(lines, fmt.Sprintf("%s %s\x07\n\r", name, content))
} else if utf8.RuneCountInString(content) > 1 && } else if utf8.RuneCountInString(content) > 1 &&
(strings.HasPrefix(content, "*") && strings.HasSuffix(content, "*") && !strings.HasPrefix(content, "**") && !strings.HasSuffix(content, "**")) || (strings.HasPrefix(content, "*") && strings.HasSuffix(content, "*") && !strings.HasPrefix(content, "**") && !strings.HasSuffix(content, "**")) ||
(strings.HasPrefix(content, "_") && strings.HasSuffix(content, "_") && !strings.HasPrefix(content, "__") && !strings.HasSuffix(content, "__")) { (strings.HasPrefix(content, "_") && strings.HasSuffix(content, "_") && !strings.HasPrefix(content, "__") && !strings.HasSuffix(content, "__")) {
@ -150,15 +159,15 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
str = ansi.Color(str, "green+b") str = ansi.Color(str, "green+b")
} }
fmt.Print(str + "\n\r") lines = append(lines, str + "\n\r")
} else if options.IsJoin { } else if options.IsJoin {
channel, err := session.State.Channel(options.Channel) channel, err := session.State.Channel(options.Channel)
if err != nil { if err != nil {
return return lines
} }
guild, err := session.State.Guild(channel.GuildID) guild, err := session.State.Guild(channel.GuildID)
if err != nil { if err != nil {
return return lines
} }
str := fmt.Sprintf("%s %s has joined %s", timestamp, options.Name, guild.Name) str := fmt.Sprintf("%s %s has joined %s", timestamp, options.Name, guild.Name)
@ -166,14 +175,14 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
str = ansi.Color(str, "yellow+b") str = ansi.Color(str, "yellow+b")
} }
fmt.Print(str + "\n\r") lines = append(lines, str + "\n\r")
} else if options.IsPin { } else if options.IsPin {
str := fmt.Sprintf("%s %s pinned a message to this channel", timestamp, options.Name) str := fmt.Sprintf("%s %s pinned a message to this channel", timestamp, options.Name)
if !options.NoColor { if !options.NoColor {
str = ansi.Color(str, "yellow+b") str = ansi.Color(str, "yellow+b")
} }
fmt.Print(str + "\n\r") lines = append(lines, str + "\n\r")
} else { } else {
nameColor := "cyan+b" nameColor := "cyan+b"
if options.IsMention { if options.IsMention {
@ -194,7 +203,7 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
if options.IsMention { if options.IsMention {
str = str + "\x07" str = str + "\x07"
} }
fmt.Print(str + "\n\r") lines = append(lines, str + "\n\r")
} }
} }
@ -205,7 +214,7 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
str = ansi.Color(str, "yellow+b") str = ansi.Color(str, "yellow+b")
} }
fmt.Print(str + "\n\r") lines = append(lines, str + "\n\r")
} }
} }
@ -216,7 +225,7 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
str = ansi.Color(str, "yellow+b") str = ansi.Color(str, "yellow+b")
} }
fmt.Print(str + "\n\r") lines = append(lines, str + "\n\r")
} }
} }
@ -225,22 +234,25 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) {
// TODO: embeds // TODO: embeds
// TODO: lines output for history // TODO: lines output for history
return lines
} }
func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options MessageOptions) { func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options MessageOptions) []string {
lines := make([]string, 0)
channel, err := session.State.Channel(msg.ChannelID) channel, err := session.State.Channel(msg.ChannelID)
if err != nil { if err != nil {
return return lines
} }
guild, err := session.State.Guild(channel.GuildID) guild, err := session.State.Guild(channel.GuildID)
if err != nil { if err != nil {
return return lines
} }
selfMember, err := session.State.Member(guild.ID, session.State.User.ID) selfMember, err := session.State.Member(guild.ID, session.State.User.ID)
if err != nil { if err != nil {
return return lines
} }
hasMentionedRole := false hasMentionedRole := false
@ -268,72 +280,75 @@ func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options
currentChannel := state.GetCurrentChannel() currentChannel := state.GetCurrentChannel()
isCurrentChannel := currentChannel == msg.ChannelID isCurrentChannel := currentChannel == msg.ChannelID
if !isCurrentChannel && !isDM && !isPing { if !isCurrentChannel && !isDM && !isPing && !options.InHistory {
return return lines
} }
if isPing && !isCurrentChannel && !isDM { if isPing && !isCurrentChannel && !isDM && !options.InHistory {
str := fmt.Sprintf("**mentioned by %s in #%s in %s**", msg.Author.Username, channel.Name, guild.Name) str := fmt.Sprintf("**mentioned by %s in #%s in %s**", msg.Author.Username, channel.Name, guild.Name)
if options.NoColor { if !options.NoColor {
fmt.Print(ansi.Color(str, "red+b")) str = ansi.Color(str, "red+b")
} else { }
fmt.Print(str) str = str + "\x07\n\r"
lines = append(lines, str)
} else {
content, _ := msg.ContentWithMoreMentionsReplaced(session)
if isEdit {
content = content + " (edited)"
} }
fmt.Print("\x07\n\r")
return
}
content, _ := msg.ContentWithMoreMentionsReplaced(session) isDump := REGEX_CODEBLOCK.MatchString(content)
if isEdit {
content = content + " (edited)"
}
isDump := REGEX_CODEBLOCK.MatchString(content) if strings.Index(content, "\n") > -1 && !isDump {
for i, line := range strings.Split(content, "\n") {
options.Content = line
options.Name = msg.Author.Username
options.Channel = msg.ChannelID
options.Bot = msg.Author.Bot
options.Webhook = msg.WebhookID != ""
options.Attachments = msg.Attachments
options.Stickers = msg.StickerItems
if i == 0 {
options.Reply = msg.ReferencedMessage
}
options.IsMention = isPing
options.IsDM = isDM
options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin
options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage
options.IsDump = false
if strings.Index(content, "\n") > -1 && !isDump { lines = FormatMessage(session, options)
for i, line := range strings.Split(content, "\n") { }
options.Content = line } else {
options.Content = content
options.Name = msg.Author.Username options.Name = msg.Author.Username
options.Channel = msg.ChannelID options.Channel = msg.ChannelID
options.Bot = msg.Author.Bot options.Bot = msg.Author.Bot
options.Webhook = msg.WebhookID != "" options.Webhook = msg.WebhookID != ""
options.Attachments = msg.Attachments options.Attachments = msg.Attachments
options.Stickers = msg.StickerItems options.Stickers = msg.StickerItems
if i == 0 { options.Reply = msg.ReferencedMessage
options.Reply = msg.ReferencedMessage
}
options.IsMention = isPing options.IsMention = isPing
options.IsDM = isDM options.IsDM = isDM
options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin
options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage
options.IsDump = false options.IsDump = isDump
FormatMessage(session, options) lines = FormatMessage(session, options)
} }
} else {
options.Content = content
options.Name = msg.Author.Username
options.Channel = msg.ChannelID
options.Bot = msg.Author.Bot
options.Webhook = msg.WebhookID != ""
options.Attachments = msg.Attachments
options.Stickers = msg.StickerItems
options.Reply = msg.ReferencedMessage
options.IsMention = isPing
options.IsDM = isDM
options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin
options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage
options.IsDump = isDump
FormatMessage(session, options)
} }
return lines
} }
func ProcessQueue(session *discordgo.Session) { func ProcessQueue(session *discordgo.Session) {
queue := state.GetMessageQueue() queue := state.GetMessageQueue()
for _, msg := range queue { for _, msg := range queue {
ProcessMessage(session, msg, MessageOptions{NoColor: state.HasNoColor()}) lines := ProcessMessage(session, msg, MessageOptions{NoColor: state.HasNoColor()})
for _, line := range lines {
fmt.Print(line)
}
} }
state.EmptyMessageQueue() state.EmptyMessageQueue()