1
0
mirror of https://shylinux.com/x/icebergs synced 2025-05-06 21:26:54 +08:00
This commit is contained in:
harveyshao 2021-10-22 12:43:09 +08:00
parent 742896a725
commit 692c2e2c11
32 changed files with 696 additions and 781 deletions

View File

@ -17,16 +17,16 @@ func _role_user(m *ice.Message, userrole string, username ...string) {
}
func _role_list(m *ice.Message, userrole string) {
m.Richs(ROLE, nil, kit.Select(kit.MDB_FOREACH, userrole), func(key string, value map[string]interface{}) {
for k := range value[WHITE].(map[string]interface{}) {
kit.Fetch(value[WHITE], func(k string, v interface{}) {
m.Push(ROLE, kit.Value(value, kit.MDB_NAME))
m.Push(kit.MDB_ZONE, WHITE)
m.Push(kit.MDB_KEY, k)
}
for k := range value[BLACK].(map[string]interface{}) {
})
kit.Fetch(value[BLACK], func(k string, v interface{}) {
m.Push(ROLE, kit.Value(value, kit.MDB_NAME))
m.Push(kit.MDB_ZONE, BLACK)
m.Push(kit.MDB_KEY, k)
}
})
})
}
func _role_chain(arg ...string) string {

View File

@ -70,7 +70,7 @@ func init() {
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
mdb.HashSelect(m.Spawn(c), arg...).Table(func(index int, value map[string]string, head []string) {
if len(arg) > 0 {
m.OptionFields("detail")
m.OptionFields(mdb.DETAIL)
}
m.Push(kit.MDB_TIME, m.Time())
m.Push(kit.MDB_NAME, value[kit.MDB_NAME])

View File

@ -142,8 +142,7 @@ func init() {
m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, kit.MDB_STATUS, ERROR)
}},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg), m.Config(kit.MDB_FIELD))
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH, kit.MDB_HASH, arg).Table(func(index int, value map[string]string, head []string) {
mdb.HashSelect(m, arg...).Table(func(index int, value map[string]string, head []string) {
switch value[kit.MDB_STATUS] {
case START:
m.PushButton(RESTART, STOP)

View File

@ -7,7 +7,6 @@ import (
"os/exec"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
)
@ -76,16 +75,6 @@ func _system_exec(m *ice.Message, cmd *exec.Cmd) {
m.Push(kit.MDB_TIME, m.Time())
m.Push(kit.MDB_CODE, int(cmd.ProcessState.ExitCode()))
}
func SystemProcess(m *ice.Message, text string, arg ...string) {
if len(arg) > 0 && arg[0] == ice.RUN {
m.Cmdy(SYSTEM, arg[1:])
return
}
m.Cmdy(ctx.COMMAND, SYSTEM)
m.ProcessField(SYSTEM, ice.RUN)
m.Push(ice.ARG, kit.Split(text))
}
func IsSuccess(m *ice.Message) bool {
return m.Append(kit.MDB_CODE) == "0"
}
@ -110,8 +99,7 @@ func init() {
}, Commands: map[string]*ice.Command{
SYSTEM: {Name: "system cmd run:button", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) == 0 {
m.Fields(len(arg), m.Config(kit.MDB_FIELD))
m.Cmdy(mdb.SELECT, SYSTEM, "", mdb.LIST)
mdb.ListSelect(m, arg)
return
}
m.Grow(SYSTEM, "", kit.Dict(kit.MDB_TIME, m.Time(), ice.CMD, kit.Join(arg, ice.SP)))

View File

@ -28,8 +28,8 @@ func _command_list(m *ice.Message, name string) {
m.Push(kit.MDB_INDEX, kit.Keys(s.Cap(ice.CTX_FOLLOW), key))
m.Push(kit.MDB_NAME, kit.Format(cmd.Name))
m.Push(kit.MDB_HELP, kit.Format(cmd.Help))
m.Push(kit.MDB_META, kit.Formats(cmd.Meta))
m.Push(kit.MDB_LIST, kit.Formats(cmd.List))
m.Push(kit.MDB_META, kit.Format(cmd.Meta))
m.Push(kit.MDB_LIST, kit.Format(cmd.List))
})
}
func _command_search(m *ice.Message, kind, name, text string) {

View File

@ -6,11 +6,6 @@ import (
const CTX = "ctx"
var Index = &ice.Context{Name: CTX, Help: "标准模块", Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
}}
var Index = &ice.Context{Name: CTX, Help: "标准模块"}
func init() { ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG, MESSAGE) }

View File

@ -9,8 +9,8 @@ import (
)
type Frame struct {
t <-chan time.Time
s chan os.Signal
t time.Duration
e chan bool
}
@ -18,22 +18,22 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server
return &Frame{}
}
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
f.t = time.Tick(kit.Duration(m.Conf(TIMER, kit.Keym(TICK))))
f.s = make(chan os.Signal, ice.MOD_CHAN)
f.e = make(chan bool, 1)
return f
}
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
f.t = kit.Duration(m.Conf(TIMER, kit.Keym(TICK)))
for {
select {
case <-f.e:
return true
case <-time.Tick(f.t):
// m.Cmd(TIMER, ACTION)
case s := <-f.s:
m.Cmd(SIGNAL, ACTION, SIGNAL, s)
// case <-f.t:
// m.Cmd(TIMER, ACTION)
}
}
return true
@ -46,8 +46,6 @@ const GDB = "gdb"
var Index = &ice.Context{Name: GDB, Help: "事件模块", Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", kit.MDB_NAME, "退出", ice.CMD, "exit 0")
m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", kit.MDB_NAME, "重启", ice.CMD, "exit 1")
m.Load()
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -44,7 +44,7 @@ func init() {
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
TIMER: {Name: TIMER, Help: "定时器", Value: kit.Data(
kit.MDB_FIELD, "time,hash,delay,interval,order,next,cmd",
TICK, "10ms",
TICK, "1s",
)},
}, Commands: map[string]*ice.Command{
TIMER: {Name: "timer hash id auto create prunes", Help: "定时器", Action: ice.MergeAction(map[string]*ice.Action{

View File

@ -8,29 +8,27 @@ import (
const ENGINE = "engine"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
ENGINE: {Name: "engine", Help: "引擎", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
},
Commands: map[string]*ice.Command{
ENGINE: {Name: "engine type name text auto", Help: "引擎", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(ENGINE, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(ENGINE, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
if len(arg) == 2 {
arg = append(arg, "")
}
m.Richs(ENGINE, nil, arg[0], func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), ENGINE, arg[0], arg[1], arg[2], arg[3:])
})
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
ENGINE: {Name: "engine", Help: "引擎", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
}, Commands: map[string]*ice.Command{
ENGINE: {Name: "engine type name text auto", Help: "引擎", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(ENGINE, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}})
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(ENGINE, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
if len(arg) == 2 {
arg = append(arg, "")
}
m.Richs(ENGINE, nil, arg[0], func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), ENGINE, arg[0], arg[1], arg[2], arg[3:])
})
}},
}})
}

View File

@ -4,26 +4,21 @@ import (
"encoding/json"
"os"
"path"
"strings"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
)
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", kit.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]++
if val = kit.GetMeta(val); kit.Format(val[kit.MDB_COUNT]) != "" {
list[kit.Format(val[field])] = kit.Int(val[kit.MDB_COUNT])
} 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])]++
}
list[kit.Format(val[field])]++
}
})
for k, i := range list {
@ -89,6 +84,7 @@ func _hash_export(m *ice.Message, prefix, chain, file string) {
e = en.Encode(m.Confv(prefix, kit.Keys(chain, HASH)))
m.Log_EXPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_FILE, p)
m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH), "")
m.Echo(p)
}
func _hash_import(m *ice.Message, prefix, chain, file string) {
@ -164,15 +160,16 @@ func HashAction(fields ...string) map[string]*ice.Action {
m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(_key(m)), arg)
}},
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(m.Config(kit.META_FIELD))
m.Cmdy(EXPORT, m.PrefixKey(), "", HASH, arg)
}},
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(IMPORT, m.PrefixKey(), "", HASH, arg)
}},
PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
list := []string{}
list, before := []string{}, kit.Time(kit.Select(m.Time("-72h"), m.Option(kit.MDB_BEFORE)))
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(kit.MDB_BEFORE)) {
if value = kit.GetMeta(value); kit.Time(kit.Format(value[kit.MDB_TIME])) < before {
list = append(list, key)
}
})

View File

@ -5,14 +5,28 @@ import (
"os"
"path"
"sort"
"strings"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
)
func _list_fields(m *ice.Message) []string {
return kit.Split(kit.Select("time,id,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
return kit.Split(kit.Select("time,id,type,name,text", kit.Join(kit.Simple(m.Optionv(FIELDS)))))
}
func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
list := map[string]int{}
m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) {
if val = kit.GetMeta(val); 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 _list_insert(m *ice.Message, prefix, chain string, arg ...string) {
m.Log_INSERT(kit.MDB_KEY, path.Join(prefix, chain), arg[0], arg[1])
@ -20,6 +34,18 @@ func _list_insert(m *ice.Message, prefix, chain string, arg ...string) {
}
func _list_delete(m *ice.Message, prefix, chain, field, value string) {
}
func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
m.Grows(prefix, chain, field, value, func(index int, 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 _list_select(m *ice.Message, prefix, chain, field, value string) {
if value == "" {
field = ""
@ -27,12 +53,11 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) {
fields := _list_fields(m)
cb := m.Optionv(kit.Keycb(SELECT))
m.Grows(prefix, chain, kit.Select(m.Option(CACHE_FIELD), field), kit.Select(m.Option(CACHE_VALUE), value), func(index int, 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("", val, fields)
@ -40,18 +65,6 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) {
}
})
}
func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
m.Grows(prefix, chain, field, value, func(index int, 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 _list_export(m *ice.Message, prefix, chain, file string) {
f, p, e := kit.Create(kit.Keys(file, CSV))
m.Assert(e)
@ -117,49 +130,45 @@ func _list_import(m *ice.Message, prefix, chain, file string) {
}
func _list_prunes(m *ice.Message, prefix, chain string, arg ...string) {
}
func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
list := map[string]int{}
m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) {
val = kit.GetMeta(val)
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 LIST = "list"
func ListAction(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(), "", LIST, arg)
}},
INSERT: {Name: "insert type=go name=hi text=hello", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INSERT, m.PrefixKey(), "", LIST, arg)
}},
DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(DELETE, m.PrefixKey(), "", LIST, m.OptionSimple(kit.MDB_ID), arg)
}},
MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(MODIFY, m.PrefixKey(), "", LIST, m.OptionSimple(kit.MDB_ID), arg)
}},
REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(DELETE, m.PrefixKey(), "", LIST, m.OptionSimple(kit.MDB_ID))
}},
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(m.Conf(m.PrefixKey(), kit.META_FIELD))
m.OptionFields(m.Config(kit.META_FIELD))
m.Cmdy(EXPORT, m.PrefixKey(), "", LIST)
m.Conf(m.PrefixKey(), kit.MDB_LIST, "")
m.Conf(m.PrefixKey(), kit.Keym(kit.MDB_COUNT), 0)
m.Config(kit.MDB_COUNT, 0)
}},
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(IMPORT, m.PrefixKey(), "", LIST)
}},
INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INPUTS, m.PrefixKey(), "", LIST, arg)
PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(PRUNES, m.PrefixKey(), "", LIST, arg)
}},
PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) {
PrevPage(m, m.Conf(m.PrefixKey(), kit.Keym(kit.MDB_COUNT)), kit.Slice(arg, 1)...)
PrevPage(m, m.Config(kit.MDB_COUNT), kit.Slice(arg, 1)...)
}},
NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
NextPage(m, m.Conf(m.PrefixKey(), kit.Keym(kit.MDB_COUNT)), kit.Slice(arg, 1)...)
NextPage(m, m.Config(kit.MDB_COUNT), kit.Slice(arg, 1)...)
}},
}, fields...)
}
func ListSelect(m *ice.Message, arg ...string) *ice.Message {
m.Fields(len(arg), m.Config(kit.MDB_FIELD))
m.Cmdy(SELECT, m.PrefixKey(), "", LIST, kit.MDB_ID, arg)
return m
}

