mirror of https://github.com/velour/catbase.git
counter: try out httpin
This commit is contained in:
parent
f602c2ec8d
commit
81fb3dd068
|
@ -11,6 +11,8 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
httpin_integration "github.com/ggicci/httpin/integration"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Web struct {
|
type Web struct {
|
||||||
|
@ -77,6 +79,8 @@ func (ws *Web) setupHTTP() {
|
||||||
ws.router.Use(middleware.Recoverer)
|
ws.router.Use(middleware.Recoverer)
|
||||||
ws.router.Use(middleware.StripSlashes)
|
ws.router.Use(middleware.StripSlashes)
|
||||||
|
|
||||||
|
httpin_integration.UseGochiURLParam("path", chi.URLParam)
|
||||||
|
|
||||||
ws.router.HandleFunc("/", ws.serveRoot)
|
ws.router.HandleFunc("/", ws.serveRoot)
|
||||||
ws.router.HandleFunc("/nav", ws.serveNav)
|
ws.router.HandleFunc("/nav", ws.serveNav)
|
||||||
ws.router.HandleFunc("/navHTML", ws.serveNavHTML)
|
ws.router.HandleFunc("/navHTML", ws.serveNavHTML)
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -17,7 +17,8 @@ require (
|
||||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90
|
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90
|
||||||
github.com/forPelevin/gomoji v1.1.6
|
github.com/forPelevin/gomoji v1.1.6
|
||||||
github.com/gabriel-vasile/mimetype v1.4.1
|
github.com/gabriel-vasile/mimetype v1.4.1
|
||||||
github.com/go-chi/chi/v5 v5.0.7
|
github.com/ggicci/httpin v0.16.0
|
||||||
|
github.com/go-chi/chi/v5 v5.0.11
|
||||||
github.com/go-chi/httprate v0.7.0
|
github.com/go-chi/httprate v0.7.0
|
||||||
github.com/gocolly/colly v1.2.0
|
github.com/gocolly/colly v1.2.0
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
|
@ -32,7 +33,7 @@ require (
|
||||||
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254
|
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254
|
||||||
github.com/rs/zerolog v1.28.0
|
github.com/rs/zerolog v1.28.0
|
||||||
github.com/slack-go/slack v0.11.3
|
github.com/slack-go/slack v0.11.3
|
||||||
github.com/stretchr/testify v1.8.2
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/trubitsyn/go-zero-width v1.0.1
|
github.com/trubitsyn/go-zero-width v1.0.1
|
||||||
github.com/velour/velour v0.0.0-20160303155839-8e090e68d158
|
github.com/velour/velour v0.0.0-20160303155839-8e090e68d158
|
||||||
golang.org/x/crypto v0.14.0
|
golang.org/x/crypto v0.14.0
|
||||||
|
@ -57,6 +58,7 @@ require (
|
||||||
github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc // indirect
|
github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc // indirect
|
||||||
github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad // indirect
|
github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad // indirect
|
||||||
github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 // indirect
|
github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 // indirect
|
||||||
|
github.com/ggicci/owl v0.7.0 // indirect
|
||||||
github.com/go-stack/stack v1.8.0 // indirect
|
github.com/go-stack/stack v1.8.0 // indirect
|
||||||
github.com/gobwas/glob v0.2.3 // indirect
|
github.com/gobwas/glob v0.2.3 // indirect
|
||||||
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
|
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
|
||||||
|
|
14
go.sum
14
go.sum
|
@ -120,9 +120,13 @@ github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkF
|
||||||
github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M=
|
github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M=
|
||||||
github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 h1:GOfMz6cRgTJ9jWV0qAezv642OhPnKEG7gtUjJSdStHE=
|
github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 h1:GOfMz6cRgTJ9jWV0qAezv642OhPnKEG7gtUjJSdStHE=
|
||||||
github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17/go.mod h1:HfkOCN6fkKKaPSAeNq/er3xObxTW4VLeY6UUK895gLQ=
|
github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17/go.mod h1:HfkOCN6fkKKaPSAeNq/er3xObxTW4VLeY6UUK895gLQ=
|
||||||
|
github.com/ggicci/httpin v0.16.0 h1:ZR6RXH1xNWg39xqM33V7iz7PP/GuR7vc3aHa2g5mWo4=
|
||||||
|
github.com/ggicci/httpin v0.16.0/go.mod h1:whE/5nx1jCp//UQ6rgNpq2WNxOr9FV0OpxMnQQC0Xvs=
|
||||||
|
github.com/ggicci/owl v0.7.0 h1:+AMlCR0AY7j72q7hjtN4pm8VJiikwpROtMgvPnXtuik=
|
||||||
|
github.com/ggicci/owl v0.7.0/go.mod h1:TRPWshRwYej6uES//YW5aNgLB370URwyta1Ytfs7KXs=
|
||||||
github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
|
github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
|
||||||
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
|
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
|
||||||
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/go-chi/httprate v0.7.0 h1:8W0dF7Xa2Duz2p8ncGaehIphrxQGNlOtoGY0+NRRfjQ=
|
github.com/go-chi/httprate v0.7.0 h1:8W0dF7Xa2Duz2p8ncGaehIphrxQGNlOtoGY0+NRRfjQ=
|
||||||
github.com/go-chi/httprate v0.7.0/go.mod h1:6GOYBSwnpra4CQfAKXu8sQZg+nZ0M1g9QnyFvxrAB8A=
|
github.com/go-chi/httprate v0.7.0/go.mod h1:6GOYBSwnpra4CQfAKXu8sQZg+nZ0M1g9QnyFvxrAB8A=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
|
@ -215,6 +219,7 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
|
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
@ -252,6 +257,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||||
|
github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
|
||||||
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
|
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
|
||||||
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
|
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
|
||||||
github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a h1:Z7+SSApKiwPjNic+NF9+j7h657Uyvdp/jA3iTKhpj4E=
|
github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a h1:Z7+SSApKiwPjNic+NF9+j7h657Uyvdp/jA3iTKhpj4E=
|
||||||
|
@ -372,8 +378,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/temoto/robotstxt v1.1.1 h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA=
|
github.com/temoto/robotstxt v1.1.1 h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA=
|
||||||
github.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
github.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
||||||
github.com/trubitsyn/go-zero-width v1.0.1 h1:AAZhtyGXW79T5BouAF0R9FtDhGcp7IGbLZo2Id3N+m8=
|
github.com/trubitsyn/go-zero-width v1.0.1 h1:AAZhtyGXW79T5BouAF0R9FtDhGcp7IGbLZo2Id3N+m8=
|
||||||
|
|
|
@ -3,10 +3,8 @@ package counter
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"github.com/ggicci/httpin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
@ -23,34 +21,48 @@ func (p *CounterPlugin) registerWeb() {
|
||||||
dur := time.Duration(seconds) * time.Second
|
dur := time.Duration(seconds) * time.Second
|
||||||
subrouter := chi.NewRouter()
|
subrouter := chi.NewRouter()
|
||||||
subrouter.Use(httprate.LimitByIP(requests, dur))
|
subrouter.Use(httprate.LimitByIP(requests, dur))
|
||||||
subrouter.HandleFunc("/api/users/{user}/items/{item}/increment/{delta}", p.mkIncrementByNAPI(1))
|
subrouter.With(httpin.NewInput(CounterChangeReq{})).
|
||||||
subrouter.HandleFunc("/api/users/{user}/items/{item}/decrement/{delta}", p.mkIncrementByNAPI(-1))
|
HandleFunc("/api/users/{user}/items/{item}/increment/{delta}", p.mkIncrementByNAPI(1))
|
||||||
subrouter.HandleFunc("/api/users/{user}/items/{item}/increment", p.mkIncrementByNAPI(1))
|
subrouter.With(httpin.NewInput(CounterChangeReq{})).
|
||||||
subrouter.HandleFunc("/api/users/{user}/items/{item}/decrement", p.mkIncrementByNAPI(-1))
|
HandleFunc("/api/users/{user}/items/{item}/decrement/{delta}", p.mkIncrementByNAPI(-1))
|
||||||
|
subrouter.With(httpin.NewInput(CounterChangeReq{})).
|
||||||
|
HandleFunc("/api/users/{user}/items/{item}/increment", p.mkIncrementByNAPI(1))
|
||||||
|
subrouter.With(httpin.NewInput(CounterChangeReq{})).
|
||||||
|
HandleFunc("/api/users/{user}/items/{item}/decrement", p.mkIncrementByNAPI(-1))
|
||||||
r.Mount("/", subrouter)
|
r.Mount("/", subrouter)
|
||||||
r.HandleFunc("/users/{user}/items/{item}/increment", p.incHandler(1))
|
r.With(httpin.NewInput(CounterChangeReq{})).
|
||||||
r.HandleFunc("/users/{user}/items/{item}/decrement", p.incHandler(-1))
|
HandleFunc("/users/{user}/items/{item}/increment", p.incHandler(1))
|
||||||
|
r.With(httpin.NewInput(CounterChangeReq{})).
|
||||||
|
HandleFunc("/users/{user}/items/{item}/decrement", p.incHandler(-1))
|
||||||
r.HandleFunc("/", p.handleCounter)
|
r.HandleFunc("/", p.handleCounter)
|
||||||
p.b.GetWeb().RegisterWebName(r, "/counter", "Counter")
|
p.b.GetWeb().RegisterWebName(r, "/counter", "Counter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CounterChangeReq struct {
|
||||||
|
UserName string `in:"path=user"`
|
||||||
|
Item string `in:"path=item"`
|
||||||
|
Password string `in:"form=password"`
|
||||||
|
Delta int `in:"path=delta"`
|
||||||
|
Body struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
} `in:"body=json"`
|
||||||
|
}
|
||||||
|
|
||||||
func (p *CounterPlugin) incHandler(delta int) http.HandlerFunc {
|
func (p *CounterPlugin) incHandler(delta int) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
userName, _ := url.QueryUnescape(chi.URLParam(r, "user"))
|
input := r.Context().Value(httpin.Input).(*CounterChangeReq)
|
||||||
itemName, _ := url.QueryUnescape(chi.URLParam(r, "item"))
|
if !p.b.CheckPassword("", input.Password) {
|
||||||
pass := r.FormValue("password")
|
|
||||||
if !p.b.CheckPassword("", pass) {
|
|
||||||
w.WriteHeader(401)
|
w.WriteHeader(401)
|
||||||
fmt.Fprintf(w, "error")
|
fmt.Fprintf(w, "error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := p.delta(userName, itemName, "", delta)
|
item, err := p.delta(input.UserName, input.Item, "", delta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
fmt.Fprintf(w, "error")
|
fmt.Fprintf(w, "error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.renderItem(userName, item).Render(r.Context(), w)
|
p.renderItem(input.UserName, item).Render(r.Context(), w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,13 +115,11 @@ func (p *CounterPlugin) delta(userName, itemName, personalMessage string, delta
|
||||||
|
|
||||||
func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWriter, r *http.Request) {
|
func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWriter, r *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
userName, _ := url.QueryUnescape(chi.URLParam(r, "user"))
|
input := r.Context().Value(httpin.Input).(*CounterChangeReq)
|
||||||
itemName, _ := url.QueryUnescape(chi.URLParam(r, "item"))
|
if input.Delta == 0 {
|
||||||
delta, err := strconv.Atoi(chi.URLParam(r, "delta"))
|
input.Delta = direction
|
||||||
if err != nil || delta == 0 {
|
|
||||||
delta = direction
|
|
||||||
} else {
|
} else {
|
||||||
delta = delta * direction
|
input.Delta = input.Delta * direction
|
||||||
}
|
}
|
||||||
|
|
||||||
secret, pass, ok := r.BasicAuth()
|
secret, pass, ok := r.BasicAuth()
|
||||||
|
@ -127,15 +137,12 @@ func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWri
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _ := io.ReadAll(r.Body)
|
|
||||||
postData := map[string]string{}
|
|
||||||
err = json.Unmarshal(body, &postData)
|
|
||||||
personalMsg := ""
|
personalMsg := ""
|
||||||
if inputMsg, ok := postData["message"]; ok {
|
if input.Body.Message != "" {
|
||||||
personalMsg = fmt.Sprintf("\nMessage: %s", inputMsg)
|
personalMsg = fmt.Sprintf("\nMessage: %s", input.Body.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := p.delta(userName, itemName, personalMsg, delta*direction); err != nil {
|
if _, err := p.delta(input.UserName, input.Item, personalMsg, input.Delta*direction); err != nil {
|
||||||
log.Error().Err(err).Msg("error finding item")
|
log.Error().Err(err).Msg("error finding item")
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(400)
|
||||||
j, _ := json.Marshal(struct {
|
j, _ := json.Marshal(struct {
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<!-- Load required Bootstrap and BootstrapVue CSS -->
|
|
||||||
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
|
|
||||||
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@^2/dist/bootstrap-vue.min.css" />
|
|
||||||
|
|
||||||
<!-- Load polyfills to support older browsers -->
|
|
||||||
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CMutationObserver"></script>
|
|
||||||
|
|
||||||
<!-- Load Vue followed by BootstrapVue -->
|
|
||||||
<script src="//unpkg.com/vue@^2/dist/vue.min.js"></script>
|
|
||||||
<script src="//unpkg.com/bootstrap-vue@^2/dist/bootstrap-vue.min.js"></script>
|
|
||||||
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
|
||||||
<title>Counters</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div id="app">
|
|
||||||
<b-navbar>
|
|
||||||
<b-navbar-brand>Counters</b-navbar-brand>
|
|
||||||
<b-navbar-nav>
|
|
||||||
<b-nav-item v-for="item in nav" :href="item.url" :active="item.name === 'Counter'">{{ item.name }}</b-nav-item>
|
|
||||||
</b-navbar-nav>
|
|
||||||
</b-navbar>
|
|
||||||
<b-alert
|
|
||||||
dismissable
|
|
||||||
:show="err"
|
|
||||||
variant="error">
|
|
||||||
{{ err }}
|
|
||||||
</b-alert>
|
|
||||||
<b-container>
|
|
||||||
<b-row>
|
|
||||||
<b-col cols="5">Password:</b-col>
|
|
||||||
<b-col><b-input v-model="answer"></b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row v-for="(counter, user) in counters">
|
|
||||||
{{ user }}:
|
|
||||||
<b-container>
|
|
||||||
<b-row v-for="(count, thing) in counter">
|
|
||||||
<b-col offset="1">
|
|
||||||
{{ thing }}:
|
|
||||||
</b-col>
|
|
||||||
<b-col>
|
|
||||||
{{ count }}
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="2">
|
|
||||||
<button @click="subtract(user,thing,count)">-</button>
|
|
||||||
<button @click="add(user,thing,count)">+</button>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</b-container>
|
|
||||||
</b-row>
|
|
||||||
</b-container>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function convertData(data) {
|
|
||||||
var newData = {};
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let entry = data[i]
|
|
||||||
if (newData[entry.Nick] === undefined) {
|
|
||||||
newData[entry.Nick] = {}
|
|
||||||
}
|
|
||||||
newData[entry.Nick][entry.Item] = entry.Count;
|
|
||||||
}
|
|
||||||
return newData;
|
|
||||||
}
|
|
||||||
var app = new Vue({
|
|
||||||
el: '#app',
|
|
||||||
data: {
|
|
||||||
err: '',
|
|
||||||
nav: [],
|
|
||||||
answer: '',
|
|
||||||
correct: 0,
|
|
||||||
counters: {}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
axios.get('/nav')
|
|
||||||
.then(resp => {
|
|
||||||
this.nav = resp.data;
|
|
||||||
})
|
|
||||||
.catch(err => console.log(err))
|
|
||||||
axios.get('/counter/api')
|
|
||||||
.then(resp => (this.counters = convertData(resp.data)))
|
|
||||||
.catch(err => (this.err = err));
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
add(user, thing, count) {
|
|
||||||
axios.post('/counter/api',
|
|
||||||
{user: user, thing: thing, action: '++', password: this.answer})
|
|
||||||
.then(resp => {this.counters = convertData(resp.data); this.err = '';})
|
|
||||||
.catch(err => this.err = err);
|
|
||||||
},
|
|
||||||
subtract(user, thing, count) {
|
|
||||||
axios.post('/counter/api',
|
|
||||||
{user: user, thing: thing, action: '--', password: this.answer})
|
|
||||||
.then(resp => {this.counters = convertData(resp.data); this.err = '';})
|
|
||||||
.catch(err => this.err = err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue