1
0
forked from x/icebergs
This commit is contained in:
harveyshao 2021-10-07 21:17:34 +08:00
parent 211fa0709d
commit 7c19c9dac1
19 changed files with 319 additions and 255 deletions

View File

@ -45,15 +45,20 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
) )
if e := cmd.Wait(); m.Warn(e != nil, cmd.Args, " ", e) { if e := cmd.Wait(); m.Warn(e != nil, cmd.Args, " ", e) {
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, if m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, h, kit.Keym(kit.MDB_STATUS))) == START {
kit.MDB_STATUS, ERROR, kit.MDB_ERROR, e) m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, ERROR, ERROR, e)
}
} else { } else {
m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode()) m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode())
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, STOP) m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, STOP)
} }
switch cb := m.Optionv(kit.Keycb(DAEMON)).(type) { switch cb := m.Optionv(kit.Keycb(DAEMON)).(type) {
case func(string):
m.Sleep("1s")
cb(m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, h, kit.Keym(kit.MDB_STATUS))))
case func(): case func():
m.Sleep("1s")
cb() cb()
} }
@ -168,6 +173,12 @@ func init() {
} else if m.Richs(DAEMON, "", arg[0], nil) != nil { // 进程详情 } else if m.Richs(DAEMON, "", arg[0], nil) != nil { // 进程详情
m.Option(mdb.FIELDS, mdb.DETAIL) m.Option(mdb.FIELDS, mdb.DETAIL)
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH, kit.MDB_HASH, arg) m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH, kit.MDB_HASH, arg)
switch m.Append(kit.MDB_STATUS) {
case START:
m.PushButton(RESTART, STOP)
default:
m.PushButton(mdb.REMOVE)
}
} else { // 启动进程 } else { // 启动进程
m.Option(CMD_TYPE, DAEMON) m.Option(CMD_TYPE, DAEMON)

View File

@ -13,13 +13,31 @@ import (
func _hash_fields(m *ice.Message) []string { func _hash_fields(m *ice.Message) []string {
return kit.Split(kit.Select("time,hash,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ","))) return kit.Split(kit.Select("time,hash,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
} }
func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
list := map[string]int{}
m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
if val = kit.GetMeta(val); field == kit.MDB_HASH {
list[key]++
} else {
if kit.Format(val[kit.MDB_COUNT]) != "" {
list[kit.Format(val[field])] = kit.Int(val[kit.MDB_COUNT])
} else {
list[kit.Format(val[field])]++
}
}
})
for k, i := range list {
m.Push(field, k)
m.Push(kit.MDB_COUNT, i)
}
m.SortIntR(kit.MDB_COUNT)
}
func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) { func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) {
if m.Option(ice.MSG_DOMAIN) != "" { if m.Option(ice.MSG_DOMAIN) != "" {
m.Conf(prefix, kit.Keys(chain, kit.MDB_META, kit.MDB_SHORT), m.Conf(prefix, kit.Keys(kit.MDB_META, kit.MDB_SHORT))) m.Conf(prefix, kit.Keys(chain, kit.Keym(kit.MDB_SHORT)), m.Conf(prefix, kit.Keym(kit.MDB_SHORT)))
} }
m.Log_INSERT(kit.MDB_KEY, path.Join(prefix, chain), arg[0], arg[1]) m.Log_INSERT(kit.MDB_KEY, path.Join(prefix, chain), arg[0], arg[1])
h := m.Rich(prefix, chain, kit.Data(arg)) m.Echo(m.Rich(prefix, chain, kit.Data(arg)))
m.Echo(h)
} }
func _hash_delete(m *ice.Message, prefix, chain, field, value string) { func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
@ -27,6 +45,18 @@ func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH, key), "") m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH, key), "")
}) })
} }
func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
val = kit.GetMeta(val)
m.Log_MODIFY(kit.MDB_KEY, path.Join(prefix, chain), field, value, arg)
for i := 0; i < len(arg); i += 2 {
if arg[i] == field {
continue
}
kit.Value(val, arg[i], kit.Select("", arg, i+1))
}
})
}
func _hash_select(m *ice.Message, prefix, chain, field, value string) { func _hash_select(m *ice.Message, prefix, chain, field, value string) {
if field == kit.MDB_HASH && value == RANDOM { if field == kit.MDB_HASH && value == RANDOM {
value = kit.MDB_RANDOMS value = kit.MDB_RANDOMS
@ -34,12 +64,11 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) {
fields := _hash_fields(m) fields := _hash_fields(m)
cb := m.Optionv(kit.Keycb(SELECT)) cb := m.Optionv(kit.Keycb(SELECT))
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
val = kit.GetMeta(val) switch val = kit.GetMeta(val); cb := cb.(type) {
switch cb := cb.(type) {
case func(fields []string, value map[string]interface{}): case func(fields []string, value map[string]interface{}):
cb(fields, val) cb(fields, val)
default: default:
if m.Option(FIELDS) == DETAIL { if m.OptionFields() == DETAIL {
m.Push(DETAIL, val) m.Push(DETAIL, val)
} else { } else {
m.Push(key, val, fields) m.Push(key, val, fields)
@ -50,18 +79,6 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) {
m.SortTimeR(kit.MDB_TIME) m.SortTimeR(kit.MDB_TIME)
} }
} }
func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
val = kit.GetMeta(val)
for i := 0; i < len(arg); i += 2 {
if arg[i] == field {
continue
}
kit.Value(val, arg[i], kit.Select("", arg, i+1))
}
m.Log_MODIFY(kit.MDB_KEY, path.Join(prefix, chain), field, value, arg)
})
}
func _hash_export(m *ice.Message, prefix, chain, file string) { func _hash_export(m *ice.Message, prefix, chain, file string) {
f, p, e := kit.Create(kit.Keys(file, JSON)) f, p, e := kit.Create(kit.Keys(file, JSON))
m.Assert(e) m.Assert(e)
@ -112,7 +129,7 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
} }
default: default:
for i := 0; i < len(arg)-1; i += 2 { for i := 0; i < len(arg)-1; i += 2 {
if val[arg[i]] != arg[i+1] { if val[arg[i]] != arg[i+1] && kit.Value(val, arg[i]) != arg[i+1] {
return return
} }
} }
@ -123,41 +140,33 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
_hash_delete(m, prefix, chain, kit.MDB_HASH, value[kit.MDB_HASH]) _hash_delete(m, prefix, chain, kit.MDB_HASH, value[kit.MDB_HASH])
}) })
} }
func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
list := map[string]int{} const HASH = "hash"
m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
val = kit.GetMeta(val)
if field == kit.MDB_HASH {
list[key]++
} else {
if kit.Format(val["count"]) != "" {
list[kit.Format(val[field])] = kit.Int(val["count"])
}
list[kit.Format(val[field])]++
}
})
for k, i := range list {
m.Push(field, k)
m.Push(kit.MDB_COUNT, i)
}
m.SortIntR(kit.MDB_COUNT)
}
func HashAction(fields ...string) map[string]*ice.Action { func HashAction(fields ...string) map[string]*ice.Action {
return ice.SelectAction(map[string]*ice.Action{ return ice.SelectAction(map[string]*ice.Action{
INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, arg)
}},
CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) { CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg) m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg)
}}, }},
MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(kit.MDB_HASH), arg)
}},
REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(kit.MDB_HASH)) m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(kit.MDB_HASH))
}}, }},
MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(kit.MDB_HASH), arg)
}},
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(EXPORT, m.PrefixKey(), "", HASH)
}},
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(IMPORT, m.PrefixKey(), "", HASH)
}},
PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) { PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
list := []string{} list := []string{}
m.Richs(m.PrefixKey(), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { m.Richs(m.PrefixKey(), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if value = kit.GetMeta(value); kit.Time(kit.Format(value[kit.MDB_TIME])) < kit.Time(m.Option("before")) { if value = kit.GetMeta(value); kit.Time(kit.Format(value[kit.MDB_TIME])) < kit.Time(m.Option(kit.MDB_BEFORE)) {
list = append(list, key) list = append(list, key)
} }
}) })
@ -166,16 +175,5 @@ func HashAction(fields ...string) map[string]*ice.Action {
m.Cmdy(DELETE, m.PrefixKey(), "", HASH, kit.MDB_HASH, v) m.Cmdy(DELETE, m.PrefixKey(), "", HASH, kit.MDB_HASH, v)
} }
}}, }},
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(EXPORT, m.PrefixKey(), "", HASH)
}},
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(IMPORT, m.PrefixKey(), "", HASH)
}},
INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, arg)
}},
}, fields...) }, fields...)
} }
const HASH = "hash"