View File

@ -8,7 +8,7 @@ import (
)
func _file_name(m *ice.Message, arg ...string) string {
return kit.Select(path.Join(m.Option(ice.MSG_LOCAL), ice.USR_LOCAL, EXPORT, path.Join(arg[:2]...), arg[2]), arg, 3)
return kit.Select(path.Join(ice.USR_LOCAL_EXPORT, m.Option(ice.MSG_DOMAIN), path.Join(arg[:2]...), arg[2]), arg, 3)
}
func _domain_chain(m *ice.Message, chain string) string {
return kit.Keys(m.Option(ice.MSG_DOMAIN), chain)
@ -21,7 +21,6 @@ const (
const (
DICT = "dict"
META = "meta"
ZONE = "zone"
)
const (
FIELDS = "fields"
@ -29,19 +28,19 @@ const (
RANDOM = "random"
CREATE = "create"
REMOVE = "remove"
INSERT = "insert"
DELETE = "delete"
MODIFY = "modify"
SELECT = "select"
DELETE = "delete"
REMOVE = "remove"
EXPORT = "export"
IMPORT = "import"
INPUTS = "inputs"
PRUNES = "prunes"
REVERT = "revert"
REPEAT = "repeat"
INPUTS = "inputs"
UPLOAD = "upload"
REPEAT = "repeat"
REVERT = "revert"
NEXT = "next"
PREV = "prev"
@ -93,6 +92,11 @@ func NextPageLimit(m *ice.Message, total string, arg ...string) {
m.ProcessHold()
}
}
func SetPage(m *ice.Message, arg ...string) {
m.Option(CACHE_LIMIT, kit.Select("10", arg, 0))
m.Option(CACHE_OFFEND, kit.Select("0", arg, 1))
m.Option(CACHE_FILTER, kit.Select("", arg, 2))
}
const MDB = "mdb"
@ -100,7 +104,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: map[string]*
INSERT: {Name: "insert key sub type arg...", Help: "添加", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case ZONE:
_list_insert(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.SubKey(arg[3]))), arg[4:]...)
_list_insert(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...)
case HASH:
_hash_insert(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
case LIST:
@ -110,7 +114,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: map[string]*
DELETE: {Name: "delete key sub type field value", Help: "删除", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case ZONE:
_list_delete(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4])
_list_delete(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4], arg[5])
case HASH:
_hash_delete(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4])
case LIST:
@ -120,7 +124,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: map[string]*
MODIFY: {Name: "modify key sub type field value arg...", Help: "编辑", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case ZONE:
_list_modify(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.SubKey(arg[3]))), kit.MDB_ID, arg[4], arg[5:]...)
_list_modify(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), kit.MDB_ID, arg[4], arg[5:]...)
case HASH:
_hash_modify(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4], arg[5:]...)
case LIST:
@ -160,7 +164,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: map[string]*
INPUTS: {Name: "inputs key sub type field value", Help: "补全", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case ZONE:
_list_inputs(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.SubKey(arg[3]))), kit.Select("name", arg, 4), kit.Select("", arg, 5))
_list_inputs(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), kit.Select("name", arg, 4), kit.Select("", arg, 5))
case HASH:
_hash_inputs(m, arg[0], _domain_chain(m, arg[1]), kit.Select("name", arg, 3), kit.Select("", arg, 4))
case LIST:
@ -169,6 +173,8 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: map[string]*
}},
PRUNES: {Name: "prunes key sub type [field value]...", Help: "清理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case ZONE:
_list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...)
case HASH:
_hash_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
case LIST:

View File

@ -8,26 +8,24 @@ import (
const PLUGIN = "plugin"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
PLUGIN: {Name: "plugin", Help: "插件", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
},
Commands: map[string]*ice.Command{
PLUGIN: {Name: "plugin type name text auto", Help: "插件", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(PLUGIN, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(PLUGIN, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
m.Richs(PLUGIN, nil, arg[0], func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), PLUGIN, arg[0], arg[1], kit.Select("", arg, 2))
})
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
PLUGIN: {Name: "plugin", Help: "插件", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
}, Commands: map[string]*ice.Command{
PLUGIN: {Name: "plugin type name text auto", Help: "插件", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(PLUGIN, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}})
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(PLUGIN, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
m.Richs(PLUGIN, nil, arg[0], func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), PLUGIN, arg[0], arg[1], kit.Select("", arg, 2))
})
}},
}})
}

View File

@ -8,26 +8,24 @@ import (
const RENDER = "render"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
RENDER: {Name: "render", Help: "渲染", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
},
Commands: map[string]*ice.Command{
RENDER: {Name: "render type name text auto", Help: "渲染", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(RENDER, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(RENDER, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
m.Richs(RENDER, nil, arg[0], func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), RENDER, arg[0], arg[1], kit.Select("", arg, 2))
})
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
RENDER: {Name: "render", Help: "渲染", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
}, Commands: map[string]*ice.Command{
RENDER: {Name: "render type name text auto", Help: "渲染", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(RENDER, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}})
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(RENDER, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
m.Richs(RENDER, nil, arg[0], func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), RENDER, arg[0], arg[1], kit.Select("", arg, 2))
})
}},
}})
}

View File

@ -10,34 +10,29 @@ import (
const SEARCH = "search"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
SEARCH: {Name: "search", Help: "搜索", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
},
Commands: map[string]*ice.Command{
SEARCH: {Name: "search type word text auto", Help: "搜索", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
if kit.Select(arg[0], arg, 1) == "" {
m.Debug(m.Format("stack"))
}
m.Rich(SEARCH, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(SEARCH, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
m.Option(ice.MSG_FIELDS, kit.Select("ctx,cmd,time,size,type,name,text", kit.Select(m.Option(ice.MSG_FIELDS), arg, 2)))
for _, k := range strings.Split(arg[0], ",") {
for _, kk := range strings.Split(arg[1], ",") {
m.Richs(SEARCH, nil, k, func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), SEARCH, k, kk, kit.Select("", arg, 2))
})
}
}
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
SEARCH: {Name: "search", Help: "搜索", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
}, Commands: map[string]*ice.Command{
SEARCH: {Name: "search type word text auto", Help: "搜索", Action: map[string]*ice.Action{
CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(SEARCH, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}},
}})
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" {
m.Richs(SEARCH, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
})
return
}
m.Option(ice.MSG_FIELDS, kit.Select("ctx,cmd,time,size,type,name,text", kit.Select(m.Option(ice.MSG_FIELDS), arg, 2)))
for _, k := range strings.Split(arg[0], ",") {
for _, kk := range strings.Split(arg[1], ",") {
m.Richs(SEARCH, nil, k, func(key string, value map[string]interface{}) {
m.Cmdy(kit.Keys(value[kit.MDB_TEXT], value[kit.MDB_NAME]), SEARCH, k, kk, kit.Select("", arg, 2))
})
}
}
}},
}})
}

View File

@ -20,8 +20,7 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
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 val = kit.GetMeta(val); zone == "" {
if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, val)
} else {
@ -31,9 +30,7 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
}
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) {
switch value = kit.GetMeta(value); 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{}):
@ -125,7 +122,7 @@ func _zone_import(m *ice.Message, prefix, chain, file string) {
m.Echo("%d", count)
}
const ZONE_FIELD = "time,zone,count"
const ZONE = "zone"
func ZoneAction(fields ...string) map[string]*ice.Action {
_zone := func(m *ice.Message) string { return kit.Select(kit.MDB_ZONE, m.Config(kit.MDB_SHORT)) }
@ -155,7 +152,6 @@ func ZoneAction(fields ...string) map[string]*ice.Action {
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(_zone(m), m.Config(kit.MDB_FIELD))
m.Cmdy(EXPORT, m.PrefixKey(), "", ZONE)
m.Conf(m.PrefixKey(), kit.MDB_HASH, "")
}},
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(_zone(m))

View File

@ -85,15 +85,15 @@ func init() {
}
_save_file(m, arg[0], arg[1:]...)
}},
DEFS: {Name: "defs file text...", Help: "默认", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_defs_file(m, arg[0], arg[1:]...)
}},
PUSH: {Name: "push file text...", Help: "追加", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 1 {
arg = append(arg, m.Option(kit.MDB_CONTENT))
}
_push_file(m, arg[0], arg[1:]...)
}},
DEFS: {Name: "defs file text...", Help: "默认", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_defs_file(m, arg[0], arg[1:]...)
}},
COPY: {Name: "copy file from...", Help: "复制", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_copy_file(m, arg[0], arg[1:]...)
}},

View File

