diff --git a/bot/access.go b/bot/access.go index 31cd5cc..bcb99fc 100644 --- a/bot/access.go +++ b/bot/access.go @@ -28,7 +28,7 @@ func (b *Bot) allowOwner(actorID id.UserID, targetRoomID id.RoomID) bool { } } - cfg, err := b.getSettings(targetRoomID) + cfg, err := b.getRoomSettings(targetRoomID) if err != nil { b.Error(context.Background(), targetRoomID, "failed to retrieve settings: %v", err) return false diff --git a/bot/bot.go b/bot/bot.go index 43e9018..8fbf124 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -23,7 +23,8 @@ type Bot struct { allowedAdmins []*regexp.Regexp commands commandList rooms sync.Map - cfg cache.Cache[settings] + botcfg cache.Cache[botsettings] + cfg cache.Cache[roomsettings] log *logger.Logger lp *linkpearl.Linkpearl mu map[id.RoomID]*sync.Mutex @@ -43,7 +44,8 @@ func New( prefix: prefix, domain: domain, rooms: sync.Map{}, - cfg: cache.NewLRU[settings](1000), + botcfg: cache.NewLRU[botsettings](1), + cfg: cache.NewLRU[roomsettings](1000), log: log, lp: lp, mu: map[id.RoomID]*sync.Mutex{}, diff --git a/bot/command.go b/bot/command.go index 926eadd..66b57fa 100644 --- a/bot/command.go +++ b/bot/command.go @@ -193,7 +193,7 @@ func (b *Bot) sendIntroduction(ctx context.Context, roomID id.RoomID) { func (b *Bot) sendHelp(ctx context.Context) { evt := eventFromContext(ctx) - cfg, serr := b.getSettings(evt.RoomID) + cfg, serr := b.getRoomSettings(evt.RoomID) if serr != nil { b.log.Error("cannot retrieve settings: %v", serr) } diff --git a/bot/command_admin.go b/bot/command_admin.go index ebec11b..38ad306 100644 --- a/bot/command_admin.go +++ b/bot/command_admin.go @@ -13,7 +13,7 @@ import ( func (b *Bot) sendMailboxes(ctx context.Context) { evt := eventFromContext(ctx) - mailboxes := map[string]settings{} + mailboxes := map[string]roomsettings{} slice := []string{} b.rooms.Range(func(key any, value any) bool { if key == nil { @@ -31,7 +31,7 @@ func (b *Bot) sendMailboxes(ctx context.Context) { if !ok { return true } - config, err := b.getSettings(roomID) + config, err := b.getRoomSettings(roomID) if err != nil { b.log.Error("cannot retrieve settings: %v", err) } @@ -79,7 +79,7 @@ func (b *Bot) runDelete(ctx context.Context, commandSlice []string) { roomID := v.(id.RoomID) b.rooms.Delete(mailbox) - err := b.setSettings(roomID, settings{}) + err := b.setRoomSettings(roomID, roomsettings{}) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return diff --git a/bot/command_owner.go b/bot/command_owner.go index 84f26cd..443dca3 100644 --- a/bot/command_owner.go +++ b/bot/command_owner.go @@ -7,7 +7,7 @@ import ( func (b *Bot) runStop(ctx context.Context) { evt := eventFromContext(ctx) - cfg, err := b.getSettings(evt.RoomID) + cfg, err := b.getRoomSettings(evt.RoomID) if err != nil { b.Error(ctx, evt.RoomID, "failed to retrieve settings: %v", err) return @@ -21,7 +21,7 @@ func (b *Bot) runStop(ctx context.Context) { b.rooms.Delete(mailbox) - err = b.setSettings(evt.RoomID, settings{}) + err = b.setRoomSettings(evt.RoomID, roomsettings{}) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return @@ -40,7 +40,7 @@ func (b *Bot) handleOption(ctx context.Context, cmd []string) { func (b *Bot) getOption(ctx context.Context, name string) { evt := eventFromContext(ctx) - cfg, err := b.getSettings(evt.RoomID) + cfg, err := b.getRoomSettings(evt.RoomID) if err != nil { b.Error(ctx, evt.RoomID, "failed to retrieve settings: %v", err) return @@ -74,7 +74,7 @@ func (b *Bot) setOption(ctx context.Context, name, value string) { } } - cfg, err := b.getSettings(evt.RoomID) + cfg, err := b.getRoomSettings(evt.RoomID) if err != nil { b.Error(ctx, evt.RoomID, "failed to retrieve settings: %v", err) return @@ -92,7 +92,7 @@ func (b *Bot) setOption(ctx context.Context, name, value string) { value = fmt.Sprintf("%s@%s", value, b.domain) } - err = b.setSettings(evt.RoomID, cfg) + err = b.setRoomSettings(evt.RoomID, cfg) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return diff --git a/bot/data.go b/bot/data.go index 310704d..327dc79 100644 --- a/bot/data.go +++ b/bot/data.go @@ -4,15 +4,11 @@ import ( "strings" "maunium.net/go/mautrix/id" - - "gitlab.com/etke.cc/postmoogle/utils" ) // account data keys const ( - messagekey = "cc.etke.postmoogle.message" - settingskey = "cc.etke.postmoogle.settings" - botconfigkey = "cc.etke.postmoogle.config" + messagekey = "cc.etke.postmoogle.message" ) // event keys @@ -21,19 +17,6 @@ const ( eventInReplyToKey = "cc.etke.postmoogle.inReplyTo" ) -// option keys -const ( - optionOwner = "owner" - optionMailbox = "mailbox" - optionNoSender = "nosender" - optionNoSubject = "nosubject" - optionNoHTML = "nohtml" - optionNoThreads = "nothreads" - optionNoFiles = "nofiles" - - botOptionUsers = "users" -) - var migrations = []string{} func (b *Bot) migrate() error { @@ -72,7 +55,7 @@ func (b *Bot) syncRooms() error { } for _, roomID := range resp.JoinedRooms { b.migrateSettings(roomID) - cfg, serr := b.getSettings(roomID) + cfg, serr := b.getRoomSettings(roomID) if serr != nil { b.log.Warn("cannot get %s settings: %v", roomID, err) continue @@ -113,44 +96,3 @@ func (b *Bot) setThreadID(roomID id.RoomID, messageID string, eventID id.EventID } } } - -// TODO: remove after migration -func (b *Bot) migrateBotSettings(users []string) error { - config := b.getBotSettings() - cfgUsers := config.Users() - if len(users) > 0 && len(cfgUsers) == 0 { - _, err := parseMXIDpatterns(users, "") - if err != nil { - return err - } - config.Set(botOptionUsers, strings.Join(users, " ")) - return b.setBotSettings(config) - } - - return nil -} - -func (b *Bot) getBotSettings() settings { - cfg := b.cfg.Get(botconfigkey) - if cfg != nil { - return cfg - } - - config := settings{} - err := b.lp.GetClient().GetAccountData(botconfigkey, &config) - if err != nil { - if strings.Contains(err.Error(), "M_NOT_FOUND") { - err = nil - } - b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) - } else { - b.cfg.Set(botconfigkey, config) - } - - return config -} - -func (b *Bot) setBotSettings(cfg settings) error { - b.cfg.Set(botconfigkey, cfg) - return utils.UnwrapError(b.lp.GetClient().SetAccountData(botconfigkey, cfg)) -} diff --git a/bot/email.go b/bot/email.go index cf8b10a..e4cbd4a 100644 --- a/bot/email.go +++ b/bot/email.go @@ -12,7 +12,7 @@ import ( "gitlab.com/etke.cc/postmoogle/utils" ) -func email2content(email *utils.Email, cfg settings, threadID id.EventID) *event.Content { +func email2content(email *utils.Email, cfg roomsettings, threadID id.EventID) *event.Content { var text strings.Builder if !cfg.NoSender() { text.WriteString("From: ") @@ -66,7 +66,7 @@ func (b *Bot) Send(ctx context.Context, email *utils.Email) error { b.lock(roomID) defer b.unlock(roomID) - cfg, err := b.getSettings(roomID) + cfg, err := b.getRoomSettings(roomID) if err != nil { b.Error(ctx, roomID, "cannot get settings: %v", err) } diff --git a/bot/settings_bot.go b/bot/settings_bot.go new file mode 100644 index 0000000..be057b4 --- /dev/null +++ b/bot/settings_bot.go @@ -0,0 +1,73 @@ +package bot + +import ( + "strings" + + "gitlab.com/etke.cc/postmoogle/utils" +) + +// account data key +const botsettingskey = "cc.etke.postmoogle.config" + +// bot options keys +const ( + botOptionUsers = "users" +) + +type botsettings map[string]string + +// Get option +func (s botsettings) Get(key string) string { + return s[strings.ToLower(strings.TrimSpace(key))] +} + +// Set option +func (s botsettings) Set(key, value string) { + s[strings.ToLower(strings.TrimSpace(key))] = value +} + +// Users option +func (s botsettings) Users() []string { + return strings.Split(s.Get(botOptionUsers), " ") +} + +// TODO: remove after migration +func (b *Bot) migrateBotSettings(users []string) error { + config := b.getBotSettings() + cfgUsers := config.Users() + if len(users) > 0 && len(cfgUsers) == 0 { + _, err := parseMXIDpatterns(users, "") + if err != nil { + return err + } + config.Set(botOptionUsers, strings.Join(users, " ")) + return b.setBotSettings(config) + } + + return nil +} + +func (b *Bot) getBotSettings() botsettings { + cfg := b.botcfg.Get(botsettingskey) + if cfg != nil { + return cfg + } + + config := botsettings{} + err := b.lp.GetClient().GetAccountData(botsettingskey, &config) + if err != nil { + if strings.Contains(err.Error(), "M_NOT_FOUND") { + err = nil + } + b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) + } else { + b.botcfg.Set(botsettingskey, config) + } + + return config +} + +func (b *Bot) setBotSettings(cfg botsettings) error { + b.botcfg.Set(botsettingskey, cfg) + return utils.UnwrapError(b.lp.GetClient().SetAccountData(botsettingskey, cfg)) +} diff --git a/bot/settings.go b/bot/settings_room.go similarity index 59% rename from bot/settings.go rename to bot/settings_room.go index 66bb29a..9ab0037 100644 --- a/bot/settings.go +++ b/bot/settings_room.go @@ -9,8 +9,21 @@ import ( "gitlab.com/etke.cc/postmoogle/utils" ) -// settings of a room -type settings map[string]string +// account data key +const roomsettingskey = "cc.etke.postmoogle.settings" + +// option keys +const ( + optionOwner = "owner" + optionMailbox = "mailbox" + optionNoSender = "nosender" + optionNoSubject = "nosubject" + optionNoHTML = "nohtml" + optionNoThreads = "nothreads" + optionNoFiles = "nofiles" +) + +type roomsettings map[string]string // settingsOld of a room type settingsOld struct { @@ -20,52 +33,47 @@ type settingsOld struct { } // Get option -func (s settings) Get(key string) string { +func (s roomsettings) Get(key string) string { return s[strings.ToLower(strings.TrimSpace(key))] } -func (s settings) Mailbox() string { +// Set option +func (s roomsettings) Set(key, value string) { + s[strings.ToLower(strings.TrimSpace(key))] = value +} + +func (s roomsettings) Mailbox() string { return s.Get(optionMailbox) } -func (s settings) Owner() string { +func (s roomsettings) Owner() string { return s.Get(optionOwner) } -func (s settings) NoSender() bool { +func (s roomsettings) NoSender() bool { return utils.Bool(s.Get(optionNoSender)) } -func (s settings) NoSubject() bool { +func (s roomsettings) NoSubject() bool { return utils.Bool(s.Get(optionNoSubject)) } -func (s settings) NoHTML() bool { +func (s roomsettings) NoHTML() bool { return utils.Bool(s.Get(optionNoHTML)) } -func (s settings) NoThreads() bool { +func (s roomsettings) NoThreads() bool { return utils.Bool(s.Get(optionNoThreads)) } -func (s settings) NoFiles() bool { +func (s roomsettings) NoFiles() bool { return utils.Bool(s.Get(optionNoFiles)) } -// Users is bot/admin option -func (s settings) Users() []string { - return strings.Split(s.Get(botOptionUsers), " ") -} - -// Set option -func (s settings) Set(key, value string) { - s[strings.ToLower(strings.TrimSpace(key))] = value -} - // TODO: remove after migration func (b *Bot) migrateSettings(roomID id.RoomID) { var config settingsOld - err := b.lp.GetClient().GetRoomAccountData(roomID, settingskey, &config) + err := b.lp.GetClient().GetRoomAccountData(roomID, roomsettingskey, &config) if err != nil { // any error = no need to migrate return @@ -74,25 +82,25 @@ func (b *Bot) migrateSettings(roomID id.RoomID) { if config.Mailbox == "" { return } - cfg := settings{} + cfg := roomsettings{} cfg.Set(optionMailbox, config.Mailbox) cfg.Set(optionOwner, config.Owner.String()) cfg.Set(optionNoSender, strconv.FormatBool(config.NoSender)) - err = b.setSettings(roomID, cfg) + err = b.setRoomSettings(roomID, cfg) if err != nil { b.log.Error("cannot migrate settings: %v", err) } } -func (b *Bot) getSettings(roomID id.RoomID) (settings, error) { +func (b *Bot) getRoomSettings(roomID id.RoomID) (roomsettings, error) { cfg := b.cfg.Get(roomID.String()) if cfg != nil { return cfg, nil } - config := settings{} - err := b.lp.GetClient().GetRoomAccountData(roomID, settingskey, &config) + config := roomsettings{} + err := b.lp.GetClient().GetRoomAccountData(roomID, roomsettingskey, &config) if err != nil { if strings.Contains(err.Error(), "M_NOT_FOUND") { // Suppress `M_NOT_FOUND (HTTP 404): Room account data not found` errors. @@ -107,7 +115,7 @@ func (b *Bot) getSettings(roomID id.RoomID) (settings, error) { return config, utils.UnwrapError(err) } -func (b *Bot) setSettings(roomID id.RoomID, cfg settings) error { +func (b *Bot) setRoomSettings(roomID id.RoomID, cfg roomsettings) error { b.cfg.Set(roomID.String(), cfg) - return utils.UnwrapError(b.lp.GetClient().SetRoomAccountData(roomID, settingskey, cfg)) + return utils.UnwrapError(b.lp.GetClient().SetRoomAccountData(roomID, roomsettingskey, cfg)) }