Replaced the gin framwwork with echo

This commit is contained in:
Sansan committed 2025-01-13 11:57:48 +01:00
1 parent 8e2d22b899
commit 034ba35fbb
32 files changed
+347 -265

No files matched your search

+54 -6
View File
@@ -1,17 +1,65 @@
package main package main
import ( import (
"embed" "context"
"fmt"
"log"
"music-server/internal/server"
"music-server/pkg/conf" "music-server/pkg/conf"
"net/http"
"os/signal"
"syscall"
"time"
) )
//go:embed swagger func gracefulShutdown(apiServer *http.Server, done chan bool) {
var swagger embed.FS // Create context that listens for the interrupt signal from the OS.
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
// Listen for the interrupt signal.
<-ctx.Done()
log.Println("shutting down gracefully, press Ctrl+C again to force")
conf.CloseDb()
// The context is used to inform the server it has 5 seconds to finish
// the request it is currently handling
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := apiServer.Shutdown(ctx); err != nil {
log.Printf("Server forced to shutdown with error: %v", err)
}
log.Println("Server exiting")
// Notify the main goroutine that the shutdown is complete
done <- true
}
func main() { func main() {
conf.SetupDb()
conf.SetupRestServer(swagger) server := server.NewServer()
conf.CloseDb() // Create a done channel to signal when the shutdown is complete
done := make(chan bool, 1)
// Run graceful shutdown in a separate goroutine
go gracefulShutdown(server, done)
log.Printf("Open http://localhost%s in the browser", server.Addr)
err := server.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
panic(fmt.Sprintf("http server error: %s", err))
}
// Wait for the graceful shutdown to complete
<-done
log.Println("Graceful shutdown complete.")
//conf.SetupDb()
//conf.SetupRestServer(swagger)
//conf.CloseDb()
} }
+4 -1
View File
@@ -3,4 +3,7 @@ package web
import "embed" import "embed"
//go:embed "assets" //go:embed "assets"
var Files embed.FS var Assets embed.FS
//go:embed "swagger"
var Swagger embed.FS
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+15 -7
View File
@@ -1,15 +1,18 @@
module music-server module music-server
go 1.22.2 go 1.23
toolchain go1.23.4
require ( require (
github.com/MShekow/directory-checksum v1.4.6 github.com/MShekow/directory-checksum v1.4.6
github.com/a-h/templ v0.2.793 github.com/a-h/templ v0.3.819
github.com/gin-contrib/static v1.1.2 github.com/gin-contrib/static v1.1.2
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0
github.com/golang-migrate/migrate/v4 v4.18.1 github.com/golang-migrate/migrate/v4 v4.18.1
github.com/jackc/pgtype v1.14.3 github.com/jackc/pgtype v1.14.3
github.com/jackc/pgx/v5 v5.5.5 github.com/jackc/pgx/v5 v5.5.5
github.com/labstack/echo v3.3.10+incompatible
github.com/lib/pq v1.10.9 github.com/lib/pq v1.10.9
github.com/spf13/afero v1.11.0 github.com/spf13/afero v1.11.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
@@ -20,6 +23,7 @@ require (
github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect github.com/cloudwego/iasm v0.2.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/docker/docker v27.3.1+incompatible // indirect github.com/docker/docker v27.3.1+incompatible // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
@@ -36,21 +40,25 @@ require (
github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect github.com/ugorji/go/codec v1.2.12 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/otel/trace v1.32.0 // indirect
go.uber.org/atomic v1.7.0 // indirect go.uber.org/atomic v1.7.0 // indirect
golang.org/x/arch v0.8.0 // indirect golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.27.0 // indirect golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.29.0 // indirect golang.org/x/net v0.33.0 // indirect
golang.org/x/sync v0.8.0 // indirect golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.25.0 // indirect golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.18.0 // indirect golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect google.golang.org/protobuf v1.34.2 // indirect
) )
+26 -12
View File
@@ -6,8 +6,8 @@ github.com/MShekow/directory-checksum v1.4.6/go.mod h1:bMfFBkaIlNk7O9VgEi8D2X7Q2
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/a-h/templ v0.2.793 h1:Io+/ocnfGWYO4VHdR0zBbf39PQlnzVCVVD+wEEs6/qY= github.com/a-h/templ v0.3.819 h1:KDJ5jTFN15FyJnmSmo2gNirIqt7hfvBD2VXVDTySckM=
github.com/a-h/templ v0.2.793/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w= github.com/a-h/templ v0.3.819/go.mod h1:iDJKJktpttVKdWoTkRNNLcllRI+BlpopJc+8au3gOUo=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
@@ -23,6 +23,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dhui/dktest v0.4.3 h1:wquqUxAFdcUgabAVLvSCOKOlag5cIZuaOjYIBOWdsR0= github.com/dhui/dktest v0.4.3 h1:wquqUxAFdcUgabAVLvSCOKOlag5cIZuaOjYIBOWdsR0=
github.com/dhui/dktest v0.4.3/go.mod h1:zNK8IwktWzQRm6I/l2Wjp7MakiyaFWv4G1hjmodmMTs= github.com/dhui/dktest v0.4.3/go.mod h1:zNK8IwktWzQRm6I/l2Wjp7MakiyaFWv4G1hjmodmMTs=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
@@ -148,6 +150,10 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@@ -158,9 +164,12 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
@@ -219,6 +228,10 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw=
@@ -257,8 +270,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@@ -273,13 +286,13 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -294,12 +307,13 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -315,8 +329,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+82
View File
@@ -0,0 +1,82 @@
package server
import (
"fmt"
"music-server/cmd/web"
"music-server/pkg/api"
"net/http"
"sort"
"strings"
"github.com/a-h/templ"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
func (s *Server) RegisterRoutes() http.Handler {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"https://*", "http://*"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
AllowHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
AllowCredentials: true,
MaxAge: 300,
}))
fileServer := http.FileServer(http.FS(web.Assets))
e.GET("/assets/*", echo.WrapHandler(fileServer))
e.GET("/search", echo.WrapHandler(templ.Handler(web.HelloForm())))
e.POST("/find", echo.WrapHandler(http.HandlerFunc(web.FindGameWebHandler)))
e.Static("/", "/frontend")
swagger := http.FileServer(http.FS(web.Swagger))
e.GET("/swagger/*", echo.WrapHandler(swagger))
index := api.NewIndex()
e.GET("/version", index.GetVersion)
e.GET("/health", index.GetDBTest)
sync := api.NewSync()
syncGroup := e.Group("/sync")
syncGroup.GET("", sync.SyncGames)
syncGroup.GET("/new", sync.SyncGamesNewOnlyChanges)
syncGroup.GET("/new/full", sync.SyncGamesNewFull)
syncGroup.GET("/quick", sync.SyncGamesQuick)
syncGroup.GET("/reset", sync.ResetGames)
music := api.NewMusic()
musicGroup := e.Group("/music")
musicGroup.GET("", music.GetSong)
musicGroup.GET("/soundTest", music.GetSoundCheckSong)
musicGroup.GET("/reset", music.ResetMusic)
musicGroup.GET("/rand", music.GetRandomSong)
musicGroup.GET("/rand/low", music.GetRandomSongLowChance)
musicGroup.GET("/rand/classic", music.GetRandomSongClassic)
musicGroup.GET("/info", music.GetSongInfo)
musicGroup.GET("/list", music.GetPlayedSongs)
musicGroup.GET("/next", music.GetNextSong)
musicGroup.GET("/previous", music.GetPreviousSong)
musicGroup.GET("/all", music.GetAllGamesRandom)
musicGroup.GET("/all/order", music.GetAllGames)
musicGroup.GET("/all/random", music.GetAllGamesRandom)
musicGroup.PUT("/played", music.PutPlayed)
musicGroup.GET("/addQue", music.AddLatestToQue)
musicGroup.GET("/addPlayed", music.AddLatestPlayed)
routes := e.Routes()
sort.Slice(routes, func(i, j int) bool {
return routes[i].Path < routes[j].Path
})
for _, r := range routes {
if (r.Method == "GET" || r.Method == "POST" || r.Method == "PUT" || r.Method == "DELETE") && !strings.Contains(r.Name, "github") {
fmt.Printf(" %s %s\n", r.Method, r.Path)
}
}
return e
}
+35
View File
@@ -0,0 +1,35 @@
package server
import (
"fmt"
"music-server/pkg/conf"
"net/http"
"os"
"strconv"
"time"
)
type Server struct {
port int
}
func NewServer() *http.Server {
port, _ := strconv.Atoi(os.Getenv("PORT"))
NewServer := &Server{
port: port,
}
conf.SetupDb()
// Declare Server config
server := &http.Server{
Addr: fmt.Sprintf(":%d", NewServer.port),
Handler: NewServer.RegisterRoutes(),
IdleTimeout: time.Minute,
ReadTimeout: 10 * time.Second,
WriteTimeout: 30 * time.Second,
}
return server
}
+8 -2
View File
@@ -1,3 +1,5 @@
set dotenv-load
# Build the application # Build the application
all: build test all: build test
@@ -16,8 +18,12 @@ templ-install:
fi; \ fi; \
fi fi
tailwind: tailwind-macos:
@if [ ! -f tailwindcss ]; then curl -sL https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-x64 -o tailwindcss; fi @if [ ! -f tailwindcss ]; then curl -sL https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-arm64 -o tailwindcss; fi
@chmod +x tailwindcss
tailwind-linux:
@if [ ! -f tailwindcss ]; then curl -sL https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64 -o tailwindcss; fi
@chmod +x tailwindcss @chmod +x tailwindcss
build: build:
+7 -8
View File
@@ -1,10 +1,10 @@
package api package api
import ( import (
"github.com/gin-gonic/gin"
"music-server/pkg/helpers"
"music-server/pkg/server" "music-server/pkg/server"
"net/http" "net/http"
"github.com/labstack/echo"
) )
type Index struct { type Index struct {
@@ -14,16 +14,15 @@ func NewIndex() *Index {
return &Index{} return &Index{}
} }
func (i *Index) GetVersion(ctx *gin.Context) { func (i *Index) GetVersion(ctx echo.Context) error {
versionHistory := server.GetVersionHistory() versionHistory := server.GetVersionHistory()
if versionHistory.Version == "" { if versionHistory.Version == "" {
helpers.NewError(ctx, http.StatusNotFound, nil) return ctx.JSON(http.StatusNotFound, "version not found")
return
} }
ctx.JSON(http.StatusOK, versionHistory) return ctx.JSON(http.StatusOK, versionHistory)
} }
func (i *Index) GetDBTest(ctx *gin.Context) { func (i *Index) GetDBTest(ctx echo.Context) error {
server.TestDB() server.TestDB()
ctx.JSON(http.StatusOK, "TestedDB") return ctx.JSON(http.StatusOK, "TestedDB")
} }
+38 -36
View File
@@ -1,11 +1,12 @@
package api package api
import ( import (
"github.com/gin-gonic/gin"
"music-server/pkg/helpers" "music-server/pkg/helpers"
"music-server/pkg/models" "music-server/pkg/models"
"music-server/pkg/server" "music-server/pkg/server"
"net/http" "net/http"
"github.com/labstack/echo"
) )
type Music struct { type Music struct {
@@ -15,86 +16,87 @@ func NewMusic() *Music {
return &Music{} return &Music{}
} }
func (m *Music) GetSong(ctx *gin.Context) { func (m *Music) GetSong(ctx echo.Context) error {
song := ctx.Query("song") song := ctx.QueryParam("song")
if song == "" { if song == "" {
ctx.String(http.StatusBadRequest, "song can't be empty") return ctx.String(http.StatusBadRequest, "song can't be empty")
} }
s := server.GetSong(song) s := server.GetSong(song)
helpers.SendSong(ctx, s) return helpers.SendSong(ctx, s)
} }
func (m *Music) GetSoundCheckSong(ctx *gin.Context) { func (m *Music) GetSoundCheckSong(ctx echo.Context) error {
song := server.GetSoundCheckSong() song := server.GetSoundCheckSong()
helpers.SendSong(ctx, song) return helpers.SendSong(ctx, song)
} }
func (m *Music) ResetMusic(ctx *gin.Context) { func (m *Music) ResetMusic(ctx echo.Context) error {
server.Reset() server.Reset()
ctx.Status(http.StatusOK) return ctx.NoContent(http.StatusOK)
} }
func (m *Music) GetRandomSong(ctx *gin.Context) { func (m *Music) GetRandomSong(ctx echo.Context) error {
song := server.GetRandomSong() song := server.GetRandomSong()
helpers.SendSong(ctx, song) return helpers.SendSong(ctx, song)
} }
func (m *Music) GetRandomSongLowChance(ctx *gin.Context) { func (m *Music) GetRandomSongLowChance(ctx echo.Context) error {
song := server.GetRandomSongLowChance() song := server.GetRandomSongLowChance()
helpers.SendSong(ctx, song) return helpers.SendSong(ctx, song)
} }
func (m *Music) GetRandomSongClassic(ctx *gin.Context) { func (m *Music) GetRandomSongClassic(ctx echo.Context) error {
song := server.GetRandomSongClassic() song := server.GetRandomSongClassic()
helpers.SendSong(ctx, song) return helpers.SendSong(ctx, song)
} }
func (m *Music) GetSongInfo(ctx *gin.Context) { func (m *Music) GetSongInfo(ctx echo.Context) error {
song := server.GetSongInfo() song := server.GetSongInfo()
ctx.JSON(http.StatusOK, song) return ctx.JSON(http.StatusOK, song)
} }
func (m *Music) GetPlayedSongs(ctx *gin.Context) { func (m *Music) GetPlayedSongs(ctx echo.Context) error {
songList := server.GetPlayedSongs() songList := server.GetPlayedSongs()
ctx.JSON(http.StatusOK, songList) return ctx.JSON(http.StatusOK, songList)
} }
func (m *Music) GetNextSong(ctx *gin.Context) { func (m *Music) GetNextSong(ctx echo.Context) error {
song := server.GetNextSong() song := server.GetNextSong()
helpers.SendSong(ctx, song) return helpers.SendSong(ctx, song)
} }
func (m *Music) GetPreviousSong(ctx *gin.Context) { func (m *Music) GetPreviousSong(ctx echo.Context) error {
song := server.GetPreviousSong() song := server.GetPreviousSong()
helpers.SendSong(ctx, song) return helpers.SendSong(ctx, song)
} }
func (m *Music) GetAllGames(ctx *gin.Context) { func (m *Music) GetAllGames(ctx echo.Context) error {
gameList := server.GetAllGames() gameList := server.GetAllGames()
ctx.JSON(http.StatusOK, gameList) return ctx.JSON(http.StatusOK, gameList)
} }
func (m *Music) GetAllGamesRandom(ctx *gin.Context) { func (m *Music) GetAllGamesRandom(ctx echo.Context) error {
gameList := server.GetAllGamesRandom() gameList := server.GetAllGamesRandom()
ctx.JSON(http.StatusOK, gameList) return ctx.JSON(http.StatusOK, gameList)
} }
func (m *Music) PutPlayed(ctx *gin.Context) { func (m *Music) PutPlayed(ctx echo.Context) error {
var played models.Played var played models.Played
if err := ctx.ShouldBindJSON(&played); err != nil { err := ctx.Bind(&played)
helpers.NewError(ctx, http.StatusBadRequest, err) if err != nil {
return //helpers.NewError(ctx, http.StatusBadRequest, err)
return ctx.JSON(http.StatusBadRequest, err)
} }
server.SetPlayed(played.Song) server.SetPlayed(played.Song)
ctx.Status(http.StatusOK) return ctx.NoContent(http.StatusOK)
} }
func (m *Music) AddLatestToQue(ctx *gin.Context) { func (m *Music) AddLatestToQue(ctx echo.Context) error {
server.AddLatestToQue() server.AddLatestToQue()
ctx.Status(http.StatusOK) return ctx.NoContent(http.StatusOK)
} }
func (m *Music) AddLatestPlayed(ctx *gin.Context) { func (m *Music) AddLatestPlayed(ctx echo.Context) error {
server.AddLatestPlayed() server.AddLatestPlayed()
ctx.Status(http.StatusOK) return ctx.NoContent(http.StatusOK)
} }
+19 -10
View File
@@ -1,10 +1,11 @@
package api package api
import ( import (
"log"
"music-server/pkg/server" "music-server/pkg/server"
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/labstack/echo"
) )
type Sync struct { type Sync struct {
@@ -14,25 +15,33 @@ func NewSync() *Sync {
return &Sync{} return &Sync{}
} }
func (s *Sync) SyncGames(ctx *gin.Context) { func (s *Sync) SyncGames(ctx echo.Context) error {
server.SyncGames() server.SyncGames()
server.Reset() server.Reset()
ctx.JSON(http.StatusOK, "Games are synced") return ctx.JSON(http.StatusOK, "Games are synced")
} }
func (s *Sync) SyncGamesQuick(ctx *gin.Context) { func (s *Sync) SyncGamesQuick(ctx echo.Context) error {
server.SyncGamesQuick() server.SyncGamesQuick()
server.Reset() server.Reset()
ctx.JSON(http.StatusOK, "Games are synced") return ctx.JSON(http.StatusOK, "Games are synced")
} }
func (s *Sync) SyncGamesNew(ctx *gin.Context) { func (s *Sync) SyncGamesNewOnlyChanges(ctx echo.Context) error {
response := server.SyncGamesNew() log.Println("Syncing games new")
response := server.SyncGamesNewOnlyChanges()
server.Reset() server.Reset()
ctx.JSON(http.StatusOK, response) return ctx.JSON(http.StatusOK, response)
} }
func (s *Sync) ResetGames(ctx *gin.Context) { func (s *Sync) SyncGamesNewFull(ctx echo.Context) error {
log.Println("Syncing games new full")
response := server.SyncGamesNewFull()
server.Reset()
return ctx.JSON(http.StatusOK, response)
}
func (s *Sync) ResetGames(ctx echo.Context) error {
server.ResetDB() server.ResetDB()
ctx.JSON(http.StatusOK, "Games and songs are deleted from the database") return ctx.JSON(http.StatusOK, "Games and songs are deleted from the database")
} }
+16 -124
View File
@@ -1,146 +1,38 @@
package conf package conf
import ( import (
"embed"
"fmt" "fmt"
"io/fs"
"log" "log"
"music-server/cmd/web"
"music-server/pkg/api"
"music-server/pkg/db" "music-server/pkg/db"
"music-server/pkg/helpers"
"music-server/pkg/server"
"net/http"
"os" "os"
"strconv" )
"github.com/a-h/templ" var (
"github.com/gin-contrib/static" host = os.Getenv("DB_HOST")
"github.com/gin-gonic/gin" dbPort = os.Getenv("DB_PORT")
database = os.Getenv("DB_NAME")
username = os.Getenv("DB_USERNAME")
password = os.Getenv("DB_PASSWORD")
musicPath = os.Getenv("MUSIC_PATH")
) )
func SetupDb() { func SetupDb() {
/*err := server.ReadConf("conf.yaml") if host == "" || dbPort == "" || username == "" || password == "" || database == "" || musicPath == "" {
if err != nil { log.Fatal("Invalid settings")
log.Fatal(err)
}*/
// Get the value of an Environment Variable
host := os.Getenv("DB_HOST")
dbPort, dbPortErr := strconv.Atoi(os.Getenv("DB_PORT"))
if dbPortErr != nil {
dbPort = 0
} }
username := os.Getenv("DB_USERNAME")
password := os.Getenv("DB_PASSWORD")
dbName := os.Getenv("DB_NAME")
fmt.Printf("host: %s, dbPort: %v, username: %s, password: %s, dbName: %s\n", fmt.Printf("host: %s, dbPort: %v, username: %s, password: %s, dbName: %s\n",
host, dbPort, username, password, dbName) host, dbPort, username, password, database)
if host == "" { log.Printf("Path: %s\n", musicPath)
host = "localhost"
}
if dbPort == 0 {
dbPort = 5432
}
if username == "" {
username = "postgres"
}
if password == "" {
password = "postgres"
}
if dbName == "" {
dbName = "music_test_local"
}
db.Migrate_db(host, dbPort, username, password, dbName) db.Migrate_db(host, dbPort, username, password, database)
db.InitDB(host, dbPort, username, password, dbName)
var dir string
if host != "localhost" {
dir = "/sorted/"
} else {
dir = "/Users/sebastian/ResilioSync/Sorterat_test/"
}
server.Conf = &server.Config{
Host: host,
Port: dbPort,
User: username,
Password: password,
Dbname: dbName,
Path: dir,
}
db.InitDB(host, dbPort, username, password, database)
} }
func CloseDb() { func CloseDb() {
defer db.CloseDb() fmt.Println("Closing connection to database")
} db.CloseDb()
func SetupRestServer(swagger embed.FS) {
router := gin.Default()
router.Use(helpers.SetCorsAndNoCacheHeaders())
sync := api.NewSync()
syncGroup := router.Group("/sync")
{
syncGroup.GET("", sync.SyncGames)
syncGroup.GET("/new", sync.SyncGamesNew)
syncGroup.GET("/quick", sync.SyncGamesQuick)
syncGroup.GET("/reset", sync.ResetGames)
}
music := api.NewMusic()
musicGroup := router.Group("/music")
{
musicGroup.GET("", music.GetSong)
musicGroup.GET("soundTest", music.GetSoundCheckSong)
musicGroup.GET("reset", music.ResetMusic)
musicGroup.GET("rand", music.GetRandomSong)
musicGroup.GET("rand/low", music.GetRandomSongLowChance)
musicGroup.GET("rand/classic", music.GetRandomSongClassic)
musicGroup.GET("info", music.GetSongInfo)
musicGroup.GET("list", music.GetPlayedSongs)
musicGroup.GET("next", music.GetNextSong)
musicGroup.GET("previous", music.GetPreviousSong)
musicGroup.GET("all", music.GetAllGamesRandom)
musicGroup.GET("all/order", music.GetAllGames)
musicGroup.GET("all/random", music.GetAllGamesRandom)
musicGroup.PUT("played", music.PutPlayed)
musicGroup.GET("addQue", music.AddLatestToQue)
musicGroup.GET("addPlayed", music.AddLatestPlayed)
}
index := api.NewIndex()
router.GET("/version", index.GetVersion)
router.GET("/health", index.GetDBTest)
router.StaticFS("/swagger", helpers.EmbedFolder(swagger, "swagger", false))
router.Use(static.Serve("/", static.LocalFile("/frontend", true)))
router.Use(static.Serve("/new", static.LocalFile("/newFrontend", true)))
staticFiles, _ := fs.Sub(web.Files, "assets")
router.StaticFS("/assets", http.FS(staticFiles))
router.GET("/search", func(c *gin.Context) {
templ.Handler(web.HelloForm()).ServeHTTP(c.Writer, c.Request)
})
router.POST("/find", func(c *gin.Context) {
web.FindGameWebHandler(c.Writer, c.Request)
})
port := os.Getenv("PORT")
if port == "" {
port = "8080"
log.Printf("Defaulting to port %s", port)
}
log.Printf("Open http://localhost:%s in the browser", port)
err := router.Run(fmt.Sprintf(":%s", port))
if err != nil {
panic(err)
}
} }
+4 -4
View File
@@ -20,9 +20,9 @@ import (
var Dbpool *pgxpool.Pool var Dbpool *pgxpool.Pool
var Ctx = context.Background() var Ctx = context.Background()
func InitDB(host string, port int, user string, password string, dbname string) { func InitDB(host string, port string, user string, password string, dbname string) {
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+ psqlInfo := fmt.Sprintf("host=%s port=%s user=%s "+
"password=%s dbname=%s sslmode=disable", "password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname) host, port, user, password, dbname)
@@ -72,8 +72,8 @@ func resetGameIdSeq() {
} }
} }
func Migrate_db(host string, port int, user string, password string, dbname string) { func Migrate_db(host string, port string, user string, password string, dbname string) {
migrationInfo := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=disable", migrationInfo := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
user, password, host, port, dbname) user, password, host, port, dbname)
fmt.Println("Migration Info: ", migrationInfo) fmt.Println("Migration Info: ", migrationInfo)
+15 -15
View File
@@ -3,7 +3,6 @@ package helpers
import ( import (
"embed" "embed"
"fmt" "fmt"
"io"
"io/fs" "io/fs"
"net/http" "net/http"
"os" "os"
@@ -12,6 +11,7 @@ import (
"github.com/gin-contrib/static" "github.com/gin-contrib/static"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/labstack/echo"
) )
func SetCorsAndNoCacheHeaders() gin.HandlerFunc { func SetCorsAndNoCacheHeaders() gin.HandlerFunc {
@@ -61,15 +61,15 @@ func EmbedFolder(fsEmbed embed.FS, targetPath string, index bool) static.ServeFi
} }
} }
func SendSong(ctx *gin.Context, Filename string) { func SendSong(ctx echo.Context, Filename string) error {
fmt.Println("Client requests: " + Filename) fmt.Println("Client requests: " + Filename)
//Check if file exists and open //Check if file exists and open
openFile, err := os.Open(Filename) openFile, err := os.Open(Filename)
if err != nil { if err != nil {
//File not found, send 404 //File not found, send 404
http.Error(ctx.Writer, "Song not found.", 404) //http.Error(ctx.Writer, "Song not found.", 404)
return return ctx.String(http.StatusNotFound, "Song not found.")
} }
defer func(openFile *os.File) { defer func(openFile *os.File) {
_ = openFile.Close() _ = openFile.Close()
@@ -91,13 +91,13 @@ func SendSong(ctx *gin.Context, Filename string) {
//Send the headers //Send the headers
//writer.Header().Set("Content-Disposition", "attachment; filename="+Filename) //writer.Header().Set("Content-Disposition", "attachment; filename="+Filename)
ctx.Writer.Header().Set("Content-Type", "audio/mpeg") ctx.Response().Header().Set("Content-Type", "audio/mpeg")
ctx.Writer.Header().Set("Content-Length", FileSize) ctx.Response().Header().Set("Content-Length", FileSize)
ctx.Writer.Header().Set("Expires", "Tue, 03 Jul 2001 06:00:00 GMT") ctx.Response().Header().Set("Expires", "Tue, 03 Jul 2001 06:00:00 GMT")
ctx.Writer.Header().Set("Last-Modified", time.Now().String()+" GMT") ctx.Response().Header().Set("Last-Modified", time.Now().String()+" GMT")
ctx.Writer.Header().Set("Cache-Control", "no-cache, no-store, private, max-age=0") ctx.Response().Header().Set("Cache-Control", "no-cache, no-store, private, max-age=0")
ctx.Writer.Header().Set("Pragma", "no-cache") ctx.Response().Header().Set("Pragma", "no-cache")
ctx.Writer.Header().Set("X-Accel-Expires", "0") ctx.Response().Header().Set("X-Accel-Expires", "0")
var etagHeaders = []string{ var etagHeaders = []string{
"ETag", "ETag",
@@ -109,14 +109,14 @@ func SendSong(ctx *gin.Context, Filename string) {
} }
for _, v := range etagHeaders { for _, v := range etagHeaders {
if ctx.Request.Header.Get(v) != "" { if ctx.Request().Header.Get(v) != "" {
ctx.Request.Header.Del(v) ctx.Request().Header.Del(v)
} }
} }
//Send the file //Send the file
//We read 512 bytes from the file already, so we reset the offset back to 0 //We read 512 bytes from the file already, so we reset the offset back to 0
_, _ = openFile.Seek(0, 0) _, _ = openFile.Seek(0, 0)
_, _ = io.Copy(ctx.Writer, openFile) //'Copy' the file to the client //_, _ = io.Copy(ctx.Writer, openFile) //'Copy' the file to the client
return return ctx.Stream(http.StatusOK, "audio/mpeg", openFile)
} }
-34
View File
@@ -1,34 +0,0 @@
package server
import (
"fmt"
"os"
"gopkg.in/yaml.v3"
)
type Config struct {
Host string
Port int
User string
Password string
Dbname string
Path string
}
var Conf *Config
func ReadConf(filename string) error {
buf, err := os.ReadFile(filename)
if err != nil {
return err
}
c := &Config{}
err = yaml.Unmarshal(buf, c)
if err != nil {
return fmt.Errorf("in file %q: %w", filename, err)
}
Conf = c
return err
}
+24 -6
View File
@@ -260,15 +260,30 @@ func checkBrokenSongs() {
} }
db.RemoveBrokenSongs(brokenSongs) db.RemoveBrokenSongs(brokenSongs)
} }
func SyncGamesNewFull() Response {
return syncGamesNew(true)
}
func SyncGamesNew() Response { func SyncGamesNewOnlyChanges() Response {
return syncGamesNew(false)
}
func syncGamesNew(full bool) Response {
musicPath := os.Getenv("MUSIC_PATH")
fmt.Printf("dir: %s\n", musicPath)
repo = repository.New(db.Dbpool) repo = repository.New(db.Dbpool)
start := time.Now() start := time.Now()
fmt.Printf("dir: %s\n", Conf.Path)
foldersToSkip := []string{".sync", "dist", "old"} foldersToSkip := []string{".sync", "dist", "old"}
fmt.Println(foldersToSkip) fmt.Println(foldersToSkip)
var err error var err error
gamesAdded = nil
gamesReAdded = nil
gamesChangedTitle = nil
gamesChangedContent = nil
gamesRemoved = nil
catchedErrors = nil
brokenSongs = nil
gamesBeforeSync, err = repo.FindAllGames(db.Ctx) gamesBeforeSync, err = repo.FindAllGames(db.Ctx)
handleError("FindAllGames Before", err, "") handleError("FindAllGames Before", err, "")
@@ -279,7 +294,7 @@ func SyncGamesNew() Response {
err = repo.SetGameDeletionDate(db.Ctx) err = repo.SetGameDeletionDate(db.Ctx)
handleError("SetGameDeletionDate", err, "") handleError("SetGameDeletionDate", err, "")
directories, err := os.ReadDir(Conf.Path) directories, err := os.ReadDir(musicPath)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@@ -288,7 +303,7 @@ func SyncGamesNew() Response {
for _, dir := range directories { for _, dir := range directories {
go func() { go func() {
defer syncWg.Done() defer syncWg.Done()
syncGameNew(dir, foldersToSkip, Conf.Path) syncGameNew(dir, foldersToSkip, musicPath, full)
}() }()
} }
syncWg.Wait() syncWg.Wait()
@@ -339,7 +354,7 @@ func SyncGamesNew() Response {
for _, game := range gamesRemovedTemp { for _, game := range gamesRemovedTemp {
var found bool = false var found bool = false
for key, _ := range gamesChangedTitle { for key := range gamesChangedTitle {
if game == key { if game == key {
found = true found = true
//fmt.Printf("Game: %s, Found: %v break2\n", game, found) //fmt.Printf("Game: %s, Found: %v break2\n", game, found)
@@ -408,7 +423,7 @@ func checkBrokenSongNew(song repository.Song) {
} }
} }
func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string) { func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string, full bool) {
if file.IsDir() && !contains(foldersToSkip, file.Name()) { if file.IsDir() && !contains(foldersToSkip, file.Name()) {
gameDir := baseDir + file.Name() + "/" gameDir := baseDir + file.Name() + "/"
@@ -441,6 +456,9 @@ func syncGameNew(file os.DirEntry, foldersToSkip []string, baseDir string) {
} }
} }
if full {
status = TitleChanged
}
entries, err := os.ReadDir(gameDir) entries, err := os.ReadDir(gameDir)
if err != nil { if err != nil {
log.Println(err) log.Println(err)