refactor: remove jsoniter

This commit is contained in:
Ash Keel 2024-03-15 23:48:34 +01:00
parent edcc4fb7f9
commit ce2ce81768
No known key found for this signature in database
GPG Key ID: 53A9E9A6035DD109
15 changed files with 147 additions and 133 deletions

12
app.go
View File

@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
@ -15,6 +16,11 @@ import (
"git.sr.ht/~ashkeel/containers/sync"
kv "git.sr.ht/~ashkeel/kilovolt/v12"
"github.com/nicklaw5/helix/v2"
"github.com/urfave/cli/v2"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/runtime"
"git.sr.ht/~ashkeel/strimertul/database"
"git.sr.ht/~ashkeel/strimertul/docs"
"git.sr.ht/~ashkeel/strimertul/loyalty"
@ -22,10 +28,6 @@ import (
"git.sr.ht/~ashkeel/strimertul/twitch"
"git.sr.ht/~ashkeel/strimertul/twitch/client"
"git.sr.ht/~ashkeel/strimertul/webserver"
"github.com/nicklaw5/helix/v2"
"github.com/urfave/cli/v2"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
// App struct
@ -155,7 +157,7 @@ func (a *App) initializeComponents() error {
}
// Initialize loyalty system
a.loyaltyManager, err = loyalty.NewManager(a.db)
a.loyaltyManager, err = loyalty.NewManager(a.db, a.twitchManager)
if err != nil {
return fmt.Errorf("could not initialize loyalty manager: %w", err)
}

View File

@ -1,6 +1,7 @@
package main
import (
"encoding/json"
"log/slog"
"os"

View File

@ -1,13 +1,12 @@
package database
import (
"encoding/json"
"errors"
"testing"
"time"
kv "git.sr.ht/~ashkeel/kilovolt/v12"
jsoniter "github.com/json-iterator/go"
)
func TestLocalDBClientPutKey(t *testing.T) {
@ -60,7 +59,7 @@ func TestLocalDBClientPutJSON(t *testing.T) {
}
var testStored test
err = jsoniter.ConfigFastest.UnmarshalFromString(stored, &testStored)
err = json.Unmarshal([]byte(stored), &testStored)
if err != nil {
t.Fatal(err)
}
@ -107,13 +106,13 @@ func TestLocalDBClientPutJSONBulk(t *testing.T) {
}
var testStored1 test
err = jsoniter.ConfigFastest.UnmarshalFromString(keys["test"], &testStored1)
err = json.Unmarshal([]byte(keys["test"]), &testStored1)
if err != nil {
t.Fatal(err)
}
var testStored2 test
err = jsoniter.ConfigFastest.UnmarshalFromString(keys["test2"], &testStored2)
err = json.Unmarshal([]byte(keys["test2"]), &testStored2)
if err != nil {
t.Fatal(err)
}
@ -171,12 +170,12 @@ func TestLocalDBClientGetJSON(t *testing.T) {
// Store a key directly in the store
key := "test"
byt, err := jsoniter.ConfigFastest.MarshalToString(testStruct)
byt, err := json.Marshal(testStruct)
if err != nil {
t.Fatal(err)
}
err = store.Set(key, byt)
err = store.Set(key, string(byt))
if err != nil {
t.Fatal(err)
}

View File

@ -1,14 +1,14 @@
package main
import (
"encoding/json"
"os"
"git.sr.ht/~ashkeel/strimertul/docs"
jsoniter "github.com/json-iterator/go"
)
func main() {
enc := jsoniter.ConfigFastest.NewEncoder(os.Stdout)
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(docs.Keys)
}

3
go.mod
View File

@ -13,7 +13,6 @@ require (
github.com/cockroachdb/pebble v1.1.0
github.com/gorilla/websocket v1.5.1
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/json-iterator/go v1.1.12
github.com/nicklaw5/helix/v2 v2.28.1
github.com/samber/slog-multi v1.0.2
github.com/urfave/cli/v2 v2.27.1
@ -59,8 +58,6 @@ require (
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.12.0 // indirect

3
go.sum
View File

@ -193,7 +193,6 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
@ -245,11 +244,9 @@ github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFW
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=

View File

@ -2,6 +2,7 @@ package main
import (
"context"
"encoding/json"
"fmt"
"log/slog"
"math/rand"
@ -66,7 +67,7 @@ func (core *LogStorage) Handle(_ context.Context, record slog.Record) error {
attributes[attrs.Key] = attrs.Value.Any()
return true
})
attrJSON, _ := json.MarshalToString(attributes)
attrJSON, _ := json.Marshal(attributes)
// Generate unique log ID
id := fmt.Sprintf("%d-%d", time.Now().UnixNano(), rand.Int31())
@ -76,7 +77,7 @@ func (core *LogStorage) Handle(_ context.Context, record slog.Record) error {
Time: record.Time.Format(time.RFC3339),
Level: record.Level.String(),
Message: record.Message,
Data: attrJSON,
Data: string(attrJSON),
}
lastLogs.Push(logEntry)
if lastLogs.Size() > LogHistory {

View File

@ -1,19 +1,19 @@
package chat
package loyalty
import (
"context"
"errors"
"fmt"
"log/slog"
"strconv"
"strings"
"time"
"git.sr.ht/~ashkeel/strimertul/twitch"
"github.com/nicklaw5/helix/v2"
"git.sr.ht/~ashkeel/containers/sync"
"git.sr.ht/~ashkeel/strimertul/loyalty"
"github.com/nicklaw5/helix/v2"
"git.sr.ht/~ashkeel/strimertul/twitch"
"git.sr.ht/~ashkeel/strimertul/twitch/chat"
)
const (
@ -23,49 +23,49 @@ const (
commandContribute = "!contribute"
)
type loyaltyIntegration struct {
type twitchIntegration struct {
ctx context.Context
manager *loyalty.Manager
module *Module
manager *Manager
module *chat.Module
activeUsers *sync.Map[string, bool]
}
func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.Manager) *loyaltyIntegration {
li := &loyaltyIntegration{
func setupTwitchIntegration(ctx context.Context, m *Manager, mod *chat.Module) *twitchIntegration {
li := &twitchIntegration{
ctx: ctx,
manager: manager,
manager: m,
module: mod,
activeUsers: sync.NewMap[string, bool](),
}
// Add loyalty-based commands
mod.commands.SetKey(commandRedeem, Command{
mod.RegisterCommand(commandRedeem, chat.Command{
Description: "Redeem a reward with loyalty points",
Usage: fmt.Sprintf("%s <reward-id> [request text]", commandRedeem),
AccessLevel: ALTEveryone,
AccessLevel: chat.ALTEveryone,
Handler: li.cmdRedeemReward,
Enabled: true,
})
mod.commands.SetKey(commandBalance, Command{
mod.RegisterCommand(commandBalance, chat.Command{
Description: "See your current point balance",
Usage: commandBalance,
AccessLevel: ALTEveryone,
AccessLevel: chat.ALTEveryone,
Handler: li.cmdBalance,
Enabled: true,
})
mod.commands.SetKey(commandGoals, Command{
mod.RegisterCommand(commandGoals, chat.Command{
Description: "Check currently active community goals",
Usage: commandGoals,
AccessLevel: ALTEveryone,
AccessLevel: chat.ALTEveryone,
Handler: li.cmdGoalList,
Enabled: true,
})
mod.commands.SetKey(commandContribute, Command{
mod.RegisterCommand(commandContribute, chat.Command{
Description: "Contribute points to a community goal",
Usage: fmt.Sprintf("%s <points> [<goal-id>]", commandContribute),
AccessLevel: ALTEveryone,
AccessLevel: chat.ALTEveryone,
Handler: li.cmdContributeGoal,
Enabled: true,
})
@ -87,9 +87,9 @@ func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.
// If stream is confirmed offline, don't give points away!
var streamInfos []helix.Stream
err := mod.db.GetJSON(twitch.StreamInfoKey, &streamInfos)
err := m.db.GetJSON(twitch.StreamInfoKey, &streamInfos)
if err != nil {
mod.logger.Error("Error retrieving stream info", "error", err)
slog.Error("Error retrieving stream info", "error", err)
continue
}
if len(streamInfos) < 1 {
@ -97,32 +97,7 @@ func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.
}
// Get user list
cursor := ""
var users []string
for {
userClient, err := twitch.GetUserClient(mod.db, false)
if err != nil {
mod.logger.Error("Could not get user api client for list of chatters", "error", err)
return
}
res, err := userClient.GetChannelChatChatters(&helix.GetChatChattersParams{
BroadcasterID: mod.user.ID,
ModeratorID: mod.user.ID,
First: "1000",
After: cursor,
})
if err != nil {
mod.logger.Error("Could not retrieve list of chatters", "error", err)
return
}
for _, user := range res.Data.Chatters {
users = append(users, user.UserLogin)
}
cursor = res.Data.Pagination.Cursor
if cursor == "" {
break
}
}
users := mod.GetChatters()
// Iterate for each user in the list
pointsToGive := make(map[string]int64)
@ -148,48 +123,48 @@ func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.
if len(users) > 0 {
err := li.manager.GivePoints(pointsToGive)
if err != nil {
mod.logger.Error("Error awarding loyalty points to user", "error", err)
slog.Error("Error awarding loyalty points to user", "error", err)
}
}
}
}()
mod.logger.Info("Loyalty system integration with Twitch is ready")
slog.Info("Loyalty system integration with Twitch is ready")
return li
}
func (li *loyaltyIntegration) Close() {
li.module.commands.DeleteKey(commandRedeem)
li.module.commands.DeleteKey(commandBalance)
li.module.commands.DeleteKey(commandGoals)
li.module.commands.DeleteKey(commandContribute)
func (li *twitchIntegration) Close() {
li.module.UnregisterCommand(commandRedeem)
li.module.UnregisterCommand(commandBalance)
li.module.UnregisterCommand(commandGoals)
li.module.UnregisterCommand(commandContribute)
}
func (li *loyaltyIntegration) HandleMessage(message helix.EventSubChannelChatMessageEvent) {
func (li *twitchIntegration) HandleMessage(message helix.EventSubChannelChatMessageEvent) {
li.activeUsers.SetKey(message.ChatterUserLogin, true)
}
func (li *loyaltyIntegration) IsActive(user string) bool {
func (li *twitchIntegration) IsActive(user string) bool {
active, ok := li.activeUsers.GetKey(user)
return ok && active
}
func (li *loyaltyIntegration) ResetActivity() {
func (li *twitchIntegration) ResetActivity() {
li.activeUsers = sync.NewMap[string, bool]()
}
func (li *loyaltyIntegration) cmdBalance(message helix.EventSubChannelChatMessageEvent) {
func (li *twitchIntegration) cmdBalance(message helix.EventSubChannelChatMessageEvent) {
// Get user balance
balance := li.manager.GetPoints(message.ChatterUserLogin)
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: fmt.Sprintf("You have %d %s!", balance, li.manager.Config.Get().Currency),
ReplyTo: message.MessageID,
})
}
func (li *loyaltyIntegration) cmdRedeemReward(message helix.EventSubChannelChatMessageEvent) {
func (li *twitchIntegration) cmdRedeemReward(message helix.EventSubChannelChatMessageEvent) {
parts := strings.Fields(message.Message.Text)
if len(parts) < 2 {
return
@ -213,7 +188,7 @@ func (li *loyaltyIntegration) cmdRedeemReward(message helix.EventSubChannelChatM
// Check if user can afford the reward
if balance-reward.Price < 0 {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: fmt.Sprintf("I'm sorry but you cannot afford this (have %d %s, need %d)", balance, config.Currency, reward.Price),
ReplyTo: message.MessageID,
})
@ -226,36 +201,36 @@ func (li *loyaltyIntegration) cmdRedeemReward(message helix.EventSubChannelChatM
}
// Perform redeem
if err := li.manager.PerformRedeem(loyalty.Redeem{
if err := li.manager.PerformRedeem(Redeem{
Username: message.ChatterUserLogin,
DisplayName: message.ChatterUserName,
When: time.Now(),
Reward: reward,
RequestText: text,
}); err != nil {
if errors.Is(err, loyalty.ErrRedeemInCooldown) {
if errors.Is(err, ErrRedeemInCooldown) {
nextAvailable := li.manager.GetRewardCooldown(reward.ID)
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: fmt.Sprintf("That reward is in cooldown (available in %s)",
time.Until(nextAvailable).Truncate(time.Second)),
ReplyTo: message.MessageID,
})
return
}
li.module.logger.Error("Error while performing redeem", "error", err)
slog.Error("Error while performing redeem", "error", err)
return
}
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: fmt.Sprintf("HolidayPresent %s has redeemed %s! (new balance: %d %s)",
message.ChatterUserName, reward.Name, li.manager.GetPoints(message.ChatterUserLogin), config.Currency),
})
}
func (li *loyaltyIntegration) cmdGoalList(message helix.EventSubChannelChatMessageEvent) {
func (li *twitchIntegration) cmdGoalList(message helix.EventSubChannelChatMessageEvent) {
goals := li.manager.Goals.Get()
if len(goals) < 1 {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: "There are no active community goals right now :(!",
ReplyTo: message.MessageID,
})
@ -269,12 +244,12 @@ func (li *loyaltyIntegration) cmdGoalList(message helix.EventSubChannelChatMessa
msg += fmt.Sprintf("%s (%d/%d %s) [id: %s] | ", goal.Name, goal.Contributed, goal.TotalGoal, li.manager.Config.Get().Currency, goal.ID)
}
msg += " Contribute with <!contribute POINTS GOALID>"
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: msg,
})
}
func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelChatMessageEvent) {
func (li *twitchIntegration) cmdContributeGoal(message helix.EventSubChannelChatMessageEvent) {
goals := li.manager.Goals.Get()
// Set defaults if user doesn't provide them
@ -297,12 +272,12 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
// Do we not have any goal we can contribute to? Hooray I guess?
if goalIndex < 0 {
if hasGoals {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: "All active community goals have been reached already! NewRecord",
ReplyTo: message.MessageID,
})
} else {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: "There are no active community goals right now :(!",
ReplyTo: message.MessageID,
})
@ -316,7 +291,7 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
newPoints, err := strconv.ParseInt(parts[1], 10, 64)
if err == nil {
if newPoints <= 0 {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: "Nice try SoBayed",
ReplyTo: message.MessageID,
})
@ -340,7 +315,7 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
}
// Invalid goal ID provided
if !found {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: "I couldn't find that goal ID :(",
ReplyTo: message.MessageID,
})
@ -354,7 +329,7 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
// Check if goal was reached already
if selectedGoal.Contributed >= selectedGoal.TotalGoal {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: "This goal was already reached! ヾ(•ω•`)o",
ReplyTo: message.MessageID,
})
@ -364,11 +339,11 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
// Add points to goal
points, err := li.manager.PerformContribution(selectedGoal, message.ChatterUserLogin, points)
if err != nil {
li.module.logger.Error("Error while contributing to goal", "error", err)
slog.Error("Error while contributing to goal", "error", err)
return
}
if points == 0 {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: "Sorry but you're broke",
ReplyTo: message.MessageID,
})
@ -378,13 +353,13 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
selectedGoal = li.manager.Goals.Get()[goalIndex]
config := li.manager.Config.Get()
newRemaining := selectedGoal.TotalGoal - selectedGoal.Contributed
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: fmt.Sprintf("NewRecord %s contributed %d %s to \"%s\"!! Only %d %s left!", message.ChatterUserName, points, config.Currency, selectedGoal.Name, newRemaining, config.Currency),
})
// Check if goal was reached!
if newRemaining <= 0 {
li.module.WriteMessage(WriteMessageRequest{
li.module.WriteMessage(chat.WriteMessageRequest{
Message: fmt.Sprintf("FallWinning The community goal \"%s\" was reached! FallWinning", selectedGoal.Name),
Announce: true,
})

View File

@ -2,6 +2,7 @@ package loyalty
import (
"context"
"encoding/json"
"errors"
"fmt"
"log/slog"
@ -10,12 +11,10 @@ import (
"git.sr.ht/~ashkeel/containers/sync"
"git.sr.ht/~ashkeel/strimertul/database"
twitchclient "git.sr.ht/~ashkeel/strimertul/twitch/client"
"git.sr.ht/~ashkeel/strimertul/utils"
jsoniter "github.com/json-iterator/go"
)
var json = jsoniter.ConfigFastest
var (
ErrRedeemNotFound = errors.New("redeem not found")
ErrRedeemInCooldown = errors.New("redeem is on cooldown")
@ -36,9 +35,11 @@ type Manager struct {
cancelFn context.CancelFunc
cancelSub database.CancelFunc
restartTwitchHandler chan struct{}
twitchManager *twitchclient.Manager
twitchIntegration *twitchIntegration
}
func NewManager(db database.Database) (*Manager, error) {
func NewManager(db database.Database, twitchManager *twitchclient.Manager) (*Manager, error) {
ctx, cancelFn := context.WithCancel(context.Background())
loyalty := &Manager{
Config: sync.NewRWSync(Config{Enabled: false}),
@ -53,6 +54,7 @@ func NewManager(db database.Database) (*Manager, error) {
ctx: ctx,
cancelFn: cancelFn,
restartTwitchHandler: make(chan struct{}),
twitchManager: twitchManager,
}
// Get data from DB
var config Config
@ -103,7 +105,7 @@ func NewManager(db database.Database) (*Manager, error) {
for k, v := range points {
var entry PointsEntry
err := json.UnmarshalFromString(v, &entry)
err := json.Unmarshal([]byte(v), &entry)
if err != nil {
return nil, err
}
@ -119,10 +121,20 @@ func NewManager(db database.Database) (*Manager, error) {
loyalty.SetBanList(config.BanList)
// Start twitch handler
if twitchManager.Client() != nil {
loyalty.twitchIntegration = setupTwitchIntegration(ctx, loyalty, twitchManager.Client().Chat)
}
return loyalty, nil
}
func (m *Manager) Close() error {
// Disable twitch integration
if m.twitchIntegration != nil {
m.twitchIntegration.Close()
}
// Stop subscription
if m.cancelSub != nil {
m.cancelSub()
@ -152,13 +164,13 @@ func (m *Manager) update(key, value string) {
err = utils.LoadJSONToWrapped[[]Redeem](value, m.Queue)
case CreateRedeemRPC:
var redeem Redeem
err = json.UnmarshalFromString(value, &redeem)
err = json.Unmarshal([]byte(value), &redeem)
if err == nil {
err = m.AddRedeem(redeem)
}
case RemoveRedeemRPC:
var redeem Redeem
err = json.UnmarshalFromString(value, &redeem)
err = json.Unmarshal([]byte(value), &redeem)
if err == nil {
err = m.RemoveRedeem(redeem)
}
@ -168,7 +180,7 @@ func (m *Manager) update(key, value string) {
// User point changed
case strings.HasPrefix(key, PointsPrefix):
var entry PointsEntry
err = json.UnmarshalFromString(value, &entry)
err = json.Unmarshal([]byte(value), &entry)
user := key[len(PointsPrefix):]
m.points.SetKey(user, entry)
}

View File

@ -12,7 +12,6 @@ import (
"git.sr.ht/~ashkeel/strimertul/utils"
"github.com/apenwarr/fixconsole"
jsoniter "github.com/json-iterator/go"
"github.com/urfave/cli/v2"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/options"
@ -20,8 +19,6 @@ import (
"github.com/wailsapp/wails/v2/pkg/runtime"
)
var json = jsoniter.ConfigFastest
const devVersionMarker = "v0.0.0-UNKNOWN"
var appVersion = devVersionMarker

View File

@ -1,7 +1,8 @@
package alerts
import (
jsoniter "github.com/json-iterator/go"
"encoding/json"
"github.com/nicklaw5/helix/v2"
)
@ -10,7 +11,7 @@ const ConfigKey = "twitch/alerts/config"
type eventSubNotification struct {
Subscription helix.EventSubSubscription `json:"subscription"`
Challenge string `json:"challenge"`
Event jsoniter.RawMessage `json:"event" desc:"Event payload, as JSON object"`
Event json.RawMessage `json:"event" desc:"Event payload, as JSON object"`
}
type subscriptionVariation struct {

View File

@ -2,23 +2,23 @@ package chat
import (
"context"
"encoding/json"
"errors"
"log/slog"
"strings"
textTemplate "text/template"
"time"
"github.com/nicklaw5/helix/v2"
"git.sr.ht/~ashkeel/containers/sync"
"git.sr.ht/~ashkeel/strimertul/database"
"git.sr.ht/~ashkeel/strimertul/twitch"
"git.sr.ht/~ashkeel/strimertul/twitch/eventsub"
"git.sr.ht/~ashkeel/strimertul/twitch/template"
"git.sr.ht/~ashkeel/strimertul/utils"
jsoniter "github.com/json-iterator/go"
"github.com/nicklaw5/helix/v2"
)
var json = jsoniter.ConfigFastest
type Module struct {
Config Config
@ -97,8 +97,8 @@ func (mod *Module) onChatMessage(newValue string) {
var chatMessage struct {
Event helix.EventSubChannelChatMessageEvent `json:"event"`
}
if err := json.UnmarshalFromString(newValue, &chatMessage); err != nil {
mod.logger.Error("Failed to decode incoming chat message", "error", err)
if err := json.Unmarshal([]byte(newValue), &chatMessage); err != nil {
mod.logger.Error("Failed to decode incoming chat message", slog.String("error", err.Error()))
return
}
@ -222,3 +222,39 @@ func (mod *Module) updateTemplates() error {
func (mod *Module) WriteMessage(request WriteMessageRequest) {
WriteMessage(mod.db, mod.logger, request)
}
func (mod *Module) RegisterCommand(name string, command Command) {
mod.commands.SetKey(name, command)
}
func (mod *Module) UnregisterCommand(name string) {
mod.commands.DeleteKey(name)
}
func (mod *Module) GetChatters() (users []string) {
cursor := ""
for {
userClient, err := twitch.GetUserClient(mod.db, false)
if err != nil {
slog.Error("Could not get user api client for list of chatters", "error", err)
return
}
res, err := userClient.GetChannelChatChatters(&helix.GetChatChattersParams{
BroadcasterID: mod.user.ID,
ModeratorID: mod.user.ID,
First: "1000",
After: cursor,
})
if err != nil {
mod.logger.Error("Could not retrieve list of chatters", "error", err)
return
}
for _, user := range res.Data.Chatters {
users = append(users, user.UserLogin)
}
cursor = res.Data.Pagination.Cursor
if cursor == "" {
return
}
}
}

View File

@ -2,6 +2,7 @@ package eventsub
import (
"context"
"encoding/json"
"fmt"
"log/slog"
"time"
@ -10,12 +11,9 @@ import (
"git.sr.ht/~ashkeel/strimertul/utils"
"github.com/gorilla/websocket"
lru "github.com/hashicorp/golang-lru/v2"
jsoniter "github.com/json-iterator/go"
"github.com/nicklaw5/helix/v2"
)
var json = jsoniter.ConfigFastest
const websocketEndpoint = "wss://eventsub.wss.twitch.tv/ws"
type Client struct {
@ -259,8 +257,8 @@ func topicCondition(topic string, id string) helix.EventSubCondition {
}
type WebsocketMessage struct {
Metadata Metadata `json:"metadata"`
Payload jsoniter.RawMessage `json:"payload"`
Metadata Metadata `json:"metadata"`
Payload json.RawMessage `json:"payload"`
}
type WelcomeMessagePayload struct {
@ -275,7 +273,7 @@ type WelcomeMessagePayload struct {
type NotificationMessagePayload struct {
Subscription helix.EventSubSubscription `json:"subscription"`
Event jsoniter.RawMessage `json:"event"`
Event json.RawMessage `json:"event"`
Date time.Time `json:"date,omitempty"`
}

View File

@ -2,6 +2,7 @@ package timers
import (
"context"
"encoding/json"
"log/slog"
"math/rand"
"time"
@ -9,11 +10,8 @@ import (
"git.sr.ht/~ashkeel/containers/sync"
"git.sr.ht/~ashkeel/strimertul/database"
"git.sr.ht/~ashkeel/strimertul/twitch/chat"
jsoniter "github.com/json-iterator/go"
)
var json = jsoniter.ConfigFastest
const AverageMessageWindow = 5
type Module struct {
@ -56,7 +54,7 @@ func Setup(ctx context.Context, db database.Database, logger *slog.Logger) *Modu
}
if err := db.SubscribeKeyContext(ctx, ConfigKey, func(value string) {
if err := json.UnmarshalFromString(value, &mod.Config); err != nil {
if err := json.Unmarshal([]byte(value), &mod.Config); err != nil {
logger.Warn("Error reloading timer config", "error", err)
return
}

View File

@ -1,10 +1,10 @@
package utils
import (
"encoding/json"
"testing"
"git.sr.ht/~ashkeel/containers/sync"
jsoniter "github.com/json-iterator/go"
)
func TestLoadJSONToWrapped(t *testing.T) {
@ -17,7 +17,7 @@ func TestLoadJSONToWrapped(t *testing.T) {
}
// Encode test object to JSON
testStr, err := jsoniter.ConfigFastest.MarshalToString(testObj)
testByt, err := json.Marshal(testObj)
if err != nil {
t.Fatal(err)
}
@ -26,7 +26,7 @@ func TestLoadJSONToWrapped(t *testing.T) {
wrapped := sync.NewSync[test](test{})
// Load JSON to wrapped
err = LoadJSONToWrapped[test](testStr, wrapped)
err = LoadJSONToWrapped[test](string(testByt), wrapped)
if err != nil {
t.Fatal(err)
}