From 43a9cf5a7e240822f843a77723c72ca64e9dcf1c Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Wed, 11 Feb 2026 11:52:34 +1100 Subject: [PATCH] bugfix --- .drone.yml | 9 ++++++++- Dockerfile | 7 +++++-- changelog-beta.md | 15 ++++++++++++++- go.mod | 13 +++++++++---- go.sum | 12 ++++++++++++ src/buffer.go | 12 +++++++----- src/provider.go | 14 +++++++++++--- src/system.go | 7 ++++++- src/user_agent.go | 15 +++++++++++++++ src/xepg.go | 2 +- xteve.go | 3 ++- 11 files changed, 90 insertions(+), 19 deletions(-) create mode 100644 src/user_agent.go diff --git a/.drone.yml b/.drone.yml index ac289f0..86f93bc 100644 --- a/.drone.yml +++ b/.drone.yml @@ -12,7 +12,14 @@ steps: - name: go-build image: cache.coadcorp.com/library/golang commands: - - go build -v ./... + - XTEVE_VERSION="$(awk '/^#### /{print $2; exit}' changelog-beta.md)" + - XTEVE_VERSION="${XTEVE_VERSION%-beta}" + - SOURCE_VERSION="$(sed -nE 's/^(const|var) Version = \"([^\"]+)\"/\\2/p' xteve.go | head -n1)" + - test -n "${XTEVE_VERSION}" || (echo "Could not parse version from changelog-beta.md" && exit 1) + - test -n "${SOURCE_VERSION}" || (echo "Could not parse source version from xteve.go" && exit 1) + - test "${SOURCE_VERSION}" = "${XTEVE_VERSION}" || (echo "Version mismatch: changelog=${XTEVE_VERSION} source=${SOURCE_VERSION}" && exit 1) + - echo "Building xTeVe version ${XTEVE_VERSION} from changelog-beta.md" + - go build -v -ldflags "-X main.Version=${XTEVE_VERSION}" ./... - name: dockerfile-lint image: cache.coadcorp.com/library/hadolint/hadolint:v2.12.0-alpine diff --git a/Dockerfile b/Dockerfile index 3f7db6a..eef90dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,8 +12,11 @@ COPY . . ARG TARGETOS ARG TARGETARCH -RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \ - go build -trimpath -ldflags='-s -w' -o /out/xteve ./xteve.go +RUN XTEVE_VERSION="$(awk '/^#### /{print $2; exit}' changelog-beta.md)" \ + && XTEVE_VERSION="${XTEVE_VERSION%-beta}" \ + && test -n "${XTEVE_VERSION}" \ + && CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \ + go build -trimpath -ldflags="-s -w -X main.Version=${XTEVE_VERSION}" -o /out/xteve ./xteve.go FROM alpine:3.20 diff --git a/changelog-beta.md b/changelog-beta.md index dae577c..1ab1555 100644 --- a/changelog-beta.md +++ b/changelog-beta.md @@ -1,3 +1,16 @@ +#### 2.2.0.0200-beta +```diff ++ Major web UI redesign focused on cleaner layout, better information hierarchy, and faster daily workflows. ++ Large mobile UX overhaul: responsive navigation, improved spacing, touch-friendly controls, and better small-screen mapping/config flows. ++ Accessibility pass across auth, configuration, and main app screens (focus visibility, keyboard flow, ARIA/announcer updates, contrast and status feedback improvements). ++ Settings UX improvements and additional polish in frontend behavior for menu, configuration, and authentication interactions. ++ Added optional Plex API refresh integration with new settings: use_plexAPI, plex.url, plex.token. ++ Added debounced/queued Plex DVR guide reload workflow after lineup and XEPG updates to reduce manual refresh work in Plex. ++ Container/runtime improvements and validation updates for easier, safer container usage. ++ Added Drone CI pipeline for tests/build checks, Docker/Compose validation, and Docker image publishing to registry.coadcorp.com via plugins/docker. ++ Pipeline build version is now derived from changelog-beta.md and validated against source version to prevent release/version drift. +``` + #### 2.1.1.0116-beta If no user agent is specified, the default FFmpeg or VLC user agent is used. @@ -85,4 +98,4 @@ Settings from the current beta can not be used for the current master version 2. + Wizard: Add HTML input placeholder (M3U, XMLTV) + Wizard: Alert by empty value (M3U, XMLTV) + Image caching: Ignore invalid image URLs -``` \ No newline at end of file +``` diff --git a/go.mod b/go.mod index 3ae8132..483d43f 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,14 @@ module xteve -go 1.16 +go 1.25 require ( - github.com/gorilla/websocket v1.4.2 // indirect - github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect - github.com/koron/go-ssdp v0.0.2 // indirect + github.com/gorilla/websocket v1.5.3 + github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 + github.com/koron/go-ssdp v0.1.0 +) + +require ( + golang.org/x/net v0.50.0 // indirect + golang.org/x/sys v0.41.0 // indirect ) diff --git a/go.sum b/go.sum index 55714e3..b9a9714 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,28 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/koron/go-ssdp v0.0.2 h1:fL3wAoyT6hXHQlORyXUW4Q23kkQpJRgEAYcZB5BR71o= github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs= +github.com/koron/go-ssdp v0.1.0 h1:ckl5x5H6qSNFmi+wCuROvvGUu2FQnMbQrU95IHCcv3Y= +github.com/koron/go-ssdp v0.1.0/go.mod h1:GltaDBjtK1kemZOusWYLGotV0kBeEf59Bp0wtSB0uyU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/src/buffer.go b/src/buffer.go index 7af38e7..8bdcf51 100644 --- a/src/buffer.go +++ b/src/buffer.go @@ -657,7 +657,7 @@ func connectToStreamingServer(streamID int, playlistID string) { Redirect: req, err := http.NewRequest("GET", currentURL, nil) - req.Header.Set("User-Agent", Settings.UserAgent) + req.Header.Set("User-Agent", getUserAgent()) req.Header.Set("Connection", "close") //req.Header.Set("Range", "bytes=0-") req.Header.Set("Accept", "*/*") @@ -1423,14 +1423,16 @@ func thirdPartyBuffer(streamID int, playlistID string) { // User-Agent setzen var args []string + var userAgent = getUserAgent() + for i, a := range strings.Split(options, " ") { switch bufferType { case "FFMPEG": a = strings.Replace(a, "[URL]", url, -1) if i == 0 { - if len(Settings.UserAgent) != 0 { - args = []string{"-user_agent", Settings.UserAgent} + if len(userAgent) != 0 { + args = []string{"-user_agent", userAgent} } } @@ -1441,8 +1443,8 @@ func thirdPartyBuffer(streamID int, playlistID string) { a = strings.Replace(a, "[URL]", url, -1) args = append(args, a) - if len(Settings.UserAgent) != 0 { - args = append(args, fmt.Sprintf(":http-user-agent=%s", Settings.UserAgent)) + if len(userAgent) != 0 { + args = append(args, fmt.Sprintf(":http-user-agent=%s", userAgent)) } } else { diff --git a/src/provider.go b/src/provider.go index f376b3a..56fd782 100644 --- a/src/provider.go +++ b/src/provider.go @@ -282,15 +282,23 @@ func downloadFileFromServer(providerURL string) (filename string, body []byte, e return } - resp, err := http.Get(providerURL) + req, err := http.NewRequest(http.MethodGet, providerURL, nil) if err != nil { return } - resp.Header.Set("User-Agent", Settings.UserAgent) + req.Header.Set("User-Agent", getUserAgent()) + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return + } + + defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - err = fmt.Errorf(fmt.Sprintf("%d: %s "+http.StatusText(resp.StatusCode), resp.StatusCode, providerURL)) + err = fmt.Errorf("%d: %s %s", resp.StatusCode, providerURL, http.StatusText(resp.StatusCode)) return } diff --git a/src/system.go b/src/system.go index b1ef51c..592b34a 100644 --- a/src/system.go +++ b/src/system.go @@ -136,7 +136,7 @@ func loadSettings() (settings SettingsStruct, err error) { defaults["ssdp"] = true defaults["tuner"] = 1 defaults["update"] = []string{"0000"} - defaults["user.agent"] = System.Name + defaults["user.agent"] = defaultUserAgent defaults["uuid"] = createUUID() defaults["udpxy"] = "" defaults["version"] = System.DBVersion @@ -204,6 +204,11 @@ func saveSettings(settings SettingsStruct) (err error) { settings.BufferTimeout = 0 } + var userAgent = strings.TrimSpace(settings.UserAgent) + if len(userAgent) == 0 || userAgent == System.Name { + settings.UserAgent = defaultUserAgent + } + System.Folder.Temp = settings.TempPath + settings.UUID + string(os.PathSeparator) err = writeByteToFile(System.File.Settings, []byte(mapToJSON(settings))) diff --git a/src/user_agent.go b/src/user_agent.go new file mode 100644 index 0000000..c1341c6 --- /dev/null +++ b/src/user_agent.go @@ -0,0 +1,15 @@ +package src + +import "strings" + +const defaultUserAgent = "otg/1.5.1 (AppleTv Apple TV 4; tvOS16.0; appletv.client) libcurl/7.58.0 OpenSSL/1.0.2o zlib/1.2.11 clib/1.8.56" + +func getUserAgent() string { + + var userAgent = strings.TrimSpace(Settings.UserAgent) + if len(userAgent) == 0 { + return defaultUserAgent + } + + return userAgent +} diff --git a/src/xepg.go b/src/xepg.go index 8ebc6a1..06f2d18 100644 --- a/src/xepg.go +++ b/src/xepg.go @@ -542,7 +542,7 @@ func mapping() (err error) { if xepgChannel.XActive == false { // Werte kann "-" sein, deswegen len < 1 - if len(xepgChannel.XmltvFile) < 1 && len(xepgChannel.XmltvFile) < 1 { + if len(xepgChannel.XmltvFile) < 1 && len(xepgChannel.XMapping) < 1 { var tvgID = xepgChannel.TvgID diff --git a/xteve.go b/xteve.go index 36a9546..f134598 100644 --- a/xteve.go +++ b/xteve.go @@ -39,7 +39,8 @@ var GitHub = GitHubStruct{Branch: "master", User: "xteve-project", Repo: "xTeVe- const Name = "xTeVe" // Version : Version, die Build Nummer wird in der main func geparst. -const Version = "2.2.0.0200" +// Can be overwritten at build time: -ldflags "-X main.Version=..." +var Version = "2.2.0.0200" // DBVersion : Datanbank Version const DBVersion = "2.1.0"