diff --git a/aur/PKGBUILD b/aur/PKGBUILD deleted file mode 100644 index 3f7f4f9..0000000 --- a/aur/PKGBUILD +++ /dev/null @@ -1,53 +0,0 @@ -# Maintainer: Ricardo Band - -pkgname=sanic -pkgver=0.0.1 -pkgrel=1 -pkgdesc="chaos music control inspired by relaxx player" -arch=('any') -url=https://git.berlin.ccc.de/cccb/sanic -license=('custom:MIT') -makedepends=('go') -source=("$pkgname.service" - "$pkgname.sysusers" - "$pkgname.tmpfiles" - "$url/archive/v$pkgver.tar.gz") -sha256sums=("1337deadbeef" - "1337deadbeef" - "1337deadbeef" - "1337deadbeef") - -prepare() { - cd "$pkgname-$pkgver" - - mkdir -p build/ -} - -build() { - cd "$pkgname-$pkgver" - - export CGO_CPPFLAGS="$CPPFLAGS" - export CGO_CFLAGS="$CFLAGS" - export CGO_CXXFLAGS="$CXXFLAGS" - export CGO_LDFLAGS="$LDFLAGS" - export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw" - - go build -o build/ . -} - -check() { - cd "$pkgname-$pkgver" - - go test ./... -} - -package() { - cd "$pkgname-$pkgver" - - install -Dm644 "LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE" - install -Dm755 build/$pkgname "$pkgdir"/usr/bin/$pkgname - install -Dm644 "../$pkgname.service" "$pkgdir/usr/lib/systemd/system/$pkgname.service" - install -Dm644 "../$pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgname.conf" - install -Dm644 "../$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf" -} - diff --git a/aur/sanic.service b/aur/sanic.service deleted file mode 100644 index 0afa7e9..0000000 --- a/aur/sanic.service +++ /dev/null @@ -1,28 +0,0 @@ -[Unit] -Description=chaos music control -After=network-online.target -Wants=network-online.target - -[Service] -Type=simple -User=sanic -Group=sanic -ExecStart=/usr/bin/sanic -Restart=always -# security -NoNewPrivileges=true -ProtectSystem=strict -ProtectHome=yes -StateDirectory=sanic -StateDirectoryMode=0750 -ConfigurationDirectory=sanic -ConfigurationDirectoryMode=0750 -PrivateTmp=true -ProtectKernelTunables=true -ProtectKernelModules=true -ProtectKernelLogs=true -ProtectControlGroups=true - -[Install] -WantedBy=multi-user.target - diff --git a/aur/sanic.sysusers b/aur/sanic.sysusers deleted file mode 100644 index a286acc..0000000 --- a/aur/sanic.sysusers +++ /dev/null @@ -1,3 +0,0 @@ -u sanic - "chaos music control" /run/sanic /usr/bin/nologin -g sanic - - - diff --git a/aur/sanic.tmpfiles b/aur/sanic.tmpfiles deleted file mode 100644 index cff6c68..0000000 --- a/aur/sanic.tmpfiles +++ /dev/null @@ -1,3 +0,0 @@ -d /etc/sanic 0750 sanic sanic -d /run/sanic 0750 sanic sanic - diff --git a/flake.nix b/flake.nix index 80aa871..8bc75c6 100644 --- a/flake.nix +++ b/flake.nix @@ -37,119 +37,7 @@ ]; }; packages.default = sanic; - nixosModules.default = { config, lib, pkgs, options, ... }: - let - cfg = config.services.sanic; - configFile = pkgs.writeText "config.ini" (pkgs.lib.generators.toINI {} cfg); - execCommand = "${cfg.package}/bin/sanic -c '${configFile}'"; - in - { - options.services.sanic = { - enable = lib.mkEnableOption "Enables the sanic systemd service."; - package = lib.mkOption { - description = "Package to use."; - type = lib.types.package; - default = sanic; - }; - ui = lib.mkOption { - description = "Setting for HTTP(S) UI."; - example = lib.literalExpression '' - { - host = "[::1]"; - port = 8443; - tls = true; - certificate = "${config.security.acme.certs."sanic.example.com".directory}/fullchain.pem"; - key = "${config.security.acme.certs."sanic.example.com".directory}/key.pem"; - } - ''; - default = { - host = "[::1]"; - port = 80; - tls = false; - }; - type = lib.types.submodule { - options = { - host = lib.mkOption { - type = lib.types.str; - default = "[::1]"; - description = "Host to bind to."; - }; - port = lib.mkOption { - type = lib.types.port; - default = 8080; - description = "Port to listen on."; - }; - tls = lib.mkOption { - type = lib.types.bool; - default = false; - description = "Enables HTTPS."; - }; - certificate = lib.mkOption { - type = lib.types.nullOr lib.types.path; - default = null; - description = "Path to TLS certificate for HTTPS."; - }; - key = lib.mkOption { - type = lib.types.nullOr lib.types.path; - default = null; - description = "Path to TLS key for HTTPS."; - }; - }; - }; - }; - backend = lib.mkOption { - description = "Configure MPD backend."; - example = lib.literalExpression '' - { - host = "localhost"; - port = 6600; - } - ''; - default = { - host = "localhost"; - port = 6600; - }; - type = lib.types.submodule { - options = { - host = lib.mkOption { - type = lib.types.str; - default = "localhost"; - description = "Hostname or IP of MPD instance."; - }; - port = lib.mkOption { - type = lib.types.port; - default = 6600; - description = "Port of MPD instance."; - }; - }; - }; - }; - }; - - config = lib.mkIf cfg.enable { - systemd.services."sanic" = { - description = "sanic - chaos music control"; - wants = [ "network-online.target" ]; - after = [ "network-online.target" ]; - serviceConfig = { - Restart = "always"; - RestartSec = 30; - ExecStart = execCommand; - User = "sanic"; - Group = "sanic"; - AmbientCapabilities = lib.mkIf (cfg.ui.port < 1000) [ "CAP_NET_BIND_SERVICE" ]; - CapabilityBoundingSet = lib.mkIf (cfg.ui.port < 1000) [ "CAP_NET_BIND_SERVICE" ]; - NoNewPrivileges = true; - }; - wantedBy = [ "multi-user.target" ]; - }; - }; - - #meta = { - # maintainers = with lib.maintainers; [ xengi ]; - # doc = ./default.xml; - #}; - }; + nixosModules.default = import ./option.nix; } ); } diff --git a/go.mod b/go.mod index 71d5a15..9577231 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/fhs/gompd/v2 v2.3.0 github.com/labstack/echo-contrib v0.17.1 github.com/labstack/echo/v4 v4.12.0 + github.com/tdewolff/minify/v2 v2.24.0 gopkg.in/ini.v1 v1.67.0 ) @@ -21,11 +22,12 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/tdewolff/parse/v2 v2.8.3 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect golang.org/x/crypto v0.26.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.30.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/go.sum b/go.sum index f056cf3..d337aa6 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,12 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tdewolff/minify/v2 v2.24.0 h1:m6j8VXvgUtmkavubzHbaNTXi9tw3hjIMZbdc57SRdvI= +github.com/tdewolff/minify/v2 v2.24.0/go.mod h1:uqtSu3w0+anqk4ofcsuLPZ8tV8yAZL1r/ILWYYl2j3c= +github.com/tdewolff/parse/v2 v2.8.3 h1:5VbvtJ83cfb289A1HzRA9sf02iT8YyUwN84ezjkdY1I= +github.com/tdewolff/parse/v2 v2.8.3/go.mod h1:Hwlni2tiVNKyzR1o6nUs4FOF07URA+JLBLd6dlIXYqo= +github.com/tdewolff/test v1.0.11 h1:FdLbwQVHxqG16SlkGveC0JVyrJN62COWTRyUFzfbtBE= +github.com/tdewolff/test v1.0.11/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= 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= @@ -45,8 +51,8 @@ golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= diff --git a/mpd.go b/mpd.go index 5e4cf37..6268441 100644 --- a/mpd.go +++ b/mpd.go @@ -1,12 +1,13 @@ package main import ( - "fmt" - "github.com/fhs/gompd/v2/mpd" - "github.com/labstack/echo/v4" - "net/http" - "strconv" - "time" + "fmt" + "net/http" + "strconv" + "time" + + "github.com/fhs/gompd/v2/mpd" + "github.com/labstack/echo/v4" ) // MPD API calls diff --git a/option.nix b/option.nix new file mode 100644 index 0000000..4ce3e1e --- /dev/null +++ b/option.nix @@ -0,0 +1,114 @@ +{ config, lib, pkgs, options, ... }: + +let + cfg = config.services.sanic; + configFile = pkgs.writeText "config.ini" (pkgs.lib.generators.toINI {} cfg); + execCommand = "${cfg.package}/bin/sanic -c '${configFile}'"; +in +{ + options.services.sanic = { + enable = lib.mkEnableOption "Enables the sanic systemd service."; + package = lib.mkOption { + description = "Package to use."; + type = lib.types.package; + default = sanic; + }; + ui = lib.mkOption { + description = "Setting for HTTP(S) UI."; + example = lib.literalExpression '' + { + host = "[::1]"; + port = 8443; + tls = true; + certificate = "${config.security.acme.certs."sanic.example.com".directory}/fullchain.pem"; + key = "${config.security.acme.certs."sanic.example.com".directory}/key.pem"; + } + ''; + default = { + host = "[::1]"; + port = 80; + tls = false; + }; + type = lib.types.submodule { + options = { + host = lib.mkOption { + type = lib.types.str; + default = "[::1]"; + description = "Host to bind to."; + }; + port = lib.mkOption { + type = lib.types.port; + default = 8080; + description = "Port to listen on."; + }; + tls = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enables HTTPS."; + }; + certificate = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to TLS certificate for HTTPS."; + }; + key = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to TLS key for HTTPS."; + }; + }; + }; + }; + backend = lib.mkOption { + description = "Configure MPD backend."; + example = lib.literalExpression '' + { + host = "localhost"; + port = 6600; + } + ''; + default = { + host = "localhost"; + port = 6600; + }; + type = lib.types.submodule { + options = { + host = lib.mkOption { + type = lib.types.str; + default = "localhost"; + description = "Hostname or IP of MPD instance."; + }; + port = lib.mkOption { + type = lib.types.port; + default = 6600; + description = "Port of MPD instance."; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services."sanic" = { + description = "sanic - chaos music control"; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + serviceConfig = { + Restart = "always"; + RestartSec = 30; + ExecStart = execCommand; + User = "sanic"; + Group = "sanic"; + AmbientCapabilities = lib.mkIf (cfg.ui.port < 1000) [ "CAP_NET_BIND_SERVICE" ]; + CapabilityBoundingSet = lib.mkIf (cfg.ui.port < 1000) [ "CAP_NET_BIND_SERVICE" ]; + NoNewPrivileges = true; + }; + wantedBy = [ "multi-user.target" ]; + }; + }; + + #meta = { + # maintainers = with lib.maintainers; [ xengi ]; + # doc = ./default.xml; + #}; +} diff --git a/sanic.container b/sanic.container index 2f6983a..add32d5 100644 --- a/sanic.container +++ b/sanic.container @@ -26,4 +26,3 @@ TimeoutStartSec=900 [Install] WantedBy=multi-user.target default.target - diff --git a/server.go b/server.go index 233c4dc..a8760ae 100644 --- a/server.go +++ b/server.go @@ -1,24 +1,29 @@ package main import ( - "fmt" - "github.com/labstack/echo-contrib/echoprometheus" - "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" - "gopkg.in/ini.v1" - "net/http" - "os" - "os/exec" + "embed" + "fmt" + "net/http" + "os" + "os/exec" + + "github.com/labstack/echo-contrib/echoprometheus" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "gopkg.in/ini.v1" ) -// Config holds the configuration for the mpd connection and for the web server. +//go:embed static/* +var staticFS embed.FS + +// Config holds the configuration for the mpd backend connection and for the web server. type Config struct { - MPD struct { + BACKEND struct { Hostname string `ini:"hostname"` Port int `ini:"port"` Username string `ini:"username"` Password string `ini:"password"` - } `ini:"mpd"` + } `ini:"backend"` UI struct { Hostname string `ini:"hostname"` Port int `ini:"port"` diff --git a/services.nix b/services.nix deleted file mode 100644 index 5303b42..0000000 --- a/services.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ self, ...}: {config, lib, pkgs, ...}: - -let - cfg = config.services.sanic; - format = pkgs.formats.ini { }; -in -{ - options.services.sanic = { - enable = mkEnableOption (lib.mdDoc "sanic"); - settings = mkOption { - type = format.type; - default = { }; - description = lib.mkDoc '' - ''; - }; - }; - - config = mkIf cfg.enable { - systemd.services.sanic = { - description = "chaos music control"; - wantedBy = [ "multi-user.target" "default.target" ]; - serviceConfig = { - DynamicUser = true; - ExecStart = "${self.packages.${pkgs.system}.default}/bin/sanic"; - Restart = "on-failure"; - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; - }; - }; - }; -} diff --git a/sse.go b/sse.go index 97fa230..554c3ad 100644 --- a/sse.go +++ b/sse.go @@ -1,13 +1,14 @@ package main import ( - "bytes" - "encoding/json" - "fmt" - "github.com/fhs/gompd/v2/mpd" - "github.com/labstack/echo/v4" - "io" - "time" + "bytes" + "encoding/json" + "fmt" + "io" + "time" + + "github.com/fhs/gompd/v2/mpd" + "github.com/labstack/echo/v4" ) // Event represents Server-Sent Event. diff --git a/static/style.css b/static/css/style.css similarity index 100% rename from static/style.css rename to static/css/style.css diff --git a/static/treeview.css b/static/css/treeview.css similarity index 100% rename from static/treeview.css rename to static/css/treeview.css diff --git a/static/index.html b/static/index.html index 531509d..7515cd7 100644 --- a/static/index.html +++ b/static/index.html @@ -1,11 +1,38 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sanic - - - + + + @@ -17,7 +44,7 @@ - +
@@ -63,20 +90,20 @@
-
+
- + - +
@@ -179,7 +206,7 @@ - +
actions diff --git a/static/index.js b/static/js/index.js similarity index 99% rename from static/index.js rename to static/js/index.js index 5bebb7a..20980e6 100644 --- a/static/index.js +++ b/static/js/index.js @@ -157,7 +157,6 @@ dialog_save_playlist_close.addEventListener("click", () => { dialog_save_playlist.close() }); - // Add API calls to controls control_search_submit.addEventListener("click", event => { @@ -215,8 +214,6 @@ control_delete_playlist.addEventListener("click", () => { }); }); -// Add API calls to controls - control_update_db.addEventListener("click", (event) => { console.log("Issuing database update"); fetch(`${API_URL}/update_db`).then(async r => { diff --git a/static/sse.js b/static/js/sse.js similarity index 100% rename from static/sse.js rename to static/js/sse.js