@ -65,10 +65,8 @@ func init() {
_tail_create(m, arg...)
}},
}, mdb.ZoneAction()), 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.Fields(len(kit.Slice(arg, 0, 2)), "time,name,count,file", m.Config(kit.MDB_FIELD))
mdb.SetPage(m, kit.Slice(arg, 2)...)
mdb.ZoneSelect(m.Spawn(c), arg...).Table(func(index int, value map[string]string, head []string) {
if strings.Contains(value[kit.MDB_TEXT], m.Option(mdb.CACHE_FILTER)) {

View File

@ -8,6 +8,4 @@ const SSH = "ssh"
var Index = &ice.Context{Name: SSH, Help: "终端模块"}
func init() {
ice.Index.Register(Index, &Frame{}, SOURCE, TARGET, PROMPT, PRINTF, SCREEN, RETURN)
}
func init() { ice.Index.Register(Index, &Frame{}, SOURCE, TARGET, PROMPT, PRINTF, SCREEN, RETURN) }

View File

@ -13,7 +13,7 @@ import (
)
func _cache_name(m *ice.Message, h string) string {
return path.Join(m.Conf(CACHE, kit.META_PATH), h[:2], h)
return path.Join(m.Config(kit.MDB_PATH), h[:2], h)
}
func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // file size
if name == "" {
@ -43,8 +43,7 @@ func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // fi
m.Push(DATA, h)
}
func _cache_watch(m *ice.Message, key, file string) {
m.Option(mdb.FIELDS, "time,hash,size,type,name,text,file")
m.Cmd(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, key).Table(func(index int, value map[string]string, head []string) {
mdb.HashSelect(m.Spawn(), key).Table(func(index int, value map[string]string, head []string) {
if value[kit.MDB_FILE] == "" {
m.Cmdy(nfs.SAVE, file, value[kit.MDB_TEXT])
} else {
@ -137,57 +136,53 @@ const (
const CACHE = "cache"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
CACHE: {Name: CACHE, Help: "缓存池", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_TEXT, kit.MDB_PATH, ice.VAR_FILE,
kit.MDB_STORE, ice.VAR_DATA, kit.MDB_FSIZE, "200000",
kit.MDB_LIMIT, "50", kit.MDB_LEAST, "30",
)},
},
Commands: map[string]*ice.Command{
CACHE: {Name: "cache hash auto", Help: "缓存池", Action: map[string]*ice.Action{
WATCH: {Name: "watch key file", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
_cache_watch(m, arg[0], arg[1])
}},
CATCH: {Name: "catch type name", Help: "捕获", Hand: func(m *ice.Message, arg ...string) {
file, size := _cache_catch(m, arg[1])
_cache_save(m, arg[0], arg[1], "", file, size)
}},
WRITE: {Name: "write type name text", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_cache_save(m, arg[0], arg[1], arg[2])
}},
UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
kind, name, file, size := _cache_upload(m, m.R)
_cache_save(m, kind, name, "", file, size)
}},
DOWNLOAD: {Name: "download type name", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
if r, ok := m.Optionv(RESPONSE).(*http.Response); ok {
file, size := _cache_download(m, r)
_cache_save(m, arg[0], arg[1], "", file, size)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg), "time,hash,size,type,name,text")
if m.Cmdy(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
return
}
if m.Append(kit.MDB_FILE) == "" {
m.Push(kit.MDB_LINK, m.Append(kit.MDB_TEXT))
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
CACHE: {Name: CACHE, Help: "缓存池", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_TEXT, kit.MDB_SHORT, "time,hash,size,type,name,text",
kit.MDB_STORE, ice.VAR_DATA, kit.MDB_PATH, ice.VAR_FILE, kit.MDB_FSIZE, "200000",
kit.MDB_LIMIT, "50", kit.MDB_LEAST, "30",
)},
}, Commands: map[string]*ice.Command{
"/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) {
if kit.Format(value[kit.MDB_FILE]) != "" {
m.RenderDownload(value[kit.MDB_FILE])
} else {
m.PushAnchor(DOWNLOAD, kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+arg[0]))
m.RenderResult(value[kit.MDB_TEXT])
}
})
}},
CACHE: {Name: "cache hash auto", Help: "缓存池", Action: ice.MergeAction(map[string]*ice.Action{
WATCH: {Name: "watch key file", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
_cache_watch(m, arg[0], arg[1])
}},
CATCH: {Name: "catch type name", Help: "捕获", Hand: func(m *ice.Message, arg ...string) {
file, size := _cache_catch(m, arg[1])
_cache_save(m, arg[0], arg[1], "", file, size)
}},
WRITE: {Name: "write type name text", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_cache_save(m, arg[0], arg[1], arg[2])
}},
UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
kind, name, file, size := _cache_upload(m, m.R)
_cache_save(m, kind, name, "", file, size)
}},
DOWNLOAD: {Name: "download type name", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
if r, ok := m.Optionv(RESPONSE).(*http.Response); ok {
file, size := _cache_download(m, r)
_cache_save(m, arg[0], arg[1], "", file, size)
}
}},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if mdb.HashSelect(m, arg...); len(arg) == 0 {
return
}
"/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) {
if kit.Format(value[kit.MDB_FILE]) == "" {
m.RenderDownload(value[kit.MDB_FILE])
} else {
m.RenderResult(value[kit.MDB_TEXT])
}
})
}},
}})
if m.Append(kit.MDB_FILE) == "" {
m.PushScript("inner", m.Append(kit.MDB_TEXT))
} else {
m.PushDownload(m.Append(kit.MDB_NAME), kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+arg[0]))
}
}},
}})
}

View File

