all repos — paprika @ 5d7c1b2e1cb095849165e6c4b2c8ec469886b5a1

go rewrite of taigabot

clean up db use
Anthony DeDominic adedomin@gmail.com
Sun, 16 Jan 2022 10:49:57 -0500
commit

5d7c1b2e1cb095849165e6c4b2c8ec469886b5a1

parent

3adf7461370de0257a5e26992348586815ceca07

5 files changed, 85 insertions(+), 29 deletions(-)

jump to
M database/db.godatabase/db.go

@@ -168,6 +168,10 @@ return []byte(fmt.Sprintf("!%c %d", lenCode, n)), nil

} } +func ToKey(prefix, key string) []byte { + return []byte(fmt.Sprintf("%s/%s", prefix, key)) +} + // encode number so it sorts lexicographically, while being semi readable. func DecodeNumber(n []byte) (int, error) { if len(n) < 3 {
M main.gomain.go

@@ -58,8 +58,17 @@ case "001":

c.Write(config.SplitChannelList(config.C.Channels)) // TODO: Generalize this case "JOIN": + err := plugins.SeenDoing(m) + if err != nil && err != plugins.NoReply { + log.Printf("error: %v", err) + } response, err := plugins.GetIntro(m) handleChatMessage(c, m, response, err) + case "PART", "QUIT": + err := plugins.SeenDoing(m) + if err != nil && err != plugins.NoReply { + log.Printf("error: %v", err) + } // TODO: Generalize this case "NOTICE": response, err := plugins.CTCPReply(m)
M plugins/introduction.goplugins/introduction.go

@@ -21,8 +21,9 @@ }

func (Introduction) Execute(m *irc.Message) (string, error) { param := strings.SplitN(m.Trailing(), " ", 2) + userKey := database.ToKey("introduction", m.Name) if len(param) != 2 { - intro, err := database.DB.Get([]byte(m.Name)) + intro, err := database.DB.Get(userKey) if err == badger.ErrKeyNotFound { return fmt.Sprintf("Usage: %s <intro text>", param[0]), nil } else if err != nil {

@@ -32,7 +33,7 @@ return string(intro), nil

} } - err := database.DB.Set([]byte(m.Name), []byte(param[1])) + err := database.DB.Set(userKey, []byte(param[1])) if err != nil { return "[Introduction] Failed to set introduction string.", nil }

@@ -41,7 +42,7 @@ return "", NoReply

} func GetIntro (m *irc.Message) (string, error) { - intro, err := database.DB.Get([]byte(m.Name)) + intro, err := database.DB.Get(database.ToKey("introduction", m.Name)) if err == badger.ErrKeyNotFound { return "", NoReply } else if err != nil {
M plugins/seen.goplugins/seen.go

@@ -1,11 +1,14 @@

package plugins import ( + "bytes" + "encoding/gob" "fmt" "strings" - "sync" "time" + "git.icyphox.sh/paprika/database" + "github.com/dgraph-io/badger/v3" "github.com/dustin/go-humanize" "gopkg.in/irc.v3" )

@@ -20,45 +23,83 @@ func (Seen) Triggers() []string {

return []string{".seen", ""} } -var LastSeen sync.Map - type LastSeenInfo struct { // The last message the user sent. Message string + // Command type + Doing string // The last time this user was seen. Time time.Time } func (Seen) Execute(m *irc.Message) (string, error) { - LastSeen.Store(m.Name, LastSeenInfo{ - Message: m.Trailing(), - // We just saw the user, so. - Time: time.Now(), - }) - - if strings.HasPrefix(m.Params[1], ".seen") { - params := strings.Split(m.Trailing(), " ") - if len(params) == 1 { + var reply string + if m.Command == "PRIVMSG" && strings.HasPrefix(m.Trailing(), ".seen") { + params := strings.SplitN(m.Trailing(), " ", 3) + if len(params) != 2 { return "Usage: .seen <nickname>", nil } - if seen, ok := LastSeen.Load(params[1]); ok { - humanized := humanize.Time(seen.(LastSeenInfo).Time) + nameKey := database.ToKey("seen", params[1]) + lastS, err := database.DB.Get(nameKey) + if err == badger.ErrKeyNotFound { + return fmt.Sprintf("I have not seen %s", params[1]), nil + } else if err != nil { + return "", err + } - // Don't want "now ago". - if humanized != "now" { - humanized = humanized + " ago" - } + var lastSeen LastSeenInfo + err = gob.NewDecoder(bytes.NewReader(lastS)).Decode(&lastSeen) + if err != nil { + return "", err + } + + humanized := humanize.Time(lastSeen.Time) + + // Don't want "now ago". + if humanized != "now" { + humanized = humanized + " ago" + } - return fmt.Sprintf( + if lastSeen.Doing == "PRIVMSG" { + reply = fmt.Sprintf( "\x02%s\x02 was last seen %s, saying: %s", params[1], humanized, - seen.(LastSeenInfo).Message, - ), nil + lastSeen.Message, + ) } else { - return "I have not seen " + params[1], nil + reply = fmt.Sprintf( + "\x02%s\x02 was last seen %s, doing: %s", + params[1], humanized, + lastSeen.Doing, + ) } } - return "", NoReply + seenDoing := LastSeenInfo{ + Message: m.Trailing(), + Doing: m.Command, + // We just saw the user, so. + Time: time.Now(), + } + + var enc bytes.Buffer + err := gob.NewEncoder(&enc).Encode(seenDoing) + if err != nil { + return "", err + } + + nameKey := database.ToKey("seen", m.Name) + database.DB.Set(nameKey, enc.Bytes()) + + if reply == "" { + return "", NoReply + } else { + return reply, nil + } +} + +func SeenDoing(m *irc.Message) error { + _, err := Seen{}.Execute(m) + return err }
M plugins/version.goplugins/version.go

@@ -31,9 +31,10 @@ if likelyInvalidNick(nickTarget) {

return fmt.Sprintf("%s does not look like an IRC Nick", nickTarget), nil } + nickKey := database.ToKey("version", nickTarget) replyTarget := m.Params[0] err := database.DB.SetWithTTL( - []byte(nickTarget), + nickKey, []byte(replyTarget), 2 * time.Minute, )

@@ -62,7 +63,7 @@

ver := params[1][:len(params[1])-1] from := m.Name - newTarget, err := database.DB.Delete([]byte(from)) + newTarget, err := database.DB.Delete(database.ToKey("version", from)) if err != nil { return "", err }

@@ -74,7 +75,7 @@ }

func NoSuchUser(m *irc.Message) (string, error) { invalidNick := m.Params[1] - newTarget, err := database.DB.Delete([]byte(invalidNick)) + newTarget, err := database.DB.Delete(database.ToKey("version", invalidNick)) if err == badger.ErrKeyNotFound { return "", NoReply } else if err != nil {