View File

@ -1,10 +1,7 @@
package mdb package mdb
import ( import (
"encoding/csv"
"os"
"path" "path"
"strings"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
@ -17,122 +14,6 @@ func _domain_chain(m *ice.Message, chain string) string {
return kit.Keys(m.Option(ice.MSG_DOMAIN), chain) return kit.Keys(m.Option(ice.MSG_DOMAIN), chain)
} }
func _zone_fields(m *ice.Message) []string {
return kit.Split(kit.Select("zone,id,time,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
}
func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
if zone == RANDOM {
zone = kit.MDB_RANDOMS
}
fields := _zone_fields(m)
cb := m.Optionv(kit.Keycb(SELECT))
m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) {
val = kit.GetMeta(val)
if zone == "" {
if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, val)
} else {
m.Push(key, val, fields)
}
return
}
m.Grows(prefix, kit.Keys(chain, kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) {
value = kit.GetMeta(value)
switch cb := cb.(type) {
case func(string, []string, map[string]interface{}, map[string]interface{}):
cb(key, fields, value, val)
case func(string, map[string]interface{}, map[string]interface{}):
cb(key, value, val)
case func(string, map[string]interface{}):
cb(key, value)
default:
if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, value)
} else {
m.Push(key, value, fields, val)
}
}
})
})
}
func _zone_export(m *ice.Message, prefix, chain, file string) {
f, p, e := kit.Create(kit.Keys(file, CSV))
m.Assert(e)
defer f.Close()
w := csv.NewWriter(f)
defer w.Flush()
fields := _zone_fields(m)
w.Write(fields)
count := 0
m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
val = kit.GetMeta(val)
m.Grows(prefix, kit.Keys(chain, kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
value = kit.GetMeta(value)
list := []string{}
for _, k := range fields {
list = append(list, kit.Select(kit.Format(kit.Value(val, k)), kit.Format(kit.Value(value, k))))
}
w.Write(list)
count++
})
})
m.Log_EXPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_FILE, p, kit.MDB_COUNT, count)
m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH), "")
m.Echo(p)
}
func _zone_import(m *ice.Message, prefix, chain, file string) {
f, e := os.Open(kit.Keys(file, CSV))
m.Assert(e)
defer f.Close()
r := csv.NewReader(f)
head, _ := r.Read()
count := 0
list := map[string]string{}
zkey := kit.Select(head[0], m.Option(FIELDS))
for {
line, e := r.Read()
if e != nil {
break
}
zone := ""
data := kit.Dict()
for i, k := range head {
switch k {
case zkey:
zone = line[i]
case kit.MDB_ID:
continue
case kit.MDB_EXTRA:
kit.Value(data, k, kit.UnMarshal(line[i]))
default:
kit.Value(data, k, line[i])
}
}
if list[zone] == "" {
list[zone] = m.Rich(prefix, chain, kit.Data(zkey, zone))
}
m.Grow(prefix, kit.Keys(chain, kit.MDB_HASH, list[zone]), data)
count++
}
m.Log_IMPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_COUNT, count)
m.Echo("%d", count)
}
const ( const (
CSV = "csv" CSV = "csv"
JSON = "json" JSON = "json"
@ -175,6 +56,14 @@ const (
CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit" CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit"
) )
func PrevPageLimit(m *ice.Message, total string, arg ...string) {
if kit.Int(kit.Select("0", arg, 1)) > 0 {
PrevPage(m, total, arg...)
} else {
m.Toast("已经是最前一页啦!")
m.ProcessHold()
}
}
func PrevPage(m *ice.Message, total string, arg ...string) { func PrevPage(m *ice.Message, total string, arg ...string) {
limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1) limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1)
offends := kit.Int(offend) - kit.Int(limit) offends := kit.Int(offend) - kit.Int(limit)
@ -196,6 +85,14 @@ func NextPage(m *ice.Message, total string, arg ...string) {
} }
m.ProcessRewrite("offend", offends) m.ProcessRewrite("offend", offends)
} }
func NextPageLimit(m *ice.Message, total string, arg ...string) {
if kit.Int(kit.Select("0", arg, 1)) < 0 {
NextPage(m, total, arg...)
} else {
m.Toast("已经是最后一页啦!")
m.ProcessHold()
}
}
const MDB = "mdb" const MDB = "mdb"

