mirror of
https://github.com/Luzifer/discord-community.git
synced 2024-12-20 10:21:22 +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 (
|
type (
|
||||||
configFile struct {
|
configFile struct {
|
||||||
BotToken string `yaml:"bot_token"`
|
BotToken string `yaml:"bot_token"`
|
||||||
GuildID string `yaml:"guild_id"`
|
GuildID string `yaml:"guild_id"`
|
||||||
|
StoreLocation string `yaml:"store_location"`
|
||||||
|
|
||||||
ModuleConfigs []moduleConfig `yaml:"module_configs"`
|
ModuleConfigs []moduleConfig `yaml:"module_configs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleConfig struct {
|
moduleConfig struct {
|
||||||
|
ID string `yaml:"id"`
|
||||||
Type string `yaml:"type"`
|
Type string `yaml:"type"`
|
||||||
Attributes moduleAttributeStore `yaml:"attributes"`
|
Attributes moduleAttributeStore `yaml:"attributes"`
|
||||||
}
|
}
|
||||||
|
|
18
main.go
18
main.go
|
@ -23,6 +23,7 @@ var (
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
config *configFile
|
config *configFile
|
||||||
|
store *metaStore
|
||||||
|
|
||||||
version = "dev"
|
version = "dev"
|
||||||
)
|
)
|
||||||
|
@ -57,6 +58,14 @@ func main() {
|
||||||
log.WithError(err).Fatal("Unable to load config file")
|
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
|
// Connect to Discord
|
||||||
if discord, err = discordgo.New(strings.Join([]string{"Bot", config.BotToken}, " ")); err != nil {
|
if discord, err = discordgo.New(strings.Join([]string{"Bot", config.BotToken}, " ")); err != nil {
|
||||||
log.WithError(err).Fatal("Unable to create discord client")
|
log.WithError(err).Fatal("Unable to create discord client")
|
||||||
|
@ -66,15 +75,22 @@ func main() {
|
||||||
|
|
||||||
for i, mc := range config.ModuleConfigs {
|
for i, mc := range config.ModuleConfigs {
|
||||||
logger := log.WithFields(log.Fields{
|
logger := log.WithFields(log.Fields{
|
||||||
|
"id": mc.ID,
|
||||||
"idx": i,
|
"idx": i,
|
||||||
"module": mc.Type,
|
"module": mc.Type,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if mc.ID == "" {
|
||||||
|
logger.Error("Module contains no ID and will be disabled")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
mod := GetModuleByName(mc.Type)
|
mod := GetModuleByName(mc.Type)
|
||||||
if mod == nil {
|
if mod == nil {
|
||||||
logger.Fatal("Found configuration for unsupported module")
|
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")
|
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 {
|
type modClearChannel struct {
|
||||||
attrs moduleAttributeStore
|
attrs moduleAttributeStore
|
||||||
discord *discordgo.Session
|
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.attrs = attrs
|
||||||
m.discord = discord
|
m.discord = discord
|
||||||
|
m.id = id
|
||||||
|
|
||||||
if err := attrs.Expect(
|
if err := attrs.Expect(
|
||||||
"discord_channel_id",
|
"discord_channel_id",
|
||||||
|
|
|
@ -36,11 +36,15 @@ func init() {
|
||||||
type modLivePosting struct {
|
type modLivePosting struct {
|
||||||
attrs moduleAttributeStore
|
attrs moduleAttributeStore
|
||||||
discord *discordgo.Session
|
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.attrs = attrs
|
||||||
m.discord = discord
|
m.discord = discord
|
||||||
|
m.id = id
|
||||||
|
|
||||||
if err := attrs.Expect(
|
if err := attrs.Expect(
|
||||||
"discord_channel_id",
|
"discord_channel_id",
|
||||||
|
|
|
@ -24,11 +24,15 @@ func init() {
|
||||||
type modLiveRole struct {
|
type modLiveRole struct {
|
||||||
attrs moduleAttributeStore
|
attrs moduleAttributeStore
|
||||||
discord *discordgo.Session
|
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.attrs = attrs
|
||||||
m.discord = discord
|
m.discord = discord
|
||||||
|
m.id = id
|
||||||
|
|
||||||
if err := attrs.Expect(
|
if err := attrs.Expect(
|
||||||
"role_streamers_live",
|
"role_streamers_live",
|
||||||
|
|
|
@ -28,11 +28,15 @@ func init() {
|
||||||
type modPresence struct {
|
type modPresence struct {
|
||||||
attrs moduleAttributeStore
|
attrs moduleAttributeStore
|
||||||
discord *discordgo.Session
|
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.attrs = attrs
|
||||||
m.discord = discord
|
m.discord = discord
|
||||||
|
m.id = id
|
||||||
|
|
||||||
if err := attrs.Expect(
|
if err := attrs.Expect(
|
||||||
"fallback_text",
|
"fallback_text",
|
||||||
|
|
|
@ -34,11 +34,15 @@ func init() {
|
||||||
type modStreamSchedule struct {
|
type modStreamSchedule struct {
|
||||||
attrs moduleAttributeStore
|
attrs moduleAttributeStore
|
||||||
discord *discordgo.Session
|
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.attrs = attrs
|
||||||
m.discord = discord
|
m.discord = discord
|
||||||
|
m.id = id
|
||||||
|
|
||||||
if err := attrs.Expect(
|
if err := attrs.Expect(
|
||||||
"discord_channel_id",
|
"discord_channel_id",
|
||||||
|
|
|
@ -15,7 +15,8 @@ var (
|
||||||
|
|
||||||
type (
|
type (
|
||||||
module interface {
|
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
|
Setup() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue