1
0
forked from x/icebergs
This commit is contained in:
shaoying 2021-07-15 01:49:55 +08:00
parent c9dfef8c55
commit ad0466cfd7
11 changed files with 259 additions and 270 deletions

View File

@ -54,7 +54,7 @@ func _cat_show(m *ice.Message, name string) {
}
// 打包文件
if b, ok := ice.BinPack[name]; ok {
if b, ok := ice.Info.BinPack[name]; ok {
m.Logs("binpack", name, kit.MDB_SIZE, len(b))
m.Echo(string(b))
return

View File

@ -73,7 +73,7 @@ func Script(m *ice.Message, name string) io.Reader {
}
// 打包文件
if b, ok := ice.BinPack["/"+name]; ok {
if b, ok := ice.Info.BinPack["/"+name]; ok {
m.Info("binpack %v %v", len(b), name)
return bytes.NewReader(b)
}

View File

@ -41,7 +41,7 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
case ice.RENDER_DOWNLOAD: // file [type [name]]
msg.W.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(arg[0]), arg, 2)))
if RenderType(msg.W, arg[0], kit.Select("", arg, 1)); !ice.DumpBinPack(msg.W, arg[0], nil) {
if RenderType(msg.W, arg[0], kit.Select("", arg, 1)); !ice.Dump(msg.W, arg[0], nil) {
http.ServeFile(msg.W, msg.R, kit.Path(arg[0]))
}

View File

@ -65,7 +65,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
}
// 文件接口
if ice.DumpBinPack(w, r.URL.Path, func(name string) { RenderType(w, name, "") }) {
if ice.Dump(w, r.URL.Path, func(name string) { RenderType(w, name, "") }) {
return false
}
return true

13
conf.go
View File

@ -19,19 +19,21 @@ const ( // REPOS
INTSHELL = "intshell"
CONTEXTS = "contexts"
PUBLISH = "publish"
INSTALL = "install"
REQUIRE = "require"
PUBLISH = "publish"
SUCCESS = "success"
FAILURE = "failure"
TRUE = "true"
OK = "ok"
)
const ( // DIR
USR_VOLCANOS = "usr/volcanos"
USR_ICEBERGS = "usr/icebergs"
USR_INTSHELL = "usr/intshell"
USR_PUBLISH = "usr/publish"
USR_INSTALL = "usr/install"
USR_PUBLISH = "usr/publish"
USR_LOCAL = "usr/local"
PROTO_JS = "proto.js"
@ -64,9 +66,10 @@ const ( // DIR
GO_MOD = "go.mod"
GO_SUM = "go.sum"
CTX_DEV = "ctx_dev"
CTX_PID = "ctx_pid"
CTX_LOG = "ctx_log"
CTX_DEBUG = "ctx_debug"
CTX_DEV = "ctx_dev"
CTX_PID = "ctx_pid"
CTX_LOG = "ctx_log"
)
const ( // MSG
MSG_DETAIL = "detail"

View File

@ -108,7 +108,7 @@ func init() {
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
for k, v := range ice.BinPack {
for k, v := range ice.Info.BinPack {
m.Push(kit.MDB_NAME, k)
m.Push(kit.MDB_SIZE, len(v))
}

142
init.go
View File

@ -1,42 +1,19 @@
package ice
import (
"fmt"
"io"
"os"
"strings"
"sync"
"sync/atomic"
"time"
kit "github.com/shylinux/toolkits"
)
var Info = struct {
HostName string
PathName string
UserName string
PassWord string
NodeType string
NodeName string
CtxShare string
CtxRiver string
Make struct {
Time string
Hash string
Remote string
Branch string
Version string
HostName string
UserName string
}
nLocalCmd int32
}{}
type Frame struct{ code int }
type Frame struct {
code int
wait chan bool
}
func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
return &Frame{}
@ -131,7 +108,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
}},
}, Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.target.server.(*Frame).code = kit.Int(kit.Select("0", arg, 0))
m.Cmd("ssh.source", "etc/exit.shy", "exit.shy", "退出配置")
m.Cmd("ssh.source", ETC_EXIT, "exit.shy", "退出配置")
m.root.Cmd(CTX_EXIT)
}},
CTX_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
@ -143,7 +120,8 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
})
}
})
wait <- true
f := c.server.(*Frame)
f.wait <- true
}},
},
}
@ -154,8 +132,64 @@ var Pulse = &Message{
source: Index, target: Index, Hand: true,
}
var wait = make(chan bool, 1)
var Info = struct {
HostName string
PathName string
UserName string
PassWord string
NodeType string
NodeName string
CtxShare string
CtxRiver string
Make struct {
Time string
Hash string
Remote string
Branch string
Version string
HostName string
UserName string
}
BinPack map[string][]byte
names map[string]interface{}
}{
BinPack: map[string][]byte{},
names: map[string]interface{}{},
}
func Dump(w io.Writer, name string, cb func(string)) bool {
if b, ok := Info.BinPack[name]; ok {
if cb != nil {
cb(name)
}
w.Write(b)
return true
}
if b, ok := Info.BinPack[strings.TrimPrefix(name, USR_VOLCANOS)]; ok {
if cb != nil {
cb(name)
}
w.Write(b)
return true
}
return false
}
func Name(name string, value interface{}) string {
if s, ok := Info.names[name]; ok {
last := ""
switch s := s.(type) {
case *Context:
last = s.Name
}
panic(kit.Format("%s %s %v", ErrExists, name, last))
}
Info.names[name] = value
return name
}
func Run(arg ...string) string {
if len(arg) == 0 {
arg = os.Args[1:]
@ -164,7 +198,7 @@ func Run(arg ...string) string {
arg = append(arg, "help")
}
frame := &Frame{}
frame := &Frame{wait: make(chan bool, 1)}
Index.root = Index
Index.server = frame
Index.Merge(Index)
@ -179,11 +213,11 @@ func Run(arg ...string) string {
frame.Close(Pulse.Spawn(), arg...)
}
<-wait
<-frame.wait
os.Exit(frame.code)
default:
_log_disable = os.Getenv("ctx_debug") != "true"
_log_disable = os.Getenv(CTX_DEBUG) != TRUE
if Pulse.Cmdy(arg); Pulse.Result() == "" {
Pulse.Table()
}
@ -195,45 +229,3 @@ func Run(arg ...string) string {
return Pulse.Result()
}
var BinPack = map[string][]byte{}
func DumpBinPack(w io.Writer, name string, cb func(string)) bool {
if b, ok := BinPack[name]; ok {
if cb != nil {
cb(name)
}
w.Write(b)
return true
}
if b, ok := BinPack[strings.TrimPrefix(name, "usr/volcanos")]; ok {
if cb != nil {
cb(name)
}
w.Write(b)
return true
}
return false
}
var names = map[string]interface{}{}
var ErrNameExists = "name already exists: "
func Name(name string, value interface{}) string {
if s, ok := names[name]; ok {
last := ""
switch s := s.(type) {
case *Context:
last = s.Name
}
panic(kit.Format("name already exits: %s %v", name, last))
}
names[name] = value
return name
}
func (m *Message) AddCmd(cmd *Command) string {
name := fmt.Sprintf("_cb_%d", atomic.AddInt32(&Info.nLocalCmd, 1))
m.target.Commands[name] = cmd
return kit.Keys(m.target.Cap(CTX_FOLLOW), name)
}

15
logs.go
View File

@ -8,13 +8,14 @@ import (
log "github.com/shylinux/toolkits/logs"
)
var OK = "ok"
var ErrWarn = "warn: "
var ErrExpire = "expire: "
var ErrNotLogin = "not login: "
var ErrNotRight = "not right: "
var ErrNotFound = "not found: "
var ErrNotShare = "not share: "
const (
ErrWarn = "warn: "
ErrExists = "exists: "
ErrExpire = "expire: "
ErrNotLogin = "not login: "
ErrNotFound = "not found: "
ErrNotRight = "not right: "
)
var _log_disable = true
var Log func(m *Message, p, l, s string)

100
meta.go
View File

@ -1,8 +1,6 @@
package ice
import (
"bytes"
"encoding/csv"
"fmt"
"sort"
"strconv"
@ -345,104 +343,6 @@ func (m *Message) Table(cbs ...func(index int, value map[string]string, head []s
}
return m
}
func (m *Message) Render(cmd string, args ...interface{}) *Message {
m.Optionv(MSG_OUTPUT, cmd)
m.Optionv(MSG_ARGS, args)
switch cmd {
case RENDER_TEMPLATE: // text [data [type]]
if len(args) == 1 {
args = append(args, m)
}
if res, err := kit.Render(args[0].(string), args[1]); m.Assert(err) {
m.Echo(string(res))
}
}
return m
}
func (m *Message) Parse(meta string, key string, arg ...string) *Message {
list := []string{}
for _, line := range kit.Split(strings.Join(arg, " "), "\n") {
ls := kit.Split(line)
for i := 0; i < len(ls); i++ {
if strings.HasPrefix(ls[i], "#") {
ls = ls[:i]
break
}
}
list = append(list, ls...)
}
switch data := kit.Parse(nil, "", list...); meta {
case MSG_OPTION:
m.Option(key, data)
case MSG_APPEND:
m.Append(key, data)
}
return m
}
func (m *Message) Split(str string, field string, space string, enter string) *Message {
indexs := []int{}
fields := kit.Split(field, space, space, space)
for i, l := range kit.Split(str, enter, enter, enter) {
if strings.HasPrefix(l, "Binary") {
continue
}
if strings.TrimSpace(l) == "" {
continue
}
if i == 0 && (field == "" || field == "index") {
// 表头行
fields = kit.Split(l, space, space)
if field == "index" {
for _, v := range fields {
indexs = append(indexs, strings.Index(l, v))
}
}
continue
}
if len(indexs) > 0 {
// 数据行
for i, v := range indexs {
if i == len(indexs)-1 {
m.Push(kit.Select("some", fields, i), l[v:])
} else {
m.Push(kit.Select("some", fields, i), l[v:indexs[i+1]])
}
}
continue
}
ls := kit.Split(l, space, space)
for i, v := range ls {
if i == len(fields)-1 {
m.Push(kit.Select("some", fields, i), strings.Join(ls[i:], space))
break
}
m.Push(kit.Select("some", fields, i), v)
}
}
return m
}
func (m *Message) CSV(text string, head ...string) *Message {
bio := bytes.NewBufferString(text)
r := csv.NewReader(bio)
if len(head) == 0 {
head, _ = r.Read()
}
for {
line, e := r.Read()
if e != nil {
break
}
for i, k := range head {
m.Push(k, kit.Select("", line, i))
}
}
return m
}
func (m *Message) Detail(arg ...interface{}) string {
return kit.Select("", m.meta[MSG_DETAIL], 0)

235
misc.go
View File

@ -1,6 +1,8 @@
package ice
import (
"bytes"
"encoding/csv"
"encoding/json"
"fmt"
"net/url"
@ -115,13 +117,6 @@ func (m *Message) PushSearchWeb(cmd string, name string) {
})
}
func (m *Message) IsCliUA() bool {
if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla/5.0") {
return true
}
return false
}
func Render(m *Message, cmd string, args ...interface{}) string {
if m.IsCliUA() {
switch arg := kit.Simple(args...); cmd {
@ -252,27 +247,62 @@ func (m *Message) SortTimeR(key string) { m.Sort(key, "time_r") }
func (m *Message) FormatMeta() string { return m.Format("meta") }
func (m *Message) FormatSize() string { return m.Format("size") }
func (m *Message) FormatCost() string { return m.Format("cost") }
func (m *Message) RenameAppend(from, to string) {
for i, v := range m.meta[MSG_APPEND] {
if v == from {
m.meta[MSG_APPEND][i] = to
m.meta[to] = m.meta[from]
delete(m.meta, from)
}
}
}
type Sort struct {
Fields string
Method string
}
type Option struct {
Name string
Value interface{}
}
func OptionFields(str string) Option { return Option{MSG_FIELDS, str} }
func OptionHash(str string) Option { return Option{kit.MDB_HASH, str} }
func OptionFields(str string) Option { return Option{MSG_FIELDS, str} }
func OptionHash(str string) Option { return Option{kit.MDB_HASH, str} }
func (m *Message) OptionFields(str string) { m.Option(MSG_FIELDS, str) }
func (m *Message) OptionLoad(file string) *Message {
if f, e := os.Open(file); e == nil {
defer f.Close()
type Sort struct {
Fields string
Method string
var data interface{}
json.NewDecoder(f).Decode(&data)
kit.Fetch(data, func(key string, value interface{}) { m.Option(key, kit.Simple(value)) })
}
return m
}
func (m *Message) Fields(condition bool, fields string) string {
return m.Option(MSG_FIELDS, kit.Select(kit.Select("detail", fields, condition), m.Option(MSG_FIELDS)))
}
func (m *Message) Upload(dir string) {
up := kit.Simple(m.Optionv(MSG_UPLOAD))
if p := path.Join(dir, up[1]); m.Option(MSG_USERPOD) == "" {
// 本机文件
m.Cmdy("web.cache", "watch", up[0], p)
} else {
// 下拉文件
m.Cmdy("web.spide", "dev", "save", p, "GET",
kit.MergeURL2(m.Option(MSG_USERWEB), path.Join("/share/cache", up[0])))
}
}
func (m *Message) Action(arg ...string) {
m.Option(MSG_ACTION, kit.Format(arg))
}
func (m *Message) Status(arg ...interface{}) {
args := kit.Simple(arg)
list := []map[string]string{}
for i := 0; i < len(args)-1; i += 2 {
list = append(list, map[string]string{
"name": args[i], "value": args[i+1],
})
}
m.Option(MSG_STATUS, kit.Format(list))
}
func (m *Message) StatusTimeCount(arg ...interface{}) {
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), arg, "cost", m.FormatCost())
}
func (m *Message) StatusTimeCountTotal(arg ...interface{}) {
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), "total", arg, "cost", m.FormatCost())
}
func (m *Message) Toast(content string, arg ...interface{}) {
@ -303,31 +333,6 @@ func (m *Message) GoToast(title string, cb func(toast func(string, int, int))) {
})
})
}
func (m *Message) Fields(condition bool, fields string) string {
return m.Option(MSG_FIELDS, kit.Select(kit.Select("detail", fields, condition), m.Option(MSG_FIELDS)))
}
func (m *Message) Action(arg ...string) {
m.Option(MSG_ACTION, kit.Format(arg))
}
func (m *Message) Status(arg ...interface{}) {
args := kit.Simple(arg)
list := []map[string]string{}
for i := 0; i < len(args)-1; i += 2 {
list = append(list, map[string]string{
"name": args[i], "value": args[i+1],
})
}
m.Option(MSG_STATUS, kit.Format(list))
}
func (m *Message) StatusTimeCount(arg ...interface{}) {
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), arg, "cost", m.FormatCost())
}
func (m *Message) StatusTimeCountTotal(arg ...interface{}) {
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), "total", arg, "cost", m.FormatCost())
}
func (m *Message) Process(action string, arg ...interface{}) {
m.Option(MSG_PROCESS, action)
m.Option("_arg", arg...)
@ -353,31 +358,6 @@ func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) }
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
func (m *Message) Upload(dir string) {
up := kit.Simple(m.Optionv(MSG_UPLOAD))
if p := path.Join(dir, up[1]); m.Option(MSG_USERPOD) == "" {
// 本机文件
m.Cmdy("web.cache", "watch", up[0], p)
} else {
// 下拉文件
m.Cmdy("web.spide", "dev", "save", p, "GET",
kit.MergeURL2(m.Option(MSG_USERWEB), path.Join("/share/cache", up[0])))
}
}
func (m *Message) OptionFields(str string) { m.Option(MSG_FIELDS, str) }
func (m *Message) OptionLoad(file string) *Message {
if f, e := os.Open(file); e == nil {
defer f.Close()
var data interface{}
json.NewDecoder(f).Decode(&data)
kit.Fetch(data, func(key string, value interface{}) { m.Option(key, kit.Simple(value)) })
}
return m
}
func (m *Message) Confi(key string, sub string) int {
return kit.Int(m.Conf(key, sub))
}
@ -391,3 +371,116 @@ func (m *Message) Cut(fields ...string) *Message {
m.meta[MSG_APPEND] = strings.Split(strings.Join(fields, ","), ",")
return m
}
func (m *Message) Render(cmd string, args ...interface{}) *Message {
m.Optionv(MSG_OUTPUT, cmd)
m.Optionv(MSG_ARGS, args)
switch cmd {
case RENDER_TEMPLATE: // text [data [type]]
if len(args) == 1 {
args = append(args, m)
}
if res, err := kit.Render(args[0].(string), args[1]); m.Assert(err) {
m.Echo(string(res))
}
}
return m
}
func (m *Message) Parse(meta string, key string, arg ...string) *Message {
list := []string{}
for _, line := range kit.Split(strings.Join(arg, " "), "\n") {
ls := kit.Split(line)
for i := 0; i < len(ls); i++ {
if strings.HasPrefix(ls[i], "#") {
ls = ls[:i]
break
}
}
list = append(list, ls...)
}
switch data := kit.Parse(nil, "", list...); meta {
case MSG_OPTION:
m.Option(key, data)
case MSG_APPEND:
m.Append(key, data)
}
return m
}
func (m *Message) Split(str string, field string, space string, enter string) *Message {
indexs := []int{}
fields := kit.Split(field, space, space, space)
for i, l := range kit.Split(str, enter, enter, enter) {
if strings.HasPrefix(l, "Binary") {
continue
}
if strings.TrimSpace(l) == "" {
continue
}
if i == 0 && (field == "" || field == "index") {
// 表头行
fields = kit.Split(l, space, space)
if field == "index" {
for _, v := range fields {
indexs = append(indexs, strings.Index(l, v))
}
}
continue
}
if len(indexs) > 0 {
// 数据行
for i, v := range indexs {
if i == len(indexs)-1 {
m.Push(kit.Select("some", fields, i), l[v:])
} else {
m.Push(kit.Select("some", fields, i), l[v:indexs[i+1]])
}
}
continue
}
ls := kit.Split(l, space, space)
for i, v := range ls {
if i == len(fields)-1 {
m.Push(kit.Select("some", fields, i), strings.Join(ls[i:], space))
break
}
m.Push(kit.Select("some", fields, i), v)
}
}
return m
}
func (m *Message) CSV(text string, head ...string) *Message {
bio := bytes.NewBufferString(text)
r := csv.NewReader(bio)
if len(head) == 0 {
head, _ = r.Read()
}
for {
line, e := r.Read()
if e != nil {
break
}
for i, k := range head {
m.Push(k, kit.Select("", line, i))
}
}
return m
}
func (m *Message) RenameAppend(from, to string) {
for i, v := range m.meta[MSG_APPEND] {
if v == from {
m.meta[MSG_APPEND][i] = to
m.meta[to] = m.meta[from]
delete(m.meta, from)
}
}
}
func (m *Message) IsCliUA() bool {
if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla/5.0") {
return true
}
return false
}