View File

@ -1,10 +1,131 @@
package mdb package mdb
import ( import (
"encoding/csv"
"os"
"path"
"strings"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
func _zone_fields(m *ice.Message) []string {
return kit.Split(kit.Select("zone,id,time,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
}
func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
if zone == RANDOM {
zone = kit.MDB_RANDOMS
}
fields := _zone_fields(m)
cb := m.Optionv(kit.Keycb(SELECT))
m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) {
val = kit.GetMeta(val)
if zone == "" {
if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, val)
} else {
m.Push(key, val, fields)
}
return
}
m.Grows(prefix, kit.Keys(chain, kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) {
value = kit.GetMeta(value)
switch cb := cb.(type) {
case func(string, []string, map[string]interface{}, map[string]interface{}):
cb(key, fields, value, val)
case func(string, map[string]interface{}, map[string]interface{}):
cb(key, value, val)
case func(string, map[string]interface{}):
cb(key, value)
default:
if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, value)
} else {
m.Push(key, value, fields, val)
}
}
})
})
}
func _zone_export(m *ice.Message, prefix, chain, file string) {
f, p, e := kit.Create(kit.Keys(file, CSV))
m.Assert(e)
defer f.Close()
w := csv.NewWriter(f)
defer w.Flush()
fields := _zone_fields(m)
w.Write(fields)
count := 0
m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
val = kit.GetMeta(val)
m.Grows(prefix, kit.Keys(chain, kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
value = kit.GetMeta(value)
list := []string{}
for _, k := range fields {
list = append(list, kit.Select(kit.Format(kit.Value(val, k)), kit.Format(kit.Value(value, k))))
}
w.Write(list)
count++
})
})
m.Log_EXPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_FILE, p, kit.MDB_COUNT, count)
m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH), "")
m.Echo(p)
}
func _zone_import(m *ice.Message, prefix, chain, file string) {
f, e := os.Open(kit.Keys(file, CSV))
m.Assert(e)
defer f.Close()
r := csv.NewReader(f)
head, _ := r.Read()
count := 0
list := map[string]string{}
zkey := kit.Select(head[0], m.Option(FIELDS))
for {
line, e := r.Read()
if e != nil {
break
}
zone := ""
data := kit.Dict()
for i, k := range head {
switch k {
case zkey:
zone = line[i]
case kit.MDB_ID:
continue
case kit.MDB_EXTRA:
kit.Value(data, k, kit.UnMarshal(line[i]))
default:
kit.Value(data, k, line[i])
}
}
if list[zone] == "" {
list[zone] = m.Rich(prefix, chain, kit.Data(zkey, zone))
}
m.Grow(prefix, kit.Keys(chain, kit.MDB_HASH, list[zone]), data)
count++
}
m.Log_IMPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_COUNT, count)
m.Echo("%d", count)
}
const ZONE_FIELD = "time,zone,count" const ZONE_FIELD = "time,zone,count"
func ZoneAction(fields ...string) map[string]*ice.Action { func ZoneAction(fields ...string) map[string]*ice.Action {

View File

@ -84,6 +84,7 @@ func _cat_show(m *ice.Message, name string) {
const ( const (
PATH = "path" PATH = "path"
FILE = "file"
SIZE = "size" SIZE = "size"
) )
const CAT = "cat" const CAT = "cat"

View File

@ -216,9 +216,10 @@ func init() {
if len(arg) == 0 { if len(arg) == 0 {
arg = append(arg, "") arg = append(arg, "")
} }
m.Debug("dir_root: %s", m.Option(DIR_ROOT))
_dir_show(m, kit.Select("./", m.Option(DIR_ROOT)), arg[0], _dir_show(m, kit.Select("./", m.Option(DIR_ROOT)), arg[0],
0, m.Options(DIR_DEEP), kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)), 0, m.Options(DIR_DEEP), kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)),
kit.Split(kit.Select(kit.Select("time,size,path,action", m.Option(mdb.FIELDS)), strings.Join(arg[1:], ",")))) kit.Split(kit.Select(kit.Select("time,path,size,action", m.Option(mdb.FIELDS)), strings.Join(arg[1:], ","))))
m.SortTimeR(kit.MDB_TIME) m.SortTimeR(kit.MDB_TIME)
}}, }},
}, },

