From fad307913226a18985f9db295d039504569566ac Mon Sep 17 00:00:00 2001 From: Martyn Ranyard Date: Fri, 21 Feb 2020 20:54:27 +0100 Subject: [PATCH] All the magic, database and admin stuff Signed-off-by: Martyn Ranyard --- internal/irc/irc.go | 100 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 8 deletions(-) diff --git a/internal/irc/irc.go b/internal/irc/irc.go index 62c2c94..310916c 100644 --- a/internal/irc/irc.go +++ b/internal/irc/irc.go @@ -3,6 +3,7 @@ package irc import ( "bufio" "encoding/json" + "encoding/base64" "errors" "fmt" "io" @@ -15,6 +16,8 @@ import ( "time" rgb "github.com/foresthoffman/rgblog" + scribble "github.com/nanobox-io/golang-scribble" + uuid "github.com/google/uuid" ) const PSTFormat = "Jan 2 15:04:05 PST" @@ -38,9 +41,6 @@ type OAuthCred struct { // The developer application client ID. Used for API calls to Twitch. ClientID string `json:"client_id,omitempty"` - - // List of Channels to join - Channels []string `json:"channels,omitempty"` } type KardBot struct { @@ -54,6 +54,16 @@ type KardBot struct { Server string startTime time.Time Prompts []string + Database scribble.Driver + channelData map[string]ChannelData +} + +type ChannelData struct { + Name string `json:"name"` + AdminKey string `json:"value,omitempty"` + CustomCommand string `json:"customcommand,omitempty"` + ExtraStrings string `json:"extrastrings,omitempty"` + JoinTime time.Time `json:"jointime"` } // Connects the bot to the Twitch IRC server. The bot will continue to try to connect until it @@ -134,7 +144,7 @@ func (bb *KardBot) HandleChat() error { } // channel-owner specific commands - if userName == bb.Channel { + if userName == channel { switch cmd { case "tbdown": rgb.CPrintf( @@ -144,6 +154,14 @@ func (bb *KardBot) HandleChat() error { bb.Disconnect() return nil + case "wat": + magicCode := bb.readOrCreateChannelKey(channel) + rgb.CPrintf( + "[%s] Magic code is %s - https://karaokards.ing.martyn.berlin/admin/%s/%s\n", + TimeStamp(), + magicCode, userName, magicCode, + ) + bb.Say("Ack.") default: // do nothing } @@ -232,15 +250,24 @@ func (bb *KardBot) Start() { err := bb.ReadCredentials() if nil != err { fmt.Println(err) - fmt.Println("Aborting...") + fmt.Println("Aborting!") + return + } + + err = bb.readChannelData() + if nil != err { + fmt.Println(err) + fmt.Println("Aborting!") return } for { bb.Connect() bb.Login() - if len(bb.Credentials.Channels) > 0 { - bb.JoinChannel(bb.Credentials.Channels...) + if len(bb.channelData) > 0 { + for channelName := range(bb.channelData) { + bb.JoinChannel(channelName) + } } else { bb.JoinChannel() } @@ -257,10 +284,67 @@ func (bb *KardBot) Start() { } } +func (bb *KardBot) readChannelData() error { + records, err := bb.Database.ReadAll("channelData") + if err != nil { + // no db? initialise one? + record := ChannelData{Name: bb.Channel, JoinTime: time.Now()} + rgb.YPrintf("[%s] No channel data for #%s exists, creating...\n", TimeStamp(), bb.Channel) + if err := bb.Database.Write("channelData", bb.Channel, record); err != nil { + return err + } + bb.channelData = make(map[string]ChannelData) + bb.channelData[bb.Channel] = record; + } else { + bb.channelData = make(map[string]ChannelData) + } + for _, data := range records { + record := ChannelData{} + err := json.Unmarshal([]byte(data), &record); + if err != nil { + return err + } + bb.channelData[record.Name] = record + } + return nil +} + +func (bb *KardBot) readOrCreateChannelKey(channel string) string { + magicCode := "" + var err error + var record ChannelData + if record, ok := bb.channelData[channel]; !ok { + rgb.YPrintf("[%s] No channel data for #%s exists, creating\n", TimeStamp(), channel) + err = bb.Database.Read("channelData", channel, &record); + if err == nil { + bb.channelData[channel] = record + } + } + record = bb.channelData[channel] + if err != nil || record.AdminKey == "" { + rgb.YPrintf("[%s] No channel key for #%s exists, creating one\n", TimeStamp(), channel) + newuu, _ := uuid.NewRandom() + magicCode = base64.StdEncoding.EncodeToString([]byte(newuu.String())) + record.AdminKey = magicCode + if record.Name == "" { + record.Name = channel + } + if err := bb.Database.Write("channelData", channel, record); err != nil { + rgb.RPrintf("[%s] Error writing channel data for #%s\n", TimeStamp(), channel) + } + bb.channelData[record.Name] = record + rgb.YPrintf("[%s] Cached channel key for #%s\n", TimeStamp(), record.Name) + } else { + magicCode = record.AdminKey + rgb.YPrintf("[%s] Loaded data for #%s\n", TimeStamp(), channel) + } + return magicCode +} + func TimeStamp() string { return TimeStampFmt(PSTFormat) } func TimeStampFmt(format string) string { return time.Now().Format(format) -} +} \ No newline at end of file