refactor: 移除二维码和交叉编译,改为列出所有 LAN IP 地址;清理依赖
This commit is contained in:
39
Taskfile.yml
39
Taskfile.yml
@@ -22,48 +22,11 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- go run .
|
- go run .
|
||||||
|
|
||||||
build:darwin-arm64:
|
|
||||||
desc: Build for macOS ARM64
|
|
||||||
env:
|
|
||||||
GOOS: darwin
|
|
||||||
GOARCH: arm64
|
|
||||||
CGO_ENABLED: "1"
|
|
||||||
cmds:
|
|
||||||
- go build -ldflags "-s -w -X main.version={{.VERSION}}" -o dist/{{.APP_NAME}}-darwin-arm64 .
|
|
||||||
|
|
||||||
build:darwin-amd64:
|
|
||||||
desc: Build for macOS AMD64
|
|
||||||
env:
|
|
||||||
GOOS: darwin
|
|
||||||
GOARCH: amd64
|
|
||||||
CGO_ENABLED: "1"
|
|
||||||
cmds:
|
|
||||||
- go build -ldflags "-s -w -X main.version={{.VERSION}}" -o dist/{{.APP_NAME}}-darwin-amd64 .
|
|
||||||
|
|
||||||
build:linux-amd64:
|
|
||||||
desc: Build for Linux AMD64
|
|
||||||
env:
|
|
||||||
GOOS: linux
|
|
||||||
GOARCH: amd64
|
|
||||||
CGO_ENABLED: "1"
|
|
||||||
cmds:
|
|
||||||
- go build -ldflags "-s -w -X main.version={{.VERSION}}" -o dist/{{.APP_NAME}}-linux-amd64 .
|
|
||||||
|
|
||||||
build:windows-amd64:
|
|
||||||
desc: Build for Windows AMD64
|
|
||||||
env:
|
|
||||||
GOOS: windows
|
|
||||||
GOARCH: amd64
|
|
||||||
CGO_ENABLED: "1"
|
|
||||||
cmds:
|
|
||||||
- go build -ldflags "-s -w -X main.version={{.VERSION}}" -o dist/{{.APP_NAME}}-windows-amd64.exe .
|
|
||||||
|
|
||||||
build:all:
|
build:all:
|
||||||
desc: Build for all platforms
|
desc: Build for all platforms
|
||||||
cmds:
|
cmds:
|
||||||
- mkdir -p dist
|
- mkdir -p dist
|
||||||
- task: build:linux-amd64
|
- task: default
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
desc: Clean build artifacts
|
desc: Clean build artifacts
|
||||||
cmds:
|
cmds:
|
||||||
|
|||||||
3
go.mod
3
go.mod
@@ -9,7 +9,6 @@ require (
|
|||||||
github.com/gofiber/contrib/v3/websocket v1.0.0
|
github.com/gofiber/contrib/v3/websocket v1.0.0
|
||||||
github.com/gofiber/fiber/v3 v3.1.0
|
github.com/gofiber/fiber/v3 v3.1.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/mdp/qrterminal/v3 v3.2.1
|
|
||||||
golang.design/x/clipboard v0.7.1
|
golang.design/x/clipboard v0.7.1
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
@@ -55,7 +54,5 @@ require (
|
|||||||
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f // indirect
|
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f // indirect
|
||||||
golang.org/x/net v0.50.0 // indirect
|
golang.org/x/net v0.50.0 // indirect
|
||||||
golang.org/x/sys v0.41.0 // indirect
|
golang.org/x/sys v0.41.0 // indirect
|
||||||
golang.org/x/term v0.40.0 // indirect
|
|
||||||
golang.org/x/text v0.34.0 // indirect
|
golang.org/x/text v0.34.0 // indirect
|
||||||
rsc.io/qr v0.2.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
6
go.sum
6
go.sum
@@ -50,8 +50,6 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
|||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mdp/qrterminal/v3 v3.2.1 h1:6+yQjiiOsSuXT5n9/m60E54vdgFsw0zhADHhHLrFet4=
|
|
||||||
github.com/mdp/qrterminal/v3 v3.2.1/go.mod h1:jOTmXvnBsMy5xqLniO0R++Jmjs2sTm9dFSuQ5kpz/SU=
|
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/otiai10/gosseract/v2 v2.4.1 h1:G8AyBpXEeSlcq8TI85LH/pM5SXk8Djy2GEXisgyblRw=
|
github.com/otiai10/gosseract/v2 v2.4.1 h1:G8AyBpXEeSlcq8TI85LH/pM5SXk8Djy2GEXisgyblRw=
|
||||||
@@ -129,8 +127,6 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
|
|
||||||
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
|
|
||||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@@ -138,5 +134,3 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
|||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
|
||||||
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs=
|
|
||||||
|
|||||||
@@ -5,17 +5,21 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetLANIP returns the first non-loopback IPv4 address.
|
// GetLANIPs returns all non-loopback IPv4 addresses.
|
||||||
func GetLANIP() (string, error) {
|
func GetLANIPs() ([]string, error) {
|
||||||
addrs, err := net.InterfaceAddrs()
|
addrs, err := net.InterfaceAddrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var ips []string
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
|
if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
|
||||||
return ipNet.IP.String(), nil
|
ips = append(ips, ipNet.IP.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("no LAN IP found")
|
if len(ips) == 0 {
|
||||||
|
return nil, fmt.Errorf("no LAN IP found")
|
||||||
|
}
|
||||||
|
return ips, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
37
main.go
37
main.go
@@ -42,12 +42,13 @@ func main() {
|
|||||||
if err := paste.Init(); err != nil {
|
if err := paste.Init(); err != nil {
|
||||||
slog.Warn("clipboard init failed, paste will be unavailable", "err", err)
|
slog.Warn("clipboard init failed, paste will be unavailable", "err", err)
|
||||||
}
|
}
|
||||||
// Detect LAN IP
|
// Detect LAN IPs
|
||||||
lanIP, err := server.GetLANIP()
|
lanIPs, err := server.GetLANIPs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("failed to detect LAN IP", "error", err)
|
slog.Error("failed to detect LAN IP", "error", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
lanIP := lanIPs[0] // Use first IP for TLS and server binding
|
||||||
|
|
||||||
// Read token from config (empty = no auth required)
|
// Read token from config (empty = no auth required)
|
||||||
token := cfg.Security.Token
|
token := cfg.Security.Token
|
||||||
@@ -66,20 +67,26 @@ func main() {
|
|||||||
scheme = "https"
|
scheme = "https"
|
||||||
host = tlsResult.Host
|
host = tlsResult.Host
|
||||||
}
|
}
|
||||||
// Build URL
|
|
||||||
var url string
|
|
||||||
if token != "" {
|
|
||||||
url = fmt.Sprintf("%s://%s:%d/?token=%s", scheme, host, cfg.Server.Port, token)
|
|
||||||
} else {
|
|
||||||
url = fmt.Sprintf("%s://%s:%d/", scheme, host, cfg.Server.Port)
|
|
||||||
}
|
|
||||||
// Print connection info
|
// Print connection info
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("╔══════════════════════════════════════╗")
|
fmt.Println("╔══════════════════════════════════════╗")
|
||||||
fmt.Println("║ VoicePaste 就绪 ║")
|
fmt.Println("║ VoicePaste 就绪 ║")
|
||||||
fmt.Println("╚══════════════════════════════════════╝")
|
fmt.Println("╚══════════════════════════════════════╝")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf(" 地址: %s\n", url)
|
// Print all accessible addresses
|
||||||
|
if len(lanIPs) == 1 {
|
||||||
|
fmt.Printf(" 地址: %s\n", buildURL(scheme, host, cfg.Server.Port, token))
|
||||||
|
} else {
|
||||||
|
fmt.Println(" 地址:")
|
||||||
|
for _, ip := range lanIPs {
|
||||||
|
h := ip
|
||||||
|
if tlsResult != nil {
|
||||||
|
h = tlsResult.Host
|
||||||
|
}
|
||||||
|
fmt.Printf(" - %s\n", buildURL(scheme, h, cfg.Server.Port, token))
|
||||||
|
}
|
||||||
|
}
|
||||||
if tlsResult != nil && tlsResult.AnyIP {
|
if tlsResult != nil && tlsResult.AnyIP {
|
||||||
fmt.Println(" 证书: AnyIP(浏览器信任)")
|
fmt.Println(" 证书: AnyIP(浏览器信任)")
|
||||||
} else if cfg.Server.TLSAuto {
|
} else if cfg.Server.TLSAuto {
|
||||||
@@ -91,9 +98,7 @@ func main() {
|
|||||||
fmt.Println(" 认证: 未启用(无需 token)")
|
fmt.Println(" 认证: 未启用(无需 token)")
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
printQRCode(url)
|
fmt.Println(" 在手机浏览器中打开上方地址")
|
||||||
fmt.Println()
|
|
||||||
fmt.Println(" 用手机扫描二维码连接")
|
|
||||||
fmt.Println(" 按 Ctrl+C 停止服务")
|
fmt.Println(" 按 Ctrl+C 停止服务")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
// Create and start server
|
// Create and start server
|
||||||
@@ -142,4 +147,10 @@ func main() {
|
|||||||
slog.Error("server error", "error", err)
|
slog.Error("server error", "error", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
func buildURL(scheme, host string, port int, token string) string {
|
||||||
|
if token != "" {
|
||||||
|
return fmt.Sprintf("%s://%s:%d/?token=%s", scheme, host, port, token)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s://%s:%d/", scheme, host, port)
|
||||||
}
|
}
|
||||||
18
qrcode.go
18
qrcode.go
@@ -1,18 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/mdp/qrterminal/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
// printQRCode prints a QR code to the terminal.
|
|
||||||
func printQRCode(url string) {
|
|
||||||
qrterminal.GenerateWithConfig(url, qrterminal.Config{
|
|
||||||
Level: qrterminal.L,
|
|
||||||
Writer: os.Stdout,
|
|
||||||
BlackChar: qrterminal.BLACK,
|
|
||||||
WhiteChar: qrterminal.WHITE,
|
|
||||||
QuietZone: 2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user