forked from x/ContextOS
302 lines
5.9 KiB
Go
302 lines
5.9 KiB
Go
package kit
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/md5"
|
|
"encoding/csv"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
type TERM interface {
|
|
Show(...interface{}) bool
|
|
}
|
|
|
|
var STDIO TERM
|
|
var DisableLog = false
|
|
|
|
func Log(action string, str string, args ...interface{}) {
|
|
if DisableLog {
|
|
return
|
|
}
|
|
|
|
if len(args) > 0 {
|
|
str = fmt.Sprintf(str, args...)
|
|
}
|
|
fmt.Fprintf(os.Stderr, "%s: %s\n", action, str)
|
|
}
|
|
func Env(key string) {
|
|
os.Getenv(key)
|
|
}
|
|
func Pwd() string {
|
|
wd, _ := os.Getwd()
|
|
return wd
|
|
}
|
|
func Create(p string) (*os.File, string, error) {
|
|
if dir, _ := path.Split(p); dir != "" {
|
|
if e := os.MkdirAll(dir, 0777); e != nil {
|
|
return nil, p, e
|
|
}
|
|
}
|
|
f, e := os.Create(p)
|
|
return f, p, e
|
|
}
|
|
|
|
func Split(str string, c rune, n int) []string {
|
|
res := []string{}
|
|
list := []rune(str)
|
|
for i, j := 0, 0; i < len(list); i++ {
|
|
if list[i] == c || c == ' ' && unicode.IsSpace(list[i]) {
|
|
continue
|
|
}
|
|
for j = i; j < len(list); j++ {
|
|
if list[j] == c || c == ' ' && unicode.IsSpace(list[j]) {
|
|
break
|
|
}
|
|
}
|
|
if n == len(res)+1 {
|
|
j = len(list)
|
|
}
|
|
res, i = append(res, string(list[i:j])), j
|
|
}
|
|
return res
|
|
}
|
|
func FmtSize(size int64) string {
|
|
if size > 1<<30 {
|
|
return fmt.Sprintf("%d.%dG", size>>30, (size>>20)%1024*100>>10)
|
|
}
|
|
|
|
if size > 1<<20 {
|
|
return fmt.Sprintf("%d.%dM", size>>20, (size>>10)%1024*100>>10)
|
|
}
|
|
|
|
if size > 1<<10 {
|
|
return fmt.Sprintf("%d.%dK", size>>10, size%1024*100>>10)
|
|
}
|
|
|
|
return fmt.Sprintf("%dB", size)
|
|
}
|
|
func FmtTime(t int64) string {
|
|
sign, time := "", t
|
|
if time < 0 {
|
|
sign, time = "-", -t
|
|
}
|
|
if time > 1000000000 {
|
|
return fmt.Sprintf("%s%d.%ds", sign, time/1000000000, (time/1000000)%1000*100/1000)
|
|
}
|
|
if time > 1000000 {
|
|
return fmt.Sprintf("%s%d.%dms", sign, time/1000000, (time/1000)%1000*100/1000)
|
|
}
|
|
if time > 1000 {
|
|
return fmt.Sprintf("%s%d.%dus", sign, time/1000, (time/1000)%1000*100/1000)
|
|
}
|
|
return fmt.Sprintf("%s%dns", sign, time)
|
|
}
|
|
|
|
func Marshal(data interface{}, arg ...interface{}) string {
|
|
if len(arg) > 0 {
|
|
switch arg := arg[0].(type) {
|
|
case string:
|
|
if f, p, e := Create(arg); e == nil {
|
|
defer f.Close()
|
|
|
|
switch {
|
|
case strings.HasSuffix(arg, ".json"):
|
|
b, _ := json.MarshalIndent(data, "", " ")
|
|
if n, e := f.Write(b); e == nil && n == len(b) {
|
|
return p
|
|
}
|
|
|
|
case strings.HasSuffix(arg, ".csv"):
|
|
switch data := data.(type) {
|
|
case []interface{}:
|
|
w := csv.NewWriter(f)
|
|
head := []string{}
|
|
for _, v := range data {
|
|
switch v := v.(type) {
|
|
case map[string]interface{}:
|
|
if len(head) == 0 {
|
|
for k, _ := range v {
|
|
head = append(head, k)
|
|
}
|
|
w.Write(head)
|
|
}
|
|
|
|
fields := []string{}
|
|
for _, k := range head {
|
|
fields = append(fields, Format(v[k]))
|
|
}
|
|
w.Write(fields)
|
|
}
|
|
}
|
|
w.Flush()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
b, _ := json.MarshalIndent(data, "", " ")
|
|
return string(b)
|
|
}
|
|
func UnMarshal(data string) interface{} {
|
|
var res interface{}
|
|
if strings.HasSuffix(data, ".json") {
|
|
if b, e := ioutil.ReadFile(data); e == nil {
|
|
json.Unmarshal(b, &res)
|
|
}
|
|
} else {
|
|
json.Unmarshal([]byte(data), &res)
|
|
}
|
|
return res
|
|
}
|
|
func UnMarshalm(data string) map[string]interface{} {
|
|
res, _ := UnMarshal(data).(map[string]interface{})
|
|
return res
|
|
}
|
|
func IsLocalIP(ip string) bool {
|
|
if strings.HasPrefix(ip, "127") {
|
|
return true
|
|
}
|
|
if ip == "::1" {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
func Hashx(f io.Reader) string {
|
|
md := md5.New()
|
|
io.Copy(md, f)
|
|
h := md.Sum(nil)
|
|
return hex.EncodeToString(h[:])
|
|
}
|
|
func Lines(p string, args ...interface{}) []string {
|
|
b, e := ioutil.ReadFile(p)
|
|
if e != nil {
|
|
return nil
|
|
}
|
|
bs := bytes.Split(b, []byte("\n"))
|
|
|
|
res := make([]string, 0, len(bs))
|
|
for _, v := range bs {
|
|
if len(args) > 0 {
|
|
switch arg := args[0].(type) {
|
|
case func(string) string:
|
|
res = append(res, arg(string(v)))
|
|
continue
|
|
case func(string):
|
|
arg(string(v))
|
|
}
|
|
}
|
|
res = append(res, string(v))
|
|
}
|
|
return res
|
|
}
|
|
func Linex(p string) map[string]string {
|
|
meta := map[string]string{}
|
|
Lines(p, func(value string) {
|
|
if strings.Contains(value, ":") {
|
|
bs := strings.SplitN(value, ":", 2)
|
|
meta[strings.TrimSpace(bs[0])] = strings.TrimSpace(bs[1])
|
|
}
|
|
})
|
|
return meta
|
|
}
|
|
|
|
func List(arg interface{}, cb interface{}) {
|
|
list := Trans(arg)
|
|
for i, v := range list {
|
|
switch cb := cb.(type) {
|
|
case func(string):
|
|
cb(v)
|
|
case func(string, int):
|
|
cb(v, i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func Merge(list interface{}, value string) interface{} {
|
|
switch val := list.(type) {
|
|
case nil:
|
|
return value
|
|
case string:
|
|
return []interface{}{val, value}
|
|
case []interface{}:
|
|
return append(val, value)
|
|
}
|
|
return list
|
|
}
|
|
func Contains(list interface{}, value string) bool {
|
|
switch val := list.(type) {
|
|
case nil:
|
|
case string:
|
|
case []string:
|
|
for _, v := range val {
|
|
if v == value {
|
|
return true
|
|
}
|
|
}
|
|
case []interface{}:
|
|
}
|
|
return false
|
|
}
|
|
func IndexOf(list interface{}, value string) int {
|
|
switch val := list.(type) {
|
|
case nil:
|
|
case string:
|
|
case []string:
|
|
for i, v := range val {
|
|
if strings.TrimSpace(v) == strings.TrimSpace(value) {
|
|
return i
|
|
}
|
|
}
|
|
case []interface{}:
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func Shortm(data map[string]interface{}, keys ...string) map[string]interface{} {
|
|
for _, k := range keys {
|
|
switch k {
|
|
case "times":
|
|
ls := strings.Split(Format(data["time"]), " ")
|
|
if len(ls) > 1 {
|
|
data["times"] = ls[1]
|
|
} else {
|
|
data["times"] = data["time"]
|
|
}
|
|
case "files":
|
|
data["files"] = path.Base(Format(data["file"]))
|
|
case "sids":
|
|
data["sids"] = Short(data["sid"], 6)
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
func Short(arg interface{}, l int) string {
|
|
switch val := arg.(type) {
|
|
case string:
|
|
if len(val) > l {
|
|
return val[:l]
|
|
}
|
|
return val
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func ShortKey(list map[string]interface{}, min int, arg ...interface{}) string {
|
|
h := Hashs(arg...)
|
|
for i := min; i < len(h); i++ {
|
|
if _, ok := list[h[:i]]; !ok {
|
|
return h[:i]
|
|
}
|
|
}
|
|
return h
|
|
}
|