grim/wasdead

Parents ebbb484ee8f0
Children 13edf213332c
Overhaul the entire database layer force it to only use bitcask for the time being
--- a/database/bitcask.go Fri Apr 19 15:34:30 2019 -0500
+++ b/database/bitcask.go Fri May 10 22:41:06 2019 -0500
@@ -1,72 +1,31 @@
package database
import (
- "fmt"
- "strings"
+ "github.com/prologic/bitcask"
+)
- "github.com/prologic/bitcask"
- log "github.com/sirupsen/logrus"
+var (
+ db *bitcask.Bitcask
)
-type db_bitcask struct {
- database *bitcask.Bitcask
-}
-
-func init() {
- database, _ := bitcask.Open("./db")
-
- Register("bitcask", db_bitcask{
- database: database,
- })
-}
-
-func (db db_bitcask) GetGuild(guildid string) *Guild {
- data, err := db.database.Get(guildid)
-
- if err != nil || len(data) == 0 {
- log.Errorf("Bitcask GetGuild error: %s", err)
-
- // We need to return a empty Guild object
- return &Guild{}
+func Open(filename string) error {
+ database, err := bitcask.Open(filename)
+ if err != nil {
+ return err
}
- guild := toGuildObject(data)
+ db = database
- return &guild
+ return nil
}
-func (db db_bitcask) AddGuild(guild *Guild) {
- err := db.database.Put(guild.ID, toJsonObject(*guild))
-
+func Close() error {
+ err := db.Close()
if err != nil {
- log.Errorf("Bitcask AddGuild error: %s", err)
- }
-}
-
-func (db db_bitcask) UpdateGuild(guild *Guild) {
- db.AddGuild(guild)
-}
-
-func (db db_bitcask) AlreadyPostedStatus(channelid, streamid string) bool {
- data, err := db.database.Get("alp_" + channelid)
-
- if err != nil || len(data) == 0 {
- log.Errorf("Bitcask AlreadySend error: %s", err)
-
- return false
+ return err
}
- return strings.EqualFold(streamid, string(data))
-}
+ db = nil
-func (db db_bitcask) AddStatusUpdate(channelid, streamid string) error {
- if db.AlreadyPostedStatus("alp_"+channelid, streamid) {
- return fmt.Errorf("Bitcask AddStatusUpdate failed for %s -> %s", channelid, streamid)
- }
-
- return db.database.Put(channelid, []byte(streamid))
+ return nil
}
-
-func (db db_bitcask) Close() {
- db.database.Close()
-}
--- a/database/database.go Fri Apr 19 15:34:30 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-package database
-
-import (
- "encoding/json"
-
- log "github.com/sirupsen/logrus"
-)
-
-type Database interface {
- GetGuild(guildid string) *Guild
- AddGuild(guild *Guild)
- UpdateGuild(guild *Guild)
- AlreadyPostedStatus(channelid, streamid string) bool
- AddStatusUpdate(channelid, streamid string) error
- Close()
-}
-
-var supported map[string]Database
-
-func Register(name string, db Database) {
- if len(supported) <= 0 {
- supported = make(map[string]Database)
- }
-
- supported[name] = db
-}
-
-func Get(name string) Database {
- return supported[name]
-}
-
-func Supported() []string {
- ret := make([]string, len(supported))
- i := 0
- for n, _ := range supported {
- ret[i] = n
- i++
- }
-
- return ret
-}
-
-func toGuildObject(data []byte) Guild {
- var item Guild
- err := json.Unmarshal(data, &item)
- if err != nil {
- log.Errorf("toGuildObject failed: %#v", err)
- return Guild{}
- }
-
- return item
-}
-
-func toJsonObject(guild Guild) []byte {
- data, err := json.Marshal(guild)
-
- if err != nil {
- log.Errorf("toJsonObject failed: %#v", err)
- return nil
- }
-
- return data
-}
--- a/database/guild.go Fri Apr 19 15:34:30 2019 -0500
+++ b/database/guild.go Fri May 10 22:41:06 2019 -0500
@@ -1,41 +1,45 @@
package database
-// TODO: enable more features like config
+import (
+ "encoding/json"
+
+ log "github.com/sirupsen/logrus"
+)
+
type Guild struct {
- ID string
- Channels []Channel
+ ID string `json:"guild_id"`
+ Channel string `json:"announce_channel"`
+
+ History map[string]string `json:"history"`
+ Ignore []string `json:"ignore"`
}
-// TODO: add methods to channel that let us use this system more
-type Channel struct {
- ID string
-}
-
-func (guild *Guild) HasChannel(channel string) bool {
- for _, g := range guild.Channels {
- if g.ID == channel {
- return true
- }
+func LoadGuild(id string) (*Guild, error) {
+ data, err := db.Get("guild-" + id)
+ if err != nil {
+ log.Debugf("guild %s not found : %v", id, err)
+ log.Infof("guild %s not found, creating new", id)
}
- return false
-}
+ guild := &Guild{}
+
+ json.Unmarshal(data, guild)
-func (guild *Guild) AddChannel(channel string) {
- if guild.HasChannel(channel) {
- return
+ // if the load failed for any reason we create a new one
+ if guild.ID == "" {
+ guild.ID = id
+ guild.History = map[string]string{}
+ guild.Ignore = []string{}
}
- guild.Channels = append(guild.Channels, Channel{channel})
+ return guild, nil
}
-func (guild *Guild) RemoveChannel(channel string) {
- newChannels := make([]Channel, 0)
- for _, g := range guild.Channels {
- if g.ID != channel {
- newChannels = append(newChannels, g)
- }
+func (g *Guild) Save() error {
+ data, err := json.Marshal(g)
+ if err != nil {
+ return err
}
- guild.Channels = newChannels
+ return db.Put("guild-"+g.ID, data)
}
--- a/discord/command_remove_channel.go Fri Apr 19 15:34:30 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-package discord
-
-import (
- "fmt"
-
- "github.com/bwmarrin/discordgo"
-)
-
-type commandRemoveChannel struct{}
-
-func (cmd *commandRemoveChannel) Help() string {
- return "removes the channel from the bot to send messages to"
-}
-
-func (cmd *commandRemoveChannel) Run(args []string, c *DiscordClient, m *discordgo.MessageCreate) (interface{}, error) {
- guild := c.db.GetGuild(m.GuildID)
- if guild.ID == "" {
- return "This guild is not registered please use `set-channel`", nil
- } else {
- if !guild.HasChannel(m.ChannelID) {
- return fmt.Sprintf("<#%s> is not a registered channel, please use `set-channel`", m.ChannelID), nil
- }
-
- guild.RemoveChannel(m.ChannelID)
- c.db.UpdateGuild(guild)
- }
-
- return fmt.Sprintf("<#%s> has been removed from the channels list", m.ChannelID), nil
-}
--- a/discord/command_set_channel.go Fri Apr 19 15:34:30 2019 -0500
+++ b/discord/command_set_channel.go Fri May 10 22:41:06 2019 -0500
@@ -4,6 +4,8 @@
"fmt"
"github.com/bwmarrin/discordgo"
+
+ "bitbucket.org/TheToyz/nowdead/database"
)
type commandSetChannel struct{}
@@ -13,17 +15,17 @@
}
func (cmd *commandSetChannel) Run(args []string, c *DiscordClient, m *discordgo.MessageCreate) (interface{}, error) {
- guild := c.db.GetGuild(m.GuildID)
- if guild.ID == "" {
- guild.ID = m.GuildID
- guild.AddChannel(m.ChannelID)
- c.db.AddGuild(guild)
+ guild, err := database.LoadGuild(m.GuildID)
+ if err != nil {
+ return nil, err
+ }
+
+ if guild.Channel != m.ChannelID {
+ guild.Channel = m.ChannelID
+ guild.Save()
return fmt.Sprintf("Set <#%s> as the announcement channel", m.ChannelID), nil
- } else {
- // TODO: actually make this do something other then update
- c.db.UpdateGuild(guild)
}
- return fmt.Sprintf("<#%s> is already set as a registered channel", m.ChannelID), nil
+ return fmt.Sprintf("<#%s> is already set as the announcement channel", m.ChannelID), nil
}
--- a/discord/commands.go Fri Apr 19 15:34:30 2019 -0500
+++ b/discord/commands.go Fri May 10 22:41:06 2019 -0500
@@ -20,7 +20,6 @@
func init() {
commands.Set("help", &commandHelp{})
commands.Set("set-channel", &commandSetChannel{})
- commands.Set("remove-channel", &commandRemoveChannel{})
commands.Set("status", &commandStatus{})
commands.Set("uptime", &commandUptime{})
}
--- a/discord/discord.go Fri Apr 19 15:34:30 2019 -0500
+++ b/discord/discord.go Fri May 10 22:41:06 2019 -0500
@@ -1,7 +1,6 @@
package discord
import (
- "errors"
"strings"
"time"
@@ -13,14 +12,13 @@
type DiscordClient struct {
client *discordgo.Session
- db database.Database
started time.Time
userID string
mentionString string
}
-func New(token string, db database.Database) (*DiscordClient, error) {
+func New(token string) (*DiscordClient, error) {
client, err := discordgo.New("Bot " + strings.TrimSpace(token))
if err != nil {
return nil, err
@@ -28,7 +26,6 @@
dc := &DiscordClient{
client: client,
- db: db,
started: time.Now().UTC(),
}
@@ -55,20 +52,12 @@
}
func (c *DiscordClient) send(guildID, message string) error {
- // channelID := c.db.GetChannel(guild)
- guild := c.db.GetGuild(guildID)
-
- if guild.ID == "" {
- return errors.New("Guild does not exist")
+ guild, err := database.LoadGuild(guildID)
+ if err != nil {
+ return err
}
- if len(guild.Channels) == 0 || guild.Channels[0].ID == "" {
- return errors.New("No channel set")
- }
-
- channelID := guild.Channels[0].ID
-
- return c.sendChannel(channelID, message)
+ return c.sendChannel(guild.Channel, message)
}
func (c *DiscordClient) sendChannel(channelID, message string) error {
--- a/discord/presence.go Fri Apr 19 15:34:30 2019 -0500
+++ b/discord/presence.go Fri May 10 22:41:06 2019 -0500
@@ -8,6 +8,7 @@
"github.com/dustin/go-humanize"
log "github.com/sirupsen/logrus"
+ "bitbucket.org/TheToyz/nowdead/database"
"bitbucket.org/TheToyz/nowdead/presence"
)
@@ -20,19 +21,27 @@
return
}
- guild, _ := c.client.Guild(p.GuildID)
+ guild, err := database.LoadGuild(p.GuildID)
+ if err != nil {
+ log.Errorf("error loading guild: %v", err)
+ return
+ }
- log.Infof("server: %s username: %s is now streaming", guild.Name, p.Presence.User.Username)
+ log.Infof("server: %s username: %s is now streaming", guild.ID, p.Presence.User.Username)
presence, _ := presence.GetPresence(p.Game.URL)
- if c.db.AlreadyPostedStatus(presence.UserID, presence.StreamID) {
- log.Debugf("already sent presence to guild %s: %v", p.GuildID, presence)
- return
+ if lastID, ok := guild.History[presence.UserID]; ok {
+ if lastID == presence.StreamID {
+ log.Infof("already sent presence to guild %s: %v", p.GuildID, presence)
+ return
+ }
}
- if err := c.db.AddStatusUpdate(presence.UserID, presence.StreamID); err != nil {
- log.Warnf("failed to add user (%s) stream (%s) to database, %v", presence.UserID, presence.StreamID, err)
+ guild.History[presence.UserID] = presence.StreamID
+ err = guild.Save()
+ if err != nil {
+ log.Warnf("failed to save stream update for %s: %v", presence.UserID, err)
}
if err := c.sendPresence(p.GuildID, presence); err != nil {
@@ -41,18 +50,20 @@
}
func (c *DiscordClient) sendPresence(guildID string, presence presence.Presence) error {
- guild := c.db.GetGuild(guildID)
+ guild, err := database.LoadGuild(guildID)
+ if err != nil {
+ return err
+ }
+
if guild.ID == "" {
return errors.New("Guild does not exist")
}
- if len(guild.Channels) == 0 || guild.Channels[0].ID == "" {
+ if guild.Channel == "" {
return errors.New("No channel set")
}
- channelID := guild.Channels[0].ID
-
- return c.sendPresenceChannel(channelID, presence)
+ return c.sendPresenceChannel(guild.Channel, presence)
}
func (c *DiscordClient) sendPresenceChannel(channelID string, presence presence.Presence) error {
--- a/main.go Fri Apr 19 15:34:30 2019 -0500
+++ b/main.go Fri May 10 22:41:06 2019 -0500
@@ -25,11 +25,7 @@
discordToken = app.Flag("discord-token", "The bot token for discord").Short('d').Envar("NOWDEAD_DISCORD_TOKEN").Required().String()
twitchClientID = app.Flag("twitch-client-id", "The client id").Short('t').Envar("NOWDEAD_TWITCH_CLIENT_ID").Required().String()
- databaseType = app.Flag("database", "The database engine to use").Default("bitcask").Enum(database.Supported()...)
-
startTime time.Time
-
- db database.Database
)
func init() {
@@ -44,7 +40,11 @@
return
}
- db = database.Get(*databaseType)
+ if err := database.Open("db"); err != nil {
+ log.Errorf("failed to open database: %v", err)
+ return
+ }
+ defer database.Close()
if len(*twitchClientID) > 0 {
provider, err := twitch.New(*twitchClientID)
@@ -60,7 +60,7 @@
errChan := make(chan error, 1)
// create the discord client
- dc, err := discord.New(*discordToken, db)
+ dc, err := discord.New(*discordToken)
if err != nil {
fmt.Println("error creating Discord session,", err)
return