14
type.go
View File

@ -79,7 +79,7 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
}
return c.Caches[key].Value
}
func (c *Context) _hand(m *Message, cmd *Command, key string, k string, h *Action, arg ...string) *Message {
func (c *Context) _cmd(m *Message, cmd *Command, key string, k string, h *Action, arg ...string) *Message {
m.Log(LOG_CMDS, "%s.%s %s %d %v %s", c.Name, key, k, len(arg), arg, kit.FileLine(h.Hand, 3))
if len(h.List) > 0 && k != "search" {
order := false
@ -118,12 +118,12 @@ func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Mess
m.meta[MSG_DETAIL] = kit.Simple(key, arg)
if m.Hand = true; len(arg) > 1 && arg[0] == kit.MDB_ACTION && cmd.Action != nil {
if h, ok := cmd.Action[arg[1]]; ok {
return c._hand(m, cmd, key, arg[1], h, arg[2:]...)
return c._cmd(m, cmd, key, arg[1], h, arg[2:]...)
}
}
if len(arg) > 0 && arg[0] != "command" && cmd.Action != nil {
if h, ok := cmd.Action[arg[0]]; ok {
return c._hand(m, cmd, key, arg[0], h, arg[1:]...)
return c._cmd(m, cmd, key, arg[0], h, arg[1:]...)
}
}
@ -182,7 +182,7 @@ func (c *Context) Merge(s *Context) *Context {
c.Commands[k] = v
if v.List == nil {
v.List = c._split(k, v, v.Name)
v.List = c.split(k, v, v.Name)
}
if v.Meta == nil {
v.Meta = kit.Dict()
@ -203,7 +203,7 @@ func (c *Context) Merge(s *Context) *Context {
continue
}
if a.List == nil {
a.List = c._split(k, nil, a.Name)
a.List = c.split(k, nil, a.Name)
}
if len(a.List) > 0 {
v.Meta[k] = a.List
@ -226,7 +226,7 @@ func (c *Context) Merge(s *Context) *Context {
}
return c
}
func (c *Context) _split(key string, cmd *Command, name string) []interface{} {
func (c *Context) split(key string, cmd *Command, name string) []interface{} {
button, list := false, []interface{}{}
for _, v := range kit.Split(kit.Select("key", name), " ", " ")[1:] {
switch v {
@ -580,7 +580,7 @@ func (m *Message) Search(key string, cb interface{}) *Message {
// 查找模块
p := m.target.root
if ctx, ok := names[key].(*Context); ok {
if ctx, ok := Info.names[key].(*Context); ok {
p = ctx
} else if key == "ice." {
p, key = m.target.root, ""