aboutsummaryrefslogtreecommitdiff
path: root/config/guild.go
diff options
context:
space:
mode:
Diffstat (limited to 'config/guild.go')
-rw-r--r--config/guild.go136
1 files changed, 106 insertions, 30 deletions
diff --git a/config/guild.go b/config/guild.go
index dc8251f..aec78ed 100644
--- a/config/guild.go
+++ b/config/guild.go
@@ -2,31 +2,33 @@ package config
import (
"context"
+ "database/sql"
+ "errors"
"fmt"
+ "slices"
"strings"
+ "git.anhgelus.world/anhgelus/les-copaings-bot/common"
"github.com/nyttikord/gokord/bot"
"github.com/nyttikord/gokord/channel"
)
type Guild struct {
- ID uint `gorm:"primarykey"`
- GuildID uint64 `gorm:"not null;unique"`
- XpRoles []XpRole `gorm:"foreignKey:GuildConfigID"`
+ ID uint64
+ XpRoles []XpRole
DisabledChannels string
FallbackChannel uint64
- DaysXPRemains uint `gorm:"default:90"` // 30 * 3 = 90 (three months)
+ DaysXPRemains uint
RrMessages []RoleReactMessage
}
type RoleReactMessage struct {
- ID uint `gorm:"primarykey"`
- MessageID uint64 `gorm:"not null;unique"`
- ChannelID uint64
- GuildID uint64
- Note string
- Roles []*RoleReact
- GuildConfigID uint
+ ID uint `gorm:"primarykey"`
+ MessageID uint64 `gorm:"not null;unique"`
+ ChannelID uint64
+ GuildID uint64
+ Note string
+ Roles []*RoleReact
}
type RoleReact struct {
@@ -37,45 +39,102 @@ type RoleReact struct {
CounterID uint `gorm:"-"`
}
-func GetGuildConfig(ctx context.Context, guildID uint64) *Guild {
- cfg := Guild{GuildID: guildID}
+func GetGuild(ctx context.Context, guildID uint64) *Guild {
+ cfg := Guild{ID: guildID}
if err := cfg.Load(ctx); err != nil {
panic(err)
}
return &cfg
}
-func (cfg *Guild) Load(ctx context.Context) error {
- return nil //common.GetDB(ctx).Where("guild_id = ?", cfg.GuildID).Preload("XpRoles").FirstOrCreate(cfg).Error
+func (g *Guild) Load(ctx context.Context) error {
+ db := common.GetDB(ctx)
+ row := db.QueryRowContext(
+ ctx,
+ `SELECT disabled_channels, fallback_channel, days_xp_remains FROM guilds WHERE id = ?`,
+ g.ID,
+ )
+ g.RrMessages = nil
+ g.XpRoles = nil
+ err := row.Err()
+ if err != nil {
+ if !errors.Is(err, sql.ErrNoRows) {
+ return err
+ }
+ _, err = db.ExecContext(
+ ctx,
+ `INSERT INTO guilds (id) VALUES (?)`,
+ g.ID,
+ )
+ return err
+ }
+ err = row.Scan(&g.DisabledChannels, &g.FallbackChannel, &g.DaysXPRemains)
+ if err != nil {
+ return err
+ }
+ g.XpRoles, err = getXpRoles(ctx, g.ID)
+ return err
}
-func (cfg *Guild) Save(ctx context.Context) error {
- return nil //common.GetDB(ctx).Save(cfg).Error
+func (g *Guild) Save(ctx context.Context) error {
+ db := common.GetDB(ctx)
+ _, err := db.ExecContext(
+ ctx,
+ `UPDATE guilds SET disabled_channels = ?, fallback_channel = ?, days_xp_remains = ? WHERE id = ?`,
+ g.DisabledChannels, g.FallbackChannel, g.DaysXPRemains, g.ID,
+ )
+ if err != nil {
+ return err
+ }
+ savedRoles, err := getXpRoles(ctx, g.ID)
+ if err != nil {
+ return err
+ }
+ roleEqual := func(base XpRole) func(XpRole) bool {
+ return func(v XpRole) bool {
+ return v.GuildID == base.GuildID && v.RoleID == base.RoleID && v.XP == base.XP
+ }
+ }
+ // super slow code, but I don't want to implement a data structure to optimize this
+ for _, role := range g.XpRoles {
+ if !slices.ContainsFunc(savedRoles, roleEqual(role)) {
+ err = role.Save(ctx)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ for _, role := range savedRoles {
+ if !slices.ContainsFunc(g.XpRoles, roleEqual(role)) {
+ err = role.Delete(ctx)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
}
-func (cfg *Guild) IsDisabled(ctx context.Context, dg bot.Session, channelID uint64) bool {
+func (g *Guild) IsDisabled(ctx context.Context, dg bot.Session, channelID uint64) bool {
ok := true
for channelID != 0 && ok {
- ok = !strings.Contains(cfg.DisabledChannels, fmt.Sprintf("%d", channelID))
+ ok = !strings.Contains(g.DisabledChannels, fmt.Sprintf("%d", channelID))
c, err := dg.ChannelState().GetChannel(channelID)
if err != nil {
- bot.Logger(ctx).Error("unable to find channel %s in state", "error", err, "channel", c)
+ bot.Logger(ctx).Warn("unable to find channel %s in state", "error", err, "channel", c)
c, err = channel.Get(channelID).Do(ctx)
if err != nil {
bot.Logger(ctx).Error("unable to fetch channel", "error", err, "channel", c)
return false
}
}
- if err != nil {
- return false
- }
channelID = c.ParentID
}
return !ok
}
-func (cfg *Guild) FindXpRole(roleID uint64) (int, *XpRole) {
- for i, r := range cfg.XpRoles {
+func (g *Guild) FindXpRole(roleID uint64) (int, *XpRole) {
+ for i, r := range g.XpRoles {
if r.RoleID == roleID {
return i, &r
}
@@ -83,11 +142,28 @@ func (cfg *Guild) FindXpRole(roleID uint64) (int, *XpRole) {
return 0, nil
}
-func (cfg *Guild) FindXpRoleID(ID uint) (int, *XpRole) {
- for i, r := range cfg.XpRoles {
- if r.ID == ID {
- return i, &r
+func getXpRoles(ctx context.Context, gID uint64) ([]XpRole, error) {
+ roles := make([]XpRole, 0)
+ rows, err := common.GetDB(ctx).QueryContext(
+ ctx,
+ `SELECT xp, role FROM xp_roles WHERE guild_id = ?`,
+ gID,
+ )
+ if err == nil {
+ defer rows.Close()
+ for rows.Next() {
+ var role XpRole
+ err = rows.Scan(&role.XP, &role.RoleID)
+ if err != nil {
+ return roles, err
+ }
+ role.GuildID = gID
+ roles = append(roles, role)
+ }
+ } else {
+ if !errors.Is(err, sql.ErrNoRows) {
+ return roles, err
}
}
- return -1, nil
+ return roles, nil
}