mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-23 16:58:31 +02:00
migrated from logrus to zerolog, improved error formatting, fixed concurrent map write, fixed crash on rapid page refresh for idle containers, fixed infinite recursion on gotfiy error, fixed websocket connection problem when using idlewatcher
This commit is contained in:
25
internal/utils/strutils/ansi/ansi.go
Normal file
25
internal/utils/strutils/ansi/ansi.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package ansi
|
||||
|
||||
import "regexp"
|
||||
|
||||
var ansiRegexp = regexp.MustCompile(`\x1b\[[0-9;]*m`)
|
||||
|
||||
const (
|
||||
BrightRed = "\x1b[91m"
|
||||
BrightGreen = "\x1b[92m"
|
||||
BrightYellow = "\x1b[93m"
|
||||
BrightCyan = "\x1b[96m"
|
||||
BrightWhite = "\x1b[97m"
|
||||
Bold = "\x1b[1m"
|
||||
Reset = "\x1b[0m"
|
||||
|
||||
HighlightRed = BrightRed + Bold
|
||||
HighlightGreen = BrightGreen + Bold
|
||||
HighlightYellow = BrightYellow + Bold
|
||||
HighlightCyan = BrightCyan + Bold
|
||||
HighlightWhite = BrightWhite + Bold
|
||||
)
|
||||
|
||||
func StripANSI(s string) string {
|
||||
return ansiRegexp.ReplaceAllString(s, "")
|
||||
}
|
||||
69
internal/utils/strutils/format.go
Normal file
69
internal/utils/strutils/format.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package strutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/utils/strutils/ansi"
|
||||
)
|
||||
|
||||
func FormatDuration(d time.Duration) string {
|
||||
// Get total seconds from duration
|
||||
totalSeconds := int64(d.Seconds())
|
||||
|
||||
// Calculate days, hours, minutes, and seconds
|
||||
days := totalSeconds / (24 * 3600)
|
||||
hours := (totalSeconds % (24 * 3600)) / 3600
|
||||
minutes := (totalSeconds % 3600) / 60
|
||||
seconds := totalSeconds % 60
|
||||
|
||||
// Create a slice to hold parts of the duration
|
||||
var parts []string
|
||||
|
||||
if days > 0 {
|
||||
parts = append(parts, fmt.Sprintf("%d day%s", days, pluralize(days)))
|
||||
}
|
||||
if hours > 0 {
|
||||
parts = append(parts, fmt.Sprintf("%d hour%s", hours, pluralize(hours)))
|
||||
}
|
||||
if minutes > 0 {
|
||||
parts = append(parts, fmt.Sprintf("%d minute%s", minutes, pluralize(minutes)))
|
||||
}
|
||||
if seconds > 0 && totalSeconds < 3600 {
|
||||
parts = append(parts, fmt.Sprintf("%d second%s", seconds, pluralize(seconds)))
|
||||
}
|
||||
|
||||
// Join the parts with appropriate connectors
|
||||
if len(parts) == 0 {
|
||||
return "0 Seconds"
|
||||
}
|
||||
if len(parts) == 1 {
|
||||
return parts[0]
|
||||
}
|
||||
return strings.Join(parts[:len(parts)-1], ", ") + " and " + parts[len(parts)-1]
|
||||
}
|
||||
|
||||
func FormatTime(t time.Time) string {
|
||||
return t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func ParseBool(s string) bool {
|
||||
switch strings.ToLower(s) {
|
||||
case "1", "true", "yes", "on":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func DoYouMean(s string) string {
|
||||
return "Did you mean " + ansi.HighlightGreen + s + ansi.Reset + "?"
|
||||
}
|
||||
|
||||
func pluralize(n int64) string {
|
||||
if n > 1 {
|
||||
return "s"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
17
internal/utils/strutils/strconv.go
Normal file
17
internal/utils/strutils/strconv.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package strutils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
E "github.com/yusing/go-proxy/internal/error"
|
||||
)
|
||||
|
||||
func Atoi(s string) (int, E.Error) {
|
||||
val, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return val, E.From(errors.Unwrap(err)).Subject(s)
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
82
internal/utils/strutils/string.go
Normal file
82
internal/utils/strutils/string.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package strutils
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func CommaSeperatedList(s string) []string {
|
||||
res := strings.Split(s, ",")
|
||||
for i, part := range res {
|
||||
res[i] = strings.TrimSpace(part)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func Title(s string) string {
|
||||
return cases.Title(language.AmericanEnglish).String(s)
|
||||
}
|
||||
|
||||
func ExtractPort(fullURL string) (int, error) {
|
||||
url, err := url.Parse(fullURL)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return Atoi(url.Port())
|
||||
}
|
||||
|
||||
func PortString(port uint16) string {
|
||||
return strconv.FormatUint(uint64(port), 10)
|
||||
}
|
||||
|
||||
func LevenshteinDistance(a, b string) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if len(a) == 0 {
|
||||
return len(b)
|
||||
}
|
||||
if len(b) == 0 {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
v0 := make([]int, len(b)+1)
|
||||
v1 := make([]int, len(b)+1)
|
||||
|
||||
for i := 0; i <= len(b); i++ {
|
||||
v0[i] = i
|
||||
}
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
v1[0] = i + 1
|
||||
|
||||
for j := 0; j < len(b); j++ {
|
||||
cost := 0
|
||||
if a[i] != b[j] {
|
||||
cost = 1
|
||||
}
|
||||
|
||||
v1[j+1] = min(v1[j]+1, v0[j+1]+1, v0[j]+cost)
|
||||
}
|
||||
|
||||
for j := 0; j <= len(b); j++ {
|
||||
v0[j] = v1[j]
|
||||
}
|
||||
}
|
||||
|
||||
return v1[len(b)]
|
||||
}
|
||||
|
||||
func min(a, b, c int) int {
|
||||
if a < b && a < c {
|
||||
return a
|
||||
}
|
||||
if b < a && b < c {
|
||||
return b
|
||||
}
|
||||
return c
|
||||
}
|
||||
Reference in New Issue
Block a user