@ -16,15 +16,15 @@ import (
)
func _dream_list(m *ice.Message) {
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "time,size,name").Table(func(index int, value map[string]string, head []string) {
m.Cmdy(nfs.DIR, m.Config(kit.MDB_PATH), "time,size,name").Table(func(index int, value map[string]string, head []string) {
if m.Richs(SPACE, nil, value[kit.MDB_NAME], func(key string, value map[string]interface{}) {
m.Push(kit.MDB_TYPE, value[kit.MDB_TYPE])
m.Push(kit.MDB_STATUS, tcp.START)
m.PushButton(tcp.STOP)
m.Push(kit.MDB_STATUS, cli.START)
m.PushButton(cli.STOP)
}) == nil {
m.Push(kit.MDB_TYPE, WORKER)
m.Push(kit.MDB_STATUS, tcp.STOP)
m.PushButton(tcp.START)
m.Push(kit.MDB_STATUS, cli.STOP)
m.PushButton(cli.START)
}
})
m.SortStrR(kit.MDB_TIME)
@ -36,9 +36,9 @@ func _dream_show(m *ice.Message, name string) {
m.Option(kit.MDB_NAME, name)
// 任务目录
p := path.Join(m.Conf(DREAM, kit.META_PATH), name)
p := path.Join(m.Config(kit.MDB_PATH), name)
if m.Option(kit.SSH_REPOS) != "" { // 下载源码
m.Cmd("web.code.git.repos", mdb.CREATE, kit.SSH_REPOS, m.Option(kit.SSH_REPOS), kit.MDB_PATH, p)
m.Cmd("web.code.git.repos", mdb.CREATE, m.OptionSimple(kit.SSH_REPOS), kit.MDB_PATH, p)
} else { // 创建目录
os.MkdirAll(p, ice.MOD_DIR)
}
@ -62,7 +62,7 @@ func _dream_show(m *ice.Message, name string) {
// 任务脚本
miss := path.Join(p, ice.ETC_MISS_SH)
if _, e := os.Stat(miss); os.IsNotExist(e) {
m.Cmd(nfs.SAVE, miss, m.Conf(DREAM, kit.Keym("miss")))
m.Cmd(nfs.SAVE, miss, m.Config("miss"))
}
if b, e := ioutil.ReadFile(path.Join(p, m.Conf(gdb.SIGNAL, kit.Keym(cli.PID)))); e == nil {
@ -77,13 +77,12 @@ func _dream_show(m *ice.Message, name string) {
m.Optionv(cli.CMD_ENV, kit.Simple(
cli.CTX_DEV, "http://:"+m.Cmd(SERVE).Append(tcp.PORT),
cli.PATH, kit.Path(path.Join(p, ice.BIN))+":"+kit.Path(ice.BIN)+":"+os.Getenv(cli.PATH),
"USER", ice.Info.UserName, m.Confv(DREAM, kit.Keym(cli.ENV)),
cli.USER, ice.Info.UserName, m.Confv(DREAM, kit.Keym(cli.ENV)),
))
// 启动任务
kit.Path(os.Args[0])
m.Optionv(cli.CMD_ERRPUT, path.Join(p, m.Conf(DREAM, kit.Keym(cli.ENV, "ctx_log"))))
m.Cmd(cli.DAEMON, m.Confv(DREAM, kit.Keym(ice.CMD)), ice.DEV, ice.DEV, kit.MDB_NAME, name, RIVER, m.Option(RIVER))
// 启动任务
m.Optionv(cli.CMD_OUTPUT, path.Join(p, m.Config(kit.Keys(cli.ENV, cli.CTX_LOG))))
m.Cmd(cli.DAEMON, m.Confv(DREAM, kit.Keym(ice.CMD)), ice.DEV, ice.DEV, kit.MDB_NAME, name, m.OptionSimple(RIVER))
m.Event(DREAM_CREATE, kit.MDB_TYPE, m.Option(kit.MDB_TYPE), kit.MDB_NAME, name)
m.Sleep(ice.MOD_TICK)
}
@ -98,50 +97,41 @@ const (
const DREAM = "dream"
func init() {
Index.Merge(&ice.Context{
Commands: map[string]*ice.Command{
DREAM: {Name: "dream name path auto start create", Help: "梦想家", Action: map[string]*ice.Action{
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case kit.MDB_NAME:
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "name,time")
case kit.MDB_TEMPLATE:
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "path,size,time")
m.SortStrR(kit.MDB_PATH)
}
}},
mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg)
m.ProcessInner()
}},
cli.START: {Name: "start name repos river", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
if m.Option(kit.MDB_NAME) == ice.OPS {
m.Option(kit.MDB_NAME, "")
}
_dream_show(m, m.Option(kit.MDB_NAME, kit.Select(path.Base(m.Option(kit.SSH_REPOS)), m.Option(kit.MDB_NAME))))
}},
cli.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(kit.MDB_NAME), "exit", "0")
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
_dream_list(m)
return
}
m.Option(nfs.DIR_ROOT, path.Join(m.Conf(DREAM, kit.META_PATH), arg[0]))
if len(arg) == 1 || strings.HasSuffix(arg[1], "/") {
m.Cmdy(nfs.DIR, arg[1:])
} else {
m.Cmdy(nfs.CAT, arg[1:])
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
DREAM: {Name: "dream name path auto start create", Help: "梦想家", Action: map[string]*ice.Action{
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case kit.MDB_NAME:
m.Cmdy(nfs.DIR, m.Config(kit.MDB_PATH), "name,time")
case kit.MDB_TEMPLATE:
m.Cmdy(nfs.DIR, m.Config(kit.MDB_PATH), "path,size,time")
m.SortStrR(kit.MDB_PATH)
}
}},
},
Configs: map[string]*ice.Config{
DREAM: {Name: DREAM, Help: "梦想家", Value: kit.Data(kit.MDB_PATH, ice.USR_LOCAL_WORK,
ice.CMD, []interface{}{"ice.bin", SPACE, tcp.DIAL},
cli.ENV, kit.Dict(cli.CTX_LOG, ice.BIN_BOOT_LOG),
"miss", `#!/bin/bash
mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg)
m.ProcessInner()
}},
cli.START: {Name: "start name repos river", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
_dream_show(m, m.Option(kit.MDB_NAME, kit.Select(path.Base(m.Option(kit.SSH_REPOS)), m.Option(kit.MDB_NAME))))
}},
cli.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(kit.MDB_NAME), "exit", "0")
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
_dream_list(m)
return
}
m.Option(nfs.DIR_ROOT, path.Join(m.Config(kit.MDB_PATH), arg[0]))
m.Cmdy(nfs.CAT, arg[1:])
}},
}, Configs: map[string]*ice.Config{
DREAM: {Name: DREAM, Help: "梦想家", Value: kit.Data(kit.MDB_PATH, ice.USR_LOCAL_WORK,
ice.CMD, []interface{}{"ice.bin", SPACE, tcp.DIAL},
cli.ENV, kit.Dict(cli.CTX_LOG, ice.BIN_BOOT_LOG),
"miss", `#!/bin/bash
if [ "$ISH_CONF_PRE" = "" ]; then
[ -f $PWD/.ish/plug.sh ] || [ -f $HOME/.ish/plug.sh ] || git clone ${ISH_CONF_HUB_PROXY:="https://"}shylinux.com/x/intshell $PWD/.ish
source $PWD/.ish/plug.sh || source $HOME/.ish/plug.sh
@ -168,7 +158,6 @@ ish_miss_prepare_contexts
make
`,
)},
},
})
)},
}})
}

View File

@ -8,6 +8,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
kit "shylinux.com/x/toolkits"
)
@ -93,3 +94,18 @@ func RenderType(w http.ResponseWriter, name, mime string) {
default:
}
}
type Buffer struct {
m *ice.Message
n string
}
func (b *Buffer) Write(buf []byte) (int, error) {
b.m.Cmd(SPACE, b.n, "grow", string(buf))
return len(buf), nil
}
func (b *Buffer) Close() error { return nil }
func PushStream(m *ice.Message) {
m.Option(cli.CMD_OUTPUT, &Buffer{m: m, n: m.Option(ice.MSG_DAEMON)})
}

View File

@ -66,78 +66,76 @@ func _route_list(m *ice.Message) {
const ROUTE = "route"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
ROUTE: {Name: ROUTE, Help: "路由器", Value: kit.Data(kit.MDB_SHORT, kit.SSH_ROUTE)},
},
Commands: map[string]*ice.Command{
ROUTE: {Name: "route route ctx cmd auto invite share", Help: "路由器", Action: map[string]*ice.Action{
SHARE: {Name: "share", Help: "共享", Hand: func(m *ice.Message, arg ...string) {
p := kit.MergeURL(m.Option(ice.MSG_USERWEB), SHARE, m.Cmdx(SHARE, mdb.CREATE, kit.MDB_TYPE, LOGIN))
m.EchoAnchor(p)
m.EchoScript(p)
m.EchoQRCode(p)
}},
aaa.INVITE: {Name: "invite", Help: "脚本", Hand: func(m *ice.Message, arg ...string) {
for _, k := range []string{"tmux", "base", "miss"} {
m.Cmdy("web.code.publish", ice.CONTEXTS, k)
}
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
ROUTE: {Name: ROUTE, Help: "路由器", Value: kit.Data(kit.MDB_SHORT, kit.SSH_ROUTE)},
}, Commands: map[string]*ice.Command{
ROUTE: {Name: "route route ctx cmd auto invite share", Help: "路由器", Action: map[string]*ice.Action{
SHARE: {Name: "share", Help: "共享", Hand: func(m *ice.Message, arg ...string) {
p := kit.MergeURL(m.Option(ice.MSG_USERWEB), SHARE, m.Cmdx(SHARE, mdb.CREATE, kit.MDB_TYPE, LOGIN))
m.EchoAnchor(p)
m.EchoScript(p)
m.EchoQRCode(p)
}},
aaa.INVITE: {Name: "invite", Help: "脚本", Hand: func(m *ice.Message, arg ...string) {
for _, k := range []string{"tmux", "base", "miss"} {
m.Cmdy("web.code.publish", ice.CONTEXTS, k)
}
m.EchoScript("shell", "# 共享环境", m.Option(ice.MSG_USERWEB))
m.EchoQRCode(m.Option(ice.MSG_USERWEB))
m.EchoAnchor(m.Option(ice.MSG_USERWEB))
}},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
switch m.Option(ctx.ACTION) {
case mdb.CREATE:
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.INPUTS, arg)
return
}
m.EchoScript("shell", "# 共享环境", m.Option(ice.MSG_USERWEB))
m.EchoQRCode(m.Option(ice.MSG_USERWEB))
m.EchoAnchor(m.Option(ice.MSG_USERWEB))
}},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
switch m.Option(ctx.ACTION) {
case mdb.CREATE:
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.INPUTS, arg)
return
}
switch arg[0] {
case kit.MDB_NAME:
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "name,size,time")
m.SortStrR(kit.MDB_PATH)
switch arg[0] {
case kit.MDB_NAME:
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "name,size,time")
m.SortStrR(kit.MDB_PATH)
case kit.MDB_TEMPLATE:
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "path,size,time")
m.SortStrR(kit.MDB_PATH)
}
}},
mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg)
m.ProcessInner()
}},
tcp.START: {Name: "start name repos template", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), DREAM, tcp.START, arg)
m.ProcessInner()
}},
ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
m.Debug(m.Option(ROUTE))
m.Cmdy(SPACE, m.Option(ROUTE), kit.Keys(m.Option(ice.CTX), m.Option(ice.CMD)), arg)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" { // 路由列表
if _route_travel(m, kit.Select("", arg, 0)); m.W != nil {
_route_list(m)
}
} else if len(arg) > 2 { // 加载插件
m.ShowPlugin(arg[0], arg[1], arg[2], ctx.ACTION, ctx.COMMAND)
} else if len(arg) > 1 { // 命令列表
m.Cmd(SPACE, arg[0], ctx.CONTEXT, arg[1], ctx.COMMAND).Table(func(index int, value map[string]string, head []string) {
m.Push(ice.CMD, value[kit.MDB_KEY])
m.Push("", value, []string{kit.MDB_NAME, kit.MDB_HELP})
})
} else if len(arg) > 0 { // 模块列表
m.Cmd(SPACE, arg[0], ctx.CONTEXT).Table(func(index int, value map[string]string, head []string) {
m.Push(ice.CTX, kit.Keys(value["ups"], value[kit.MDB_NAME]))
m.Push("", value, []string{ice.CTX_STATUS, ice.CTX_STREAM, kit.MDB_HELP})
})
case kit.MDB_TEMPLATE:
m.Cmdy(nfs.DIR, m.Conf(DREAM, kit.META_PATH), "path,size,time")
m.SortStrR(kit.MDB_PATH)
}
}},
}})
mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg)
m.ProcessInner()
}},
tcp.START: {Name: "start name repos template", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), DREAM, tcp.START, arg)
m.ProcessInner()
}},
ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
m.Debug(m.Option(ROUTE))
m.Cmdy(SPACE, m.Option(ROUTE), kit.Keys(m.Option(ice.CTX), m.Option(ice.CMD)), arg)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 || arg[0] == "" { // 路由列表
if _route_travel(m, kit.Select("", arg, 0)); m.W != nil {
_route_list(m)
}
} else if len(arg) > 2 { // 加载插件
m.ShowPlugin(arg[0], arg[1], arg[2], ctx.ACTION, ctx.COMMAND)
} else if len(arg) > 1 { // 命令列表
m.Cmd(SPACE, arg[0], ctx.CONTEXT, arg[1], ctx.COMMAND).Table(func(index int, value map[string]string, head []string) {
m.Push(ice.CMD, value[kit.MDB_KEY])
m.Push("", value, []string{kit.MDB_NAME, kit.MDB_HELP})
})
} else if len(arg) > 0 { // 模块列表
m.Cmd(SPACE, arg[0], ctx.CONTEXT).Table(func(index int, value map[string]string, head []string) {
m.Push(ice.CTX, kit.Keys(value["ups"], value[kit.MDB_NAME]))
m.Push("", value, []string{ice.CTX_STATUS, ice.CTX_STREAM, kit.MDB_HELP})
})
}
}},
}})
}

View File

@ -37,7 +37,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
m.Info("").Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL)
// 参数日志
if m.Conf(SERVE, kit.Keym(LOGHEADERS)) == ice.TRUE {
if m.Config(LOGHEADERS) == ice.TRUE {
for k, v := range r.Header {
m.Info("%s: %v", k, kit.Format(v))
}
@ -67,7 +67,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
msg := m.Spawn()
msg.W, msg.R = w, r
repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get("User-Agent"), "Mozilla/5.0"))
Render(msg, ice.RENDER_DOWNLOAD, path.Join(m.Conf(SERVE, kit.Keym(repos, kit.MDB_PATH)), m.Conf(SERVE, kit.Keym(repos, kit.MDB_INDEX))))
Render(msg, ice.RENDER_DOWNLOAD, path.Join(m.Config(kit.Keys(repos, kit.MDB_PATH)), m.Config(kit.Keys(repos, kit.MDB_INDEX))))
return false
}
@ -107,7 +107,6 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
}
// 请求变量
_serve_params(msg, r.URL.Path)
if u, e := url.Parse(r.Header.Get("Referer")); e == nil {
_serve_params(msg, u.Path)
for k, v := range u.Query() {
@ -115,6 +114,7 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
msg.Option(k, v)
}
}
_serve_params(msg, r.URL.Path)
// 请求地址
msg.Option(ice.MSG_USERWEB, kit.Select(msg.Conf(SHARE, kit.Keym(kit.MDB_DOMAIN)), r.Header.Get("Referer")))
@ -142,7 +142,7 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
}
}
default:
r.ParseMultipartForm(kit.Int64(kit.Select(r.Header.Get(ContentLength), "4096")))
r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength))))
if r.ParseForm(); len(r.PostForm) > 0 {
for k, v := range r.PostForm {
msg.Logs("form", k, v)
@ -152,11 +152,9 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
// 请求参数
for k, v := range r.Form {
if r.Header.Get(ContentType) != ContentJSON {
if msg.IsCliUA() {
for i, p := range v {
v[i], _ = url.QueryUnescape(p)
}
if msg.IsCliUA() {
for i, p := range v {
v[i], _ = url.QueryUnescape(p)
}
}
if msg.Optionv(k, v); k == ice.MSG_SESSID {
@ -191,7 +189,7 @@ func _serve_login(msg *ice.Message, cmds []string, w http.ResponseWriter, r *htt
// 会话认证
}
if msg.Option(ice.MSG_USERNAME) == "" && tcp.IsLocalHost(msg, msg.Option(ice.MSG_USERIP)) && msg.Conf(SERVE, kit.Keym(tcp.LOCALHOST)) == ice.TRUE {
if msg.Option(ice.MSG_USERNAME) == "" && msg.Config(tcp.LOCALHOST) == ice.TRUE && tcp.IsLocalHost(msg, msg.Option(ice.MSG_USERIP)) {
aaa.UserRoot(msg)
// 主机认证
}
@ -199,12 +197,12 @@ func _serve_login(msg *ice.Message, cmds []string, w http.ResponseWriter, r *htt
if _, ok := msg.Target().Commands[WEB_LOGIN]; ok {
// 权限检查
msg.Target().Cmd(msg, WEB_LOGIN, cmds...)
return cmds, msg.Result(0) != ice.ErrWarn && msg.Result() != ice.FALSE
return cmds, msg.Result(0) != ice.ErrWarn && msg.Result(0) != ice.FALSE
}
if ls := strings.Split(r.URL.Path, "/"); msg.Conf(SERVE, kit.Keym(aaa.BLACK, ls[1])) == ice.TRUE {
if ls := strings.Split(r.URL.Path, "/"); msg.Config(kit.Keys(aaa.BLACK, ls[1])) == ice.TRUE {
return cmds, false // 黑名单
} else if msg.Conf(SERVE, kit.Keym(aaa.WHITE, ls[1])) == ice.TRUE {
} else if msg.Config(kit.Keys(aaa.WHITE, ls[1])) == ice.TRUE {
if msg.Option(ice.MSG_USERNAME) == "" && msg.Option(SHARE) != "" {
switch share := msg.Cmd(SHARE, msg.Option(SHARE)); share.Append(kit.MDB_TYPE) {
case LOGIN:
@ -236,82 +234,86 @@ const (
const SERVE = "serve"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
SERVE: {Name: SERVE, Help: "服务器", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME,
tcp.LOCALHOST, true, aaa.BLACK, kit.Dict(), aaa.WHITE, kit.Dict(
LOGIN, true, SPACE, true, SHARE, true,
ice.VOLCANOS, true, ice.INTSHELL, true,
ice.REQUIRE, true, ice.PUBLISH, true,
"x", true, ice.PUBLISH, true,
), LOGHEADERS, false,
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
SERVE: {Name: SERVE, Help: "服务器", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_FIELD, "time,status,name,port,dev",
tcp.LOCALHOST, ice.TRUE, aaa.BLACK, kit.Dict(), aaa.WHITE, kit.Dict(
LOGIN, ice.TRUE, SHARE, ice.TRUE, SPACE, ice.TRUE,
ice.VOLCANOS, ice.TRUE, ice.PUBLISH, ice.TRUE,
ice.INTSHELL, ice.TRUE, ice.REQUIRE, ice.TRUE,
"x", ice.TRUE,
), LOGHEADERS, ice.FALSE,
"static", kit.Dict("/", ice.USR_VOLCANOS),
ice.VOLCANOS, kit.Dict(kit.MDB_PATH, ice.USR_VOLCANOS, kit.MDB_INDEX, "page/index.html",
kit.SSH_REPOS, "https://shylinux.com/x/volcanos", kit.SSH_BRANCH, kit.SSH_MASTER,
), ice.PUBLISH, ice.USR_PUBLISH,
kit.MDB_PATH, kit.Dict("/", ice.USR_VOLCANOS),
ice.VOLCANOS, kit.Dict(kit.MDB_PATH, ice.USR_VOLCANOS, kit.MDB_INDEX, "page/index.html",
kit.SSH_REPOS, "https://shylinux.com/x/volcanos", kit.SSH_BRANCH, kit.SSH_MASTER,
), ice.PUBLISH, ice.USR_PUBLISH,
ice.INTSHELL, kit.Dict(kit.MDB_PATH, ice.USR_INTSHELL, kit.MDB_INDEX, ice.INDEX_SH,
kit.SSH_REPOS, "https://shylinux.com/x/intshell", kit.SSH_BRANCH, kit.SSH_MASTER,
), ice.REQUIRE, ".ish/pluged",
)},
},
Commands: map[string]*ice.Command{
SERVE: {Name: "serve name auto start", Help: "服务器", Action: map[string]*ice.Action{
aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
for _, k := range arg {
m.Conf(SERVE, kit.Keys(kit.MDB_META, aaa.BLACK, k), true)
}
}},
aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
for _, k := range arg {
m.Conf(SERVE, kit.Keys(kit.MDB_META, aaa.WHITE, k), true)
}
}},
cli.START: {Name: "start dev name=ops proto=http host port=9020", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
if cli.NodeInfo(m, SERVER, ice.Info.HostName); m.Option(tcp.PORT) == tcp.RANDOM {
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
}
m.Target().Start(m, kit.MDB_NAME, m.Option(kit.MDB_NAME), tcp.HOST, m.Option(tcp.HOST), tcp.PORT, m.Option(tcp.PORT))
m.Sleep(ice.MOD_TICK)
m.Option(kit.MDB_NAME, "")
for _, k := range kit.Split(m.Option(ice.DEV)) {
m.Cmd(SPACE, tcp.DIAL, ice.DEV, k, kit.MDB_NAME, ice.Info.NodeName)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg), "time,status,name,port,dev")
m.Cmdy(mdb.SELECT, SERVE, "", mdb.HASH, kit.MDB_NAME, arg)
}},
"/volcanos/": {Name: "/volcanos/", Help: "浏览器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderIndex(SERVE, ice.VOLCANOS, arg...)
}},
"/intshell/": {Name: "/intshell/", Help: "命令行", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderIndex(SERVE, ice.INTSHELL, arg...)
}},
"/publish/": {Name: "/publish/", Help: "私有云", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if arg[0] == ice.ORDER_JS {
if p := path.Join(ice.USR_PUBLISH, ice.ORDER_JS); m.PodCmd(nfs.CAT, p) {
m.RenderResult()
return
}
ice.INTSHELL, kit.Dict(kit.MDB_PATH, ice.USR_INTSHELL, kit.MDB_INDEX, ice.INDEX_SH,
kit.SSH_REPOS, "https://shylinux.com/x/intshell", kit.SSH_BRANCH, kit.SSH_MASTER,
), ice.REQUIRE, ".ish/pluged",
)},
}, Commands: map[string]*ice.Command{
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Done(true)
m.Cmd(SERVE).Table(func(index int, value map[string]string, head []string) {
m.Done(value[kit.MDB_STATUS] == tcp.START)
})
}},
SERVE: {Name: "serve name auto start", Help: "服务器", Action: ice.MergeAction(map[string]*ice.Action{
aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
for _, k := range arg {
m.Config(kit.Keys(aaa.BLACK, k), ice.TRUE)
}
_share_local(m, m.Conf(SERVE, kit.Keym(ice.PUBLISH)), path.Join(arg...))
}},
"/require/": {Name: "/require/", Help: "公有云", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_repos(m, path.Join(arg[0], arg[1], arg[2]), arg[3:]...)
}},
"/help/": {Name: "/help/", Help: "帮助", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
arg = append(arg, "tutor.shy")
aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
for _, k := range arg {
m.Config(kit.Keys(aaa.WHITE, k), ice.TRUE)
}
if len(arg) > 0 && arg[0] != ctx.ACTION {
arg[0] = "src/help/" + arg[0]
}
m.Cmdy("web.chat./cmd/", arg)
}},
}})
cli.START: {Name: "start dev name=ops proto=http host port=9020", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
if cli.NodeInfo(m, SERVER, ice.Info.HostName); m.Option(tcp.PORT) == tcp.RANDOM {
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
}
m.Target().Start(m, m.OptionSimple(kit.MDB_NAME, tcp.HOST, tcp.PORT)...)
m.Sleep(ice.MOD_TICK)
m.Option(kit.MDB_NAME, "")
for _, k := range kit.Split(m.Option(ice.DEV)) {
m.Cmd(SPACE, tcp.DIAL, ice.DEV, k, kit.MDB_NAME, ice.Info.NodeName)
}
}},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
mdb.HashSelect(m, arg...)
}},
"/intshell/": {Name: "/intshell/", Help: "命令行", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderIndex(SERVE, ice.INTSHELL, arg...)
}},
"/volcanos/": {Name: "/volcanos/", Help: "浏览器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderIndex(SERVE, ice.VOLCANOS, arg...)
}},
"/require/": {Name: "/require/", Help: "代码库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_repos(m, path.Join(arg[0], arg[1], arg[2]), arg[3:]...)
}},
"/publish/": {Name: "/publish/", Help: "定制化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if arg[0] == ice.ORDER_JS {
if p := path.Join(ice.USR_PUBLISH, ice.ORDER_JS); m.PodCmd(nfs.CAT, p) {
m.RenderResult()
return
}
}
_share_local(m, m.Conf(SERVE, kit.Keym(ice.PUBLISH)), path.Join(arg...))
}},
"/help/": {Name: "/help/", Help: "帮助", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
arg = append(arg, "tutor.shy")
}
if len(arg) > 0 && arg[0] != ctx.ACTION {
arg[0] = "src/help/" + arg[0]
}
m.Cmdy("web.chat./cmd/", arg)
}},
}})
}

View File

@ -19,7 +19,25 @@ import (
func _share_link(m *ice.Message, p string, arg ...interface{}) string {
p = kit.Select("", "/share/local/", !strings.HasPrefix(p, "/")) + p
return tcp.ReplaceLocalhost(m, kit.MergeURL2(kit.Select(m.Option(ice.MSG_USERWEB), m.Conf(SHARE, kit.Keym(kit.MDB_DOMAIN))), p, arg...))
return tcp.ReplaceLocalhost(m, kit.MergeURL2(m.Option(ice.MSG_USERWEB), p, arg...))
}
func _share_repos(m *ice.Message, repos string, arg ...string) {
prefix := kit.Path(m.Conf(SERVE, kit.Keym(ice.REQUIRE)))
if _, e := os.Stat(path.Join(prefix, repos)); e != nil { // 克隆代码
m.Cmd("web.code.git.repos", mdb.CREATE, kit.SSH_REPOS, "https://"+repos, kit.MDB_PATH, path.Join(prefix, repos))
}
m.RenderDownload(path.Join(prefix, repos, path.Join(arg...)))
}
func _share_proxy(m *ice.Message, arg ...string) {
switch p := path.Join(ice.VAR_PROXY, m.Option(ice.POD), m.Option(kit.MDB_PATH)); m.R.Method {
case http.MethodGet: // 下发文件
m.RenderDownload(path.Join(p, m.Option(kit.MDB_NAME)))
case http.MethodPost: // 上传文件
m.Cmdy(CACHE, UPLOAD)
m.Cmdy(CACHE, WATCH, m.Option(kit.MDB_DATA), p)
m.RenderResult(m.Option(kit.MDB_PATH))
}
}
func _share_cache(m *ice.Message, arg ...string) {
if pod := m.Option(ice.POD); m.PodCmd(CACHE, arg[0]) {
@ -64,7 +82,7 @@ func _share_local(m *ice.Message, arg ...string) {
p = pp
}
}
if p == path.Join(ice.USR_PUBLISH, ice.ORDER_JS) {
if strings.HasSuffix(p, path.Join(ice.USR_PUBLISH, ice.ORDER_JS)) {
if _, e := os.Stat(p); os.IsNotExist(e) {
m.RenderResult("")
return
@ -72,24 +90,6 @@ func _share_local(m *ice.Message, arg ...string) {
}
m.RenderDownload(p)
}
func _share_proxy(m *ice.Message, arg ...string) {
switch p := path.Join(ice.VAR_PROXY, m.Option(ice.POD), m.Option(kit.MDB_PATH)); m.R.Method {
case http.MethodGet: // 下发文件
m.RenderDownload(path.Join(p, m.Option(kit.MDB_NAME)))
case http.MethodPost: // 上传文件
m.Cmdy(CACHE, UPLOAD)
m.Cmdy(CACHE, WATCH, m.Option(kit.MDB_DATA), p)
m.RenderResult(m.Option(kit.MDB_PATH))
}
}
func _share_repos(m *ice.Message, repos string, arg ...string) {
prefix := kit.Path(m.Conf(SERVE, kit.Keym(ice.REQUIRE)))
if _, e := os.Stat(path.Join(prefix, repos)); e != nil { // 克隆代码
m.Cmd("web.code.git.repos", mdb.CREATE, kit.SSH_REPOS, "https://"+repos, kit.MDB_PATH, path.Join(prefix, repos))
}
m.RenderDownload(path.Join(prefix, repos, path.Join(arg...)))
}
const (
LOGIN = "login"
@ -100,84 +100,79 @@ const (
const SHARE = "share"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
SHARE: {Name: SHARE, Help: "共享链", Value: kit.Data(
kit.MDB_EXPIRE, "72h", kit.MDB_FIELD, "time,hash,userrole,username,river,storm,type,name,text",
)},
},
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
ice.AddRender(ice.RENDER_DOWNLOAD, func(m *ice.Message, cmd string, args ...interface{}) string {
list := []string{}
if m.Option(ice.MSG_USERPOD) != "" {
list = append(list, ice.POD, m.Option(ice.MSG_USERPOD))
}
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
SHARE: {Name: SHARE, Help: "共享链", Value: kit.Data(
kit.MDB_EXPIRE, "72h", kit.MDB_FIELD, "time,hash,userrole,username,river,storm,type,name,text",
)},
}, Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
ice.AddRender(ice.RENDER_DOWNLOAD, func(msg *ice.Message, cmd string, args ...interface{}) string {
list := []string{}
if msg.Option(ice.MSG_USERPOD) != "" {
list = append(list, ice.POD, msg.Option(ice.MSG_USERPOD))
}
arg := kit.Simple(args...)
if len(arg) > 1 {
list = append(list, "filename", arg[0])
}
return fmt.Sprintf(`<a href="%s" download="%s">%s</a>`,
_share_link(m, kit.Select(arg[0], arg, 1), list), path.Base(arg[0]), arg[0])
})
}},
SHARE: {Name: "share hash auto prunes", Help: "共享链", Action: ice.MergeAction(map[string]*ice.Action{
mdb.CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, kit.MDB_TIME, m.Time(m.Config(kit.MDB_EXPIRE)),
aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME),
RIVER, m.Option(ice.MSG_RIVER), STORM, m.Option(ice.MSG_STORM), arg)
// m.Option(kit.MDB_LINK, _share_link(m, "/share/"+m.Result()))
m.Option(kit.MDB_LINK, kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/"+m.Result()))
}},
LOGIN: {Name: "login userrole=void,tech username", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
msg := m.Cmd(SHARE, mdb.CREATE, kit.MDB_TYPE, LOGIN, m.OptionSimple(aaa.USERROLE, aaa.USERNAME))
m.EchoQRCode(msg.Option(kit.MDB_LINK))
m.ProcessInner()
}},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if m.PodCmd(SHARE, arg) {
return
arg := kit.Simple(args...)
if len(arg) > 1 {
list = append(list, "filename", arg[0])
}
m.Fields(len(arg), m.Conf(SHARE, kit.META_FIELD))
if m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.HASH, kit.MDB_HASH, arg); len(arg) > 0 {
link := _share_link(m, "/share/"+arg[0])
m.PushQRCode(cli.QRCODE, link)
m.PushScript(ssh.SCRIPT, link)
m.PushAnchor(link)
} else {
m.Action(LOGIN)
}
m.PushAction(mdb.REMOVE)
m.StatusTimeCount()
return fmt.Sprintf(`<a href="%s" download="%s">%s</a>`,
_share_link(msg, kit.Select(arg[0], arg, 1), list), path.Base(arg[0]), arg[0])
})
}},
SHARE: {Name: "share hash auto prunes", Help: "共享链", Action: ice.MergeAction(map[string]*ice.Action{
mdb.CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, kit.MDB_TIME, m.Time(m.Config(kit.MDB_EXPIRE)),
aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME),
RIVER, m.Option(ice.MSG_RIVER), STORM, m.Option(ice.MSG_STORM), arg)
m.Option(kit.MDB_LINK, _share_link(m, "/share/"+m.Result()))
}},
"/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(SHARE, kit.Select(m.Option(SHARE), arg, 0))
if msg := m.Cmd(SHARE, m.Option(SHARE)); kit.Int(msg.Append(kit.MDB_TIME)) < kit.Int(msg.FormatTime()) {
m.RenderResult("共享超时")
return
}
m.RenderIndex(SERVE, ice.VOLCANOS)
LOGIN: {Name: "login userrole=void,tech username", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
msg := m.Cmd(SHARE, mdb.CREATE, kit.MDB_TYPE, LOGIN, m.OptionSimple(aaa.USERROLE, aaa.USERNAME))
m.EchoQRCode(msg.Option(kit.MDB_LINK))
m.ProcessInner()
}},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if m.PodCmd(SHARE, arg) {
return
}
if mdb.HashSelect(m, arg...); len(arg) > 0 {
link := _share_link(m, "/share/"+arg[0])
m.PushQRCode(cli.QRCODE, link)
m.PushScript(ssh.SCRIPT, link)
m.PushAnchor(link)
} else {
m.Action(LOGIN)
}
m.PushAction(mdb.REMOVE)
m.StatusTimeCount()
}},
"/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(SHARE, kit.Select(m.Option(SHARE), arg, 0))
if msg := m.Cmd(SHARE, m.Option(SHARE)); kit.Int(msg.Append(kit.MDB_TIME)) < kit.Int(msg.FormatTime()) {
m.RenderResult("共享超时")
return
}
m.RenderIndex(SERVE, ice.VOLCANOS)
}},
"/share/cache/": {Name: "/share/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_cache(m, arg...)
}},
"/share/proxy/": {Name: "/share/proxy/", Help: "文件流", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_proxy(m, arg...)
}},
"/share/repos/": {Name: "/share/repos/", Help: "代码库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_repos(m, path.Join(arg[0], arg[1], arg[2]), arg[3:]...)
}},
"/share/local/": {Name: "/share/local/", Help: "文件夹", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_local(m, arg...)
}},
"/share/local/avatar": {Name: "avatar", Help: "头像", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME)).Append(aaa.AVATAR), "/share/local/"))
}},
"/share/local/background": {Name: "background", Help: "壁纸", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME)).Append(aaa.BACKGROUND), "/share/local/"))
}},
},
})
"/share/repos/": {Name: "/share/repos/", Help: "代码库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_repos(m, path.Join(arg[0], arg[1], arg[2]), arg[3:]...)
}},
"/share/proxy/": {Name: "/share/proxy/", Help: "文件流", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_proxy(m, arg...)
}},
"/share/cache/": {Name: "/share/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_cache(m, arg...)
}},
"/share/local/": {Name: "/share/local/", Help: "文件夹", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_local(m, arg...)
}},
"/share/local/avatar": {Name: "avatar", Help: "头像", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME)).Append(aaa.AVATAR), "/share/local/"))
}},
"/share/local/background": {Name: "background", Help: "壁纸", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME)).Append(aaa.BACKGROUND), "/share/local/"))
}},
}})
}

View File

@ -3,7 +3,6 @@ package web
import (
"math/rand"
"net"
"net/url"
"strings"
"time"
@ -19,30 +18,21 @@ import (
func _space_link(m *ice.Message, pod string, arg ...interface{}) string {
return tcp.ReplaceLocalhost(m, kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/chat/pod/"+pod, arg...))
}
func _space_domain(m *ice.Message) string {
link := m.Conf(SHARE, kit.Keym(kit.MDB_DOMAIN))
func _space_domain(m *ice.Message) (link string) {
if link == "" {
link = m.Cmd(SPACE, ice.DEV, cli.PWD).Append(kit.MDB_LINK)
}
if link == "" {
link = m.Cmd(SPACE, ice.SHY, cli.PWD).Append(kit.MDB_LINK)
}
if link == "" {
link = m.Option(ice.MSG_USERWEB)
}
if link == "" {
link = kit.Format("http://localhost:%s", m.Cmd(SERVE).Append(tcp.PORT))
}
return tcp.ReplaceLocalhost(m, link)
}
func _space_list(m *ice.Message, space string) {
m.OptionFields(kit.Select(ice.MSG_DETAIL, "time,type,name,text", space == ""))
m.Cmdy(mdb.SELECT, SPACE, "", mdb.HASH, kit.MDB_NAME, space)
if space == "" {
m.Table(func(index int, value map[string]string, head []string) {
m.PushAnchor(value[kit.MDB_NAME], _space_link(m, kit.Keys(m.Option(ice.MSG_USERPOD), value[kit.MDB_NAME])))
})
m.SortStrR(kit.MDB_NAME)
}
}
func _space_dial(m *ice.Message, dev, name string, arg ...string) {
m.Richs(SPIDE, nil, dev, func(key string, value map[string]interface{}) {
client := kit.Value(value, tcp.CLIENT).(map[string]interface{})
@ -53,95 +43,36 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
proto := strings.Replace(kit.Format(client[tcp.PROTOCOL]), "http", "ws", 1)
uri := kit.MergeURL(proto+"://"+host+"/space/", kit.MDB_TYPE, ice.Info.NodeType,
kit.MDB_NAME, name, SHARE, ice.Info.CtxShare, RIVER, kit.Select(ice.Info.CtxRiver, m.Option(RIVER)), arg)
u := kit.ParseURL(uri)
if u, e := url.Parse(uri); m.Assert(e) {
m.Go(func() {
for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ {
msg := m.Spawn()
msg.Option(kit.Keycb(tcp.DIAL), func(s net.Conn, e error) {
if msg.Warn(e != nil, e) {
return
m.Go(func() {
for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ {
msg := m.Spawn()
msg.Option(kit.Keycb(tcp.DIAL), func(s net.Conn, e error) {
if msg.Warn(e != nil, e) {
return
}
if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e != nil, e) {
msg.Rich(SPACE, nil, kit.Dict(SOCKET, s, kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host))
msg.Log_CREATE(SPACE, dev, "retry", i, "uri", uri)
// 连接成功
if i = 0; _space_handle(msg, true, frame.send, s, dev) {
i = -2 // 连接关闭
}
}
})
ls := strings.Split(host, ":")
msg.Cmd(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "wss", kit.MDB_NAME, dev, tcp.HOST, ls[0], tcp.PORT, kit.Select("443", ls, 1))
if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e != nil, e) {
msg.Rich(SPACE, nil, kit.Dict(SOCKET, s, kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host))
msg.Log_CREATE(SPACE, dev, "retry", i, "uri", uri)
// 连接成功
if i = 0; _space_handle(msg, true, frame.send, s, dev) {
i = -2 // 连接关闭
}
}
})
ls := strings.Split(host, ":")
msg.Cmd(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "wss", kit.MDB_NAME, dev, tcp.HOST, ls[0], tcp.PORT, kit.Select("443", ls, 1))
// 断线重连
sleep := time.Duration(rand.Intn(kit.Int(redial["a"])*i+2)+kit.Int(redial["b"])) * time.Millisecond
msg.Cost("order", i, "sleep", sleep, "reconnect", u)
time.Sleep(sleep)
}
})
}
})
}
func _space_send(m *ice.Message, space string, arg ...string) {
if space == "" || space == MYSELF || space == ice.Info.NodeName {
m.Cmdy(arg) // 本地命令
return
}
target := kit.Split(space, ".", ".")
m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) {
if socket, ok := value[SOCKET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, SOCKET) {
// 复制选项
for _, k := range kit.Simple(m.Optionv(ice.MSG_OPTS)) {
switch k {
case ice.MSG_DETAIL, ice.MSG_CMDS, ice.MSG_SESSID:
default:
m.Optionv(k, m.Optionv(k))
}
// 断线重连
sleep := time.Duration(rand.Intn(kit.Int(redial["a"])*i+2)+kit.Int(redial["b"])) * time.Millisecond
msg.Cost("order", i, "sleep", sleep, "reconnect", u)
time.Sleep(sleep)
}
m.Optionv(ice.MSG_OPTS, m.Optionv(ice.MSG_OPTS))
m.Optionv(ice.MSG_OPTION, m.Optionv(ice.MSG_OPTS))
// 构造路由
frame := m.Target().Server().(*Frame)
id := kit.Format(m.Target().ID())
frame.send[id] = m
// 下发命令
_space_echo(m.Set(ice.MSG_DETAIL, arg...), []string{id}, target[1:], socket, target[0])
m.Option("timeout", m.Conf(SPACE, "meta.timeout.c"))
m.Call(m.Option("_async") == "", func(res *ice.Message) *ice.Message {
// 返回结果
if delete(frame.send, id); res != nil && m != nil {
return m.Cost(kit.Format("[%v]->%v %v %v", id, target, arg, m.Copy(res).Format(ice.MSG_APPEND)))
}
return nil
})
}
}) == nil, ice.ErrNotFound, space)
}
func _space_echo(msg *ice.Message, source, target []string, c *websocket.Conn, name string) {
msg.Optionv(ice.MSG_SOURCE, source)
msg.Optionv(ice.MSG_TARGET, target)
msg.Assert(c.WriteMessage(1, []byte(msg.Format(kit.MDB_META))))
target = append([]string{name}, target...)
msg.Log("send", "%v->%v %v %v", source, target, msg.Detailv(), msg.Format(kit.MDB_META))
}
func _space_exec(msg *ice.Message, source, target []string, c *websocket.Conn, name string) {
if !msg.Warn(!msg.Right(msg.Detailv()), ice.ErrNotRight) {
msg = msg.Cmd()
}
msg.Set(ice.MSG_OPTS)
_space_echo(msg, []string{}, kit.Revert(source)[1:], c, name)
msg.Cost(kit.Format("%v->%v %v %v", source, target, msg.Detailv(), msg.Format(ice.MSG_APPEND)))
})
})
}
func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *websocket.Conn, name string) bool {
for running := true; running; {
@ -195,6 +126,63 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w
}
return false
}
func _space_exec(msg *ice.Message, source, target []string, c *websocket.Conn, name string) {
if !msg.Warn(!msg.Right(msg.Detailv()), ice.ErrNotRight) {
msg = msg.Cmd()
}
msg.Set(ice.MSG_OPTS)
_space_echo(msg, []string{}, kit.Revert(source)[1:], c, name)
msg.Cost(kit.Format("%v->%v %v %v", source, target, msg.Detailv(), msg.Format(ice.MSG_APPEND)))
}
func _space_echo(msg *ice.Message, source, target []string, c *websocket.Conn, name string) {
msg.Optionv(ice.MSG_SOURCE, source)
msg.Optionv(ice.MSG_TARGET, target)
msg.Assert(c.WriteMessage(1, []byte(msg.Format(kit.MDB_META))))
target = append([]string{name}, target...)
msg.Log("send", "%v->%v %v %v", source, target, msg.Detailv(), msg.Format(kit.MDB_META))
}
func _space_send(m *ice.Message, space string, arg ...string) {
if space == "" || space == MYSELF || space == ice.Info.NodeName {
m.Cmdy(arg) // 本地命令
return
}
target := kit.Split(space, ice.PT, ice.PT)
m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) {
if socket, ok := value[SOCKET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, SOCKET) {
// 复制选项
for _, k := range kit.Simple(m.Optionv(ice.MSG_OPTS)) {
switch k {
case ice.MSG_DETAIL, ice.MSG_CMDS, ice.MSG_SESSID:
default:
m.Optionv(k, m.Optionv(k))
}
}
m.Optionv(ice.MSG_OPTS, m.Optionv(ice.MSG_OPTS))
m.Optionv(ice.MSG_OPTION, m.Optionv(ice.MSG_OPTS))
// 构造路由
frame := m.Target().Server().(*Frame)
id := kit.Format(m.Target().ID())
frame.send[id] = m
// 下发命令
_space_echo(m.Set(ice.MSG_DETAIL, arg...), []string{id}, target[1:], socket, target[0])
m.Option("timeout", m.Config("timeout.c"))
m.Call(m.Option("_async") == "", func(res *ice.Message) *ice.Message {
// 返回结果
if delete(frame.send, id); res != nil && m != nil {
return m.Cost(kit.Format("[%v]->%v %v %v", id, target, arg, m.Copy(res).Format(ice.MSG_APPEND)))
}
return nil
})
}
}) == nil, ice.ErrNotFound, space)
}
func _space_search(m *ice.Message, kind, name, text string, arg ...string) {
m.Richs(SPACE, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if value = kit.GetMeta(value); !strings.Contains(kit.Format(value[kit.MDB_NAME]), name) {
@ -233,7 +221,6 @@ const (
SERVER = "server"
WORKER = "worker"
)
const (
SPACE_START = "space.start"
SPACE_STOP = "space.stop"
@ -244,29 +231,38 @@ const SPACE = "space"
func init() {
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
SPACE: {Name: SPACE, Help: "空间站", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME,
SPACE: {Name: SPACE, Help: "空间站", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_FIELD, "time,type,name,text",
"redial", kit.Dict("a", 3000, "b", 1000, "c", 1000, "r", ice.MOD_BUFS, "w", ice.MOD_BUFS),
"timeout", kit.Dict("c", "180s"),
)},
}, Commands: map[string]*ice.Command{
SPACE: {Name: "space name cmd auto", Help: "空间站", Action: map[string]*ice.Action{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Conf(SPACE, kit.MDB_HASH, "")
m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE, m.Prefix(SPACE))
}},
SPACE: {Name: "space name cmd auto", Help: "空间站", Action: ice.MergeAction(map[string]*ice.Action{
tcp.DIAL: {Name: "dial dev name river", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
_space_dial(m, m.Option(ice.DEV), kit.Select(ice.Info.NodeName, m.Option(kit.MDB_NAME)))
}},
mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
_space_search(m, arg[0], arg[1], kit.Select("", arg, 2))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 { // 节点列表
_space_list(m, kit.Select("", arg, 0))
if mdb.HashSelect(m, arg...); len(arg) == 0 {
m.Table(func(index int, value map[string]string, head []string) {
m.PushAnchor(value[kit.MDB_NAME], _space_link(m, kit.Keys(m.Option(ice.MSG_USERPOD), value[kit.MDB_NAME])))
})
m.SortStrR(kit.MDB_NAME)
}
return
}
// 下发命令
_space_send(m, arg[0], arg[1:]...)
}},
"/space/": {Name: "/space/ type name share river", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if s, e := websocket.Upgrade(m.W, m.R, nil, kit.Int(m.Conf(SPACE, "meta.buffer.r")), kit.Int(m.Conf(SPACE, "meta.buffer.w"))); m.Assert(e) {
if s, e := websocket.Upgrade(m.W, m.R, nil, kit.Int(m.Config("buffer.r")), kit.Int(m.Config("buffer.w"))); m.Assert(e) {
name := kit.Select(s.RemoteAddr().String(), m.Option(kit.MDB_NAME))
name = m.Option(kit.MDB_NAME, strings.Replace(name, ".", "_", -1))
name = m.Option(kit.MDB_NAME, strings.Replace(name, ":", "-", -1))

View File

@ -14,6 +14,7 @@ import (
"time"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
@ -28,17 +29,17 @@ func _spide_create(m *ice.Message, name, address string) {
dir, file := path.Split(uri.EscapedPath())
m.Echo(m.Rich(SPIDE, nil, kit.Dict(
SPIDE_COOKIE, kit.Dict(), SPIDE_HEADER, kit.Dict(), SPIDE_CLIENT, kit.Dict(
kit.MDB_NAME, name, "url", address, SPIDE_METHOD, SPIDE_POST,
kit.MDB_NAME, name, SPIDE_METHOD, SPIDE_POST, "url", address,
tcp.PROTOCOL, uri.Scheme, tcp.HOSTNAME, uri.Host,
kit.MDB_PATH, dir, kit.MDB_FILE, file, "query", uri.RawQuery,
kit.MDB_TIMEOUT, "600s", LOGHEADERS, false,
kit.MDB_TIMEOUT, "600s", LOGHEADERS, ice.FALSE,
),
)))
}
m.Log_CREATE(SPIDE, name, ADDRESS, address)
}
}
func _spide_show(m *ice.Message, arg ...string) {
func _spide_list(m *ice.Message, arg ...string) {
m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) {
// 缓存方式
cache, save := "", ""
@ -88,7 +89,7 @@ func _spide_show(m *ice.Message, arg ...string) {
return
}
if m.Config("logheaders") == ice.TRUE {
if m.Config(LOGHEADERS) == ice.TRUE {
for k, v := range res.Header {
m.Debug("%v: %v", k, v)
}
@ -101,27 +102,24 @@ func _spide_show(m *ice.Message, arg ...string) {
// 缓存配置
for _, v := range res.Cookies() {
kit.Value(value, kit.Keys(SPIDE_COOKIE, v.Name), v.Value)
m.Log(ice.LOG_IMPORT, "%s: %s", v.Name, v.Value)
m.Log_IMPORT(v.Name, v.Value)
}
// 错误信息
if m.Warn(res.StatusCode != http.StatusOK, res.Status) {
switch m.Set(ice.MSG_RESULT); res.StatusCode {
case http.StatusNotFound:
m.Warn(true, ice.ErrNotFound, " of ", uri)
m.Warn(true, ice.ErrNotFound, ice.OF, uri)
return
case http.StatusUnauthorized:
m.Warn(true, ice.ErrNotRight, " of ", uri)
m.Warn(true, ice.ErrNotRight, ice.OF, uri)
return
default:
}
}
// 解析结果
_spide_save(m, cache, save, uri, res)
})
}
func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, map[string]string, []string) {
head := map[string]string{}
@ -215,18 +213,18 @@ func _spide_head(m *ice.Message, req *http.Request, head map[string]string, valu
})
kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) {
req.AddCookie(&http.Cookie{Name: key, Value: value})
m.Info("%s: %s", key, value)
m.Logs(key, value)
})
list := kit.Simple(m.Optionv(SPIDE_HEADER))
for i := 0; i < len(list)-1; i += 2 {
req.Header.Set(list[i], list[i+1])
m.Info("%s: %s", list[i], list[i+1])
m.Logs(list[i], list[i+1])
}
for k, v := range head {
req.Header.Set(k, v)
}
if req.Method == SPIDE_POST {
m.Info("%s: %s", req.Header.Get(ContentLength), req.Header.Get(ContentType))
m.Logs(req.Header.Get(ContentLength), req.Header.Get(ContentType))
}
}
func _spide_send(m *ice.Message, req *http.Request, timeout string) (*http.Response, error) {
@ -297,20 +295,15 @@ const (
SPIDE_POST = "POST"
SPIDE_DELETE = "DELETE"
SPIDE_BODY = "body"
SPIDE_FORM = "form"
SPIDE_PART = "part"
SPIDE_JSON = "json"
SPIDE_DATA = "data"
SPIDE_FILE = "file"
SPIDE_BODY = "body"
SPIDE_JSON = "json"
SPIDE_RES = "content_data"
SPIDE_CLIENT = "client"
SPIDE_METHOD = "method"
SPIDE_HEADER = "header"
SPIDE_COOKIE = "cookie"
ContentType = "Content-Type"
ContentLength = "Content-Length"
@ -320,6 +313,11 @@ const (
ContentPNG = "image/png"
)
const (
SPIDE_CLIENT = "client"
SPIDE_METHOD = "method"
SPIDE_HEADER = "header"
SPIDE_COOKIE = "cookie"
ADDRESS = "address"
REQUEST = "request"
RESPONSE = "response"
@ -330,46 +328,43 @@ const (
const SPIDE = "spide"
func init() {
Index.Merge(&ice.Context{
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{
SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg run:button create", Help: "蜘蛛侠", Action: ice.MergeAction(map[string]*ice.Action{
mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_spide_create(m, m.Option(kit.MDB_NAME), m.Option(ADDRESS))
}},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
m.Fields(len(kit.Slice(arg, 0, 1)), m.Conf(SPIDE, kit.META_FIELD))
m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.HASH, CLIENT_NAME, arg)
m.PushAction(mdb.REMOVE)
return
}
_spide_show(m, arg...)
Index.Merge(&ice.Context{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, ice.FALSE,
)},
}, Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(SPIDE, mdb.CREATE, ice.OPS, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_ops")))
m.Cmd(SPIDE, mdb.CREATE, ice.DEV, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev")))
m.Cmd(SPIDE, mdb.CREATE, ice.SHY, kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy")))
}},
SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg run:button create", Help: "蜘蛛侠", Action: ice.MergeAction(map[string]*ice.Action{
mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_spide_create(m, m.Option(kit.MDB_NAME), m.Option(ADDRESS))
}},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
mdb.HashSelect(m, kit.Slice(arg, 0, 1)...)
m.PushAction(mdb.REMOVE)
return
}
_spide_list(m, arg...)
}},
SPIDE_GET: {Name: "GET url key value run:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_GET, arg[0], arg[1:]))))
SPIDE_GET: {Name: "GET url key value run:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, m.OptionSimple(CLIENT_NAME))
}},
SPIDE_POST: {Name: "POST url key value run:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 2 {
m.Option(SPIDE_HEADER, ContentType, ContentJSON)
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_POST, arg[0], SPIDE_DATA, arg[1:]))))
return
}
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_POST, arg[0], SPIDE_JSON, arg[1:]))))
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_GET, arg[0], arg[1:]))))
}},
SPIDE_POST: {Name: "POST url key value run:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, m.OptionSimple(CLIENT_NAME))
}},
}})
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_POST, arg[0], arg[1:]))))
}},
}})
}

View File

@ -1,21 +0,0 @@
package web
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli"
)
type Buffer struct {
m *ice.Message
n string
}
func (b *Buffer) Write(buf []byte) (int, error) {
b.m.Cmd(SPACE, b.n, "grow", string(buf))
return len(buf), nil
}
func (b *Buffer) Close() error { return nil }
func PushStream(m *ice.Message) {
m.Option(cli.CMD_OUTPUT, &Buffer{m: m, n: m.Option(ice.MSG_DAEMON)})
}

View File

@ -6,7 +6,6 @@ import (
"path"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
@ -43,7 +42,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
// 静态路由
msg := m.Spawn(s)
m.Confm(SERVE, kit.Keym("static"), func(key string, value string) {
m.Confm(SERVE, kit.META_PATH, func(key string, value string) {
m.Log("route", "%s <- %s <- %s", s.Name, key, value)
w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
})
@ -94,25 +93,7 @@ func (web *Frame) Close(m *ice.Message, arg ...string) bool {
const WEB = "web"
var Index = &ice.Context{Name: WEB, Help: "网络模块", Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
m.Conf(SPACE, kit.MDB_HASH, "")
m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE, m.Prefix(SPACE))
m.Cmd(SPIDE, mdb.CREATE, ice.OPS, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_ops")))
m.Cmd(SPIDE, mdb.CREATE, ice.DEV, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev")))
m.Cmd(SPIDE, mdb.CREATE, ice.SHY, kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy")))
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save()
m.Done(true)
m.Cmd(SERVE).Table(func(index int, value map[string]string, head []string) {
m.Done(value[kit.MDB_STATUS] == tcp.START)
})
}},
}}
var Index = &ice.Context{Name: WEB, Help: "网络模块"}
func init() {
ice.Index.Register(Index, &Frame{},

View File

@ -40,8 +40,7 @@ func init() {
}},
"exit": {Name: "exit", Help: "退出"},
}, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg), mdb.ZONE_FIELD, m.Conf(ROOM, kit.META_FIELD))
m.Cmdy(mdb.SELECT, m.Prefix(ROOM), "", mdb.ZONE, arg)
mdb.ZoneSelect(m, arg...)
}},
JOIN: {Name: "join zone hash auto", Help: "join", Action: ice.MergeAction(map[string]*ice.Action{
mdb.CREATE: {Name: "create zone", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
@ -58,8 +57,7 @@ func init() {
m.Cmdy(mdb.DELETE, m.Prefix(JOIN), kit.KeyHash(m.Option(kit.MDB_ZONE)), mdb.HASH, m.OptionSimple(web.SOCKET))
}},
}), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg), mdb.ZONE_FIELD, m.Conf(JOIN, kit.META_FIELD))
if len(arg) == 0 {
if mdb.ZoneSelect(m, arg...); len(arg) == 0 {
m.Cmdy(mdb.SELECT, m.Prefix(JOIN), "", mdb.HASH)
} else {
m.Cmdy(mdb.SELECT, m.Prefix(JOIN), kit.KeyHash(arg[0]), mdb.HASH, arg[1:])

View File

@ -27,8 +27,7 @@ func init() {
})
}},
}, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg), mdb.ZONE_FIELD, m.Conf(FIELD, kit.META_FIELD))
if m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.ZONE, arg); len(arg) == 0 {
if mdb.ZoneSelect(m, arg...); len(arg) == 0 {
m.PushAction(mdb.REMOVE)
}
}},

View File

@ -24,8 +24,7 @@ func init() {
})
}},
}, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg), mdb.ZONE_FIELD, m.Conf(STYLE, kit.META_FIELD))
if m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.ZONE, arg); len(arg) == 0 {
if mdb.ZoneSelect(m, arg...); len(arg) == 0 {
m.PushAction(mdb.REMOVE)
}
}},