mirror of
https://github.com/Luzifer/discord-community.git
synced 2024-11-08 15:10:02 +00:00
Add persistent store and module IDs
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
da426e7d68
commit
5bd54dd15c
9 changed files with 134 additions and 9 deletions
|
@ -13,13 +13,15 @@ import (
|
|||
|
||||
type (
|
||||
configFile struct {
|
||||
BotToken string `yaml:"bot_token"`
|
||||
GuildID string `yaml:"guild_id"`
|
||||
BotToken string `yaml:"bot_token"`
|
||||
GuildID string `yaml:"guild_id"`
|
||||
StoreLocation string `yaml:"store_location"`
|
||||
|
||||
ModuleConfigs []moduleConfig `yaml:"module_configs"`
|
||||
}
|
||||
|
||||
moduleConfig struct {
|
||||
ID string `yaml:"id"`
|
||||
Type string `yaml:"type"`
|
||||
Attributes moduleAttributeStore `yaml:"attributes"`
|
||||
}
|
||||
|
|
18
main.go
18
main.go
|
@ -23,6 +23,7 @@ var (
|
|||
}{}
|
||||
|
||||
config *configFile
|
||||
store *metaStore
|
||||
|
||||
version = "dev"
|
||||
)
|
||||
|
@ -57,6 +58,14 @@ func main() {
|
|||
log.WithError(err).Fatal("Unable to load config file")
|
||||
}
|
||||
|
||||
if config.StoreLocation == "" {
|
||||
log.Fatal("Config contains no store location")
|
||||
}
|
||||
|
||||
if store, err = newMetaStoreFromDisk(config.StoreLocation); err != nil {
|
||||
log.WithError(err).Fatal("Unable to load store")
|
||||
}
|
||||
|
||||
// Connect to Discord
|
||||
if discord, err = discordgo.New(strings.Join([]string{"Bot", config.BotToken}, " ")); err != nil {
|
||||
log.WithError(err).Fatal("Unable to create discord client")
|
||||
|
@ -66,15 +75,22 @@ func main() {
|
|||
|
||||
for i, mc := range config.ModuleConfigs {
|
||||
logger := log.WithFields(log.Fields{
|
||||
"id": mc.ID,
|
||||
"idx": i,
|
||||
"module": mc.Type,
|
||||
})
|
||||
|
||||
if mc.ID == "" {
|
||||
logger.Error("Module contains no ID and will be disabled")
|
||||
continue
|
||||
}
|
||||
|
||||
mod := GetModuleByName(mc.Type)
|
||||
if mod == nil {
|
||||
logger.Fatal("Found configuration for unsupported module")
|
||||
}
|
||||
|
||||
if err = mod.Initialize(crontab, discord, mc.Attributes); err != nil {
|
||||
if err = mod.Initialize(mc.ID, crontab, discord, mc.Attributes); err != nil {
|
||||
logger.WithError(err).Fatal("Unable to initialize module")
|
||||
}
|
||||
|
||||
|
|
86
metastore.go
Normal file
86
metastore.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type metaStore struct {
|
||||
ModuleAttributes map[string]moduleAttributeStore `json:"module_attributes"`
|
||||
|
||||
filename string
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func newMetaStoreFromDisk(filename string) (*metaStore, error) {
|
||||
out := &metaStore{
|
||||
ModuleAttributes: map[string]moduleAttributeStore{},
|
||||
filename: filename,
|
||||
}
|
||||
|
||||
f, err := os.Open(filename)
|
||||
switch {
|
||||
case err == nil:
|
||||
// This is fine
|
||||
|
||||
case os.IsNotExist(err):
|
||||
// No store yet, return empty store
|
||||
return out, nil
|
||||
|
||||
default:
|
||||
return nil, errors.Wrap(err, "opening store")
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return out, errors.Wrap(
|
||||
json.NewDecoder(f).Decode(out),
|
||||
"decoding store",
|
||||
)
|
||||
}
|
||||
|
||||
func (m *metaStore) Save() error {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
|
||||
return m.save()
|
||||
}
|
||||
|
||||
func (m *metaStore) save() error {
|
||||
f, err := os.Create(m.filename)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating storage file")
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return errors.Wrap(
|
||||
json.NewEncoder(f).Encode(m),
|
||||
"encoding storage file",
|
||||
)
|
||||
}
|
||||
|
||||
func (m *metaStore) Set(moduleID, key string, value interface{}) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
if m.ModuleAttributes[moduleID] == nil {
|
||||
m.ModuleAttributes[moduleID] = make(moduleAttributeStore)
|
||||
}
|
||||
|
||||
m.ModuleAttributes[moduleID][key] = value
|
||||
|
||||
return errors.Wrap(m.save(), "saving store")
|
||||
}
|
||||
|
||||
func (m *metaStore) ReadWithLock(moduleID string, fn func(m moduleAttributeStore) error) error {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
|
||||
if m.ModuleAttributes[moduleID] == nil {
|
||||
return fn(moduleAttributeStore{})
|
||||
}
|
||||
|
||||
return fn(m.ModuleAttributes[moduleID])
|
||||
}
|
|
@ -28,11 +28,15 @@ func init() {
|
|||
type modClearChannel struct {
|
||||
attrs moduleAttributeStore
|
||||
discord *discordgo.Session
|
||||
id string
|
||||
}
|
||||
|
||||
func (m *modClearChannel) Initialize(crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
func (m modClearChannel) ID() string { return m.id }
|
||||
|
||||
func (m *modClearChannel) Initialize(id string, crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
m.attrs = attrs
|
||||
m.discord = discord
|
||||
m.id = id
|
||||
|
||||
if err := attrs.Expect(
|
||||
"discord_channel_id",
|
||||
|
|
|
@ -36,11 +36,15 @@ func init() {
|
|||
type modLivePosting struct {
|
||||
attrs moduleAttributeStore
|
||||
discord *discordgo.Session
|
||||
id string
|
||||
}
|
||||
|
||||
func (m *modLivePosting) Initialize(crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
func (m modLivePosting) ID() string { return m.id }
|
||||
|
||||
func (m *modLivePosting) Initialize(id string, crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
m.attrs = attrs
|
||||
m.discord = discord
|
||||
m.id = id
|
||||
|
||||
if err := attrs.Expect(
|
||||
"discord_channel_id",
|
||||
|
|
|
@ -24,11 +24,15 @@ func init() {
|
|||
type modLiveRole struct {
|
||||
attrs moduleAttributeStore
|
||||
discord *discordgo.Session
|
||||
id string
|
||||
}
|
||||
|
||||
func (m *modLiveRole) Initialize(crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
func (m modLiveRole) ID() string { return m.id }
|
||||
|
||||
func (m *modLiveRole) Initialize(id string, crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
m.attrs = attrs
|
||||
m.discord = discord
|
||||
m.id = id
|
||||
|
||||
if err := attrs.Expect(
|
||||
"role_streamers_live",
|
||||
|
|
|
@ -28,11 +28,15 @@ func init() {
|
|||
type modPresence struct {
|
||||
attrs moduleAttributeStore
|
||||
discord *discordgo.Session
|
||||
id string
|
||||
}
|
||||
|
||||
func (m *modPresence) Initialize(crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
func (m modPresence) ID() string { return m.id }
|
||||
|
||||
func (m *modPresence) Initialize(id string, crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
m.attrs = attrs
|
||||
m.discord = discord
|
||||
m.id = id
|
||||
|
||||
if err := attrs.Expect(
|
||||
"fallback_text",
|
||||
|
|
|
@ -34,11 +34,15 @@ func init() {
|
|||
type modStreamSchedule struct {
|
||||
attrs moduleAttributeStore
|
||||
discord *discordgo.Session
|
||||
id string
|
||||
}
|
||||
|
||||
func (m *modStreamSchedule) Initialize(crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
func (m modStreamSchedule) ID() string { return m.id }
|
||||
|
||||
func (m *modStreamSchedule) Initialize(id string, crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error {
|
||||
m.attrs = attrs
|
||||
m.discord = discord
|
||||
m.id = id
|
||||
|
||||
if err := attrs.Expect(
|
||||
"discord_channel_id",
|
||||
|
|
|
@ -15,7 +15,8 @@ var (
|
|||
|
||||
type (
|
||||
module interface {
|
||||
Initialize(crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error
|
||||
ID() string
|
||||
Initialize(id string, crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error
|
||||
Setup() error
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue