diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/.gitignore /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/.gitignore --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/.gitignore 2024-11-19 21:29:46.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/.gitignore 2024-11-19 13:16:52.000000000 +0000 @@ -37,9 +37,9 @@ config.toml -qt6 data remote.go changelog_reader.go http_client.go +telemetry.go *.log diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/Makefile /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/Makefile --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/Makefile 2024-11-20 15:17:48.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/Makefile 2024-11-19 13:16:52.000000000 +0000 @@ -444,5 +444,5 @@ fi; \ fi - go build -v -ldflags="-X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.packaged=$(PACKAGED) -X main.packageFormat=$(PACKAGEFORMAT) -X main.branch=$(BRANCH) -X main.date=$(DATE) $(EXTRALDFLAGS)" $(EXTRAGOFLAGS) -o $(TARGET) -tags "$(BUILDTAGS)" . + go build -v -ldflags="-X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.packaged=$(PACKAGED) -X main.packageFormat=$(PACKAGEFORMAT) -X main.branch=$(BRANCH) $(EXTRALDFLAGS)" $(EXTRAGOFLAGS) -o $(TARGET) -tags "$(BUILDTAGS)" . .PHONY: spell diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/PKGBUILD /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/PKGBUILD --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/PKGBUILD 2024-11-20 15:18:18.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/PKGBUILD 2024-11-19 13:18:28.000000000 +0000 @@ -2,5 +2,5 @@ pkgname=rokon -pkgver=1.0.0+082b1c4 +pkgver=1.0.0+95c38a7 pkgrel=1 epoch=0 diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/PRIVACY.md /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/PRIVACY.md --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/PRIVACY.md 2024-11-20 15:17:48.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/PRIVACY.md 2024-11-19 13:16:52.000000000 +0000 @@ -18,5 +18,5 @@ - Your Roku's operating system ie `Roku/13.1.4 UPnP/1.0 Roku/13.1.4` - General Region ie `United States` -- How many times you've run the application ie `19`, minutesActive ie `320` +- How many times you've ran the application ie `19`, minutesActive ie `320` All this data helps to improve Rokon as it is [Free software](https://www.gnu.org/licenses/agpl-3.0.en.html). Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: aboutWindow.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: cli.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: contextMenu.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: displayChangelog.go diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/flathub/go.mod.yml /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/flathub/go.mod.yml --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/flathub/go.mod.yml 2024-11-20 15:17:48.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/flathub/go.mod.yml 2024-11-19 13:16:52.000000000 +0000 @@ -38,9 +38,4 @@ type: archive url: https://proxy.golang.org/github.com/koron/go-ssdp/@v/v0.0.4.zip -- dest: vendor/github.com/spf13/viper - sha256: 5b773a712a646ff2f1bca4c45d50853e881ad8f6c363ca30fab1c4a9b19e59b2 - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/spf13/viper/@v/v1.19.0.zip - dest: vendor/golang.org/x/mod sha256: 0d0a96054b32dfa40cec2a2868bf87cdda31e3bb2dac0a5e2218efe3ef3ef3cc @@ -48,79 +43,19 @@ type: archive url: https://proxy.golang.org/golang.org/x/mod/@v/v0.22.0.zip -- dest: vendor/github.com/KarpelesLab/weak - sha256: 95beab3258f52af7133a707f6e6dc53f52e84dc7d81857b9022267146e3fdc0e - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/!karpeles!lab/weak/@v/v0.1.1.zip -- dest: vendor/github.com/fsnotify/fsnotify - sha256: f98f08a95224f2c7a77b62aa4840cefe4970f0ff00e0a027d7e457c3df752bb2 - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/fsnotify/fsnotify/@v/v1.7.0.zip -- dest: vendor/github.com/hashicorp/hcl - sha256: 54149a2e5121b3e81f961c79210e63d6798eb63de28d2599ee59ade1fa76c82b +- dest: vendor/github.com/davecgh/go-spew + sha256: b4d0923b169b194f0016ec46f3df1ab0c68e27999743e43fe2de59ecb2484128 strip-components: 3 type: archive - url: https://proxy.golang.org/github.com/hashicorp/hcl/@v/v1.0.0.zip -- dest: vendor/github.com/magiconair/properties - sha256: ae77e5969fe064035fb543004478c3a819f95bb7bc1da084435bb2134532aaa7 + url: https://proxy.golang.org/github.com/davecgh/go-spew/@v/v1.1.2-0.20180830191138-d8f796af33cc.zip +- dest: vendor/github.com/pmezard/go-difflib + sha256: 24ff45e356f638a53bd0c89fff961fbeaecfdb0dc5e482ceed0a2230e0e5f3b7 strip-components: 3 type: archive - url: https://proxy.golang.org/github.com/magiconair/properties/@v/v1.8.7.zip -- dest: vendor/github.com/mitchellh/mapstructure - sha256: 118d5b2cb65c50dba967fb6d708f450a9caf93f321f8fc99080675b2ee374199 - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/mitchellh/mapstructure/@v/v1.5.0.zip -- dest: vendor/github.com/pelletier/go-toml/v2 - sha256: 8d724e35b485503810f866bca278d518e731713441e380634f6b33c27aefdf3e - strip-components: 4 - type: archive - url: https://proxy.golang.org/github.com/pelletier/go-toml/v2/@v/v2.2.2.zip -- dest: vendor/github.com/sagikazarmark/locafero - sha256: 9d46f8f58d29c0c9f96fe65c8e324aae5aab1e6497e8658d31407b101cceb912 - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/sagikazarmark/locafero/@v/v0.4.0.zip -- dest: vendor/github.com/sagikazarmark/slog-shim - sha256: 20b764879fb481aebdcef5eb9ce044fec48e3414d256571b632f1adb1778bfef - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/sagikazarmark/slog-shim/@v/v0.1.0.zip -- dest: vendor/github.com/sourcegraph/conc - sha256: 98d3147d14fbd070099a61c37b65c5ccd95a1823cade101c4c5a04c1b1ba6576 - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/sourcegraph/conc/@v/v0.3.0.zip -- dest: vendor/github.com/spf13/afero - sha256: 70ae59086db6bfb64b509f597c8eff3d7ab56f8f0052f947f67b68899da3491c - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/spf13/afero/@v/v1.11.0.zip -- dest: vendor/github.com/spf13/cast - sha256: ee938d479c19c4cacc5e1bebd71fa5a4d00b84f4d71ee527a96a8adb7e0736e8 - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/spf13/cast/@v/v1.6.0.zip -- dest: vendor/github.com/spf13/pflag - sha256: fc6e704f2f6a84ddcdce6de0404e5340fa20c8676181bf5d381b17888107ba84 - strip-components: 3 - type: archive - url: https://proxy.golang.org/github.com/spf13/pflag/@v/v1.0.5.zip -- dest: vendor/github.com/subosito/gotenv - sha256: 142db3dd2328e744c157e85cf3291d027013b79f92a45984f860fe38bc0f1f8d + url: https://proxy.golang.org/github.com/pmezard/go-difflib/@v/v1.0.1-0.20181226105442-5d4384ee4fb2.zip +- dest: vendor/github.com/KarpelesLab/weak + sha256: 95beab3258f52af7133a707f6e6dc53f52e84dc7d81857b9022267146e3fdc0e strip-components: 3 type: archive - url: https://proxy.golang.org/github.com/subosito/gotenv/@v/v1.6.0.zip -- dest: vendor/go.uber.org/atomic - sha256: 6a1b34a0510c5d0d09f141b3afcd40e6500a2005f5f36578e29b5fc6dc64c24a - strip-components: 2 - type: archive - url: https://proxy.golang.org/go.uber.org/atomic/@v/v1.9.0.zip -- dest: vendor/go.uber.org/multierr - sha256: b029b936a6b10ae3fa158e14f89910da317bd678fc66f51f9c4612098005d367 - strip-components: 2 - type: archive - url: https://proxy.golang.org/go.uber.org/multierr/@v/v1.9.0.zip + url: https://proxy.golang.org/github.com/!karpeles!lab/weak/@v/v0.1.1.zip - dest: vendor/go4.org/unsafe/assume-no-moving-gc sha256: e9f5fa7ec7ae45153c6cb5b0c21e813860f9a4370b35ed1ab27398ba365dbb43 @@ -148,17 +83,2 @@ type: archive url: https://proxy.golang.org/golang.org/x/sys/@v/v0.27.0.zip -- dest: vendor/golang.org/x/text - sha256: 73b665d0df2cca11badc259586ccb0ba1101637d669d7abaafb27b90b7c028af - strip-components: 3 - type: archive - url: https://proxy.golang.org/golang.org/x/text/@v/v0.20.0.zip -- dest: vendor/gopkg.in/ini.v1 - sha256: bd845dfc762a87a56e5a32a07770dc83e86976db7705d7f89c5dbafdc60b06c6 - strip-components: 2 - type: archive - url: https://proxy.golang.org/gopkg.in/ini.v1/@v/v1.67.0.zip -- dest: vendor/gopkg.in/yaml.v3 - sha256: aab8fbc4e6300ea08e6afe1caea18a21c90c79f489f52c53e2f20431f1a9a015 - strip-components: 2 - type: archive - url: https://proxy.golang.org/gopkg.in/yaml.v3/@v/v3.0.1.zip diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/flathub/modules.txt /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/flathub/modules.txt --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/flathub/modules.txt 2024-11-20 15:17:48.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/flathub/modules.txt 2024-11-19 13:16:52.000000000 +0000 @@ -16,4 +16,6 @@ github.com/brycensranch/go-aptabase/pkg/locale github.com/brycensranch/go-aptabase/pkg/osinfo/v1 +# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc +## explicit # github.com/diamondburned/gotk4/pkg v0.3.1 ## explicit; go 1.21.0 @@ -37,23 +39,8 @@ github.com/diamondburned/gotk4/pkg/gtk/v4 github.com/diamondburned/gotk4/pkg/pango -# github.com/fsnotify/fsnotify v1.7.0 -## explicit; go 1.17 -github.com/fsnotify/fsnotify # github.com/go-resty/resty/v2 v2.16.0 ## explicit; go 1.20 github.com/go-resty/resty/v2 github.com/go-resty/resty/v2/shellescape -# github.com/hashicorp/hcl v1.0.0 -## explicit -github.com/hashicorp/hcl -github.com/hashicorp/hcl/hcl/ast -github.com/hashicorp/hcl/hcl/parser -github.com/hashicorp/hcl/hcl/printer -github.com/hashicorp/hcl/hcl/scanner -github.com/hashicorp/hcl/hcl/strconv -github.com/hashicorp/hcl/hcl/token -github.com/hashicorp/hcl/json/parser -github.com/hashicorp/hcl/json/scanner -github.com/hashicorp/hcl/json/token # github.com/ianlancetaylor/cgosymbolizer v0.0.0-20241025222116-6b205f073fdd ## explicit; go 1.12 @@ -64,61 +51,6 @@ github.com/koron/go-ssdp/internal/multicast github.com/koron/go-ssdp/internal/ssdplog -# github.com/magiconair/properties v1.8.7 -## explicit; go 1.19 -github.com/magiconair/properties -# github.com/mitchellh/mapstructure v1.5.0 -## explicit; go 1.14 -github.com/mitchellh/mapstructure -# github.com/pelletier/go-toml/v2 v2.2.2 -## explicit; go 1.16 -github.com/pelletier/go-toml/v2 -github.com/pelletier/go-toml/v2/internal/characters -github.com/pelletier/go-toml/v2/internal/danger -github.com/pelletier/go-toml/v2/internal/tracker -github.com/pelletier/go-toml/v2/unstable -# github.com/sagikazarmark/locafero v0.4.0 -## explicit; go 1.20 -github.com/sagikazarmark/locafero -# github.com/sagikazarmark/slog-shim v0.1.0 -## explicit; go 1.20 -github.com/sagikazarmark/slog-shim -# github.com/sourcegraph/conc v0.3.0 -## explicit; go 1.19 -github.com/sourcegraph/conc -github.com/sourcegraph/conc/internal/multierror -github.com/sourcegraph/conc/iter -github.com/sourcegraph/conc/panics -# github.com/spf13/afero v1.11.0 -## explicit; go 1.19 -github.com/spf13/afero -github.com/spf13/afero/internal/common -github.com/spf13/afero/mem -# github.com/spf13/cast v1.6.0 -## explicit; go 1.19 -github.com/spf13/cast -# github.com/spf13/pflag v1.0.5 -## explicit; go 1.12 -github.com/spf13/pflag -# github.com/spf13/viper v1.19.0 -## explicit; go 1.20 -github.com/spf13/viper -github.com/spf13/viper/internal/encoding -github.com/spf13/viper/internal/encoding/dotenv -github.com/spf13/viper/internal/encoding/hcl -github.com/spf13/viper/internal/encoding/ini -github.com/spf13/viper/internal/encoding/javaproperties -github.com/spf13/viper/internal/encoding/json -github.com/spf13/viper/internal/encoding/toml -github.com/spf13/viper/internal/encoding/yaml -github.com/spf13/viper/internal/features -# github.com/subosito/gotenv v1.6.0 -## explicit; go 1.18 -github.com/subosito/gotenv -# go.uber.org/atomic v1.9.0 -## explicit; go 1.13 -go.uber.org/atomic -# go.uber.org/multierr v1.9.0 -## explicit; go 1.19 -go.uber.org/multierr +# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 +## explicit # go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 ## explicit; go 1.11 @@ -126,10 +58,5 @@ # golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f ## explicit; go 1.22.0 -golang.org/x/exp/constraints golang.org/x/exp/rand -golang.org/x/exp/slices -golang.org/x/exp/slog -golang.org/x/exp/slog/internal -golang.org/x/exp/slog/internal/buffer # golang.org/x/mod v0.22.0 ## explicit; go 1.22.0 @@ -150,18 +77,2 @@ golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/text v0.20.0 -## explicit; go 1.18 -golang.org/x/text/encoding -golang.org/x/text/encoding/internal -golang.org/x/text/encoding/internal/identifier -golang.org/x/text/encoding/unicode -golang.org/x/text/internal/utf8internal -golang.org/x/text/runes -golang.org/x/text/transform -golang.org/x/text/unicode/norm -# gopkg.in/ini.v1 v1.67.0 -## explicit -gopkg.in/ini.v1 -# gopkg.in/yaml.v3 v3.0.1 -## explicit -gopkg.in/yaml.v3 diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/go.mod /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/go.mod --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/go.mod 2024-11-20 15:17:48.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/go.mod 2024-11-19 13:16:52.000000000 +0000 @@ -11,14 +11,16 @@ github.com/ianlancetaylor/cgosymbolizer v0.0.0-20241025222116-6b205f073fdd github.com/koron/go-ssdp v0.0.4 - github.com/spf13/viper v1.19.0 - golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f golang.org/x/mod v0.22.0 ) require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect +) + +require ( github.com/KarpelesLab/weak v0.1.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -29,10 +31,11 @@ github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 // indirect + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect golang.org/x/net v0.31.0 // indirect golang.org/x/sync v0.9.0 // indirect diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/go.sum /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/go.sum --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/go.sum 2024-11-20 15:17:48.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/go.sum 2024-11-19 13:16:52.000000000 +0000 @@ -7,5 +7,4 @@ github.com/brycensranch/go-aptabase/pkg v0.0.0-20241110150153-bfe02ddfffce h1:9OOSlKtlfLIBLZjnEO6mRWhTUuG3OwWjo41/Bbv5yB8= github.com/brycensranch/go-aptabase/pkg v0.0.0-20241110150153-bfe02ddfffce/go.mod h1:+CLh6qvqShXtx96GWizVY1D2mtk/or2TET+uirQR0Rk= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -14,24 +13,16 @@ github.com/diamondburned/gotk4/pkg v0.3.1 h1:uhkXSUPUsCyz3yujdvl7DSN8jiLS2BgNTQE95hk6ygg= github.com/diamondburned/gotk4/pkg v0.3.1/go.mod h1:DqeOW+MxSZFg9OO+esk4JgQk0TiUJJUBfMltKhG+ub4= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8= +github.com/go-resty/resty/v2 v2.15.3/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/go-resty/resty/v2 v2.16.0 h1:qpKalHWI2bpp9BIKlyT8TYWEJXOk1NuKbfiT3RRnzWc= github.com/go-resty/resty/v2 v2.16.0/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/cgosymbolizer v0.0.0-20241025222116-6b205f073fdd h1:ZQWb/5KPclX4ztaKJaC0Esm6qLmjKjl0C3cYsg9Qi0s= github.com/ianlancetaylor/cgosymbolizer v0.0.0-20241025222116-6b205f073fdd/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= @@ -43,7 +34,4 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= @@ -56,6 +44,4 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -95,6 +81,4 @@ golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: gui.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: logging.go diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/main.go /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/main.go --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/main.go 2024-11-20 15:17:48.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/main.go 2024-11-19 13:16:52.000000000 +0000 @@ -3,32 +3,125 @@ import ( + "encoding/xml" "fmt" "io" "log" + "net" "os" + "path" "path/filepath" "runtime" + "strconv" + "strings" + "time" "github.com/adrg/xdg" "github.com/spf13/viper" + "golang.org/x/mod/semver" + "github.com/brycensranch/go-aptabase/pkg/aptabase/v1" + "github.com/brycensranch/go-aptabase/pkg/osinfo/v1" "github.com/diamondburned/gotk4/pkg/gio/v2" "github.com/diamondburned/gotk4/pkg/glib/v2" "github.com/diamondburned/gotk4/pkg/gtk/v4" + "github.com/go-resty/resty/v2" "github.com/koron/go-ssdp" ) +var aptabaseClient *aptabase.Client // Package-level variable + +// Root represents the root element of the XML. +type Root struct { + XMLName xml.Name `xml:"root"` + SpecVersion SpecVersion `xml:"specVersion"` + Device Device `xml:"device"` +} + +// SpecVersion holds the major and minor version numbers. +type SpecVersion struct { + Major int `xml:"major"` + Minor int `xml:"minor"` +} + +// Device represents the device details. +type Device struct { + DeviceType string `xml:"deviceType"` + FriendlyName string `xml:"friendlyName"` + Manufacturer string `xml:"manufacturer"` + ManufacturerURL string `xml:"manufacturerURL"` + ModelDescription string `xml:"modelDescription"` + ModelName string `xml:"modelName"` + ModelNumber string `xml:"modelNumber"` + ModelURL string `xml:"modelURL"` + SerialNumber string `xml:"serialNumber"` + UDN string `xml:"UDN"` + IconList IconList `xml:"iconList"` + ServiceList ServiceList `xml:"serviceList"` +} + +// IconList holds a list of icons. +type IconList struct { + Icons []Icon `xml:"icon"` +} + +// Icon represents an individual icon. +type Icon struct { + MimeType string `xml:"mimetype"` + Width int `xml:"width"` + Height int `xml:"height"` + Depth int `xml:"depth"` + URL string `xml:"url"` +} + +// ServiceList holds a list of services. +type ServiceList struct { + Services []Service `xml:"service"` +} + +// Service represents an individual service. +type Service struct { + ServiceType string `xml:"serviceType"` + ServiceID string `xml:"serviceId"` + ControlURL string `xml:"controlURL"` + EventSubURL string `xml:"eventSubURL"` + SCPDURL string `xml:"SCPDURL"` +} + +// Structure to hold GitHub release information. +type GitHubRelease struct { + TagName string `json:"tag_name"` + HTMLURL string `json:"html_url"` +} + +func getOSRelease() string { + osName, osVersion := osinfo.GetOSInfo() + return fmt.Sprintf("%s %s", osName, osVersion) +} + +func createEvent(eventName string, eventData map[string]interface{}) { + event := aptabase.EventData{ + EventName: eventName, + Props: eventData, + } + aptabaseClient.TrackEvent(event) +} + +func fileExists(path string) bool { + if _, err := os.Stat(path); err == nil { + return true + } + return false +} + var ( - version = "0.0.0-SNAPSHOT" - isPackaged = "false" - packageFormat = "native" - telemetryOnByDefault = "true" - commit = "unknown" - branch = "unknown" - date = "unknown" - logFilePath = filepath.Join(xdg.DataHome, "rokon", "logs", "latest.log") - portableDataFolderName = "data" - tempDirPath = filepath.Join(xdg.CacheHome, "rokon") - configDirectoryPath = filepath.Join(xdg.ConfigHome, "rokon") + version = "0.0.0-SNAPSHOT" + isPackaged = "false" + packageFormat = "native" + telemetryOnByDefault = "true" + commit = "unknown" + branch = "unknown" + date = "unknown" + logFilePath = filepath.Join(xdg.DataHome, "rokon", "logs", "latest.log") + tempDir = filepath.Join(xdg.CacheHome, "rokon") ) @@ -42,7 +135,6 @@ if fileExists(filepath.Join(execDir, "portable.txt")) { - logFilePath = filepath.Join(execDir, portableDataFolderName, "logs", "latest.log") - tempDirPath = filepath.Join(execDir, portableDataFolderName, "cache") - configDirectoryPath = filepath.Join(execDir, portableDataFolderName, "config") + logFilePath = filepath.Join(execDir, "data", "logs", "latest.log") + tempDir = filepath.Join(execDir, "data", "cache") } logDir := filepath.Dir(logFilePath) @@ -53,6 +145,31 @@ return } - renameLogFileIfExists(logDir, logFilePath) + // Check if the latest.log file exists, and if so, rename it to the date-based file name + if fileExists(logFilePath) { + // Generate the new log filename based on the current date + today := time.Now().Format("2006-01-02") // Date format: YYYY-MM-DD + backupLogPath := filepath.Join(logDir, fmt.Sprintf("main-%s.log", today)) + + if fileExists(backupLogPath) { + backupLogFileBytes, err := os.ReadFile(backupLogPath) + // Irresponsibly ignoring errors! Don't do this at home, kids. + logFileBytes, _ := os.ReadFile(logFilePath) + combinedLogFileBytes := append(backupLogFileBytes, logFileBytes...) + if err != nil { + log.Printf("Couldn't read %s. Not attempting to append it with latest.log from today.", backupLogPath) + } else { + os.WriteFile(backupLogPath, combinedLogFileBytes, 0o755) + } + } else { + // Rename the current latest.log to the new file + err := os.Rename(logFilePath, backupLogPath) + if err != nil { + log.Printf("Error renaming log file: %v\n", err) + return + } + } + log.Printf("Renamed **OLD** latest.log to %s\n", backupLogPath) + } logFile, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o755) if err != nil { @@ -63,27 +180,21 @@ multiWriter := io.MultiWriter(os.Stdout, logFile) + // Set the logger to output to the file log.SetOutput(multiWriter) + // You can also customize the logger with a prefix and timestamp log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) + // Create a new logger that writes to the file. + customLogger := log.New(logFile, "SSDP: ", log.Ldate|log.Ltime|log.Lshortfile) - ssdpLogger := log.New(logFile, "SSDP: ", log.Ldate|log.Ltime|log.Lshortfile) + // Assign the custom logger to the SSDP.Logger field. + ssdp.Logger = customLogger telemetryLogger := log.New(logFile, "TELEMETRY: ", log.Ldate|log.Ltime|log.Lshortfile) - ssdp.Logger = ssdpLogger - - log.Printf("Config directory: %s", configDirectoryPath) - log.Printf("Cache directory: %s", tempDirPath) log.Printf("Log file: %s", logFilePath) log.Println("Starting Rokon. Now with more telemetry!") - switch runtime.GOOS { - case "windows", "darwin": - log.Println("Running on Windows or macOS.") - // Use GLib to set the GTK_CSD environment variable for Client-Side Decorations - glib.Setenv("GTK_CSD", "0", true) - os.Setenv("GTK_CSD", "0") - default: - } viper.SetConfigName("config") viper.SetConfigType("toml") viper.AddConfigPath(".") + configDirectoryPath := filepath.Join(xdg.ConfigHome, "rokon") viper.AddConfigPath(configDirectoryPath) viper.AutomaticEnv() @@ -100,33 +211,616 @@ viper.WriteConfigAs(filepath.Join(configDirectoryPath, "config.toml")) // Deploy the default config! } else { + // Handle errors reading the config file panic(fmt.Errorf("fatal error reading config file: %w", err)) } } - - app := gtk.NewApplication("io.github.brycensranch.Rokon", gio.ApplicationHandlesCommandLine) - app.SetDefault() telemetry := viper.GetBool("telemetry") + if telemetry { + switch runtime.GOOS { + case "windows", "darwin": + telemetryLogger.Println("Running on Windows or macOS.") + // Use GLib to set the GTK_CSD environment variable for Client-Side Decorations + glib.Setenv("GTK_CSD", "0", true) + os.Setenv("GTK_CSD", "0") + default: + } + + if packageFormat == "detect" { + _, err = os.Stat("/.dockerenv") + + switch { + case os.Getenv("APPIMAGE") != "": + packageFormat = "AppImage" + case err == nil: + packageFormat = "docker" + case os.Getenv("CONTAINER") == "oci": + packageFormat = "docker" + + case fileExists(filepath.Join(execDir, "share", "packageFormat")): + content, err := os.ReadFile(filepath.Join(execDir, "share", "packageFormat")) + if err == nil { + packageFormat = string(content) + } + case fileExists(filepath.Join(execDir, "usr", "share", "packageFormat")): + content, err := os.ReadFile(filepath.Join(execDir, "usr", "share", "packageFormat")) + if err == nil { + packageFormat = string(content) + } + case fileExists(filepath.Join(execDir, "usr", "share", "rokon", "packageFormat")): + content, err := os.ReadFile(filepath.Join(execDir, "usr", "share", "rokon", "packageFormat")) + if err == nil { + packageFormat = string(content) + } + case fileExists(filepath.Join(execDir, "usr", "local", "share", "rokon", "packageFormat")): + content, err := os.ReadFile(filepath.Join(execDir, "usr", "share", "rokon", "packageFormat")) + if err == nil { + packageFormat = string(content) + } + default: + // Set to "native" if no valid package format is detected + packageFormat = "native" + } + + log.Println("Detected package format:", packageFormat) + } +} + + app := gtk.NewApplication("io.github.brycensranch.Rokon", gio.ApplicationFlagsNone) + if telemetry { + aptabaseClient = aptabase.NewClient("A-US-0332858461", version, uint64(133), false, "") + aptabaseClient.Logger = telemetryLogger + } if version != "" { app.SetVersion(version) } + log.Printf("Version %s commit %s branch %s (built on %s)\n", version, commit, branch, date) if telemetry { - doTelemetry(*telemetryLogger, app, execDir) + + switch runtime.GOOS { + case "linux": + release := getOSRelease() + arch := runtime.GOARCH + desktop := os.Getenv("XDG_CURRENT_DESKTOP") + sessionType := os.Getenv("XDG_SESSION_TYPE") + + kdeSessionVersion := "" + if desktop == "KDE" { + kdeSessionVersion = os.Getenv("KDE_SESSION_VERSION") + } + + telemetryLogger.Printf("Running on Linux. Specifically: %s %s with %s %s %s and %s\n", + release, arch, desktop, os.Getenv("DESKTOP_SESSION"), kdeSessionVersion, sessionType) + + createEvent("linux_run", map[string]interface{}{ + "arch": arch, + "desktop": desktop, + "desktopVersion": kdeSessionVersion, + "sessionType": sessionType, + "packageFormat": packageFormat, + }) + + container := os.Getenv("container") + if container != "" && container == "flatpak" { + telemetryLogger.Println("Running from a Flatpak") + createEvent("flatpak_run", map[string]interface{}{ + "flatpak": container, + "flatpakVersion": version, // Replace with your app version logic + }) + } else if snap := os.Getenv("SNAP"); snap != "" { + telemetryLogger.Println("Running from a Snap") + createEvent("snap_run", map[string]interface{}{ + "snap": snap, + "snapVersion": version, // Replace with your app version logic + }) + } else if appImage := os.Getenv("APPIMAGE"); appImage != "" { + telemetryLogger.Println("Running from an AppImage") + firejail := isRunningWithFirejail() + + if firejail { + telemetryLogger.Println("Running from an AppImage with firejail") + } + + createEvent("appimage_run", map[string]interface{}{ + "appimage": filepath.Base(appImage), + "appimageVersion": version, // Replace with your app version logic + "firejail": firejail, + "desktopIntegration": os.Getenv("DESKTOPINTEGRATION"), + }) + } else if isPackaged == "true" { + telemetryLogger.Println("Running from a native package") + createEvent("native_run", map[string]interface{}{ + "nativeVersion": version, // Replace with your app version logic + "path": path.Base(os.Args[0]), + "packageFormat": packageFormat, + }) + } + case "windows": + release := getOSRelease() + arch := runtime.GOARCH + telemetryLogger.Printf("Running on Windows. Specifically: %s %s\n", + release, arch) + + if packageFormat == "portable" { + telemetryLogger.Println("Running from a portable executable") + } + + createEvent("windows_run", map[string]interface{}{ + "arch": arch, + "version": version, // Replace with your app version logic + "packageFormat": packageFormat, + }) + case "darwin": + release := getOSRelease() + arch := runtime.GOARCH + telemetryLogger.Printf("Running on macOS. Specifically: %s %s\n", + release, arch) + + createEvent("macos_run", map[string]interface{}{ + "arch": arch, + "mas": os.Getenv("MAS"), + "version": version, // Replace with your app version logic + "path": path.Base(os.Args[0]), + "packageFormat": packageFormat, + }) + default: + telemetryLogger.Printf("Unsupported telemetry platform: %s %s %s. However, the application will continue.\n", + runtime.GOOS, getOSRelease(), runtime.GOARCH) + createEvent("unsupported_platform", map[string]interface{}{ + "platform": runtime.GOOS, + "arch": runtime.GOARCH, + "version": version, // Replace with your app version logic + "path": path.Base(os.Args[0]), + "packageFormat": packageFormat, + }) } - log.Printf("Version %s commit %s branch %s (built on %s)\n", version, commit, branch, date) +} app.ConnectActivate(func() { activate(app) }) app.ConnectCommandLine(func(commandLine *gio.ApplicationCommandLine) int { return activateCommandLine(app, commandLine) }) - // Get the command-line arguments - args := os.Args + if telemetry { + // Flush buffered events before the program terminates. + // Set the timeout to the maximum duration the program can afford to wait. + aptabaseClient.Quit = true + aptabaseClient.Stop() + } + if code := app.Run(os.Args); code > 0 { + os.Exit(code) + } +} - // Check for the flags that should trigger empty args - // if containsFlag(args, "--version") || containsFlag(args, "--gpplication-service") || containsFlag(args, "--help-gapplication") { - // // Create an empty argument list to pass to app.Run() - // args = []string{} - // } +func activateCommandLine(_ *gtk.Application, commandLine *gio.ApplicationCommandLine) int { + args := commandLine.Arguments() // Get the command-line arguments + // Check if --version flag is present + for _, arg := range args { + if arg == "version" || arg == "--version" { + // Print version info + log.Println(applicationInfo()) + return 0 // Return 0 to indicate success + } + } + commandLine.PrintLiteral("HI FROM COMMAND LINE RAHH") + return 0 +} - if code := app.Run(args); code > 0 { - os.Exit(code) +func applicationInfo() string { + qualifier := func() string { + switch { + case os.Getenv("SNAP") != "": + return " (Snap)" + case os.Getenv("container") == "flatpak": + return " (Flatpak)" + case os.Getenv("APPIMAGE") != "": + return " (AppImage)" + case os.Getenv("CONTAINER") != "": + return " (Container)" + case strings.Contains(version, "SNAPSHOT"): + return " (Development)" + default: + return "" + } + }() + return "Rokon" + qualifier +} + +func isRunningWithFirejail() bool { + appImage := os.Getenv("APPIMAGE") + appDir := os.Getenv("APPDIR") + return (appImage != "" && contains(appImage, "/run/firejail")) || + (appDir != "" && contains(appDir, "/run/firejail")) +} + +// Helper function to check if a string contains a substring. +func contains(s, substr string) bool { + return strings.Contains(s, substr) +} + +// Search for Rokus asynchronously and return via channel. +func searchForRokus() chan []ssdp.Service { + resultChan := make(chan []ssdp.Service) + + go func() { + defer close(resultChan) + + discoveredRokus, err := ssdp.Search("roku:ecp", 1, "") + if err != nil { + log.Println("Error discovering Rokus:", err) + return + } + + if discoveredRokus != nil { + resultChan <- discoveredRokus // Send results back to the main thread + // Deduplicate based on LOCATION + // Needed because the SSDP code runs on EVERY interface :) + // So, if you have WiFi and Ethernet enabled, it will show two callbacks from your Roku TV. + // The code is just that *good* + locationMap := make(map[string]ssdp.Service) + for _, roku := range discoveredRokus { + locationMap[roku.Location] = roku + } + + // Convert map back to a slice + uniqueRokus := make([]ssdp.Service, 0, len(locationMap)) + for _, roku := range locationMap { + uniqueRokus = append(uniqueRokus, roku) + } + resultChan <- uniqueRokus // Send results back to the main thread + } else { + resultChan <- nil // No Rokus found, send nil + } + }() + + return resultChan +} + +// Show the "About" window. +func showAboutWindow(mainWindow *gtk.ApplicationWindow, app *gtk.Application) { + aboutWindow := gtk.NewAboutDialog() + aboutWindow.SetApplication(app) + aboutWindow.SetProgramName(applicationInfo()) + aboutWindow.SetVersion(app.Version()) + aboutWindow.SetComments("Control your Roku TV from your desktop") + aboutWindow.SetWebsite("https://github.com/BrycensRanch/Rokon") + aboutWindow.SetWebsiteLabel("GitHub") + //nolint:gosec // In GTK We trust. + aboutWindow.SetSystemInformation( + fmt.Sprintf("OS: %s (%s,%s)\n", getOSRelease(), runtime.GOOS, runtime.GOARCH) + fmt.Sprintf("Go: %s\n", runtime.Version()) + fmt.Sprintf("GTK: %d.%d.%d", int(gtk.GetMajorVersion()), int(gtk.GetMinorVersion()), int(gtk.GetMicroVersion())), + ) + aboutWindow.SetCopyright("©️ 2024 Brycen G and contributors, but mostly Brycen") + aboutWindow.SetWrapLicense(true) + aboutWindow.SetModal(false) + aboutWindow.SetDestroyWithParent(true) + + switch { + case os.Getenv("SNAP") != "": + image := gtk.NewImageFromFile(os.Getenv("SNAP") + "/meta/gui/icon.png") + if image != nil { + logo := image.Paintable() + if logo != nil { + aboutWindow.SetLogo(logo) + } + } + case os.Getenv("FLATPAK") != "": + image := gtk.NewImageFromFile("/app/share/icons/hicolor/256x256/apps/io.github.brycensranch.Rokon.png") + if image != nil { + logo := image.Paintable() + if logo != nil { + aboutWindow.SetLogo(logo) + } + } + default: + // Assume native packaging + aboutWindow.SetLogoIconName("io.github.brycensranch.Rokon") + + if os.Getenv("CONTAINER") != "" { + log.Println("Running in a container, the logo icon may not be displayed due to wrong path") + } + } + // aboutWindow.SetAuthors([]string{"Brycen G. (BrycensRanch)"}) + aboutWindow.SetLicenseType(gtk.LicenseAGPL30) + + aboutWindow.Present() + aboutWindow.Focus() +} + +// Create the main menu. +func createMenu(window *gtk.ApplicationWindow, app *gtk.Application) *gio.Menu { + menu := gio.NewMenu() + + // Create "Example" menu item + exampleMenu := gio.NewMenuItem("Example", "example") + exampleSubMenu := gio.NewMenu() + + // "About This App" menu item + aboutMenuItem := gio.NewMenuItem("About This App", "app.about") + aboutMenuItem.Connect("activate", func() { + showAboutWindow(window, app) + }) + + // "Check For Updates" menu item + updateMenuItem := gio.NewMenuItem("Check For Updates", "app.check-for-updates") + + // "Quit" menu item + quitMenuItem := gio.NewMenuItem("Quit", "quit") + quitMenuItem.Connect("activate", func() { + app.Quit() + }) + + aboutAction := gio.NewSimpleAction("about", nil) + aboutAction.Connect("activate", func() { + showAboutWindow(window, app) + }) + app.AddAction(aboutAction) + exampleSubMenu.AppendItem(aboutMenuItem) + + // Add "Check For Updates" action + checkForUpdatesAction := gio.NewSimpleAction("check-for-updates", nil) + checkForUpdatesAction.Connect("activate", func() { + const url = "https://api.github.com/repos/BrycensRanch/Rokon/releases/latest" + + // Create a Resty client + client := resty.New() + + // Make the request + resp, err := client.R().SetResult(&GitHubRelease{}).Get(url) + if err != nil { + log.Printf("Update Check Failed. Error fetching release information: %v", err) + return + } + + if resp.StatusCode() != 200 { + log.Printf("Update Check Failed. Unable to fetch release info: " + resp.Status()) + return + } + + release := resp.Result().(*GitHubRelease) + latestReleaseVersion := release.TagName + appVersion := app.Version() + if semver.Compare(latestReleaseVersion, appVersion) > 0 { + log.Printf("A new version is available: " + latestReleaseVersion) + } else if semver.Compare(latestReleaseVersion, appVersion) == 0 { + log.Printf("Rokon is up to date!") + } else { + log.Printf("You're ahead of the latest release", "You are using a newer version than the available release.") + } + }) + + app.AddAction(checkForUpdatesAction) + exampleSubMenu.AppendItem(updateMenuItem) + + // Add "Quit" action + quitAction := gio.NewSimpleAction("quit", nil) + quitAction.Connect("activate", func() { + app.Quit() + }) + app.AddAction(quitAction) + exampleSubMenu.AppendItem(quitMenuItem) + + exampleMenu.SetSubmenu(exampleSubMenu) + menu.AppendItem(exampleMenu) + + return menu +} + +// Function to show a dialog with the specified title and message. +func showDialog(title, message string, app *gtk.Application) { + theWindow := gtk.NewWindow() + dialog := gtk.NewMessageDialog( + theWindow, + gtk.DialogDestroyWithParent, + gtk.MessageInfo, + gtk.ButtonsNone, + ) + + dialog.SetTitle(title) + dialog.SetApplication(app) + dialog.SetModal(true) + dialog.SetChild(gtk.NewLabel(message)) + theWindow.Show() + dialog.Show() +} + +func fetchImageAsPaintable(url string) (string, error) { + client := resty.New() + resp, err := client.SetOutputDirectory(tempDir).EnableTrace().R(). + // SetDebug(true). + EnableTrace(). + SetOutput(filepath.Join(tempDir, "device-image.png")). + Get(url) + if err != nil { + return "", err + } + successfulHTTPCode := 200 + if resp.StatusCode() != successfulHTTPCode { + return "", fmt.Errorf("failed to get image: status code %d", resp.StatusCode()) } + imagePath := filepath.Join(tempDir, "device-image.png") + log.Println(imagePath) + // image := gtk.NewImageFromFile(imagePath) + + return imagePath, nil +} + +func activate(app *gtk.Application) { + interfaces, err := net.Interfaces() + if err != nil { + log.Println("Error fetching network interfaces:", err) + return + } + + for _, iface := range interfaces { + // Get the interface status + status := "down" + if iface.Flags&net.FlagUp != 0 { + status = "up" + } + + // Determine the type of the interface + var ifaceType string + switch { + case iface.Flags&net.FlagLoopback != 0: + ifaceType = "loopback" + case strings.Contains(iface.Name, "en") || strings.Contains(iface.Name, "eth"): + ifaceType = "Ethernet" + case strings.Contains(iface.Name, "wl"): + ifaceType = "Wi-Fi" + default: + ifaceType = "Unknown" + } + + // Print interface details + fmt.Printf("Interface: %s, Status: %s, Type: %s\n", iface.Name, status, ifaceType) + } + + window := gtk.NewApplicationWindow(app) + window.SetTitle("Rokon: Control your Roku from your desktop") + window.SetChild(>k.NewLabel("Searching for Rokus on your network...").Widget) + // Create the main menu + menu := createMenu(window, app) + app.SetMenubar(menu) + window.SetShowMenubar(true) + window.SetTitle("Rokon: Control your Roku from your desktop") + window.SetChild(>k.NewLabel("Searching for Rokus on your network...").Widget) + windowWidth := 800 + windowHeight := 400 + window.SetDefaultSize(windowWidth, windowHeight) + window.SetVisible(true) + + // Event controller setup + keyController := gtk.NewEventControllerKey() + keyController.SetName("keyController") + window.AddController(keyController) + + keyController.Connect("key-pressed", func(controller *gtk.EventControllerKey, code uint) { + println(controller.Name() + " " + strconv.FormatUint(uint64(code), 10)) + const ( + RightClickCode = uint(93) // Code representing a right-click + ) + if code == RightClickCode { + println("right clicked") + } + }) + + focusController := gtk.NewEventControllerFocus() + focusController.SetName("focusController") + + focusController.Connect("enter", func() { + println("Keyboard focus entered!") + }) + window.AddController(focusController) + + gestureClick := gtk.NewGestureClick() + gestureClick.SetName("gestureClick") + gestureClick.Connect("pressed", func(_, numberOfPresses uint) { + log.Printf("Number of presses %v", numberOfPresses) + }) + window.AddController(gestureClick) + + // window.Maximize() + scanOnStartup := viper.GetBool("scanOnStartup") + // Start searching for Rokus when the app is activated + var rokuChan chan []ssdp.Service + if scanOnStartup { + rokuChan = searchForRokus() + } else { + // Empty! + rokuChan = make(chan []ssdp.Service) + log.Printf("scanOnStartup is FALSE. Not scanning for Rokus.") + glib.IdleAdd(func() { + window.SetChild(>k.NewLabel("Welcome to Rokon, to get started, enter your Roku's IP address.\nTo get it's IP address, go into Settings -> Network").Widget) + }) + } + + // Goroutine that waits for Roku discovery to finish + go func() { + discoveredRokus := <-rokuChan // Receive the result from the Roku discovery + + // Use glib.IdleAdd to ensure UI updates happen on the main thread + glib.IdleAdd(func() { + if discoveredRokus != nil { + log.Println("Discovered Rokus:", discoveredRokus) + window.SetChild(>k.NewLabel("Discovered Rokus:").Widget) + log.Println("Number of goroutines:", runtime.NumGoroutine()) + + } else { + window.SetChild(>k.NewLabel("No Rokus discovered via SSDP!").Widget) + } + }) + + // Perform the request and unmarshal directly into the Root struct + var root Root + + // Once Roku discovery completes, run Resty logic + if discoveredRokus != nil { + client := resty.New() + resp, err := client.R(). + SetResult(&root). // Set the result to automatically unmarshal the response + Get(discoveredRokus[0].Location + "/") + + if err != nil { + log.Println("Error:", err) + } else { + log.Println("Trace Info:", resp.Request.TraceInfo()) + log.Println("Status Code:", resp.StatusCode()) + log.Println("Status:", resp.Status()) + log.Println("Proto:", resp.Proto()) + log.Println("Time:", resp.Time()) + log.Println("Received At:", resp.ReceivedAt()) + log.Println("Body:", resp) + } + + notification := gio.NewNotification("Roku discovered") + var rokuList []string + const ( + MaxValue = int(3) // Maximum allowed Rokus to display in notification + ) + for i, roku := range discoveredRokus { + if i < MaxValue { + rokuList = append(rokuList, fmt.Sprintf("Roku Device %d: %v", i+1, roku.Location)) + } + } + if len(discoveredRokus) > MaxValue { + rokuList = append(rokuList, fmt.Sprintf("...and %d more devices", len(discoveredRokus)-MaxValue)) + } + rokuListString := strings.Join(rokuList, "\n") + notification.SetBody(rokuListString) + + url := discoveredRokus[0].Location + "/device-image.png" + imagePath, err := fetchImageAsPaintable(url) + if err != nil { + log.Println("Error getting image from URL:", err) + return + } + notification.SetIcon(gio.NewFileIcon(gio.NewFileForPath(imagePath))) + notification.SetDefaultAction("app.connect-roku") + notification.SetCategory("device") + app.SendNotification("roku-discovered", notification) + + // UI update for discovered Rokus + glib.IdleAdd(func() { + if discoveredRokus != nil { + log.Println("Discovered Rokus:", discoveredRokus) + const spacing = int(5) + vbox := gtk.NewBox(gtk.OrientationVertical, spacing) + grid := gtk.NewGrid() + grid.Attach(&vbox.Widget, 1, 0, 1, 1) + vbox.SetMarginTop(10) // Optional: Add some margin to the top + vbox.SetMarginEnd(10) // Optional: Add some margin to the right + vbox.SetHAlign(gtk.AlignEnd) // Align horizontally to the right (end) + vbox.SetVAlign(gtk.AlignStart) // Align vertically to the top (start) + window.SetChild(grid) + + labelText := fmt.Sprintf("Friendly Name: %s\nIP Address: %s", + root.Device.FriendlyName, discoveredRokus[0].Location) + + label := gtk.NewLabel(labelText) + vbox.Append(label) // Add label to the vertical box + log.Println("Number of goroutines:", runtime.NumGoroutine()) + + } else { + window.SetChild(>k.NewLabel("No Rokus discovered via SSDP!").Widget) + } + }) + } + }() } Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: rokuDiscover.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: telemetry.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: types.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: updateManager.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0: utilities.go Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/vendor/github.com: inconshreveable Only in /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/vendor/github.com/spf13: cobra diff -U2 -r /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/vendor/modules.txt /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/vendor/modules.txt --- /var/lib/copr-rpmbuild/results/rokon/upstream-unpacked/Source0/vendor/modules.txt 2024-11-20 15:19:54.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/rokon/srpm-unpacked/rokon-vendored-source.zip-extract/vendor/modules.txt 2024-11-19 13:20:16.000000000 +0000 @@ -16,4 +16,6 @@ github.com/brycensranch/go-aptabase/pkg/locale github.com/brycensranch/go-aptabase/pkg/osinfo/v1 +# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc +## explicit # github.com/diamondburned/gotk4/pkg v0.3.1 ## explicit; go 1.21.0 @@ -59,7 +61,4 @@ ## explicit; go 1.12 github.com/ianlancetaylor/cgosymbolizer -# github.com/inconshreveable/mousetrap v1.1.0 -## explicit; go 1.18 -github.com/inconshreveable/mousetrap # github.com/koron/go-ssdp v0.0.4 ## explicit; go 1.19 @@ -80,4 +79,6 @@ github.com/pelletier/go-toml/v2/internal/tracker github.com/pelletier/go-toml/v2/unstable +# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 +## explicit # github.com/sagikazarmark/locafero v0.4.0 ## explicit; go 1.20 @@ -100,7 +101,4 @@ ## explicit; go 1.19 github.com/spf13/cast -# github.com/spf13/cobra v1.8.1 -## explicit; go 1.15 -github.com/spf13/cobra # github.com/spf13/pflag v1.0.5 ## explicit; go 1.12