matrix-veles/internal/config/helpers.go

182 lines
4.6 KiB
Go

/*
* Copyright © 2022 Kevin Kandlbinder.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package config
import (
"context"
"errors"
"github.com/Unkn0wnCat/matrix-veles/internal/db"
"github.com/Unkn0wnCat/matrix-veles/internal/tracer"
"github.com/spf13/viper"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"maunium.net/go/mautrix/id"
"sync"
)
var (
roomConfigWg sync.WaitGroup
)
// SetRoomConfigActive updates the active state for a given room
func SetRoomConfigActive(id string, active bool) {
// Lock room config system to prevent race conditions
roomConfigWg.Wait()
roomConfigWg.Add(1)
roomConfig := GetRoomConfig(id)
roomConfig.Active = active
err := SaveRoomConfig(&roomConfig)
if err != nil {
log.Panicf("Error writing room config to database: %v", err)
}
// Unlock room config system
roomConfigWg.Done()
}
// GetRoomConfig returns the RoomConfig linked to the specified ID
func GetRoomConfig(id string) RoomConfig {
config, err := GetRoomConfigByRoomID(id)
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return AddRoomConfig(id)
}
}
return *config
}
// RoomConfigInitialUpdate updates all RoomConfig entries to set activity and create blank configs
func RoomConfigInitialUpdate(ids []id.RoomID, parentCtx context.Context) {
ctx, span := tracer.Tracer.Start(parentCtx, "initial_room_config_update")
defer span.End()
_, dbGetAllSpan := tracer.Tracer.Start(ctx, "db_fetch_room_configs")
database := db.DbClient.Database(viper.GetString("bot.mongo.database"))
cursor, err := database.Collection("rooms").Find(context.TODO(), bson.D{}, nil)
if err != nil {
dbGetAllSpan.RecordError(err)
log.Panicf("Error querying room configs: %v", err)
}
var roomConfigs []RoomConfig
err = cursor.All(context.TODO(), &roomConfigs)
if err != nil {
dbGetAllSpan.RecordError(err)
log.Panicf("Error querying room configs: %v", err)
}
dbGetAllSpan.End()
ctx2, updateConfigs := tracer.Tracer.Start(ctx, "update_room_configs")
activeRooms := make(map[string]bool)
// Set all active states to "false" for a blank start
for _, roomConfig := range roomConfigs {
activeRooms[roomConfig.RoomID] = false
}
_, updateRooms := tracer.Tracer.Start(ctx2, "update_joined_rooms")
// Go over all joined rooms
for _, roomID := range ids {
activeRooms[roomID.String()] = true
GetRoomConfig(roomID.String())
}
updateRooms.End()
_, saveConfigs := tracer.Tracer.Start(ctx2, "save_room_configs")
for roomID, isActive := range activeRooms {
SetRoomConfigActive(roomID, isActive)
}
saveConfigs.End()
updateConfigs.End()
}
func AddRoomConfig(id string) RoomConfig {
// Lock room config system to prevent race conditions
roomConfigWg.Wait()
roomConfigWg.Add(1)
config := GetDefaultRoomConfig()
config.RoomID = id
err := SaveRoomConfig(&config)
if err != nil {
log.Panicf("Error writing room config to database: %v", err)
}
// Unlock room config system
roomConfigWg.Done()
return config
}
func SaveRoomConfig(roomConfig *RoomConfig) error {
database := db.DbClient.Database(viper.GetString("bot.mongo.database"))
opts := options.Replace().SetUpsert(true)
filter := bson.D{{"room_id", roomConfig.RoomID}}
_, err := database.Collection(viper.GetString("bot.mongo.collection.rooms")).ReplaceOne(context.TODO(), filter, roomConfig, opts)
return err
}
func GetRoomConfigByRoomID(id string) (*RoomConfig, error) {
database := db.DbClient.Database(viper.GetString("bot.mongo.database"))
res := database.Collection(viper.GetString("bot.mongo.collection.rooms")).FindOne(context.TODO(), bson.D{{"room_id", id}})
if res.Err() != nil {
return nil, res.Err()
}
object := GetDefaultRoomConfig()
err := res.Decode(&object)
if err != nil {
return nil, err
}
return &object, nil
}
func GetDefaultRoomConfig() RoomConfig {
return RoomConfig{
ID: primitive.NewObjectID(),
Active: true,
RoomID: "",
Debug: false,
AdminPowerLevel: 100,
HashChecker: HashCheckerConfig{
NoticeToChat: true,
NotificationPowerLevel: 50,
HashCheckMode: 1,
},
}
}