added glob matching
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,7 +8,6 @@ tmp/
|
|||||||
static/css/output.css
|
static/css/output.css
|
||||||
internal/view/**/*_templ.go
|
internal/view/**/*_templ.go
|
||||||
internal/view/**/*_templ.txt
|
internal/view/**/*_templ.txt
|
||||||
oslstats
|
|
||||||
|
|
||||||
# Database backups (compressed)
|
# Database backups (compressed)
|
||||||
backups/*.sql.gz
|
backups/*.sql.gz
|
||||||
|
|||||||
@@ -33,15 +33,8 @@ func setupHttpServer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ignoredPaths := []string{
|
ignoredPaths := []string{
|
||||||
"/static/css/output.css",
|
"/static/*",
|
||||||
"/static/favicon.ico",
|
"/.well-known/*",
|
||||||
"/static/js/toasts.js",
|
|
||||||
"/static/js/copytoclipboard.js",
|
|
||||||
"/static/js/theme.js",
|
|
||||||
"/static/js/pagination.js",
|
|
||||||
"/static/vendored/htmx@2.0.8.min.js",
|
|
||||||
"/static/vendored/htmx-ext-ws.min.js",
|
|
||||||
"/static/vendored/alpinejs@3.15.4.min.js",
|
|
||||||
"/ws/notifications",
|
"/ws/notifications",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
cmd/oslstats/migrations/20260127194815_seasons.go
Normal file
34
cmd/oslstats/migrations/20260127194815_seasons.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.haelnorr.com/h/oslstats/internal/db"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Migrations.MustRegister(
|
||||||
|
// UP migration
|
||||||
|
func(ctx context.Context, dbConn *bun.DB) error {
|
||||||
|
_, err := dbConn.NewCreateTable().
|
||||||
|
Model((*db.Season)(nil)).
|
||||||
|
Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
// DOWN migration
|
||||||
|
func(ctx context.Context, dbConn *bun.DB) error {
|
||||||
|
_, err := dbConn.NewDropTable().
|
||||||
|
Model((*db.Season)(nil)).
|
||||||
|
IfExists().
|
||||||
|
Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
5
go.mod
5
go.mod
@@ -6,8 +6,8 @@ require (
|
|||||||
git.haelnorr.com/h/golib/env v0.9.1
|
git.haelnorr.com/h/golib/env v0.9.1
|
||||||
git.haelnorr.com/h/golib/ezconf v0.1.1
|
git.haelnorr.com/h/golib/ezconf v0.1.1
|
||||||
git.haelnorr.com/h/golib/hlog v0.10.4
|
git.haelnorr.com/h/golib/hlog v0.10.4
|
||||||
git.haelnorr.com/h/golib/hws v0.4.3
|
git.haelnorr.com/h/golib/hws v0.4.4
|
||||||
git.haelnorr.com/h/golib/hwsauth v0.5.3
|
git.haelnorr.com/h/golib/hwsauth v0.5.4
|
||||||
git.haelnorr.com/h/golib/notify v0.1.0
|
git.haelnorr.com/h/golib/notify v0.1.0
|
||||||
github.com/a-h/templ v0.3.977
|
github.com/a-h/templ v0.3.977
|
||||||
github.com/coder/websocket v1.8.14
|
github.com/coder/websocket v1.8.14
|
||||||
@@ -19,6 +19,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/gobwas/glob v0.2.3 // indirect
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
golang.org/x/crypto v0.47.0 // indirect
|
golang.org/x/crypto v0.47.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
6
go.sum
6
go.sum
@@ -8,8 +8,12 @@ git.haelnorr.com/h/golib/hlog v0.10.4 h1:vpCsV/OddjIYx8F48U66WxojjmhEbeLGQAOBG4V
|
|||||||
git.haelnorr.com/h/golib/hlog v0.10.4/go.mod h1:+wJ8vecQY/JITTXKmI3JfkHiUGyMs7N6wooj2wuWZbc=
|
git.haelnorr.com/h/golib/hlog v0.10.4/go.mod h1:+wJ8vecQY/JITTXKmI3JfkHiUGyMs7N6wooj2wuWZbc=
|
||||||
git.haelnorr.com/h/golib/hws v0.4.3 h1:rpqe0Dcbm3b5XZ/Bfy0LUhph6RR7+bmANrSA/W81l0A=
|
git.haelnorr.com/h/golib/hws v0.4.3 h1:rpqe0Dcbm3b5XZ/Bfy0LUhph6RR7+bmANrSA/W81l0A=
|
||||||
git.haelnorr.com/h/golib/hws v0.4.3/go.mod h1:UqB83p9lGjidDkk0pWRqxxOFrCkg8t+9J6uGtBOjNLo=
|
git.haelnorr.com/h/golib/hws v0.4.3/go.mod h1:UqB83p9lGjidDkk0pWRqxxOFrCkg8t+9J6uGtBOjNLo=
|
||||||
|
git.haelnorr.com/h/golib/hws v0.4.4 h1:tV9UjZ4q96UlOdJKsC7b3kDV+bpQYqKVPQuaV1n3U3k=
|
||||||
|
git.haelnorr.com/h/golib/hws v0.4.4/go.mod h1:dxAbbGGNzqLXhZXwgt091QsvsPBdrS+1YsNQNldNVoM=
|
||||||
git.haelnorr.com/h/golib/hwsauth v0.5.3 h1:Vgw8khDQZJRCc3m7z9QlbL9CYPyFB9JXUC3+omKRZPc=
|
git.haelnorr.com/h/golib/hwsauth v0.5.3 h1:Vgw8khDQZJRCc3m7z9QlbL9CYPyFB9JXUC3+omKRZPc=
|
||||||
git.haelnorr.com/h/golib/hwsauth v0.5.3/go.mod h1:NOonrVU/lX8lzuV77eDEiTwBjn7RrzYVcSdXUJWeHmQ=
|
git.haelnorr.com/h/golib/hwsauth v0.5.3/go.mod h1:NOonrVU/lX8lzuV77eDEiTwBjn7RrzYVcSdXUJWeHmQ=
|
||||||
|
git.haelnorr.com/h/golib/hwsauth v0.5.4 h1:nuaiVpJHHXgKVRPoQSE/v3CJHSkivViK5h3SVhEcbbM=
|
||||||
|
git.haelnorr.com/h/golib/hwsauth v0.5.4/go.mod h1:eIjRPeGycvxRWERkxCoRVMEEhHuUdiPDvjpzzZOhQ0w=
|
||||||
git.haelnorr.com/h/golib/jwt v0.10.1 h1:1Adxt9H3Y4fWFvFjWpvg/vSFhbgCMDMxgiE3m7KvDMI=
|
git.haelnorr.com/h/golib/jwt v0.10.1 h1:1Adxt9H3Y4fWFvFjWpvg/vSFhbgCMDMxgiE3m7KvDMI=
|
||||||
git.haelnorr.com/h/golib/jwt v0.10.1/go.mod h1:fbuPrfucT9lL0faV5+Q5Gk9WFJxPlwzRPpbMQKYZok4=
|
git.haelnorr.com/h/golib/jwt v0.10.1/go.mod h1:fbuPrfucT9lL0faV5+Q5Gk9WFJxPlwzRPpbMQKYZok4=
|
||||||
git.haelnorr.com/h/golib/notify v0.1.0 h1:xdf6zd21F6n+SuGTeJiuLNMf6zFXMvwpKD0gmNq8N10=
|
git.haelnorr.com/h/golib/notify v0.1.0 h1:xdf6zd21F6n+SuGTeJiuLNMf6zFXMvwpKD0gmNq8N10=
|
||||||
@@ -27,6 +31,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ func throwError(
|
|||||||
statusCode int,
|
statusCode int,
|
||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
level string,
|
level hws.ErrorLevel,
|
||||||
) {
|
) {
|
||||||
err = s.ThrowError(w, r, hws.HWSError{
|
err = s.ThrowError(w, r, hws.HWSError{
|
||||||
StatusCode: statusCode,
|
StatusCode: statusCode,
|
||||||
Message: msg,
|
Message: msg,
|
||||||
Error: err,
|
Error: err,
|
||||||
Level: hws.ErrorLevel(level),
|
Level: level,
|
||||||
RenderErrorPage: true, // throw* family always renders error pages
|
RenderErrorPage: true, // throw* family always renders error pages
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -39,7 +39,7 @@ func throwInternalServiceError(
|
|||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
throwError(s, w, r, http.StatusInternalServerError, msg, err, "error")
|
throwError(s, w, r, http.StatusInternalServerError, msg, err, hws.ErrorERROR)
|
||||||
}
|
}
|
||||||
|
|
||||||
// throwServiceUnavailable handles 503 errors
|
// throwServiceUnavailable handles 503 errors
|
||||||
@@ -50,7 +50,7 @@ func throwServiceUnavailable(
|
|||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
throwError(s, w, r, http.StatusServiceUnavailable, msg, err, "error")
|
throwError(s, w, r, http.StatusServiceUnavailable, msg, err, hws.ErrorERROR)
|
||||||
}
|
}
|
||||||
|
|
||||||
// throwBadRequest handles 400 errors (malformed requests)
|
// throwBadRequest handles 400 errors (malformed requests)
|
||||||
@@ -61,7 +61,7 @@ func throwBadRequest(
|
|||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
throwError(s, w, r, http.StatusBadRequest, msg, err, "debug")
|
throwError(s, w, r, http.StatusBadRequest, msg, err, hws.ErrorDEBUG)
|
||||||
}
|
}
|
||||||
|
|
||||||
// throwForbidden handles 403 errors (normal permission denials)
|
// throwForbidden handles 403 errors (normal permission denials)
|
||||||
@@ -72,7 +72,7 @@ func throwForbidden(
|
|||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
throwError(s, w, r, http.StatusForbidden, msg, err, "debug")
|
throwError(s, w, r, http.StatusForbidden, msg, err, hws.ErrorDEBUG)
|
||||||
}
|
}
|
||||||
|
|
||||||
// throwForbiddenSecurity handles 403 errors for security events (uses WARN level)
|
// throwForbiddenSecurity handles 403 errors for security events (uses WARN level)
|
||||||
@@ -83,7 +83,7 @@ func throwForbiddenSecurity(
|
|||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
throwError(s, w, r, http.StatusForbidden, msg, err, "warn")
|
throwError(s, w, r, http.StatusForbidden, msg, err, hws.ErrorWARN)
|
||||||
}
|
}
|
||||||
|
|
||||||
// throwUnauthorized handles 401 errors (not authenticated)
|
// throwUnauthorized handles 401 errors (not authenticated)
|
||||||
@@ -94,7 +94,7 @@ func throwUnauthorized(
|
|||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
throwError(s, w, r, http.StatusUnauthorized, msg, err, "debug")
|
throwError(s, w, r, http.StatusUnauthorized, msg, err, hws.ErrorDEBUG)
|
||||||
}
|
}
|
||||||
|
|
||||||
// throwUnauthorizedSecurity handles 401 errors for security events (uses WARN level)
|
// throwUnauthorizedSecurity handles 401 errors for security events (uses WARN level)
|
||||||
@@ -105,7 +105,7 @@ func throwUnauthorizedSecurity(
|
|||||||
msg string,
|
msg string,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
throwError(s, w, r, http.StatusUnauthorized, msg, err, "warn")
|
throwError(s, w, r, http.StatusUnauthorized, msg, err, hws.ErrorWARN)
|
||||||
}
|
}
|
||||||
|
|
||||||
// throwNotFound handles 404 errors
|
// throwNotFound handles 404 errors
|
||||||
@@ -117,7 +117,7 @@ func throwNotFound(
|
|||||||
) {
|
) {
|
||||||
msg := fmt.Sprintf("The requested resource was not found: %s", path)
|
msg := fmt.Sprintf("The requested resource was not found: %s", path)
|
||||||
err := errors.New("Resource not found")
|
err := errors.New("Resource not found")
|
||||||
throwError(s, w, r, http.StatusNotFound, msg, err, "debug")
|
throwError(s, w, r, http.StatusNotFound, msg, err, hws.ErrorDEBUG)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorDetails contains structured error information for WebSocket error modals
|
// ErrorDetails contains structured error information for WebSocket error modals
|
||||||
|
|||||||
Reference in New Issue
Block a user