View File

@ -12,9 +12,9 @@ import (
) )
func _tail_create(m *ice.Message, arg ...string) { func _tail_create(m *ice.Message, arg ...string) {
h := m.Cmdx(mdb.INSERT, m.Prefix(TAIL), "", kit.MDB_HASH, arg) h := m.Cmdx(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, arg)
kit.ForEach(kit.Split(m.Option(kit.MDB_FILE), ","), func(file string) { kit.ForEach(kit.Split(m.Option(FILE)), func(file string) {
r, w := io.Pipe() r, w := io.Pipe()
m.Go(func() { m.Go(func() {
for bio := bufio.NewScanner(r); bio.Scan(); { for bio := bufio.NewScanner(r); bio.Scan(); {
@ -32,61 +32,61 @@ func _tail_create(m *ice.Message, arg ...string) {
}) })
} }
func _tail_count(m *ice.Message, name string) string { func _tail_count(m *ice.Message, name string) string {
return m.Conf(TAIL, kit.Keys(kit.MDB_HASH, kit.Hashs(name), kit.MDB_META, kit.MDB_COUNT)) return m.Conf(TAIL, kit.KeyHash(name, kit.Keym(kit.MDB_COUNT)))
} }
const TAIL = "tail" const TAIL = "tail"
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
Configs: map[string]*ice.Config{ TAIL: {Name: TAIL, Help: "日志流", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)},
TAIL: {Name: TAIL, Help: "日志流", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, }, Commands: map[string]*ice.Command{
}, ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
Commands: map[string]*ice.Command{ m.Richs(TAIL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { value, _ = kit.GetMeta(value), m.Option(kit.MDB_HASH, key)
m.Richs(TAIL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { m.Cmd(TAIL, mdb.CREATE, kit.MDB_FILE, kit.Format(value[kit.MDB_FILE]), kit.MDB_NAME, kit.Format(value[kit.MDB_NAME]))
value, _ = kit.GetMeta(value), m.Option(kit.MDB_HASH, key) })
m.Cmd(TAIL, mdb.CREATE, kit.MDB_FILE, kit.Format(value[kit.MDB_FILE]), kit.MDB_NAME, kit.Format(value[kit.MDB_NAME])) }},
}) TAIL: {Name: "tail name id auto page filter:text create", Help: "日志流", Action: map[string]*ice.Action{
}}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
TAIL: {Name: "tail name id auto page filter:text create", Help: "日志流", Action: map[string]*ice.Action{ switch arg[0] {
mdb.CREATE: {Name: "create file name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { case FILE:
_tail_create(m, arg...) m.Cmdy(DIR, kit.Select("./", arg, 1), PATH).RenameAppend(PATH, FILE)
}}, m.ProcessAgain()
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { case kit.MDB_NAME:
switch arg[0] { m.Push(arg[0], kit.Split(m.Option(FILE), "/"))
case "file":
m.Cmdy(DIR, kit.Select("./", arg, 1), "path")
}
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, TAIL, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME))
}},
"prev": {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) {
mdb.PrevPage(m, _tail_count(m, arg[0]), kit.Slice(arg, 2)...)
}},
"next": {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
mdb.NextPage(m, _tail_count(m, arg[0]), kit.Slice(arg, 2)...)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(kit.Slice(arg, 0, 2)), "time,name,count,name,file", "time,id,file,text")
m.Option(mdb.CACHE_FILTER, kit.Select("", arg, 4))
m.Option(mdb.CACHE_OFFEND, kit.Select("0", arg, 3))
m.Option(mdb.CACHE_LIMIT, kit.Select("10", arg, 2))
m.Cmd(mdb.SELECT, TAIL, "", mdb.ZONE, arg).Table(func(index int, value map[string]string, head []string) {
if strings.Contains(value[kit.MDB_TEXT], m.Option(mdb.CACHE_FILTER)) {
m.Push("", value, head)
}
})
if len(arg) == 0 {
m.PushAction(mdb.REMOVE)
} else {
m.StatusTimeCountTotal(m.Conf(TAIL, kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0]), kit.MDB_META, kit.MDB_COUNT)))
} }
}}, }},
}, mdb.CREATE: {Name: "create file name", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
_tail_create(m, arg...)
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, TAIL, "", mdb.HASH, m.OptionSimple(kit.MDB_NAME))
}},
mdb.PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) {
mdb.PrevPage(m, arg[0], arg[1:]...)
}},
mdb.NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
mdb.NextPageLimit(m, arg[0], arg[1:]...)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(kit.Slice(arg, 0, 2)), "time,name,count,file", "time,id,file,text")
m.Option(mdb.CACHE_FILTER, kit.Select("", arg, 4))
m.Option(mdb.CACHE_OFFEND, kit.Select("0", arg, 3))
m.Option(mdb.CACHE_LIMIT, kit.Select("10", arg, 2))
m.Cmd(mdb.SELECT, TAIL, "", mdb.ZONE, arg).Table(func(index int, value map[string]string, head []string) {
if strings.Contains(value[kit.MDB_TEXT], m.Option(mdb.CACHE_FILTER)) {
m.Push("", value, head)
}
})
if len(arg) == 0 {
m.PushAction(mdb.REMOVE)
} else {
m.StatusTimeCountTotal(_tail_count(m, arg[0]))
}
}},
},
}) })
} }

