initial commit [141.14.140.180,mike]
This commit is contained in:
@@ -0,0 +1,341 @@
|
||||
// ======================================================================================= go toolbox (mwx'2026)
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/eknkc/basex"
|
||||
"github.com/fatih/color"
|
||||
"github.com/minio/selfupdate"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
var tbversion = "0.4.1"
|
||||
|
||||
var CHRS = "VW9IdGJ6eXh1T25DRHdrc2M5MlhOQVNQcEJFWnJhWVY2ZEowaFJLdmoxNUdxVDRJZkZpTTdRZW0zTFc4Z2w="
|
||||
var LR = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
|
||||
|
||||
|
||||
func checkforupdate() { // --------------------------------------------------------------- check for new version
|
||||
prg := prgname()
|
||||
resp, err := http.Get(VERSIONURL)
|
||||
if err == nil {
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
if scanner.Scan() {
|
||||
lversion := strings.TrimSpace(scanner.Text())
|
||||
sv_version, err := semver.NewVersion(version)
|
||||
if err == nil {
|
||||
sv_lversion, err := semver.NewVersion(lversion)
|
||||
if err == nil {
|
||||
if (sv_lversion.GreaterThan(sv_version)) {
|
||||
ans:=Yesno(SF("new '%s' version found (%s -> %s), update now?",prg,sv_version,sv_lversion),true);
|
||||
if (ans) {
|
||||
updateurl:=SF("%s/%s_%s_%s_%s",UPDATEBASEURL,prg,lversion,runtime.GOOS,runtime.GOARCH)
|
||||
|
||||
if err := doupdate(updateurl); err != nil {
|
||||
PO(SF("Update failed: %v\n", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
PO("Update successful!","please run your last command again")
|
||||
os.Exit(0)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func doupdate(url string) error { // ----------------------------------------------------------------- do update
|
||||
resp, err := http.Get(url)
|
||||
if err != nil { return err }
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK { return fmt.Errorf("server returned status: %v", resp.Status) }
|
||||
err = selfupdate.Apply(resp.Body, selfupdate.Options{})
|
||||
if err != nil { return err }
|
||||
return nil
|
||||
}
|
||||
|
||||
func Enc(str string) string { // ----------------------------------------------------------------- encode string
|
||||
enc, _ := basex.NewEncoding(Db64(CHRS))
|
||||
return enc.Encode([]byte(Rndstr(2) + str))
|
||||
}
|
||||
|
||||
func Dec(str string) string { // ----------------------------------------------------------------- decode string
|
||||
enc, _ := basex.NewEncoding(Db64(CHRS))
|
||||
b, _ := enc.Decode(str)
|
||||
return string(b[2:])
|
||||
}
|
||||
|
||||
func Db64(txt string) string { // ------------------------------------------------------------- string to base64
|
||||
d, _ := base64.StdEncoding.DecodeString(txt)
|
||||
return string(d)
|
||||
}
|
||||
|
||||
func Rndstr(n int) string { // ------------------------------------------------------- random string with length
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(LR))))
|
||||
b[i] = LR[n.Int64()]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func Input(msg string, def string) string { // -------------------------------- AlecAivazis/survey: input string
|
||||
tmp := ""
|
||||
err := survey.AskOne(&survey.Input{Message: msg, Default: def}, &tmp)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
P(Crb("Interrupted."))
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
return tmp
|
||||
}
|
||||
|
||||
func Inputpw(msg string) string { // ---------------------------------------- AlecAivazis/survey: input password
|
||||
tmp := ""
|
||||
err := survey.AskOne(&survey.Password{Message: msg}, &tmp)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
P(Crb("Interrupted."))
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
return tmp
|
||||
}
|
||||
|
||||
func Yesno(msg string, def bool) bool { // ------------------------------------------ AlecAivazis/survey: yes/no
|
||||
var err error
|
||||
tmp := ""
|
||||
if def {
|
||||
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"Yes", "No"}}, &tmp)
|
||||
} else {
|
||||
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"No", "Yes"}}, &tmp)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
P(Crb("Interrupted."))
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
if tmp == "Yes" {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func Getid(n int) string { // --------------------------------------------------------- get base62 random string
|
||||
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
ret := make([]byte, n)
|
||||
for i := 0; i < n; i++ {
|
||||
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
||||
ret[i] = letters[num.Int64()]
|
||||
}
|
||||
return string(ret)
|
||||
}
|
||||
|
||||
func GETid(n int) string { // --------------------------------------------------------- get base36 random string
|
||||
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
ret := make([]byte, n)
|
||||
for i := 0; i < n; i++ {
|
||||
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
||||
ret[i] = letters[num.Int64()]
|
||||
}
|
||||
return string(ret)
|
||||
}
|
||||
|
||||
func Mytable(rows *sql.Rows) []map[string]interface{} { // ----------------------------- load mysql result table
|
||||
defer rows.Close()
|
||||
columns, _ := rows.Columns()
|
||||
count := len(columns)
|
||||
tableData := make([]map[string]interface{}, 0)
|
||||
values := make([]interface{}, count)
|
||||
valuePtrs := make([]interface{}, count)
|
||||
for rows.Next() {
|
||||
for i := 0; i < count; i++ {
|
||||
valuePtrs[i] = &values[i]
|
||||
}
|
||||
rows.Scan(valuePtrs...)
|
||||
entry := make(map[string]interface{})
|
||||
for i, col := range columns {
|
||||
var v interface{}
|
||||
val := values[i]
|
||||
b, ok := val.([]byte)
|
||||
if ok {
|
||||
v = string(b)
|
||||
} else {
|
||||
v = val
|
||||
}
|
||||
entry[col] = v
|
||||
}
|
||||
tableData = append(tableData, entry)
|
||||
}
|
||||
return (tableData)
|
||||
}
|
||||
|
||||
func Checkip(network string, ip string) bool { // ---------- check if ip is in range (cidr address or single ip)
|
||||
if net.ParseIP(ip) == nil {
|
||||
return false
|
||||
}
|
||||
_, subnet, err := net.ParseCIDR(network)
|
||||
if err == nil {
|
||||
if subnet.Contains(net.ParseIP(ip)) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if network == ip {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Isflagpassed(name string) bool { // -------------------------------------------------- check if flag is set
|
||||
found := false
|
||||
flag.Visit(func(f *flag.Flag) {
|
||||
if f.Name == name {
|
||||
found = true
|
||||
}
|
||||
})
|
||||
return found
|
||||
}
|
||||
|
||||
func Body(r *http.Response) string { // ------------------------------------------------------------ http body
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err == nil {
|
||||
return string(body)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func Atoi(s string) int { // ------------------------------------------------------------------------------ atoi
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func Itoa(i int) string { // ------------------------------------------------------------------------------ itoa
|
||||
return strconv.Itoa(i)
|
||||
}
|
||||
|
||||
func GJA(j string, k string) []string { // -------------------------------------------------- convert gjson array
|
||||
var ret []string
|
||||
for _, c := range gjson.Get(j, k).Array() {
|
||||
ret = append(ret, c.String())
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ print simple
|
||||
|
||||
func P(a ...any) (n int, err error) { return fmt.Fprintln(os.Stdout, a...) }
|
||||
func PN(a ...any) (n int, err error) { return fmt.Fprint(os.Stdout, a...) }
|
||||
func PF(format string, a ...any) (n int, err error) { return fmt.Fprintf(os.Stdout, format, a...) }
|
||||
func SF(format string, a ...any) string { return fmt.Sprintf(format, a...) }
|
||||
|
||||
func PE(msg ...string) (n int, err error) {
|
||||
if (len(msg)==2) { return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Crb("ERROR"), Cwb(msg[0]),msg[1]) }
|
||||
return fmt.Fprintf(os.Stdout, "%s: %s\n", Crb("ERROR"), Cwb(msg))
|
||||
}
|
||||
func PO(msg ...string) (n int, err error) {
|
||||
if (len(msg)==2) { return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Cgb("OK"), Cwb(msg[0]),msg[1]) }
|
||||
return fmt.Fprintf(os.Stdout, "%s: %s\n", Cgb("OK"), Cwb(msg))
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------ regular expression
|
||||
|
||||
func ReplaceFirst(re *regexp.Regexp, str, replace string) string {
|
||||
loc := re.FindStringIndex(str)
|
||||
if loc == nil { return str }
|
||||
return str[:loc[0]] + replace + str[loc[1]:]
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------- string functions
|
||||
|
||||
func Shortstr(s string, length int) string {
|
||||
runes := []rune(s)
|
||||
if len(runes) <= length {
|
||||
return s
|
||||
}
|
||||
return string(runes[:length-2]) + ".."
|
||||
}
|
||||
|
||||
func SR(str string, n int) string { return strings.Repeat(str, n) }
|
||||
|
||||
func RemoveAllMatches(slice []string, target string) []string { // remove matching string from array
|
||||
result := slice[:0]
|
||||
for _, v := range slice {
|
||||
if v != target {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------- system functions
|
||||
|
||||
func prgname() string { // program name
|
||||
exepath, err := os.Executable()
|
||||
if err != nil {
|
||||
PE(SF("Error getting executable path: %s", err))
|
||||
return ""
|
||||
}
|
||||
exename := filepath.Base(exepath)
|
||||
return exename
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------ viper abbrevations
|
||||
|
||||
func VX(key string) bool { return viper.IsSet(key) }
|
||||
func VS(key string) string { return viper.GetString(key) }
|
||||
func VSS(key string) []string { return viper.GetStringSlice(key) }
|
||||
func VB(key string) bool { return viper.GetBool(key) }
|
||||
func VI(key string) int { return viper.GetInt(key) }
|
||||
|
||||
// ------------------------------------------------------------------------------------------------- text colors
|
||||
|
||||
var Cr func(...interface{}) string = color.New(color.FgRed).SprintFunc()
|
||||
var Cg func(...interface{}) string = color.New(color.FgGreen).SprintFunc()
|
||||
var Cy func(...interface{}) string = color.New(color.FgYellow).SprintFunc()
|
||||
var Cb func(...interface{}) string = color.New(color.FgBlue).SprintFunc()
|
||||
var Cm func(...interface{}) string = color.New(color.FgMagenta).SprintFunc()
|
||||
var Cc func(...interface{}) string = color.New(color.FgCyan).SprintFunc()
|
||||
var Cw func(...interface{}) string = color.New(color.FgWhite).SprintFunc()
|
||||
|
||||
var Crb func(...interface{}) string = color.New(color.Bold, color.FgRed).SprintFunc()
|
||||
var Cgb func(...interface{}) string = color.New(color.Bold, color.FgGreen).SprintFunc()
|
||||
var Cyb func(...interface{}) string = color.New(color.Bold, color.FgYellow).SprintFunc()
|
||||
var Cbb func(...interface{}) string = color.New(color.Bold, color.FgBlue).SprintFunc()
|
||||
var Cmb func(...interface{}) string = color.New(color.Bold, color.FgMagenta).SprintFunc()
|
||||
var Ccb func(...interface{}) string = color.New(color.Bold, color.FgCyan).SprintFunc()
|
||||
var Cwb func(...interface{}) string = color.New(color.Bold, color.FgWhite).SprintFunc()
|
||||
|
||||
// ========================================================================================================= END
|
||||
Reference in New Issue
Block a user