diff --git a/base/cli/daemon.go b/base/cli/daemon.go index 0627de35..dcdd0464 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -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) { - m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, - kit.MDB_STATUS, ERROR, kit.MDB_ERROR, e) + if m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, h, kit.Keym(kit.MDB_STATUS))) == START { + m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, ERROR, ERROR, e) + } } else { m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode()) m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, STOP) } 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(): + m.Sleep("1s") cb() } @@ -168,6 +173,12 @@ func init() { } else if m.Richs(DAEMON, "", arg[0], nil) != nil { // 进程详情 m.Option(mdb.FIELDS, mdb.DETAIL) 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 { // 启动进程 m.Option(CMD_TYPE, DAEMON) diff --git a/base/mdb/hash.go b/base/mdb/hash.go index da4d377c..5caa9384 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -13,13 +13,31 @@ import ( func _hash_fields(m *ice.Message) []string { 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) { 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]) - h := m.Rich(prefix, chain, kit.Data(arg)) - m.Echo(h) + m.Echo(m.Rich(prefix, chain, kit.Data(arg))) } func _hash_delete(m *ice.Message, prefix, chain, field, value string) { 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), "") }) } +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) { if field == kit.MDB_HASH && value == RANDOM { value = kit.MDB_RANDOMS @@ -34,12 +64,11 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) { fields := _hash_fields(m) cb := m.Optionv(kit.Keycb(SELECT)) m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { - val = kit.GetMeta(val) - switch cb := cb.(type) { + switch val = kit.GetMeta(val); cb := cb.(type) { case func(fields []string, value map[string]interface{}): cb(fields, val) default: - if m.Option(FIELDS) == DETAIL { + if m.OptionFields() == DETAIL { m.Push(DETAIL, val) } else { 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) } } -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) { f, p, e := kit.Create(kit.Keys(file, JSON)) m.Assert(e) @@ -112,7 +129,7 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { } default: 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 } } @@ -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]) }) } -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{}) { - 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) -} + +const HASH = "hash" func HashAction(fields ...string) 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) { 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) { 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) { list := []string{} 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) } }) @@ -166,16 +175,5 @@ func HashAction(fields ...string) map[string]*ice.Action { 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...) } - -const HASH = "hash" diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index b736f2d8..b99c73de 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -1,10 +1,7 @@ package mdb import ( - "encoding/csv" - "os" "path" - "strings" ice "shylinux.com/x/icebergs" 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) } -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 ( CSV = "csv" JSON = "json" @@ -175,6 +56,14 @@ const ( 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) { limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1) offends := kit.Int(offend) - kit.Int(limit) @@ -196,6 +85,14 @@ func NextPage(m *ice.Message, total string, arg ...string) { } 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" diff --git a/base/mdb/zone.go b/base/mdb/zone.go index 1d87ad86..aa459933 100644 --- a/base/mdb/zone.go +++ b/base/mdb/zone.go @@ -1,10 +1,131 @@ package mdb import ( + "encoding/csv" + "os" + "path" + "strings" + ice "shylinux.com/x/icebergs" 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" func ZoneAction(fields ...string) map[string]*ice.Action { diff --git a/base/nfs/cat.go b/base/nfs/cat.go index 27e9c3f2..6c6cf0fc 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -84,6 +84,7 @@ func _cat_show(m *ice.Message, name string) { const ( PATH = "path" + FILE = "file" SIZE = "size" ) const CAT = "cat" diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 02c50cd2..6592682c 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -216,9 +216,10 @@ func init() { if len(arg) == 0 { arg = append(arg, "") } + m.Debug("dir_root: %s", m.Option(DIR_ROOT)) _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)), - 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) }}, }, diff --git a/base/nfs/tail.go b/base/nfs/tail.go index 52c0eb93..67043d40 100644 --- a/base/nfs/tail.go +++ b/base/nfs/tail.go @@ -12,9 +12,9 @@ import ( ) 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() m.Go(func() { 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 { - 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" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - 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) { - m.Richs(TAIL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - 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.CREATE: {Name: "create file name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - _tail_create(m, arg...) - }}, - mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { - switch arg[0] { - 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))) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + 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) { + m.Richs(TAIL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { + 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) { + switch arg[0] { + case FILE: + m.Cmdy(DIR, kit.Select("./", arg, 1), PATH).RenameAppend(PATH, FILE) + m.ProcessAgain() + case kit.MDB_NAME: + m.Push(arg[0], kit.Split(m.Option(FILE), "/")) } }}, - }, + 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])) + } + }}, + }, }) } diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go index f2b6687c..1bda2f2e 100644 --- a/base/ssh/scripts.go +++ b/base/ssh/scripts.go @@ -251,8 +251,8 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame { func (f *Frame) close() { if stdin, ok := f.stdin.(io.Closer); ok { stdin.Close() - f.stdin = nil } + f.stdin = nil } func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { diff --git a/base/web/dream.go b/base/web/dream.go index 73a90103..22ec6d76 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -43,6 +43,8 @@ func _dream_show(m *ice.Message, name string) { os.MkdirAll(p, ice.MOD_DIR) } + m.ProcessOpen(kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/chat/pod/"+name)) + // 任务模板 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} { diff --git a/base/web/spide.go b/base/web/spide.go index b4ef4ec7..cfb65653 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -88,8 +88,10 @@ func _spide_show(m *ice.Message, arg ...string) { return } - for k, v := range res.Header { - m.Debug("%v: %v", k, v) + if m.Config("logheaders") == ice.TRUE { + 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{} body, ok := m.Optionv(SPIDE_BODY).(io.Reader) if !ok && len(arg) > 0 && method != SPIDE_GET { + if len(arg) == 1 { + arg = []string{SPIDE_DATA, arg[0]} + } switch arg[0] { case SPIDE_FORM: data := []string{} @@ -142,6 +147,7 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, map[s arg = append(arg, "{}") } body, arg = bytes.NewBufferString(arg[1]), arg[2:] + head[ContentType] = ContentJSON case SPIDE_FILE: if f, e := os.Open(arg[1]); m.Assert(e) { @@ -332,6 +338,7 @@ func init() { Configs: map[string]*ice.Config{ SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data( kit.MDB_SHORT, CLIENT_NAME, kit.MDB_FIELD, "time,client.name,client.url", + "logheaders", "false", )}, }, Commands: map[string]*ice.Command{ diff --git a/conf.go b/conf.go index bbca0328..08787a66 100644 --- a/conf.go +++ b/conf.go @@ -152,6 +152,7 @@ const ( // PROCESS PROCESS_DISPLAY = "_display" PROCESS_FIELD = "_field" PROCESS_INNER = "_inner" + PROCESS_AGAIN = "_again" PROCESS_HOLD = "_hold" PROCESS_BACK = "_back" diff --git a/core/wiki/title.go b/core/wiki/title.go index 16203197..b38aaae1 100644 --- a/core/wiki/title.go +++ b/core/wiki/title.go @@ -33,7 +33,6 @@ func _title_parse(m *ice.Message, dir string, root map[string]interface{}, list continue case 1: default: - m.Debug("what %v %v", dir, ls) ls[1] = path.Join(dir, ls[1]) } diff --git a/go.mod b/go.mod index 3fc9a0ef..37b2b1ea 100644 --- a/go.mod +++ b/go.mod @@ -7,5 +7,5 @@ require ( github.com/kr/pty v1.1.8 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 - shylinux.com/x/toolkits v0.3.2 + shylinux.com/x/toolkits v0.3.3 ) diff --git a/meta.go b/meta.go index e5a8a9ff..11d542d4 100644 --- a/meta.go +++ b/meta.go @@ -24,6 +24,13 @@ func (m *Message) Add(key string, arg ...string) *Message { } 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 { switch key { case MSG_DETAIL, MSG_RESULT: @@ -41,6 +48,20 @@ func (m *Message) Set(key string, arg ...string) *Message { return m } 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) for _, k := range arg { delete(m.meta, k) diff --git a/misc.go b/misc.go index 10a9a1b1..e87f7e57 100644 --- a/misc.go +++ b/misc.go @@ -463,11 +463,6 @@ func (m *Message) AppendSimple(key ...string) (res []string) { return } -func (m *Message) SetResult() { - m.Set(MSG_RESULT) - return -} - func (m *Message) AppendTrans(cb func(value string, key string, index int) string) { for _, k := range m.meta[MSG_APPEND] { for i, v := range m.meta[k] { @@ -483,6 +478,9 @@ func (m *Message) OptionUserWeb() *url.URL { func (m *Message) Config(key string) string { 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 { if len(fields) == 0 { diff --git a/misc/git/status.go b/misc/git/status.go index fa2a6e49..af846fd8 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -85,7 +85,7 @@ func _status_list(m *ice.Message) (files, adds, dels int, last time.Time) { list = append(list, COMMIT) } } - m.PushButton(list...) + m.PushButton(list) } files, adds, dels = _status_stat(m, files, adds, dels) diff --git a/misc/vim/sync.go b/misc/vim/sync.go index 6ff77880..34352881 100644 --- a/misc/vim/sync.go +++ b/misc/vim/sync.go @@ -36,10 +36,10 @@ func init() { }}, 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.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.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) { m.OptionPage(kit.Slice(arg, _sync_index)...) diff --git a/option.go b/option.go index 9f4b9a2f..f936e907 100644 --- a/option.go +++ b/option.go @@ -20,9 +20,14 @@ type Option struct { Value interface{} } -func OptionHash(str string) Option { return Option{kit.MDB_HASH, 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 OptionHash(str string) Option { return Option{kit.MDB_HASH, str} } +func OptionFields(str ...string) Option { return 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) { m.Option("cache.offend", kit.Select("0", arg, 1)) m.Option("cache.limit", kit.Select("10", arg, 0)) @@ -179,9 +184,11 @@ func (m *Message) ProcessDisplay(arg ...interface{}) { m.Process(PROCESS_DISPLAY) m.Option("_display", arg...) } -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) ProcessInner() { m.Process(PROCESS_INNER) } +func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) } +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) { m.Cmdy("web.space", pod, "context", ctx, "command", cmd) diff --git a/render.go b/render.go index 93d953ac..7bc2c9b2 100644 --- a/render.go +++ b/render.go @@ -58,10 +58,16 @@ func (m *Message) PushAnchor(arg ...interface{}) { // [name] link m.Push(kit.MDB_LINK, Render(m, RENDER_ANCHOR, arg...)) } } -func (m *Message) PushButton(arg ...string) { - if !m.IsCliUA() { - m.Push(kit.MDB_ACTION, Render(m, RENDER_BUTTON, strings.ToLower(kit.Join(arg)))) +func (m *Message) PushButton(list ...interface{}) { + if m.IsCliUA() { + 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... 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)) } 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.PushButton(kit.Simple(list...)...) + m.PushButton(list...) }) }