View File

@ -251,8 +251,8 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
func (f *Frame) close() { func (f *Frame) close() {
if stdin, ok := f.stdin.(io.Closer); ok { if stdin, ok := f.stdin.(io.Closer); ok {
stdin.Close() stdin.Close()
f.stdin = nil
} }
f.stdin = nil
} }
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {

View File

@ -43,6 +43,8 @@ func _dream_show(m *ice.Message, name string) {
os.MkdirAll(p, ice.MOD_DIR) os.MkdirAll(p, ice.MOD_DIR)
} }
m.ProcessOpen(kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/chat/pod/"+name))
// 任务模板 // 任务模板
if m.Option(kit.MDB_TEMPLATE) != "" { if m.Option(kit.MDB_TEMPLATE) != "" {
for _, file := range []string{ice.ETC_MISS, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.GO_MOD, ice.MAKEFILE} { for _, file := range []string{ice.ETC_MISS, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.GO_MOD, ice.MAKEFILE} {

View File

@ -88,8 +88,10 @@ func _spide_show(m *ice.Message, arg ...string) {
return return
} }
for k, v := range res.Header { if m.Config("logheaders") == ice.TRUE {
m.Debug("%v: %v", k, v) for k, v := range res.Header {
m.Debug("%v: %v", k, v)
}
} }
// 检查结果 // 检查结果
@ -125,6 +127,9 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, map[s
head := map[string]string{} head := map[string]string{}
body, ok := m.Optionv(SPIDE_BODY).(io.Reader) body, ok := m.Optionv(SPIDE_BODY).(io.Reader)
if !ok && len(arg) > 0 && method != SPIDE_GET { if !ok && len(arg) > 0 && method != SPIDE_GET {
if len(arg) == 1 {
arg = []string{SPIDE_DATA, arg[0]}
}
switch arg[0] { switch arg[0] {
case SPIDE_FORM: case SPIDE_FORM:
data := []string{} data := []string{}
@ -142,6 +147,7 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, map[s
arg = append(arg, "{}") arg = append(arg, "{}")
} }
body, arg = bytes.NewBufferString(arg[1]), arg[2:] body, arg = bytes.NewBufferString(arg[1]), arg[2:]
head[ContentType] = ContentJSON
case SPIDE_FILE: case SPIDE_FILE:
if f, e := os.Open(arg[1]); m.Assert(e) { if f, e := os.Open(arg[1]); m.Assert(e) {
@ -332,6 +338,7 @@ func init() {
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data( SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data(
kit.MDB_SHORT, CLIENT_NAME, kit.MDB_FIELD, "time,client.name,client.url", kit.MDB_SHORT, CLIENT_NAME, kit.MDB_FIELD, "time,client.name,client.url",
"logheaders", "false",
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{

View File

@ -152,6 +152,7 @@ const ( // PROCESS
PROCESS_DISPLAY = "_display" PROCESS_DISPLAY = "_display"
PROCESS_FIELD = "_field" PROCESS_FIELD = "_field"
PROCESS_INNER = "_inner" PROCESS_INNER = "_inner"
PROCESS_AGAIN = "_again"
PROCESS_HOLD = "_hold" PROCESS_HOLD = "_hold"
PROCESS_BACK = "_back" PROCESS_BACK = "_back"

View File

@ -33,7 +33,6 @@ func _title_parse(m *ice.Message, dir string, root map[string]interface{}, list
continue continue
case 1: case 1:
default: default:
m.Debug("what %v %v", dir, ls)
ls[1] = path.Join(dir, ls[1]) ls[1] = path.Join(dir, ls[1])
} }

2
go.mod
View File

@ -7,5 +7,5 @@ require (
github.com/kr/pty v1.1.8 github.com/kr/pty v1.1.8
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
shylinux.com/x/toolkits v0.3.2 shylinux.com/x/toolkits v0.3.3
) )

21
meta.go
View File

@ -24,6 +24,13 @@ func (m *Message) Add(key string, arg ...string) *Message {
} }
return m return m
} }
func (m *Message) SetResult(arg ...interface{}) *Message {
m.Set(MSG_RESULT)
if len(arg) > 0 {
m.Echo(kit.Format(arg[0]), arg[1:]...)
}
return m
}
func (m *Message) Set(key string, arg ...string) *Message { func (m *Message) Set(key string, arg ...string) *Message {
switch key { switch key {
case MSG_DETAIL, MSG_RESULT: case MSG_DETAIL, MSG_RESULT:
@ -41,6 +48,20 @@ func (m *Message) Set(key string, arg ...string) *Message {
return m return m
} }
default: default:
if len(m.meta[MSG_APPEND]) == 2 && m.meta[MSG_APPEND][0] == kit.MDB_KEY && m.meta[MSG_APPEND][1] == kit.MDB_VALUE {
for i := 0; i < len(m.meta[kit.MDB_KEY]); i++ {
if m.meta[kit.MDB_KEY][i] == key {
for ; i < len(m.meta[kit.MDB_KEY])-1; i++ {
m.meta[kit.MDB_KEY][i] = m.meta[kit.MDB_KEY][i+1]
m.meta[kit.MDB_VALUE][i] = m.meta[kit.MDB_VALUE][i+1]
}
m.meta[kit.MDB_KEY] = kit.Slice(m.meta[kit.MDB_KEY], 0, -1)
m.meta[kit.MDB_VALUE] = kit.Slice(m.meta[kit.MDB_VALUE], 0, -1)
break
}
}
break
}
delete(m.meta, key) delete(m.meta, key)
for _, k := range arg { for _, k := range arg {
delete(m.meta, k) delete(m.meta, k)

View File

@ -463,11 +463,6 @@ func (m *Message) AppendSimple(key ...string) (res []string) {
return return
} }
func (m *Message) SetResult() {
m.Set(MSG_RESULT)
return
}
func (m *Message) AppendTrans(cb func(value string, key string, index int) string) { func (m *Message) AppendTrans(cb func(value string, key string, index int) string) {
for _, k := range m.meta[MSG_APPEND] { for _, k := range m.meta[MSG_APPEND] {
for i, v := range m.meta[k] { for i, v := range m.meta[k] {
@ -483,6 +478,9 @@ func (m *Message) OptionUserWeb() *url.URL {
func (m *Message) Config(key string) string { func (m *Message) Config(key string) string {
return m.Conf(m.PrefixKey(), kit.Keym(key)) return m.Conf(m.PrefixKey(), kit.Keym(key))
} }
func (m *Message) ConfigSimple(key string) []string {
return []string{key, m.Conf(m.PrefixKey(), kit.Keym(key))}
}
func SelectAction(list map[string]*Action, fields ...string) map[string]*Action { func SelectAction(list map[string]*Action, fields ...string) map[string]*Action {
if len(fields) == 0 { if len(fields) == 0 {

View File

@ -85,7 +85,7 @@ func _status_list(m *ice.Message) (files, adds, dels int, last time.Time) {
list = append(list, COMMIT) list = append(list, COMMIT)
} }
} }
m.PushButton(list...) m.PushButton(list)
} }
files, adds, dels = _status_stat(m, files, adds, dels) files, adds, dels = _status_stat(m, files, adds, dels)

View File

@ -36,10 +36,10 @@ func init() {
}}, }},
SYNC: {Name: "sync id auto page", Help: "同步流", Action: map[string]*ice.Action{ SYNC: {Name: "sync id auto page", Help: "同步流", Action: map[string]*ice.Action{
mdb.PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) { mdb.PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) {
mdb.PrevPage(m, _sync_count(m), kit.Slice(arg, _sync_index)...) mdb.PrevPage(m, arg[0], arg[1:]...)
}}, }},
mdb.NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) { mdb.NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
mdb.NextPage(m, _sync_count(m), kit.Slice(arg, _sync_index)...) mdb.NextPage(m, arg[0], arg[1:]...)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.OptionPage(kit.Slice(arg, _sync_index)...) m.OptionPage(kit.Slice(arg, _sync_index)...)

View File

@ -20,9 +20,14 @@ type Option struct {
Value interface{} Value interface{}
} }
func OptionHash(str string) Option { return Option{kit.MDB_HASH, str} } func OptionHash(str string) Option { return Option{kit.MDB_HASH, str} }
func OptionFields(str ...string) Option { return Option{MSG_FIELDS, strings.Join(str, ",")} } func OptionFields(str ...string) Option { return Option{MSG_FIELDS, strings.Join(str, ",")} }
func (m *Message) OptionFields(str ...string) { m.Option(MSG_FIELDS, strings.Join(str, ",")) } func (m *Message) OptionFields(str ...string) string {
if len(str) > 0 {
m.Option(MSG_FIELDS, strings.Join(str, ","))
}
return m.Option(MSG_FIELDS)
}
func (m *Message) OptionPage(arg ...string) { func (m *Message) OptionPage(arg ...string) {
m.Option("cache.offend", kit.Select("0", arg, 1)) m.Option("cache.offend", kit.Select("0", arg, 1))
m.Option("cache.limit", kit.Select("10", arg, 0)) m.Option("cache.limit", kit.Select("10", arg, 0))
@ -179,9 +184,11 @@ func (m *Message) ProcessDisplay(arg ...interface{}) {
m.Process(PROCESS_DISPLAY) m.Process(PROCESS_DISPLAY)
m.Option("_display", arg...) m.Option("_display", arg...)
} }
func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) } func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) } func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) }
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) } func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) }
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) }
func (m *Message) ShowPlugin(pod, ctx, cmd string, arg ...string) { func (m *Message) ShowPlugin(pod, ctx, cmd string, arg ...string) {
m.Cmdy("web.space", pod, "context", ctx, "command", cmd) m.Cmdy("web.space", pod, "context", ctx, "command", cmd)

View File

@ -58,10 +58,16 @@ func (m *Message) PushAnchor(arg ...interface{}) { // [name] link
m.Push(kit.MDB_LINK, Render(m, RENDER_ANCHOR, arg...)) m.Push(kit.MDB_LINK, Render(m, RENDER_ANCHOR, arg...))
} }
} }
func (m *Message) PushButton(arg ...string) { func (m *Message) PushButton(list ...interface{}) {
if !m.IsCliUA() { if m.IsCliUA() {
m.Push(kit.MDB_ACTION, Render(m, RENDER_BUTTON, strings.ToLower(kit.Join(arg)))) return
} }
for i, item := range list {
if t := reflect.TypeOf(item); t.Kind() == reflect.Func {
list[i] = kit.FuncName(item)
}
}
m.Push(kit.MDB_ACTION, Render(m, RENDER_BUTTON, strings.ToLower(kit.Join(kit.Simple(list)))))
} }
func (m *Message) PushScript(arg ...string) *Message { // [type] text... func (m *Message) PushScript(arg ...string) *Message { // [type] text...
return m.Push(kit.MDB_SCRIPT, Render(m, RENDER_SCRIPT, arg)) return m.Push(kit.MDB_SCRIPT, Render(m, RENDER_SCRIPT, arg))
@ -76,14 +82,8 @@ func (m *Message) PushVideos(key, src string, arg ...string) { // key src [size]
m.Push(key, Render(m, RENDER_VIDEOS, src, arg)) m.Push(key, Render(m, RENDER_VIDEOS, src, arg))
} }
func (m *Message) PushAction(list ...interface{}) { func (m *Message) PushAction(list ...interface{}) {
for i, item := range list {
if t := reflect.TypeOf(item); t.Kind() == reflect.Func {
list[i] = kit.FuncName(item)
}
}
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
m.PushButton(kit.Simple(list...)...) m.PushButton(list...)
}) })
} }