forked from Elara6331/itd
Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
63976af404 | |||
5f5c67f7cc | |||
248beffa2f | |||
73a679d10b | |||
d475c6905e | |||
0e6e3848d7 | |||
ceff536e92 | |||
5e24e8aafa | |||
f4da64a8dd | |||
76320aa813 | |||
b64e6d27d4 | |||
|
f215e4fd90 | ||
|
1e8c9484d2 | ||
b6c47b7383 | |||
e97c1fef48 | |||
3f2bccc40c | |||
d80230b9d4 | |||
c81ac19dda | |||
4a397d4c1e | |||
c5fb3e1a33 | |||
908bd7d5f3 | |||
c97fcaeefb | |||
992eb2e085 | |||
f33b3d2b56 | |||
03f3968fe1 | |||
dea92c6404 | |||
006f245c10 | |||
d232340edd | |||
c6458720e9 | |||
1e072a3540 | |||
f639fef992 | |||
2d0db1dcf1 | |||
4efa4380c4 | |||
fca64afbf3 | |||
cf24c5ace8 | |||
a25b2e3e62 | |||
2d0b64d92f | |||
5efafe9be7 | |||
6f87980d4b | |||
851f1975d6 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
/itctl
|
/itctl
|
||||||
/itd
|
/itd
|
||||||
/itgui
|
/itgui
|
||||||
|
/itgui-linux-*
|
||||||
/version.txt
|
/version.txt
|
||||||
dist/
|
dist/
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
[repos]
|
|
||||||
origin = "ssh://git@192.168.100.62:2222/Arsen6331/itd.git"
|
|
||||||
gitlab = "git@gitlab.com:moussaelianarsen/itd.git"
|
|
@ -1,8 +1,6 @@
|
|||||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
|
||||||
# Make sure to check the documentation at https://goreleaser.com
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
# You may remove this if you don't use go modules.
|
- go generate
|
||||||
- go mod tidy
|
- go mod tidy
|
||||||
builds:
|
builds:
|
||||||
- id: itd
|
- id: itd
|
||||||
@ -16,6 +14,8 @@ builds:
|
|||||||
- amd64
|
- amd64
|
||||||
- arm
|
- arm
|
||||||
- arm64
|
- arm64
|
||||||
|
goarm:
|
||||||
|
- 7
|
||||||
- id: itctl
|
- id: itctl
|
||||||
env:
|
env:
|
||||||
- CGO_ENABLED=0
|
- CGO_ENABLED=0
|
||||||
@ -28,24 +28,33 @@ builds:
|
|||||||
- amd64
|
- amd64
|
||||||
- arm
|
- arm
|
||||||
- arm64
|
- arm64
|
||||||
|
goarm:
|
||||||
|
- 7
|
||||||
archives:
|
archives:
|
||||||
- replacements:
|
- name_template: >-
|
||||||
386: i386
|
{{- .ProjectName }}-{{.Version}}-{{.Os}}-
|
||||||
amd64: x86_64
|
{{- if eq .Arch "386" }}i386
|
||||||
arm64: aarch64
|
{{- else if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "arm64" }}aarch64
|
||||||
|
{{- else }}{{.Arch}}
|
||||||
|
{{- end }}
|
||||||
files:
|
files:
|
||||||
- LICENSE
|
- LICENSE
|
||||||
- README.md
|
- README.md
|
||||||
- itd.toml
|
- itd.toml
|
||||||
- itd.service
|
- itd.service
|
||||||
|
- itgui.desktop
|
||||||
|
- itgui-linux-{{.Arch}}{{if eq .Arch "arm"}}-7{{end}}
|
||||||
nfpms:
|
nfpms:
|
||||||
- id: itd
|
- id: itd
|
||||||
file_name_template: '{{.PackageName}}-{{.Version}}-{{.Os}}-{{.Arch}}'
|
file_name_template: >-
|
||||||
|
{{- .PackageName }}-{{.Version}}-{{.Os}}-
|
||||||
|
{{- if eq .Arch "386" }}i386
|
||||||
|
{{- else if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "arm64" }}aarch64
|
||||||
|
{{- else }}{{.Arch}}
|
||||||
|
{{- end }}
|
||||||
description: "Companion daemon for the InfiniTime firmware on the PineTime smartwatch"
|
description: "Companion daemon for the InfiniTime firmware on the PineTime smartwatch"
|
||||||
replacements:
|
|
||||||
386: i386
|
|
||||||
amd64: x86_64
|
|
||||||
arm64: aarch64
|
|
||||||
homepage: 'https://gitea.arsenm.dev/Arsen6331/itd'
|
homepage: 'https://gitea.arsenm.dev/Arsen6331/itd'
|
||||||
maintainer: 'Arsen Musyaelyan <arsen@arsenm.dev>'
|
maintainer: 'Arsen Musyaelyan <arsen@arsenm.dev>'
|
||||||
license: GPLv3
|
license: GPLv3
|
||||||
@ -53,16 +62,22 @@ nfpms:
|
|||||||
- apk
|
- apk
|
||||||
- deb
|
- deb
|
||||||
- rpm
|
- rpm
|
||||||
|
- archlinux
|
||||||
dependencies:
|
dependencies:
|
||||||
- dbus
|
- dbus
|
||||||
- bluez
|
- bluez
|
||||||
- pulseaudio-utils
|
|
||||||
contents:
|
contents:
|
||||||
- src: itd.toml
|
- src: itd.toml
|
||||||
dst: /etc/itd.toml
|
dst: /etc/itd.toml
|
||||||
type: "config|noreplace"
|
type: "config|noreplace"
|
||||||
- src: itd.service
|
- src: itd.service
|
||||||
dst: /usr/lib/systemd/user/itd.service
|
dst: /usr/lib/systemd/user/itd.service
|
||||||
|
- src: itgui.desktop
|
||||||
|
dst: /usr/share/applications/itgui.desktop
|
||||||
|
- src: itgui-linux-{{.Arch}}{{if eq .Arch "arm"}}-7{{end}}
|
||||||
|
dst: /usr/bin/itgui
|
||||||
|
file_info:
|
||||||
|
mode: 0755
|
||||||
aurs:
|
aurs:
|
||||||
- name: itd-bin
|
- name: itd-bin
|
||||||
homepage: 'https://gitea.arsenm.dev/Arsen6331/itd'
|
homepage: 'https://gitea.arsenm.dev/Arsen6331/itd'
|
||||||
@ -81,11 +96,14 @@ aurs:
|
|||||||
depends:
|
depends:
|
||||||
- dbus
|
- dbus
|
||||||
- bluez
|
- bluez
|
||||||
- libpulse
|
|
||||||
package: |-
|
package: |-
|
||||||
# binaries
|
# binaries
|
||||||
install -Dm755 "./itd" "${pkgdir}/usr/bin/itd"
|
install -Dm755 ./itd "${pkgdir}/usr/bin/itd"
|
||||||
install -Dm755 "./itctl" "${pkgdir}/usr/bin/itctl"
|
install -Dm755 ./itctl "${pkgdir}/usr/bin/itctl"
|
||||||
|
install -Dm755 ./itgui-linux-* "${pkgdir/usr/bin/itgui}"
|
||||||
|
|
||||||
|
# desktop files
|
||||||
|
install -Dm644 "./itgui.desktop" "${pkgdir}/usr/share/applications/itgui.desktop"
|
||||||
|
|
||||||
# service
|
# service
|
||||||
install -Dm644 "./itd.service" ${pkgdir}/usr/lib/systemd/user/itd.service
|
install -Dm644 "./itd.service" ${pkgdir}/usr/lib/systemd/user/itd.service
|
||||||
|
20
.woodpecker.yml
Normal file
20
.woodpecker.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
pipeline:
|
||||||
|
xgo-itgui:
|
||||||
|
image: arsen6331/fyne-xgo
|
||||||
|
environment:
|
||||||
|
- 'TARGETS=linux/amd64 linux/arm64 linux/386 linux/arm-7'
|
||||||
|
- 'OUT=itgui'
|
||||||
|
- 'PACK=./cmd/itgui'
|
||||||
|
commands:
|
||||||
|
- export SOURCE_DIR=$${CI_WORKSPACE} OUT_DIR=$${CI_WORKSPACE}
|
||||||
|
- /build.sh
|
||||||
|
when:
|
||||||
|
event: tag
|
||||||
|
|
||||||
|
release:
|
||||||
|
image: goreleaser/goreleaser
|
||||||
|
commands:
|
||||||
|
- goreleaser release
|
||||||
|
secrets: [ gitea_token, aur_key ]
|
||||||
|
when:
|
||||||
|
event: tag
|
2
Makefile
2
Makefile
@ -25,6 +25,6 @@ uninstall:
|
|||||||
rm $(CFG_PREFIX)/itd.toml
|
rm $(CFG_PREFIX)/itd.toml
|
||||||
|
|
||||||
version.txt:
|
version.txt:
|
||||||
printf "r%s.%s" "$(shell git rev-list --count HEAD)" "$(shell git rev-parse --short HEAD)" > version.txt
|
go generate
|
||||||
|
|
||||||
.PHONY: all clean install uninstall
|
.PHONY: all clean install uninstall
|
70
README.md
70
README.md
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
`itd` is a daemon that uses my infinitime [library](https://go.arsenm.dev/infinitime) to interact with the [PineTime](https://www.pine64.org/pinetime/) running [InfiniTime](https://infinitime.io).
|
`itd` is a daemon that uses my infinitime [library](https://go.arsenm.dev/infinitime) to interact with the [PineTime](https://www.pine64.org/pinetime/) running [InfiniTime](https://infinitime.io).
|
||||||
|
|
||||||
[![Build status](https://ci.appveyor.com/api/projects/status/01qpwa2bn7c7fdi2?svg=true)](https://ci.appveyor.com/project/moussaelianarsen/itd-7t6ko)
|
[![status-badge](https://ci.arsenm.dev/api/badges/Arsen6331/itd/status.svg)](https://ci.arsenm.dev/Arsen6331/itd)
|
||||||
[![Binary downloads](https://img.shields.io/badge/download-binary-orange)](https://minio.arsenm.dev/minio/itd/)
|
[![itd-git AUR package](https://img.shields.io/aur/version/itd-git?label=itd-git&logo=archlinux)](https://aur.archlinux.org/packages/itd-git/)
|
||||||
[![AUR package](https://img.shields.io/aur/version/itd-git?label=itd-git&logo=archlinux)](https://aur.archlinux.org/packages/itd-git/)
|
[![itd-bin AUR package](https://img.shields.io/aur/version/itd-bin?label=itd-bin&logo=archlinux)](https://aur.archlinux.org/packages/itd-bin/)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -21,6 +21,37 @@
|
|||||||
- Firmware upgrades
|
- Firmware upgrades
|
||||||
- Weather
|
- Weather
|
||||||
- BLE Filesystem
|
- BLE Filesystem
|
||||||
|
- Navigation (PureMaps)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
Since ITD 0.0.7, packages are built and uploaded whenever a new release is created.
|
||||||
|
|
||||||
|
#### Arch Linux
|
||||||
|
|
||||||
|
Use the `itd-bin` or `itd-git` AUR packages.
|
||||||
|
|
||||||
|
#### Debian/Ubuntu
|
||||||
|
|
||||||
|
- Go to the [latest release](https://gitea.arsenm.dev/Arsen6331/itd/releases/latest) and download the `.deb` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal.
|
||||||
|
- Run `sudo apt install <package>`, replacing `<package>` with the path to the downloaded file. Note: relative paths must begin with `./`.
|
||||||
|
- Example: `sudo apt install ~/Downloads/itd-0.0.7-linux-aarch64.deb`
|
||||||
|
|
||||||
|
#### Fedora
|
||||||
|
|
||||||
|
- Go to the [latest release](https://gitea.arsenm.dev/Arsen6331/itd/releases/latest) and download the `.rpm` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal.
|
||||||
|
- Run `sudo dnf install <package>`, replacing `<package>` with the path to the downloaded file.
|
||||||
|
- Example: `sudo dnf install ~/Downloads/itd-0.0.7-linux-aarch64.rpm`
|
||||||
|
|
||||||
|
#### Alpine (and postmarketOS)
|
||||||
|
|
||||||
|
- Go to the [latest release](https://gitea.arsenm.dev/Arsen6331/itd/releases/latest) and download the `.apk` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal.
|
||||||
|
- Run `sudo apk add --allow-untrusted <package>`, replacing `<package>` with the path to the downloaded file.
|
||||||
|
- Example: `sudo apk add --allow-untrusted ~/Downloads/itd-0.0.7-linux-aarch64.apk`
|
||||||
|
|
||||||
|
Note: `--allow-untrusted` is required because ITD isn't part of a repository, and therefore is not signed.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -81,24 +112,25 @@ This daemon comes with a binary called `itctl` which uses the socket to control
|
|||||||
|
|
||||||
This is the `itctl` usage screen:
|
This is the `itctl` usage screen:
|
||||||
```
|
```
|
||||||
Control the itd daemon for InfiniTime smartwatches
|
NAME:
|
||||||
|
itctl - A new cli application
|
||||||
|
|
||||||
Usage:
|
USAGE:
|
||||||
itctl [flags]
|
itctl [global options] command [command options] [arguments...]
|
||||||
itctl [command]
|
|
||||||
|
|
||||||
Available Commands:
|
COMMANDS:
|
||||||
firmware Manage InfiniTime firmware
|
help Display help screen for a command
|
||||||
get Get information from InfiniTime
|
resources, res Handle InfiniTime resource loading
|
||||||
help Help about any command
|
filesystem, fs Perform filesystem operations on the PineTime
|
||||||
notify Send notification to InfiniTime
|
firmware, fw Manage InfiniTime firmware
|
||||||
set Set information on InfiniTime
|
get Get information from InfiniTime
|
||||||
|
notify Send notification to InfiniTime
|
||||||
|
set Set information on InfiniTime
|
||||||
|
update, upd Update information on InfiniTime
|
||||||
|
watch Watch a value for changes
|
||||||
|
|
||||||
Flags:
|
GLOBAL OPTIONS:
|
||||||
-h, --help help for itctl
|
--socket-path value, -s value Path to itd socket (default: "/tmp/itd/socket")
|
||||||
-s, --socket-path string Path to itd socket
|
|
||||||
|
|
||||||
Use "itctl [command] --help" for more information about a command.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -133,6 +165,8 @@ Due to the use of OpenGL, cross-compilation of `itgui` isn't as simple as that o
|
|||||||
|
|
||||||
![FS mkdir](cmd/itgui/screenshots/mkdir.png)
|
![FS mkdir](cmd/itgui/screenshots/mkdir.png)
|
||||||
|
|
||||||
|
![FS resource upload](cmd/itgui/screenshots/resources.png)
|
||||||
|
|
||||||
![Time tab](cmd/itgui/screenshots/time.png)
|
![Time tab](cmd/itgui/screenshots/time.png)
|
||||||
|
|
||||||
![Firmware tab](cmd/itgui/screenshots/firmware.png)
|
![Firmware tab](cmd/itgui/screenshots/firmware.png)
|
||||||
|
20
api/fs.go
20
api/fs.go
@ -2,6 +2,16 @@ package api
|
|||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
|
||||||
|
func (c *Client) RemoveAll(ctx context.Context, paths ...string) error {
|
||||||
|
return c.client.Call(
|
||||||
|
ctx,
|
||||||
|
"FS",
|
||||||
|
"RemoveAll",
|
||||||
|
paths,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) Remove(ctx context.Context, paths ...string) error {
|
func (c *Client) Remove(ctx context.Context, paths ...string) error {
|
||||||
return c.client.Call(
|
return c.client.Call(
|
||||||
ctx,
|
ctx,
|
||||||
@ -22,6 +32,16 @@ func (c *Client) Rename(ctx context.Context, old, new string) error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) MkdirAll(ctx context.Context, paths ...string) error {
|
||||||
|
return c.client.Call(
|
||||||
|
ctx,
|
||||||
|
"FS",
|
||||||
|
"MkdirAll",
|
||||||
|
paths,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) Mkdir(ctx context.Context, paths ...string) error {
|
func (c *Client) Mkdir(ctx context.Context, paths ...string) error {
|
||||||
return c.client.Call(
|
return c.client.Call(
|
||||||
ctx,
|
ctx,
|
||||||
|
26
api/resources.go
Normal file
26
api/resources.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"go.arsenm.dev/infinitime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LoadResources loads resources onto the watch from the given
|
||||||
|
// file path to the resources zip
|
||||||
|
func (c *Client) LoadResources(ctx context.Context, path string) (<-chan infinitime.ResourceLoadProgress, error) {
|
||||||
|
progCh := make(chan infinitime.ResourceLoadProgress)
|
||||||
|
|
||||||
|
err := c.client.Call(
|
||||||
|
ctx,
|
||||||
|
"FS",
|
||||||
|
"LoadResources",
|
||||||
|
path,
|
||||||
|
progCh,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return progCh, nil
|
||||||
|
}
|
5
calls.go
5
calls.go
@ -7,11 +7,12 @@ import (
|
|||||||
"github.com/godbus/dbus/v5"
|
"github.com/godbus/dbus/v5"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"go.arsenm.dev/infinitime"
|
"go.arsenm.dev/infinitime"
|
||||||
|
"go.arsenm.dev/itd/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initCallNotifs(ctx context.Context, dev *infinitime.Device) error {
|
func initCallNotifs(ctx context.Context, dev *infinitime.Device) error {
|
||||||
// Connect to system bus. This connection is for method calls.
|
// Connect to system bus. This connection is for method calls.
|
||||||
conn, err := newSystemBusConn(ctx)
|
conn, err := utils.NewSystemBusConn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -29,7 +30,7 @@ func initCallNotifs(ctx context.Context, dev *infinitime.Device) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect to system bus. This connection is for monitoring.
|
// Connect to system bus. This connection is for monitoring.
|
||||||
monitorConn, err := newSystemBusConn(ctx)
|
monitorConn, err := utils.NewSystemBusConn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,26 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cheggaaa/pb/v3"
|
"github.com/cheggaaa/pb/v3"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"go.arsenm.dev/itd/api"
|
"go.arsenm.dev/itd/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fwUpgrade(c *cli.Context) error {
|
func fwUpgrade(c *cli.Context) error {
|
||||||
|
resources := c.String("resources")
|
||||||
|
if resources != "" {
|
||||||
|
absRes, err := filepath.Abs(resources)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resLoad(c.Context, []string{absRes})
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msg("Resource loading has returned an error. This can happen if your current version of InfiniTime doesn't support BLE FS. Try updating without resource loading, and then load them after using the `itctl res load` command.")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
var upgType api.UpgradeType
|
var upgType api.UpgradeType
|
||||||
|
@ -34,7 +34,12 @@ func fsMkdir(c *cli.Context) error {
|
|||||||
return cli.Exit("Command mkdir requires one or more arguments", 1)
|
return cli.Exit("Command mkdir requires one or more arguments", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.Mkdir(c.Context, c.Args().Slice()...)
|
var err error
|
||||||
|
if c.Bool("parents") {
|
||||||
|
err = client.MkdirAll(c.Context, c.Args().Slice()...)
|
||||||
|
} else {
|
||||||
|
err = client.Mkdir(c.Context, c.Args().Slice()...)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -109,7 +114,12 @@ func fsRemove(c *cli.Context) error {
|
|||||||
return cli.Exit("Command remove requires one or more arguments", 1)
|
return cli.Exit("Command remove requires one or more arguments", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.Remove(c.Context, c.Args().Slice()...)
|
var err error
|
||||||
|
if c.Bool("recursive") {
|
||||||
|
err = client.RemoveAll(c.Context, c.Args().Slice()...)
|
||||||
|
} else {
|
||||||
|
err = client.Remove(c.Context, c.Args().Slice()...)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"context"
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@ -24,17 +24,17 @@ func main() {
|
|||||||
syscall.SIGINT,
|
syscall.SIGINT,
|
||||||
syscall.SIGTERM,
|
syscall.SIGTERM,
|
||||||
)
|
)
|
||||||
|
|
||||||
// This goroutine ensures that itctl will exit
|
// This goroutine ensures that itctl will exit
|
||||||
// at most 200ms after the user sends SIGINT/SIGTERM.
|
// at most 200ms after the user sends SIGINT/SIGTERM.
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
time.Sleep(200*time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
app := cli.App{
|
app := cli.App{
|
||||||
Name: "itctl",
|
Name: "itctl",
|
||||||
HideHelpCommand: true,
|
HideHelpCommand: true,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -46,10 +46,23 @@ func main() {
|
|||||||
},
|
},
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
{
|
{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
ArgsUsage: "<command>",
|
ArgsUsage: "<command>",
|
||||||
Usage: "Display help screen for a command",
|
Usage: "Display help screen for a command",
|
||||||
Action: helpCmd,
|
Action: helpCmd,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "resources",
|
||||||
|
Aliases: []string{"res"},
|
||||||
|
Usage: "Handle InfiniTime resource loading",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "load",
|
||||||
|
ArgsUsage: "<path>",
|
||||||
|
Usage: "Load an InifiniTime resources package",
|
||||||
|
Action: resourcesLoad,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "filesystem",
|
Name: "filesystem",
|
||||||
@ -64,6 +77,13 @@ func main() {
|
|||||||
Action: fsList,
|
Action: fsList,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "parents",
|
||||||
|
Aliases: []string{"p"},
|
||||||
|
Usage: "Make parent directories if needed, no error if already existing",
|
||||||
|
},
|
||||||
|
},
|
||||||
Name: "mkdir",
|
Name: "mkdir",
|
||||||
ArgsUsage: "<paths...>",
|
ArgsUsage: "<paths...>",
|
||||||
Usage: "Create new directories",
|
Usage: "Create new directories",
|
||||||
@ -84,6 +104,13 @@ func main() {
|
|||||||
Action: fsRead,
|
Action: fsRead,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "recursive",
|
||||||
|
Aliases: []string{"r", "R"},
|
||||||
|
Usage: "Remove directories and their contents recursively",
|
||||||
|
},
|
||||||
|
},
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
ArgsUsage: "<paths...>",
|
ArgsUsage: "<paths...>",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
@ -116,6 +143,11 @@ func main() {
|
|||||||
Aliases: []string{"f"},
|
Aliases: []string{"f"},
|
||||||
Usage: "Path to firmware image (.bin file)",
|
Usage: "Path to firmware image (.bin file)",
|
||||||
},
|
},
|
||||||
|
&cli.PathFlag{
|
||||||
|
Name: "resources",
|
||||||
|
Aliases: []string{"r"},
|
||||||
|
Usage: "Path to resources file (.zip file)",
|
||||||
|
},
|
||||||
&cli.PathFlag{
|
&cli.PathFlag{
|
||||||
Name: "archive",
|
Name: "archive",
|
||||||
Aliases: []string{"a"},
|
Aliases: []string{"a"},
|
||||||
@ -284,4 +316,4 @@ func isHelpCmd() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
57
cmd/itctl/resources.go
Normal file
57
cmd/itctl/resources.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/cheggaaa/pb/v3"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"go.arsenm.dev/infinitime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourcesLoad(c *cli.Context) error {
|
||||||
|
return resLoad(c.Context, c.Args().Slice())
|
||||||
|
}
|
||||||
|
|
||||||
|
func resLoad(ctx context.Context, args []string) error {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return cli.Exit("Command load requires one argument.", 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create progress bar templates
|
||||||
|
rmTmpl := `Removing {{string . "filename"}}`
|
||||||
|
upTmpl := `Uploading {{string . "filename"}} {{counters . }} B {{bar . "|" "-" (cycle .) " " "|"}} {{percent . }} {{rtime . "%s"}}`
|
||||||
|
// Start full bar at 0 total
|
||||||
|
bar := pb.ProgressBarTemplate(rmTmpl).Start(0)
|
||||||
|
|
||||||
|
path, err := filepath.Abs(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
progCh, err := client.LoadResources(ctx, path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for evt := range progCh {
|
||||||
|
if evt.Err != nil {
|
||||||
|
return evt.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
if evt.Operation == infinitime.ResourceOperationRemoveObsolete {
|
||||||
|
bar.SetTemplateString(rmTmpl)
|
||||||
|
bar.Set("filename", evt.Name)
|
||||||
|
} else {
|
||||||
|
bar.SetTemplateString(upTmpl)
|
||||||
|
bar.Set("filename", evt.Name)
|
||||||
|
|
||||||
|
bar.SetTotal(evt.Total)
|
||||||
|
bar.SetCurrent(evt.Sent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bar.Finish()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -8,8 +8,10 @@ import (
|
|||||||
"fyne.io/fyne/v2/container"
|
"fyne.io/fyne/v2/container"
|
||||||
"fyne.io/fyne/v2/data/binding"
|
"fyne.io/fyne/v2/data/binding"
|
||||||
"fyne.io/fyne/v2/dialog"
|
"fyne.io/fyne/v2/dialog"
|
||||||
|
"fyne.io/fyne/v2/storage"
|
||||||
"fyne.io/fyne/v2/theme"
|
"fyne.io/fyne/v2/theme"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
|
"go.arsenm.dev/infinitime"
|
||||||
"go.arsenm.dev/itd/api"
|
"go.arsenm.dev/itd/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,6 +55,52 @@ func fsTab(ctx context.Context, client *api.Client, w fyne.Window, opened chan s
|
|||||||
refresh(ctx, cwdData, lsData, client, w, c)
|
refresh(ctx, cwdData, lsData, client, w, c)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
widget.NewToolbarAction(
|
||||||
|
theme.FileApplicationIcon(),
|
||||||
|
func() {
|
||||||
|
dlg := dialog.NewFileOpen(func(uc fyne.URIReadCloser, err error) {
|
||||||
|
if err != nil || uc == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resPath := uc.URI().Path()
|
||||||
|
uc.Close()
|
||||||
|
|
||||||
|
progressDlg := newProgress(w)
|
||||||
|
progressDlg.Show()
|
||||||
|
|
||||||
|
progCh, err := client.LoadResources(ctx, resPath)
|
||||||
|
if err != nil {
|
||||||
|
guiErr(err, "Error loading resources", false, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for evt := range progCh {
|
||||||
|
if evt.Err != nil {
|
||||||
|
guiErr(evt.Err, "Error loading resources", false, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch evt.Operation {
|
||||||
|
case infinitime.ResourceOperationRemoveObsolete:
|
||||||
|
progressDlg.SetText("Removing " + evt.Name)
|
||||||
|
case infinitime.ResourceOperationUpload:
|
||||||
|
progressDlg.SetText("Uploading " + evt.Name)
|
||||||
|
progressDlg.SetTotal(float64(evt.Total))
|
||||||
|
progressDlg.SetValue(float64(evt.Sent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
progressDlg.Hide()
|
||||||
|
refresh(ctx, cwdData, lsData, client, w, c)
|
||||||
|
}, w)
|
||||||
|
dlg.SetConfirmText("Upload Resources")
|
||||||
|
dlg.SetFilter(storage.NewExtensionFileFilter([]string{
|
||||||
|
".zip",
|
||||||
|
}))
|
||||||
|
dlg.Show()
|
||||||
|
},
|
||||||
|
),
|
||||||
widget.NewToolbarAction(
|
widget.NewToolbarAction(
|
||||||
theme.UploadIcon(),
|
theme.UploadIcon(),
|
||||||
func() {
|
func() {
|
||||||
@ -113,7 +161,6 @@ func fsTab(ctx context.Context, client *api.Client, w fyne.Window, opened chan s
|
|||||||
uploadDlg.Show()
|
uploadDlg.Show()
|
||||||
}, w)
|
}, w)
|
||||||
dlg.Show()
|
dlg.Show()
|
||||||
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
widget.NewToolbarAction(
|
widget.NewToolbarAction(
|
||||||
|
@ -11,17 +11,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type progress struct {
|
type progress struct {
|
||||||
lbl *widget.Label
|
lbl *widget.Label
|
||||||
pb *widget.ProgressBar
|
progLbl *widget.Label
|
||||||
|
pb *widget.ProgressBar
|
||||||
*widget.PopUp
|
*widget.PopUp
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProgress(w fyne.Window) progress {
|
func newProgress(w fyne.Window) progress {
|
||||||
out := progress{}
|
out := progress{}
|
||||||
|
|
||||||
|
out.lbl = widget.NewLabel("")
|
||||||
|
out.lbl.Hide()
|
||||||
|
|
||||||
// Create label to show how many bytes transfered and center it
|
// Create label to show how many bytes transfered and center it
|
||||||
out.lbl = widget.NewLabel("0 / 0 B")
|
out.progLbl = widget.NewLabel("0 / 0 B")
|
||||||
out.lbl.Alignment = fyne.TextAlignCenter
|
out.progLbl.Alignment = fyne.TextAlignCenter
|
||||||
|
|
||||||
// Create new progress bar
|
// Create new progress bar
|
||||||
out.pb = widget.NewProgressBar()
|
out.pb = widget.NewProgressBar()
|
||||||
@ -31,20 +35,30 @@ func newProgress(w fyne.Window) progress {
|
|||||||
sizeRect.SetMinSize(fyne.NewSize(300, 50))
|
sizeRect.SetMinSize(fyne.NewSize(300, 50))
|
||||||
|
|
||||||
// Create vbox for label and progress bar
|
// Create vbox for label and progress bar
|
||||||
l := container.NewVBox(out.lbl, out.pb)
|
l := container.NewVBox(out.lbl, out.progLbl, out.pb)
|
||||||
// Create popup
|
// Create popup
|
||||||
out.PopUp = widget.NewModalPopUp(container.NewMax(l, sizeRect), w.Canvas())
|
out.PopUp = widget.NewModalPopUp(container.NewMax(l, sizeRect), w.Canvas())
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p progress) SetText(s string) {
|
||||||
|
p.lbl.SetText(s)
|
||||||
|
|
||||||
|
if s == "" {
|
||||||
|
p.lbl.Hide()
|
||||||
|
} else {
|
||||||
|
p.lbl.Show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p progress) SetTotal(v float64) {
|
func (p progress) SetTotal(v float64) {
|
||||||
p.pb.Max = v
|
p.pb.Max = v
|
||||||
p.pb.Refresh()
|
p.pb.Refresh()
|
||||||
p.lbl.SetText(fmt.Sprintf("%.0f / %.0f B", p.pb.Value, v))
|
p.progLbl.SetText(fmt.Sprintf("%.0f / %.0f B", p.pb.Value, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p progress) SetValue(v float64) {
|
func (p progress) SetValue(v float64) {
|
||||||
p.pb.SetValue(v)
|
p.pb.SetValue(v)
|
||||||
p.lbl.SetText(fmt.Sprintf("%.0f / %.0f B", v, p.pb.Max))
|
p.progLbl.SetText(fmt.Sprintf("%.0f / %.0f B", v, p.pb.Max))
|
||||||
}
|
}
|
||||||
|
BIN
cmd/itgui/screenshots/resources.png
Normal file
BIN
cmd/itgui/screenshots/resources.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
28
config.go
28
config.go
@ -16,6 +16,8 @@ import (
|
|||||||
var cfgDir string
|
var cfgDir string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
etcPath := "/etc/itd.toml";
|
||||||
|
|
||||||
// Set up logger
|
// Set up logger
|
||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||||
|
|
||||||
@ -29,7 +31,7 @@ func init() {
|
|||||||
// If config dir is not readable
|
// If config dir is not readable
|
||||||
if _, err = os.ReadDir(cfgDir); err != nil {
|
if _, err = os.ReadDir(cfgDir); err != nil {
|
||||||
// Create config dir with 700 permissions
|
// Create config dir with 700 permissions
|
||||||
err = os.MkdirAll(cfgDir, 0700)
|
err = os.MkdirAll(cfgDir, 0o700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -51,15 +53,9 @@ func init() {
|
|||||||
// Set config defaults
|
// Set config defaults
|
||||||
setCfgDefaults()
|
setCfgDefaults()
|
||||||
|
|
||||||
// Load config files
|
// Load and watch config files
|
||||||
etcProvider := file.Provider("/etc/itd.toml")
|
loadAndwatchCfgFile(etcPath)
|
||||||
cfgProvider := file.Provider(cfgPath)
|
loadAndwatchCfgFile(cfgPath)
|
||||||
k.Load(etcProvider, toml.Parser())
|
|
||||||
k.Load(cfgProvider, toml.Parser())
|
|
||||||
|
|
||||||
// Watch configs for changes
|
|
||||||
cfgWatch(etcProvider)
|
|
||||||
cfgWatch(cfgProvider)
|
|
||||||
|
|
||||||
// Load envireonment variables
|
// Load envireonment variables
|
||||||
k.Load(env.Provider("ITD_", "_", func(s string) string {
|
k.Load(env.Provider("ITD_", "_", func(s string) string {
|
||||||
@ -67,14 +63,22 @@ func init() {
|
|||||||
}), nil)
|
}), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cfgWatch(provider *file.File) {
|
func loadAndwatchCfgFile(filename string) {
|
||||||
|
provider := file.Provider(filename)
|
||||||
|
|
||||||
|
if cfgError := k.Load(provider, toml.Parser()); cfgError != nil {
|
||||||
|
log.Warn().Str("filename", filename).Err(cfgError).Msg("Error while trying to read config file")
|
||||||
|
}
|
||||||
|
|
||||||
// Watch for changes and reload when detected
|
// Watch for changes and reload when detected
|
||||||
provider.Watch(func(_ interface{}, err error) {
|
provider.Watch(func(_ interface{}, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
k.Load(provider, toml.Parser())
|
if cfgError := k.Load(provider, toml.Parser()); cfgError != nil {
|
||||||
|
log.Warn().Str("filename", filename).Err(cfgError).Msg("Error while trying to read config file")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
go.mod
46
go.mod
@ -5,40 +5,45 @@ go 1.17
|
|||||||
replace fyne.io/x/fyne => github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb
|
replace fyne.io/x/fyne => github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb
|
||||||
|
|
||||||
require (
|
require (
|
||||||
fyne.io/fyne/v2 v2.1.4
|
fyne.io/fyne/v2 v2.2.3
|
||||||
fyne.io/x/fyne v0.0.0-20220107050838-c4a1de51d4ce
|
fyne.io/x/fyne v0.0.0-20220107050838-c4a1de51d4ce
|
||||||
github.com/cheggaaa/pb/v3 v3.0.8
|
github.com/cheggaaa/pb/v3 v3.0.8
|
||||||
github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b
|
github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b
|
||||||
github.com/godbus/dbus/v5 v5.0.6
|
github.com/godbus/dbus/v5 v5.1.0
|
||||||
github.com/knadh/koanf v1.4.0
|
github.com/knadh/koanf v1.4.0
|
||||||
github.com/mattn/go-isatty v0.0.14
|
github.com/mattn/go-isatty v0.0.14
|
||||||
github.com/mozillazg/go-pinyin v0.19.0
|
github.com/mozillazg/go-pinyin v0.19.0
|
||||||
github.com/rs/zerolog v1.26.1
|
github.com/rs/zerolog v1.26.1
|
||||||
github.com/urfave/cli/v2 v2.3.0
|
github.com/urfave/cli/v2 v2.4.0
|
||||||
go.arsenm.dev/infinitime v0.0.0-20220819210252-d199fba93c2f
|
go.arsenm.dev/infinitime v0.0.0-20221119224612-0c369dc5df94
|
||||||
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0
|
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0
|
||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.7
|
||||||
modernc.org/sqlite v1.17.2
|
modernc.org/sqlite v1.17.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93 // indirect
|
||||||
github.com/VividCortex/ewma v1.1.1 // indirect
|
github.com/VividCortex/ewma v1.1.1 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fatih/color v1.10.0 // indirect
|
github.com/fatih/color v1.10.0 // indirect
|
||||||
github.com/fatih/structs v1.1.0 // indirect
|
github.com/fatih/structs v1.1.0 // indirect
|
||||||
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
|
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
||||||
|
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
|
||||||
|
github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 // indirect
|
||||||
|
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
|
||||||
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
|
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211204153444-caad923f49f4 // indirect
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec // indirect
|
||||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||||
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect
|
github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||||
|
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.12 // indirect
|
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
@ -47,24 +52,25 @@ require (
|
|||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
|
||||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
github.com/srwiley/oksvg v0.0.0-20211120171407-1837d6608d8c // indirect
|
github.com/srwiley/oksvg v0.0.0-20220128195007-1f435e4c2b44 // indirect
|
||||||
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect
|
github.com/srwiley/rasterx v0.0.0-20220128185129-2efea2b9ea41 // indirect
|
||||||
github.com/stretchr/testify v1.7.1 // indirect
|
github.com/stretchr/testify v1.7.2 // indirect
|
||||||
|
github.com/tevino/abool v1.2.0 // indirect
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
github.com/yuin/goldmark v1.4.4 // indirect
|
github.com/yuin/goldmark v1.4.10 // indirect
|
||||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
|
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd // indirect
|
||||||
|
golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect
|
||||||
golang.org/x/mod v0.4.2 // indirect
|
golang.org/x/mod v0.4.2 // indirect
|
||||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
|
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||||
golang.org/x/tools v0.1.7 // indirect
|
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
|
||||||
lukechampine.com/uint128 v1.1.1 // indirect
|
lukechampine.com/uint128 v1.1.1 // indirect
|
||||||
modernc.org/cc/v3 v3.36.0 // indirect
|
modernc.org/cc/v3 v3.36.0 // indirect
|
||||||
modernc.org/ccgo/v3 v3.16.6 // indirect
|
modernc.org/ccgo/v3 v3.16.6 // indirect
|
||||||
|
89
go.sum
89
go.sum
@ -38,16 +38,20 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
|||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
fyne.io/fyne/v2 v2.1.0/go.mod h1:c1vwI38Ebd0dAdxVa6H1Pj6/+cK1xtDy61+I31g+s14=
|
fyne.io/fyne/v2 v2.1.0/go.mod h1:c1vwI38Ebd0dAdxVa6H1Pj6/+cK1xtDy61+I31g+s14=
|
||||||
fyne.io/fyne/v2 v2.1.4 h1:bt1+28++kAzRzPB0GM2EuSV4cnl8rXNX4cjfd8G06Rc=
|
fyne.io/fyne/v2 v2.2.3 h1:Umi3vVVW8XnWWPJmMkhIWQOMU/jxB1OqpWVUmjhODD0=
|
||||||
fyne.io/fyne/v2 v2.1.4/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ=
|
fyne.io/fyne/v2 v2.2.3/go.mod h1:MBoGuHzLLSXdQOWFAwWhIhYTEMp33zqtGCReSWhaQTA=
|
||||||
|
fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93 h1:V2IC9t0Zj9Ur6qDbfhUuzVmIvXKFyxZXRJyigUvovs4=
|
||||||
|
fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE=
|
||||||
github.com/Andrew-M-C/go.jsonvalue v1.1.2-0.20211223013816-e873b56b4a84/go.mod h1:oTJGG91FhtsxvUFVwHSvr6zuaTcAuroj/ToxfT7Ox8U=
|
github.com/Andrew-M-C/go.jsonvalue v1.1.2-0.20211223013816-e873b56b4a84/go.mod h1:oTJGG91FhtsxvUFVwHSvr6zuaTcAuroj/ToxfT7Ox8U=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I=
|
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I=
|
||||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||||
|
github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
@ -77,8 +81,9 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
|
|||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.1/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.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=
|
||||||
@ -100,10 +105,16 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga
|
|||||||
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA=
|
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA=
|
||||||
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8=
|
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||||
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
|
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
|
||||||
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||||
|
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe h1:A/wiwvQ0CAjPkuJytaD+SsXkPU0asQ+guQEIg1BJGX4=
|
||||||
|
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe/go.mod h1:d4clgH0/GrRwWjRzJJQXxT/h1TyuNSfF/X64zb/3Ggg=
|
||||||
|
github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 h1:+31CdF/okdokeFNoy9L/2PccG3JFidQT3ev64/r4pYU=
|
||||||
|
github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504/go.mod h1:gLRWYfYnMA9TONeppRSikMdXlHQ97xVsPojddUv3b/E=
|
||||||
|
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 h1:hnLq+55b7Zh7/2IRzWCpiTcAvjv/P8ERF+N7+xXbZhk=
|
||||||
|
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0=
|
||||||
github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b h1:M0/hjawi9ur15zpqL/h66ga87jlYA7iAuZ4HC6ak08k=
|
github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b h1:M0/hjawi9ur15zpqL/h66ga87jlYA7iAuZ4HC6ak08k=
|
||||||
github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b/go.mod h1:/eFcjDXaU2THSOOqLxOPETIbHETnamk8FA/hMjhg/gU=
|
github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b/go.mod h1:/eFcjDXaU2THSOOqLxOPETIbHETnamk8FA/hMjhg/gU=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
@ -115,22 +126,23 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
|
|||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211204153444-caad923f49f4 h1:KgfIc81yNEUKNAsF+Mt3C1Cl+iQqKF1r7nWEKzL0c2Y=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211204153444-caad923f49f4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||||
|
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
||||||
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8=
|
|
||||||
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
|
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
|
||||||
|
github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c h1:JGCm/+tJ9gC6THUxooTldS+CUDsba0qvkvU3DHklqW8=
|
||||||
|
github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
@ -199,9 +211,12 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20211219123610-ec9572f70e60/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
|
||||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY=
|
||||||
|
github.com/goxjs/glfw v0.0.0-20191126052801-d2efb5f20838/go.mod h1:oS8P8gVOT4ywTcjV6wZlOU4GuVFQ8F5328KY3MJ79CY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
@ -240,14 +255,18 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
|||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
|
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
|
||||||
|
github.com/jackmordaunt/icns/v2 v2.2.1/go.mod h1:6aYIB9eSzyfHHMKqDf17Xrs1zetQPReAkiUSHzdw4cI=
|
||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
|
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
|
||||||
|
github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY=
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
|
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e h1:LvL4XsI70QxOGHed6yhQtAU34Kx3Qq2wwBzGFKY8zKk=
|
||||||
|
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
@ -270,10 +289,12 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
|
|||||||
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.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
|
|
||||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
|
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||||
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
|
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
|
||||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
|
||||||
github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb h1:+fP6ENsbd+BUOmD/kSjNtrOmi2vgJ/JfWDSWjTKmTVY=
|
github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb h1:+fP6ENsbd+BUOmD/kSjNtrOmi2vgJ/JfWDSWjTKmTVY=
|
||||||
github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb/go.mod h1:jBspDudEQ+Rdono8vBGHDtMUPE8ZpB/xq7FUYRqT3CI=
|
github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb/go.mod h1:jBspDudEQ+Rdono8vBGHDtMUPE8ZpB/xq7FUYRqT3CI=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
@ -336,15 +357,15 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
|
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
|
||||||
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
|
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
@ -362,11 +383,12 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||||
github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4=
|
github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4=
|
||||||
github.com/srwiley/oksvg v0.0.0-20211120171407-1837d6608d8c h1:+e9myEHblxwU1r2Jb5PKzepMcsuig7+NUz+K53lBNaQ=
|
github.com/srwiley/oksvg v0.0.0-20220128195007-1f435e4c2b44 h1:XPYXKIuH/n5zpUoEWk2jWV/SjEMNYmqDYmTgbjmhtaI=
|
||||||
github.com/srwiley/oksvg v0.0.0-20211120171407-1837d6608d8c/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4=
|
github.com/srwiley/oksvg v0.0.0-20220128195007-1f435e4c2b44/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
|
||||||
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
|
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
|
||||||
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 h1:oDMiXaTMyBEuZMU53atpxqYsSB3U1CHkeAu2zr6wTeY=
|
|
||||||
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
|
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
|
||||||
|
github.com/srwiley/rasterx v0.0.0-20220128185129-2efea2b9ea41 h1:YR16ysw3I1bqwtEcYV9dpvhHEe7j55hIClkLoAqY31I=
|
||||||
|
github.com/srwiley/rasterx v0.0.0-20220128185129-2efea2b9ea41/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
@ -374,12 +396,16 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
|||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||||
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
github.com/suapapa/go_eddystone v1.3.1/go.mod h1:bXC11TfJOS+3g3q/Uzd7FKd5g62STQEfeEIhcKe4Qy8=
|
github.com/suapapa/go_eddystone v1.3.1/go.mod h1:bXC11TfJOS+3g3q/Uzd7FKd5g62STQEfeEIhcKe4Qy8=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA=
|
||||||
|
github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
|
github.com/urfave/cli/v2 v2.4.0 h1:m2pxjjDFgDxSPtO8WSdbndj17Wu2y8vOT86wE/tjr+I=
|
||||||
|
github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||||
@ -394,10 +420,10 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs=
|
github.com/yuin/goldmark v1.4.10 h1:+WgKGo8CQrlMTRJpGCFCyNddOhW801TKC2QijVV9QVg=
|
||||||
github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
github.com/yuin/goldmark v1.4.10/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
||||||
go.arsenm.dev/infinitime v0.0.0-20220819210252-d199fba93c2f h1:Np0ZNlgVC5D9NOilN14HJ1mSXM8vl2LYGfK0fZOYUbY=
|
go.arsenm.dev/infinitime v0.0.0-20221119224612-0c369dc5df94 h1:b3kEsAfUyJN5781f0+K72v30MDrwusyPDh/1kPFCDNQ=
|
||||||
go.arsenm.dev/infinitime v0.0.0-20220819210252-d199fba93c2f/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc=
|
go.arsenm.dev/infinitime v0.0.0-20221119224612-0c369dc5df94/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc=
|
||||||
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 h1:1K96g1eww+77GeGchwMhd0NTrs7Mk/Hc3M3ItW5NbG4=
|
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 h1:1K96g1eww+77GeGchwMhd0NTrs7Mk/Hc3M3ItW5NbG4=
|
||||||
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w=
|
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||||
@ -425,6 +451,7 @@ golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5
|
|||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
@ -435,8 +462,9 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk
|
|||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
|
|
||||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||||
|
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd h1:9NbNcTg//wfC5JskFW4Z3sqwVnjmJKHxLAol1bW2qgw=
|
||||||
|
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@ -451,6 +479,8 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI
|
|||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
|
golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee h1:/tShaw8UTf0XzI8DOZwQHzC7d6Vi3EtrBnftiZ4vAvU=
|
||||||
|
golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
|
||||||
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.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
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=
|
||||||
@ -499,6 +529,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
|
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
|
||||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
@ -579,8 +610,8 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f h1:8w7RhxzTVgUzw/AH/9mUV5q0vMgy40SQRursCcfmkCw=
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||||
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
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=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -651,8 +682,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
|||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
|
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 h1:YuekqPskqwCCPM79F1X5Dhv4ezTCj+Ki1oNwiafxkA0=
|
||||||
|
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@ -777,8 +809,11 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 h1:oomkgU6VaQDsV6qZby2uz1Lap0eXmku8+2em3A/l700=
|
||||||
|
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/godbus/dbus/v5"
|
"github.com/godbus/dbus/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newSystemBusConn(ctx context.Context) (*dbus.Conn, error) {
|
func NewSystemBusConn(ctx context.Context) (*dbus.Conn, error) {
|
||||||
// Connect to dbus session bus
|
// Connect to dbus session bus
|
||||||
conn, err := dbus.SystemBusPrivate(dbus.WithContext(ctx))
|
conn, err := dbus.SystemBusPrivate(dbus.WithContext(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -23,7 +23,7 @@ func newSystemBusConn(ctx context.Context) (*dbus.Conn, error) {
|
|||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSessionBusConn(ctx context.Context) (*dbus.Conn, error) {
|
func NewSessionBusConn(ctx context.Context) (*dbus.Conn, error) {
|
||||||
// Connect to dbus session bus
|
// Connect to dbus session bus
|
||||||
conn, err := dbus.SessionBusPrivate(dbus.WithContext(ctx))
|
conn, err := dbus.SessionBusPrivate(dbus.WithContext(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
20
itd
Normal file
20
itd
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
name="itd"
|
||||||
|
description="Infinitime Daemon (itd)"
|
||||||
|
command="@bindir@/itd"
|
||||||
|
pidfile="@piddir@/${RC_SVCNAME}.pid"
|
||||||
|
command_user="user:group"
|
||||||
|
command_background="yes"
|
||||||
|
respawn_period=30
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
after bluetooth
|
||||||
|
}
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
checkconfig || return $?
|
||||||
|
ebegin "Reloading ${RC_SVCNAME}"
|
||||||
|
start-stop-daemon --signal HUP --pidfile "${pidfile}"
|
||||||
|
eend $?
|
||||||
|
}
|
5
itgui.desktop
Normal file
5
itgui.desktop
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Terminal=false
|
||||||
|
Exec=/usr/bin/itgui
|
||||||
|
Name=itgui
|
11
main.go
11
main.go
@ -39,9 +39,6 @@ import (
|
|||||||
|
|
||||||
var k = koanf.New(".")
|
var k = koanf.New(".")
|
||||||
|
|
||||||
//go:embed version.txt
|
|
||||||
var version string
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
firmwareUpdating = false
|
firmwareUpdating = false
|
||||||
// The FS must be updated when the watch is reconnected
|
// The FS must be updated when the watch is reconnected
|
||||||
@ -149,7 +146,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize music controls
|
// Initialize music controls
|
||||||
err = initMusicCtrl(dev)
|
err = initMusicCtrl(ctx, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error initializing music control")
|
log.Error().Err(err).Msg("Error initializing music control")
|
||||||
}
|
}
|
||||||
@ -178,6 +175,12 @@ func main() {
|
|||||||
log.Error().Err(err).Msg("Error intializing metrics collection")
|
log.Error().Err(err).Msg("Error intializing metrics collection")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize metrics collection
|
||||||
|
err = initPureMaps(ctx, dev)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Error intializing puremaps integration")
|
||||||
|
}
|
||||||
|
|
||||||
// Start control socket
|
// Start control socket
|
||||||
err = startSocket(ctx, dev)
|
err = startSocket(ctx, dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
211
maps.go
Normal file
211
maps.go
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/godbus/dbus/v5"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"go.arsenm.dev/infinitime"
|
||||||
|
"go.arsenm.dev/itd/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
interfaceName = "io.github.rinigus.PureMaps.navigator"
|
||||||
|
iconProperty = interfaceName + ".icon"
|
||||||
|
narrativeProperty = interfaceName + ".narrative"
|
||||||
|
manDistProperty = interfaceName + ".manDist"
|
||||||
|
progressProperty = interfaceName + ".progress"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initPureMaps(ctx context.Context, dev *infinitime.Device) error {
|
||||||
|
// Connect to session bus. This connection is for method calls.
|
||||||
|
conn, err := utils.NewSessionBusConn(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := pureMapsExists(ctx, conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to session bus. This connection is for method calls.
|
||||||
|
monitorConn, err := utils.NewSessionBusConn(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define rules to listen for
|
||||||
|
rules := []string{
|
||||||
|
"type='signal',interface='io.github.rinigus.PureMaps.navigator'",
|
||||||
|
}
|
||||||
|
var flag uint = 0
|
||||||
|
// Becode monitor for notifications
|
||||||
|
call := monitorConn.BusObject().CallWithContext(
|
||||||
|
ctx, "org.freedesktop.DBus.Monitoring.BecomeMonitor", 0, rules, flag,
|
||||||
|
)
|
||||||
|
if call.Err != nil {
|
||||||
|
return call.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
var navigator dbus.BusObject
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator")
|
||||||
|
err = setAll(navigator, dev)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Error setting all navigation fields")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
signalCh := make(chan *dbus.Message, 10)
|
||||||
|
monitorConn.Eavesdrop(signalCh)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case sig := <-signalCh:
|
||||||
|
if sig.Type != dbus.TypeSignal {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var member string
|
||||||
|
err = sig.Headers[dbus.FieldMember].Store(&member)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Error getting dbus member field")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasSuffix(member, "Changed") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Str("member", member).Msg("Signal received from PureMaps navigator")
|
||||||
|
|
||||||
|
// The object must be retrieved in this loop in case PureMaps was not
|
||||||
|
// open at the time ITD was started.
|
||||||
|
navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator")
|
||||||
|
member = strings.TrimSuffix(member, "Changed")
|
||||||
|
|
||||||
|
switch member {
|
||||||
|
case "icon":
|
||||||
|
var icon string
|
||||||
|
err = navigator.StoreProperty(iconProperty, &icon)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev.Navigation.SetFlag(infinitime.NavFlag(icon))
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case "narrative":
|
||||||
|
var narrative string
|
||||||
|
err = navigator.StoreProperty(narrativeProperty, &narrative)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev.Navigation.SetNarrative(narrative)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case "manDist":
|
||||||
|
var manDist string
|
||||||
|
err = navigator.StoreProperty(manDistProperty, &manDist)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev.Navigation.SetManDist(manDist)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case "progress":
|
||||||
|
var progress int32
|
||||||
|
err = navigator.StoreProperty(progressProperty, &progress)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev.Navigation.SetProgress(uint8(progress))
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
log.Info().Msg("Sending PureMaps data to InfiniTime")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setAll(navigator dbus.BusObject, dev *infinitime.Device) error {
|
||||||
|
var icon string
|
||||||
|
err := navigator.StoreProperty(iconProperty, &icon)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev.Navigation.SetFlag(infinitime.NavFlag(icon))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var narrative string
|
||||||
|
err = navigator.StoreProperty(narrativeProperty, &narrative)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev.Navigation.SetNarrative(narrative)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var manDist string
|
||||||
|
err = navigator.StoreProperty(manDistProperty, &manDist)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dev.Navigation.SetManDist(manDist)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var progress int32
|
||||||
|
err = navigator.StoreProperty(progressProperty, &progress)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev.Navigation.SetProgress(uint8(progress))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pureMapsExists checks to make sure the PureMaps service exists on the bus
|
||||||
|
func pureMapsExists(ctx context.Context, conn *dbus.Conn) (bool, error) {
|
||||||
|
var names []string
|
||||||
|
err := conn.BusObject().CallWithContext(
|
||||||
|
ctx, "org.freedesktop.DBus.ListNames", 0,
|
||||||
|
).Store(&names)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return strSlcContains(names, "io.github.rinigus.PureMaps"), nil
|
||||||
|
}
|
270
mpris/mpris.go
Normal file
270
mpris/mpris.go
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
package mpris
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/godbus/dbus/v5"
|
||||||
|
"go.arsenm.dev/itd/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
method, monitor *dbus.Conn
|
||||||
|
monitorCh chan *dbus.Message
|
||||||
|
onChangeOnce sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
// Init makes required connections to DBus and
|
||||||
|
// initializes change monitoring channel
|
||||||
|
func Init(ctx context.Context) error {
|
||||||
|
// Connect to session bus for monitoring
|
||||||
|
monitorConn, err := utils.NewSessionBusConn(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Add match rule for PropertiesChanged on media player
|
||||||
|
monitorConn.AddMatchSignal(
|
||||||
|
dbus.WithMatchObjectPath("/org/mpris/MediaPlayer2"),
|
||||||
|
dbus.WithMatchInterface("org.freedesktop.DBus.Properties"),
|
||||||
|
dbus.WithMatchMember("PropertiesChanged"),
|
||||||
|
)
|
||||||
|
monitorCh = make(chan *dbus.Message, 10)
|
||||||
|
monitorConn.Eavesdrop(monitorCh)
|
||||||
|
|
||||||
|
// Connect to session bus for method calls
|
||||||
|
methodConn, err := utils.NewSessionBusConn(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
method, monitor = methodConn, monitorConn
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit closes all connections and channels
|
||||||
|
func Exit() {
|
||||||
|
close(monitorCh)
|
||||||
|
method.Close()
|
||||||
|
monitor.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play uses MPRIS to play media
|
||||||
|
func Play() error {
|
||||||
|
player, err := getPlayerObj()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if player != nil {
|
||||||
|
call := player.Call("org.mpris.MediaPlayer2.Player.Play", 0)
|
||||||
|
if call.Err != nil {
|
||||||
|
return call.Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pause uses MPRIS to pause media
|
||||||
|
func Pause() error {
|
||||||
|
player, err := getPlayerObj()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if player != nil {
|
||||||
|
call := player.Call("org.mpris.MediaPlayer2.Player.Pause", 0)
|
||||||
|
if call.Err != nil {
|
||||||
|
return call.Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next uses MPRIS to skip to next media
|
||||||
|
func Next() error {
|
||||||
|
player, err := getPlayerObj()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if player != nil {
|
||||||
|
call := player.Call("org.mpris.MediaPlayer2.Player.Next", 0)
|
||||||
|
if call.Err != nil {
|
||||||
|
return call.Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prev uses MPRIS to skip to previous media
|
||||||
|
func Prev() error {
|
||||||
|
player, err := getPlayerObj()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if player != nil {
|
||||||
|
call := player.Call("org.mpris.MediaPlayer2.Player.Previous", 0)
|
||||||
|
if call.Err != nil {
|
||||||
|
return call.Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func VolUp(percent uint) error {
|
||||||
|
player, err := getPlayerObj()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if player != nil {
|
||||||
|
currentVal, err := player.GetProperty("org.mpris.MediaPlayer2.Player.Volume")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newVal := currentVal.Value().(float64) + (float64(percent) / 100)
|
||||||
|
err = player.SetProperty("org.mpris.MediaPlayer2.Player.Volume", newVal)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func VolDown(percent uint) error {
|
||||||
|
player, err := getPlayerObj()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if player != nil {
|
||||||
|
currentVal, err := player.GetProperty("org.mpris.MediaPlayer2.Player.Volume")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newVal := currentVal.Value().(float64) - (float64(percent) / 100)
|
||||||
|
err = player.SetProperty("org.mpris.MediaPlayer2.Player.Volume", newVal)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChangeType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ChangeTypeTitle ChangeType = iota
|
||||||
|
ChangeTypeArtist
|
||||||
|
ChangeTypeAlbum
|
||||||
|
ChangeTypeStatus
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ct ChangeType) String() string {
|
||||||
|
switch ct {
|
||||||
|
case ChangeTypeTitle:
|
||||||
|
return "Title"
|
||||||
|
case ChangeTypeAlbum:
|
||||||
|
return "Album"
|
||||||
|
case ChangeTypeArtist:
|
||||||
|
return "Artist"
|
||||||
|
case ChangeTypeStatus:
|
||||||
|
return "Status"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnChange runs cb when a value changes
|
||||||
|
func OnChange(cb func(ChangeType, string)) {
|
||||||
|
go onChangeOnce.Do(func() {
|
||||||
|
// For every message on channel
|
||||||
|
for msg := range monitorCh {
|
||||||
|
// Parse PropertiesChanged
|
||||||
|
iface, changed, ok := parsePropertiesChanged(msg)
|
||||||
|
if !ok || iface != "org.mpris.MediaPlayer2.Player" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// For every property changed
|
||||||
|
for name, val := range changed {
|
||||||
|
// If metadata changed
|
||||||
|
if name == "Metadata" {
|
||||||
|
// Get fields
|
||||||
|
fields := val.Value().(map[string]dbus.Variant)
|
||||||
|
// For every field
|
||||||
|
for name, val := range fields {
|
||||||
|
// Handle each field appropriately
|
||||||
|
if strings.HasSuffix(name, "title") {
|
||||||
|
title := val.Value().(string)
|
||||||
|
if title == "" {
|
||||||
|
title = "Unknown " + ChangeTypeTitle.String()
|
||||||
|
}
|
||||||
|
cb(ChangeTypeTitle, title)
|
||||||
|
} else if strings.HasSuffix(name, "album") {
|
||||||
|
album := val.Value().(string)
|
||||||
|
if album == "" {
|
||||||
|
album = "Unknown " + ChangeTypeAlbum.String()
|
||||||
|
}
|
||||||
|
cb(ChangeTypeAlbum, album)
|
||||||
|
} else if strings.HasSuffix(name, "artist") {
|
||||||
|
var artists string
|
||||||
|
switch artistVal := val.Value().(type) {
|
||||||
|
case string:
|
||||||
|
artists = artistVal
|
||||||
|
case []string:
|
||||||
|
artists = strings.Join(artistVal, ", ")
|
||||||
|
}
|
||||||
|
if artists == "" {
|
||||||
|
artists = "Unknown " + ChangeTypeArtist.String()
|
||||||
|
}
|
||||||
|
cb(ChangeTypeArtist, artists)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if name == "PlaybackStatus" {
|
||||||
|
// Handle status change
|
||||||
|
cb(ChangeTypeStatus, val.Value().(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPlayerNames gets all DBus MPRIS player bus names
|
||||||
|
func getPlayerNames(conn *dbus.Conn) ([]string, error) {
|
||||||
|
var names []string
|
||||||
|
err := conn.BusObject().Call("org.freedesktop.DBus.ListNames", 0).Store(&names)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var players []string
|
||||||
|
for _, name := range names {
|
||||||
|
if strings.HasPrefix(name, "org.mpris.MediaPlayer2") {
|
||||||
|
players = append(players, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return players, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPlayerObj gets the object corresponding to the first
|
||||||
|
// bus name found in DBus
|
||||||
|
func getPlayerObj() (dbus.BusObject, error) {
|
||||||
|
players, err := getPlayerNames(method)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(players) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return method.Object(players[0], "/org/mpris/MediaPlayer2"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsePropertiesChanged parses a DBus PropertiesChanged signal
|
||||||
|
func parsePropertiesChanged(msg *dbus.Message) (iface string, changed map[string]dbus.Variant, ok bool) {
|
||||||
|
if len(msg.Body) != 3 {
|
||||||
|
return "", nil, false
|
||||||
|
}
|
||||||
|
iface, ok = msg.Body[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
changed, ok = msg.Body[1].(map[string]dbus.Variant)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
84
mpris/mpris_test.go
Normal file
84
mpris/mpris_test.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package mpris
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/godbus/dbus/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestParsePropertiesChanged checks the parsePropertiesChanged function to
|
||||||
|
// make sure it correctly parses a DBus PropertiesChanged signal.
|
||||||
|
func TestParsePropertiesChanged(t *testing.T) {
|
||||||
|
// Create a DBus message
|
||||||
|
msg := &dbus.Message{
|
||||||
|
Body: []interface{}{
|
||||||
|
"com.example.Interface",
|
||||||
|
map[string]dbus.Variant{
|
||||||
|
"Property1": dbus.MakeVariant(true),
|
||||||
|
"Property2": dbus.MakeVariant("Hello, world!"),
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the message
|
||||||
|
iface, changed, ok := parsePropertiesChanged(msg)
|
||||||
|
if !ok {
|
||||||
|
t.Error("Expected parsePropertiesChanged to return true, but got false")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the parsed values
|
||||||
|
expectedIface := "com.example.Interface"
|
||||||
|
if iface != expectedIface {
|
||||||
|
t.Errorf("Expected iface to be %q, but got %q", expectedIface, iface)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedChanged := map[string]dbus.Variant{
|
||||||
|
"Property1": dbus.MakeVariant(true),
|
||||||
|
"Property2": dbus.MakeVariant("Hello, world!"),
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(changed, expectedChanged) {
|
||||||
|
t.Errorf("Expected changed to be %v, but got %v", expectedChanged, changed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test a message with an invalid number of arguments
|
||||||
|
msg = &dbus.Message{
|
||||||
|
Body: []interface{}{
|
||||||
|
"com.example.Interface",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, _, ok = parsePropertiesChanged(msg)
|
||||||
|
if ok {
|
||||||
|
t.Error("Expected parsePropertiesChanged to return false, but got true")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test a message with an invalid first argument
|
||||||
|
msg = &dbus.Message{
|
||||||
|
Body: []interface{}{
|
||||||
|
123,
|
||||||
|
map[string]dbus.Variant{
|
||||||
|
"Property1": dbus.MakeVariant(true),
|
||||||
|
"Property2": dbus.MakeVariant("Hello, world!"),
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, _, ok = parsePropertiesChanged(msg)
|
||||||
|
if ok {
|
||||||
|
t.Error("Expected parsePropertiesChanged to return false, but got true")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test a message with an invalid second argument
|
||||||
|
msg = &dbus.Message{
|
||||||
|
Body: []interface{}{
|
||||||
|
"com.example.Interface",
|
||||||
|
123,
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, _, ok = parsePropertiesChanged(msg)
|
||||||
|
if ok {
|
||||||
|
t.Error("Expected parsePropertiesChanged to return false, but got true")
|
||||||
|
}
|
||||||
|
}
|
30
music.go
30
music.go
@ -19,29 +19,31 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"go.arsenm.dev/infinitime"
|
"go.arsenm.dev/infinitime"
|
||||||
"go.arsenm.dev/infinitime/pkg/player"
|
"go.arsenm.dev/itd/mpris"
|
||||||
"go.arsenm.dev/itd/translit"
|
"go.arsenm.dev/itd/translit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initMusicCtrl(dev *infinitime.Device) error {
|
func initMusicCtrl(ctx context.Context, dev *infinitime.Device) error {
|
||||||
player.Init()
|
mpris.Init(ctx)
|
||||||
|
|
||||||
maps := k.Strings("notifs.translit.use")
|
maps := k.Strings("notifs.translit.use")
|
||||||
translit.Transliterators["custom"] = translit.Map(k.Strings("notifs.translit.custom"))
|
translit.Transliterators["custom"] = translit.Map(k.Strings("notifs.translit.custom"))
|
||||||
|
|
||||||
player.OnChange(func(ct player.ChangeType, val string) {
|
mpris.OnChange(func(ct mpris.ChangeType, val string) {
|
||||||
newVal := translit.Transliterate(val, maps...)
|
newVal := translit.Transliterate(val, maps...)
|
||||||
if !firmwareUpdating {
|
if !firmwareUpdating {
|
||||||
switch ct {
|
switch ct {
|
||||||
case player.ChangeTypeStatus:
|
case mpris.ChangeTypeStatus:
|
||||||
dev.Music.SetStatus(val == "Playing")
|
dev.Music.SetStatus(val == "Playing")
|
||||||
case player.ChangeTypeTitle:
|
case mpris.ChangeTypeTitle:
|
||||||
dev.Music.SetTrack(newVal)
|
dev.Music.SetTrack(newVal)
|
||||||
case player.ChangeTypeAlbum:
|
case mpris.ChangeTypeAlbum:
|
||||||
dev.Music.SetAlbum(newVal)
|
dev.Music.SetAlbum(newVal)
|
||||||
case player.ChangeTypeArtist:
|
case mpris.ChangeTypeArtist:
|
||||||
dev.Music.SetArtist(newVal)
|
dev.Music.SetArtist(newVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,17 +60,17 @@ func initMusicCtrl(dev *infinitime.Device) error {
|
|||||||
// Perform appropriate action based on event
|
// Perform appropriate action based on event
|
||||||
switch musicEvt {
|
switch musicEvt {
|
||||||
case infinitime.MusicEventPlay:
|
case infinitime.MusicEventPlay:
|
||||||
player.Play()
|
mpris.Play()
|
||||||
case infinitime.MusicEventPause:
|
case infinitime.MusicEventPause:
|
||||||
player.Pause()
|
mpris.Pause()
|
||||||
case infinitime.MusicEventNext:
|
case infinitime.MusicEventNext:
|
||||||
player.Next()
|
mpris.Next()
|
||||||
case infinitime.MusicEventPrev:
|
case infinitime.MusicEventPrev:
|
||||||
player.Prev()
|
mpris.Prev()
|
||||||
case infinitime.MusicEventVolUp:
|
case infinitime.MusicEventVolUp:
|
||||||
player.VolUp(uint(k.Int("music.vol.interval")))
|
mpris.VolUp(uint(k.Int("music.vol.interval")))
|
||||||
case infinitime.MusicEventVolDown:
|
case infinitime.MusicEventVolDown:
|
||||||
player.VolDown(uint(k.Int("music.vol.interval")))
|
mpris.VolDown(uint(k.Int("music.vol.interval")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -25,18 +25,19 @@ import (
|
|||||||
"github.com/godbus/dbus/v5"
|
"github.com/godbus/dbus/v5"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"go.arsenm.dev/infinitime"
|
"go.arsenm.dev/infinitime"
|
||||||
|
"go.arsenm.dev/itd/internal/utils"
|
||||||
"go.arsenm.dev/itd/translit"
|
"go.arsenm.dev/itd/translit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initNotifRelay(ctx context.Context, dev *infinitime.Device) error {
|
func initNotifRelay(ctx context.Context, dev *infinitime.Device) error {
|
||||||
// Connect to dbus session bus
|
// Connect to dbus session bus
|
||||||
bus, err := newSessionBusConn(ctx)
|
bus, err := utils.NewSessionBusConn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define rules to listen for
|
// Define rules to listen for
|
||||||
var rules = []string{
|
rules := []string{
|
||||||
"type='method_call',member='Notify',path='/org/freedesktop/Notifications',interface='org.freedesktop.Notifications'",
|
"type='method_call',member='Notify',path='/org/freedesktop/Notifications',interface='org.freedesktop.Notifications'",
|
||||||
}
|
}
|
||||||
var flag uint = 0
|
var flag uint = 0
|
||||||
|
3
scripts/gen-version.sh
Executable file
3
scripts/gen-version.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
git describe --tags > version.txt
|
50
socket.go
50
socket.go
@ -43,7 +43,7 @@ var (
|
|||||||
|
|
||||||
func startSocket(ctx context.Context, dev *infinitime.Device) error {
|
func startSocket(ctx context.Context, dev *infinitime.Device) error {
|
||||||
// Make socket directory if non-existant
|
// Make socket directory if non-existant
|
||||||
err := os.MkdirAll(filepath.Dir(k.String("socket.path")), 0755)
|
err := os.MkdirAll(filepath.Dir(k.String("socket.path")), 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -293,6 +293,17 @@ type FS struct {
|
|||||||
fs *blefs.FS
|
fs *blefs.FS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *FS) RemoveAll(_ *server.Context, paths []string) error {
|
||||||
|
fs.updateFS()
|
||||||
|
for _, path := range paths {
|
||||||
|
err := fs.fs.RemoveAll(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *FS) Remove(_ *server.Context, paths []string) error {
|
func (fs *FS) Remove(_ *server.Context, paths []string) error {
|
||||||
fs.updateFS()
|
fs.updateFS()
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
@ -309,6 +320,17 @@ func (fs *FS) Rename(_ *server.Context, paths [2]string) error {
|
|||||||
return fs.fs.Rename(paths[0], paths[1])
|
return fs.fs.Rename(paths[0], paths[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *FS) MkdirAll(_ *server.Context, paths []string) error {
|
||||||
|
fs.updateFS()
|
||||||
|
for _, path := range paths {
|
||||||
|
err := fs.fs.MkdirAll(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *FS) Mkdir(_ *server.Context, paths []string) error {
|
func (fs *FS) Mkdir(_ *server.Context, paths []string) error {
|
||||||
fs.updateFS()
|
fs.updateFS()
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
@ -424,6 +446,32 @@ func (fs *FS) Download(ctx *server.Context, paths [2]string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *FS) LoadResources(ctx *server.Context, path string) error {
|
||||||
|
resFl, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
progCh, err := infinitime.LoadResources(resFl, fs.fs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := ctx.MakeChannel()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for evt := range progCh {
|
||||||
|
ch <- evt
|
||||||
|
}
|
||||||
|
close(ch)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *FS) updateFS() {
|
func (fs *FS) updateFS() {
|
||||||
if fs.fs == nil || updateFS {
|
if fs.fs == nil || updateFS {
|
||||||
// Get new FS
|
// Get new FS
|
||||||
|
@ -35,8 +35,6 @@ func (ct *ChineseTranslit) Transliterate(s string) string {
|
|||||||
// Reset temporary buffer
|
// Reset temporary buffer
|
||||||
tmpBuf.Reset()
|
tmpBuf.Reset()
|
||||||
}
|
}
|
||||||
// Write character to output
|
|
||||||
outBuf.WriteRune(char)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If buffer contains characters
|
// If buffer contains characters
|
||||||
|
47
translit/translit_test.go
Normal file
47
translit/translit_test.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package translit
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestTransliterate(t *testing.T) {
|
||||||
|
type testCase struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected string
|
||||||
|
}
|
||||||
|
|
||||||
|
var cases = []testCase{
|
||||||
|
{"eASCII", "œª°«»", `oeao""`},
|
||||||
|
{"Scandinavian", "ÆæØøÅå", "AeaeOeoeAaaa"},
|
||||||
|
{"German", "äöüÄÖÜßẞ", "aeoeueAeOeUessSS"},
|
||||||
|
{"Hebrew", "אבגדהוזחטיכלמנסעפצקרשתףץךםן", "abgdhuzkhtyclmns'ptskrshthftschmn"},
|
||||||
|
{"Greek", "αάβγδεέζηήθιίϊΐκλμνξοόπρσςτυύϋΰφχψωώΑΆΒΓΔΕΈΖΗΉΘΙΊΪΚΛΜΝΞΟΌΠΡΣΤΥΎΫΦΧΨΩΏ", "aavgdeeziithiiiiklmnksooprsstyyyyfchpsooAABGDEEZIIThIIIKLMNKsOOPRSTYYYFChPsOO"},
|
||||||
|
{"Russian", "Ёё", "Йoйo"},
|
||||||
|
{"Ukranian", "ґєіїҐЄІЇ", "ghjeijiGhJeIJI"},
|
||||||
|
{"Arabic", "ابتثجحخدذرزسشصضطظعغفقكلمنهويىﺓآئإؤأء٠١٢٣٤٥٦٧٨٩", "abtthj75dthrzssh99'66'33'fqklmnhwya2222220123456789"},
|
||||||
|
{"Farsi", "پچژکگی\u200c؟٪؛،۱۲۳۴۵۶۷۸۹۰»«َُِّ", "pchzhkgy ?%;:1234567890<>eao"},
|
||||||
|
{"Polish", "Łł", "Ll"},
|
||||||
|
{"Lithuanian", "ąčęėįšųūž", "aceeisuuz"},
|
||||||
|
{"Estonian", "äÄöõÖÕüÜ", "aAooOOuU"},
|
||||||
|
{"Icelandic", "ÞþÐð", "ThthDd"},
|
||||||
|
{"Czech", "řěýáíéóúůďťň", "reyaieouudtn"},
|
||||||
|
{"French", "àâéèêëùüÿç", "aaeeeeuuyc"},
|
||||||
|
{"Romanian", "ăĂâÂîÎșȘțȚşŞţŢ„”", `aAaAiIsStTsStT""`},
|
||||||
|
{
|
||||||
|
"Emoji",
|
||||||
|
"😂🤣😊☺️😌😃😁😋😛😜🙃😎😶😩😕😏💜💖💗❤️💕💞💘💓💚💙💟❣️💔😱😮😯😝🤔😔😍😘😚😙👍👌🤞✌️🌄🌞🤗🌻🥱🙄🔫🥔😬✨🌌💀😅😢💯🔥😉😴💤",
|
||||||
|
`XDXD:):):):D:D:P:P;P(:8):#-_-:(:‑J<3<3<3<3<3<3<3<3<3<3<3<3!</3D::O:OxP',:-|:|:*:*:*:*:thumbsup::ok_hand::crossed_fingers::victory_hand::sunrise_over_mountains::sun_with_face::hugging_face::sunflower::yawning_face::face_with_rolling_eyes::gun::potato::E******8-X':D:'(:100::fire:;):zzz::zzz:`,
|
||||||
|
},
|
||||||
|
{"Korean", "\ucc2c\ubbf8\ub97c \uc637\uc744 \uc5bc\ub9c8\ub098 \ud48d\ubd80\ud558\uac8c \uccad\ucd98\uc774 \uc5ed\uc0ac\ub97c", "chanmireul oteul eolmana pungbuhage cheongchuni yeoksareul"},
|
||||||
|
{"Chinese", "\u81e8\u8cc7\u601d\u7531\u554f\u805e\u907f\u6c5a\u81f3\u5c0e\u524d\u99ac\u59cb\u4e00\u79fb\u3002", "lin zi si you wen wen bi wu zhi dao qian ma shi yi yi"},
|
||||||
|
{"Armenian", "\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053a\u053b\u053c\u053d\u053e\u053f\u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054a\u054b\u054c\u054d\u054e\u054f\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056a\u056b\u056c\u056d\u056e\u056f\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057a\u057b\u057c\u057d\u057e\u057f\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587", "ABGDEZEYTJILXCKHDzXCMYNShVoChPJRSVTRCPQOFabgdezeytjilxckhdzxcmynsochpjrsvtrcpqofev"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tCase := range cases {
|
||||||
|
t.Run(tCase.name, func(t *testing.T) {
|
||||||
|
out := Transliterate(tCase.input, tCase.name)
|
||||||
|
if out != tCase.expected {
|
||||||
|
t.Errorf("Expected %q, got %q", tCase.expected, out)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
8
version.go
Normal file
8
version.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import _ "embed"
|
||||||
|
|
||||||
|
//go:generate scripts/gen-version.sh
|
||||||
|
|
||||||
|
//go:embed version.txt
|
||||||
|
var version string
|
Loading…
Reference in New Issue
Block a user