mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-12-20 11:51:17 +00:00
[counter] Allow counterTopList
to specify how to sort
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
94b040ed81
commit
293a7d9e30
4 changed files with 69 additions and 10 deletions
|
@ -128,9 +128,9 @@ Example:
|
|||
|
||||
### `counterTopList`
|
||||
|
||||
Returns the top n counters for the given prefix as objects with Name and Value fields
|
||||
Returns the top n counters for the given prefix as objects with Name and Value fields. Can be ordered by `name` / `value` / `first_seen` / `last_modified` ascending (`ASC`) or descending (`DESC`): i.e. `last_modified DESC` defaults to `value DESC`
|
||||
|
||||
Syntax: `counterTopList <prefix> <n>`
|
||||
Syntax: `counterTopList <prefix> <n> [orderBy]`
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -467,7 +467,7 @@ Example:
|
|||
|
||||
```
|
||||
# Your int this hour: {{ printf "%.0f" (mulf (seededRandom (list "int" .username (now | date "2006-01-02 15") | join ":")) 100) }}%
|
||||
< Your int this hour: 70%
|
||||
< Your int this hour: 88%
|
||||
```
|
||||
|
||||
### `spotifyCurrentPlaying`
|
||||
|
|
|
@ -166,11 +166,11 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
},
|
||||
})
|
||||
|
||||
args.RegisterTemplateFunction("counterTopList", plugins.GenericTemplateFunctionGetter(func(prefix string, n int) ([]counter, error) {
|
||||
return getCounterTopList(db, prefix, n)
|
||||
args.RegisterTemplateFunction("counterTopList", plugins.GenericTemplateFunctionGetter(func(prefix string, n int, orderBy string) ([]counter, error) {
|
||||
return getCounterTopList(db, prefix, n, orderBy)
|
||||
}), plugins.TemplateFuncDocumentation{
|
||||
Description: "Returns the top n counters for the given prefix as objects with Name and Value fields",
|
||||
Syntax: `counterTopList <prefix> <n>`,
|
||||
Description: "Returns the top n counters for the given prefix as objects with Name and Value fields. Can be ordered by `name` / `value` / `first_seen` / `last_modified` ascending (`ASC`) or descending (`DESC`): i.e. `last_modified DESC` defaults to `value DESC`",
|
||||
Syntax: `counterTopList <prefix> <n> [orderBy]`,
|
||||
Example: &plugins.TemplateFuncDocumentationExample{
|
||||
Template: `{{ range (counterTopList (list .channel "test" "" | join ":") 3) }}{{ .Name }}: {{ .Value }} - {{ end }}`,
|
||||
FakedOutput: "#example:test:foo: 5 - #example:test:bar: 4 - ",
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package counter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
|
||||
"github.com/Luzifer/go_helpers/v2/str"
|
||||
"github.com/Luzifer/twitch-bot/v3/internal/helpers"
|
||||
"github.com/Luzifer/twitch-bot/v3/pkg/database"
|
||||
)
|
||||
|
@ -79,12 +82,39 @@ func getCounterRank(db database.Connector, prefix, name string) (rank, count int
|
|||
return rank, count, nil
|
||||
}
|
||||
|
||||
func getCounterTopList(db database.Connector, prefix string, n int) ([]counter, error) {
|
||||
var cc []counter
|
||||
func getCounterTopList(db database.Connector, prefix string, n int, orderBy ...string) ([]counter, error) {
|
||||
var (
|
||||
cc []counter
|
||||
|
||||
order string
|
||||
validOrderCols = []string{"first_seen", "last_modified", "name", "value"}
|
||||
validOrderDirs = []string{"ASC", "DESC"}
|
||||
)
|
||||
|
||||
if len(orderBy) == 0 || orderBy[0] == "" {
|
||||
order = "value DESC"
|
||||
} else {
|
||||
order = orderBy[0]
|
||||
}
|
||||
|
||||
col, dir, _ := strings.Cut(order, " ")
|
||||
if col == "" {
|
||||
col = "value"
|
||||
}
|
||||
if dir == "" {
|
||||
dir = "ASC"
|
||||
}
|
||||
|
||||
if !str.StringInSlice(col, validOrderCols) {
|
||||
return nil, fmt.Errorf("invalid orderBy column")
|
||||
}
|
||||
if !str.StringInSlice(dir, validOrderDirs) {
|
||||
return nil, fmt.Errorf("invalid orderBy direction")
|
||||
}
|
||||
|
||||
err := helpers.Retry(func() error {
|
||||
return db.DB().
|
||||
Order("value DESC").
|
||||
Order(strings.Join([]string{col, dir}, " ")).
|
||||
Limit(n).
|
||||
Find(&cc, "name LIKE ?", prefix+"%").
|
||||
Error
|
||||
|
|
|
@ -64,6 +64,35 @@ func TestCounterTopListAndRank(t *testing.T) {
|
|||
{Name: "#example:test:3", Value: 3, FirstSeen: testTime, LastModified: testTime},
|
||||
}, cc)
|
||||
|
||||
cc, err = getCounterTopList(dbc, fmt.Sprintf(counterTemplate, ""), 3, "name DESC")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, cc, 3)
|
||||
|
||||
assert.Equal(t, []counter{
|
||||
{Name: "#example:test:5", Value: 5, FirstSeen: testTime, LastModified: testTime},
|
||||
{Name: "#example:test:4", Value: 4, FirstSeen: testTime, LastModified: testTime},
|
||||
{Name: "#example:test:3", Value: 3, FirstSeen: testTime, LastModified: testTime},
|
||||
}, cc)
|
||||
|
||||
cc, err = getCounterTopList(dbc, fmt.Sprintf(counterTemplate, ""), 3, "name")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, cc, 3)
|
||||
|
||||
assert.Equal(t, []counter{
|
||||
{Name: "#example:test:0", Value: 0, FirstSeen: testTime, LastModified: testTime},
|
||||
{Name: "#example:test:1", Value: 1, FirstSeen: testTime, LastModified: testTime},
|
||||
{Name: "#example:test:2", Value: 2, FirstSeen: testTime, LastModified: testTime},
|
||||
}, cc)
|
||||
|
||||
_, err = getCounterTopList(dbc, fmt.Sprintf(counterTemplate, ""), 3, "foobar")
|
||||
assert.Error(t, err)
|
||||
|
||||
_, err = getCounterTopList(dbc, fmt.Sprintf(counterTemplate, ""), 3, "name foo")
|
||||
assert.Error(t, err)
|
||||
|
||||
_, err = getCounterTopList(dbc, fmt.Sprintf(counterTemplate, ""), 3, "name ASC; DROP TABLE counters;")
|
||||
assert.Error(t, err)
|
||||
|
||||
rank, count, err := getCounterRank(dbc,
|
||||
fmt.Sprintf(counterTemplate, ""),
|
||||
fmt.Sprintf(counterTemplate, 4))
|
||||
|
|
Loading…
Reference in a new issue