2020-12-21 00:32:39 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-08-28 15:27:24 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2021-03-06 00:42:40 +00:00
|
|
|
"strconv"
|
|
|
|
|
2021-08-19 13:33:56 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/plugins"
|
2020-12-21 00:32:39 +00:00
|
|
|
"github.com/go-irc/irc"
|
2021-08-28 15:27:24 +00:00
|
|
|
"github.com/gorilla/mux"
|
2020-12-21 00:32:39 +00:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2021-08-19 13:33:56 +00:00
|
|
|
registerAction(func() plugins.Actor { return &ActorCounter{} })
|
2021-08-28 15:27:24 +00:00
|
|
|
|
|
|
|
registerRoute(plugins.HTTPRouteRegistrationArgs{
|
|
|
|
Description: "Returns the (formatted) value as a plain string",
|
|
|
|
HandlerFunc: routeActorCounterGetValue,
|
|
|
|
Method: http.MethodGet,
|
|
|
|
Module: "counter",
|
|
|
|
Name: "Get Counter Value",
|
|
|
|
Path: "/{name}",
|
|
|
|
QueryParams: []plugins.HTTPRouteParamDocumentation{
|
|
|
|
{
|
|
|
|
Description: "Template to apply to the value: Variations of %d sprintf template are supported once",
|
|
|
|
Name: "template",
|
|
|
|
Required: false,
|
|
|
|
Type: "string",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ResponseType: plugins.HTTPRouteResponseTypeTextPlain,
|
|
|
|
RouteParams: []plugins.HTTPRouteParamDocumentation{
|
|
|
|
{
|
|
|
|
Description: "Name of the counter to query",
|
|
|
|
Name: "name",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
registerRoute(plugins.HTTPRouteRegistrationArgs{
|
|
|
|
Description: "Updates the value of the counter",
|
|
|
|
HandlerFunc: routeActorCounterSetValue,
|
|
|
|
Method: http.MethodPatch,
|
|
|
|
Module: "counter",
|
|
|
|
Name: "Set Counter Value",
|
|
|
|
Path: "/{name}",
|
|
|
|
QueryParams: []plugins.HTTPRouteParamDocumentation{
|
|
|
|
{
|
|
|
|
Description: "If set to `true` the given value is set instead of added",
|
|
|
|
Name: "absolute",
|
|
|
|
Required: false,
|
|
|
|
Type: "boolean",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Description: "Value to add / set for the given counter",
|
|
|
|
Name: "value",
|
|
|
|
Required: true,
|
|
|
|
Type: "int64",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
RouteParams: []plugins.HTTPRouteParamDocumentation{
|
|
|
|
{
|
|
|
|
Description: "Name of the counter to update",
|
|
|
|
Name: "name",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
2021-06-11 11:52:42 +00:00
|
|
|
}
|
2020-12-21 00:32:39 +00:00
|
|
|
|
2021-06-11 11:52:42 +00:00
|
|
|
type ActorCounter struct {
|
|
|
|
CounterSet *string `json:"counter_set" yaml:"counter_set"`
|
|
|
|
CounterStep *int64 `json:"counter_step" yaml:"counter_step"`
|
|
|
|
Counter *string `json:"counter" yaml:"counter"`
|
|
|
|
}
|
|
|
|
|
2021-09-02 21:26:39 +00:00
|
|
|
func (a ActorCounter) Execute(c *irc.Client, m *irc.Message, r *plugins.Rule, eventData plugins.FieldCollection) (preventCooldown bool, err error) {
|
2021-06-11 11:52:42 +00:00
|
|
|
if a.Counter == nil {
|
2021-08-11 22:12:10 +00:00
|
|
|
return false, nil
|
2021-06-11 11:52:42 +00:00
|
|
|
}
|
2020-12-25 23:31:49 +00:00
|
|
|
|
2021-09-02 15:09:30 +00:00
|
|
|
counterName, err := formatMessage(*a.Counter, m, r, eventData)
|
2021-06-11 11:52:42 +00:00
|
|
|
if err != nil {
|
2021-08-11 22:12:10 +00:00
|
|
|
return false, errors.Wrap(err, "preparing response")
|
2021-06-11 11:52:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if a.CounterSet != nil {
|
2021-09-02 15:09:30 +00:00
|
|
|
parseValue, err := formatMessage(*a.CounterSet, m, r, eventData)
|
2021-06-11 11:52:42 +00:00
|
|
|
if err != nil {
|
2021-08-11 22:12:10 +00:00
|
|
|
return false, errors.Wrap(err, "execute counter value template")
|
2021-03-06 00:35:20 +00:00
|
|
|
}
|
|
|
|
|
2021-06-28 22:05:11 +00:00
|
|
|
counterValue, err := strconv.ParseInt(parseValue, 10, 64) //nolint:gomnd // Those numbers are static enough
|
2021-06-11 11:52:42 +00:00
|
|
|
if err != nil {
|
2021-08-11 22:12:10 +00:00
|
|
|
return false, errors.Wrap(err, "parse counter value")
|
2020-12-21 00:32:39 +00:00
|
|
|
}
|
|
|
|
|
2021-08-11 22:12:10 +00:00
|
|
|
return false, errors.Wrap(
|
2021-06-11 11:52:42 +00:00
|
|
|
store.UpdateCounter(counterName, counterValue, true),
|
|
|
|
"set counter",
|
2020-12-21 00:32:39 +00:00
|
|
|
)
|
2021-06-11 11:52:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var counterStep int64 = 1
|
|
|
|
if a.CounterStep != nil {
|
|
|
|
counterStep = *a.CounterStep
|
|
|
|
}
|
|
|
|
|
2021-08-11 22:12:10 +00:00
|
|
|
return false, errors.Wrap(
|
2021-06-11 11:52:42 +00:00
|
|
|
store.UpdateCounter(counterName, counterStep, false),
|
|
|
|
"update counter",
|
|
|
|
)
|
2020-12-21 00:32:39 +00:00
|
|
|
}
|
2021-06-11 11:52:42 +00:00
|
|
|
|
|
|
|
func (a ActorCounter) IsAsync() bool { return false }
|
|
|
|
func (a ActorCounter) Name() string { return "counter" }
|
2021-08-28 15:27:24 +00:00
|
|
|
|
|
|
|
func routeActorCounterGetValue(w http.ResponseWriter, r *http.Request) {
|
|
|
|
template := r.FormValue("template")
|
|
|
|
if template == "" {
|
|
|
|
template = "%d"
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "text-plain")
|
|
|
|
fmt.Fprintf(w, template, store.GetCounterValue(mux.Vars(r)["name"]))
|
|
|
|
}
|
|
|
|
|
|
|
|
func routeActorCounterSetValue(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var (
|
|
|
|
absolute = r.FormValue("absolute") == "true"
|
|
|
|
err error
|
|
|
|
value int64
|
|
|
|
)
|
|
|
|
|
2021-08-28 15:58:31 +00:00
|
|
|
if value, err = strconv.ParseInt(r.FormValue("value"), 10, 64); err != nil { //nolint:gomnd // Those numbers are static enough
|
2021-08-28 15:27:24 +00:00
|
|
|
http.Error(w, errors.Wrap(err, "parsing value").Error(), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = store.UpdateCounter(mux.Vars(r)["name"], value, absolute); err != nil {
|
|
|
|
http.Error(w, errors.Wrap(err, "updating value").Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
}
|