From c675d0f65531de251e135ab5b529ea51b01b149b Mon Sep 17 00:00:00 2001 From: rxdn <29165304+rxdn@users.noreply.github.com> Date: Sat, 20 Jul 2024 00:07:55 +0100 Subject: [PATCH] Allow client to request a channel refresh --- app/http/endpoints/api/channels.go | 47 +++++++++++++++---- cmd/api/main.go | 2 +- .../src/components/manage/SettingsCard.svelte | 20 +++++++- redis/channelrefreshcooldown.go | 20 ++++++++ redis/redis.go | 6 +-- 5 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 redis/channelrefreshcooldown.go diff --git a/app/http/endpoints/api/channels.go b/app/http/endpoints/api/channels.go index 2f1e83e..ae6dd34 100644 --- a/app/http/endpoints/api/channels.go +++ b/app/http/endpoints/api/channels.go @@ -1,29 +1,58 @@ package api import ( - "context" - "errors" + "github.com/TicketsBot/GoPanel/botcontext" + "github.com/TicketsBot/GoPanel/redis" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" - cache2 "github.com/rxdn/gdl/cache" "github.com/rxdn/gdl/objects/channel" + "github.com/rxdn/gdl/rest" "sort" ) func ChannelsHandler(ctx *gin.Context) { guildId := ctx.Keys["guildid"].(uint64) - // TODO: Use proper context - channels, err := cache.Instance.GetGuildChannels(context.Background(), guildId) + botContext, err := botcontext.ContextForGuild(guildId) if err != nil { - if errors.Is(err, cache2.ErrNotFound) { - ctx.JSON(200, make([]channel.Channel, 0)) - } else { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + var channels []channel.Channel + if ctx.Query("refresh") == "true" { + hasToken, err := redis.Client.TakeChannelRefreshToken(ctx, guildId) + if err != nil { ctx.JSON(500, utils.ErrorJson(err)) + return } - return + if hasToken { + channels, err = rest.GetGuildChannels(ctx, botContext.Token, botContext.RateLimiter, guildId) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + if err := cache.Instance.StoreChannels(ctx, channels); err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + } else { + channels, err = cache.Instance.GetGuildChannels(ctx, guildId) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + } + } else { + var err error + channels, err = botContext.GetGuildChannels(ctx, guildId) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } } filtered := make([]channel.Channel, 0, len(channels)) diff --git a/cmd/api/main.go b/cmd/api/main.go index 25e07e3..fea32bd 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -81,7 +81,7 @@ func main() { app.StartServer(socketManager) } -func ListenChat(client redis.RedisClient, sm *livechat.SocketManager) { +func ListenChat(client *redis.RedisClient, sm *livechat.SocketManager) { ch := make(chan chatrelay.MessageData) go chatrelay.Listen(client.Client, ch) diff --git a/frontend/src/components/manage/SettingsCard.svelte b/frontend/src/components/manage/SettingsCard.svelte index 5ef1279..886bfd4 100644 --- a/frontend/src/components/manage/SettingsCard.svelte +++ b/frontend/src/components/manage/SettingsCard.svelte @@ -245,8 +245,13 @@ panels = res.data; } - async function loadChannels() { - const res = await axios.get(`${API_URL}/api/${guildId}/channels`); + async function loadChannels(refresh) { + let uri = `${API_URL}/api/${guildId}/channels`; + if (refresh === true) { + uri += "?refresh=true"; + } + + const res = await axios.get(uri); if (res.status !== 200) { notifyError(res.data.error); return; @@ -404,6 +409,17 @@ loadSettings() ]); + if (data.archive_channel && !channels.some(c => c.id === data.archive_channel)) { + await loadChannels(true); + + const tmp = data.archive_channel; + data.archive_channel = null; + + setTimeout(() => { + data.archive_channel = tmp; + }, 100); + } + doOverrides(); // Depends on channels }); diff --git a/redis/channelrefreshcooldown.go b/redis/channelrefreshcooldown.go new file mode 100644 index 0000000..341bccc --- /dev/null +++ b/redis/channelrefreshcooldown.go @@ -0,0 +1,20 @@ +package redis + +import ( + "context" + "fmt" + "time" +) + +const ChannelRefreshCooldown = 60 * time.Second + +func (c *RedisClient) TakeChannelRefreshToken(ctx context.Context, guildId uint64) (bool, error) { + key := fmt.Sprintf("tickets:channelrefershcooldown:%d", guildId) + + res, err := c.SetNX(ctx, key, "1", ChannelRefreshCooldown).Result() + if err != nil { + return false, err + } + + return res, nil +} diff --git a/redis/redis.go b/redis/redis.go index 5781e3f..9193b41 100644 --- a/redis/redis.go +++ b/redis/redis.go @@ -12,16 +12,16 @@ type RedisClient struct { *redis.Client } -var Client RedisClient +var Client *RedisClient -func NewRedisClient() RedisClient { +func NewRedisClient() *RedisClient { client := redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", config.Conf.Redis.Host, config.Conf.Redis.Port), Password: config.Conf.Redis.Password, PoolSize: config.Conf.Redis.Threads, }) - return RedisClient{ + return &RedisClient{ client, } }