1
0
forked from x/icebergs

opt icebergs

This commit is contained in:
harveyshao 2022-04-10 23:03:58 +08:00
parent a37674abec
commit bc8d965683
29 changed files with 399 additions and 810 deletions

View File

@ -26,14 +26,14 @@ func _role_chain(arg ...string) string {
func _role_black(m *ice.Message, userrole, chain string) { func _role_black(m *ice.Message, userrole, chain string) {
m.Richs(ROLE, nil, userrole, func(key string, value map[string]interface{}) { m.Richs(ROLE, nil, userrole, func(key string, value map[string]interface{}) {
list := value[BLACK].(map[string]interface{}) list := value[BLACK].(map[string]interface{})
m.Log_CREATE(ROLE, userrole, BLACK, chain) m.Log_INSERT(ROLE, userrole, BLACK, chain)
list[chain] = true list[chain] = true
}) })
} }
func _role_white(m *ice.Message, userrole, chain string) { func _role_white(m *ice.Message, userrole, chain string) {
m.Richs(ROLE, nil, userrole, func(key string, value map[string]interface{}) { m.Richs(ROLE, nil, userrole, func(key string, value map[string]interface{}) {
list := value[WHITE].(map[string]interface{}) list := value[WHITE].(map[string]interface{})
m.Log_CREATE(ROLE, userrole, WHITE, chain) m.Log_INSERT(ROLE, userrole, WHITE, chain)
list[chain] = true list[chain] = true
}) })
} }
@ -106,14 +106,14 @@ func init() {
}}, }},
mdb.INSERT: {Name: "insert role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) { mdb.INSERT: {Name: "insert role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) { m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) {
m.Log_CREATE(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) m.Log_INSERT(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY))
list := value[m.Option(mdb.ZONE)].(map[string]interface{}) list := value[m.Option(mdb.ZONE)].(map[string]interface{})
list[m.Option(mdb.KEY)] = true list[m.Option(mdb.KEY)] = true
}) })
}}, }},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) { m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) {
m.Log_REMOVE(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) m.Log_DELETE(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY))
list := value[m.Option(mdb.ZONE)].(map[string]interface{}) list := value[m.Option(mdb.ZONE)].(map[string]interface{})
delete(list, m.Option(mdb.KEY)) delete(list, m.Option(mdb.KEY))
}) })

View File

@ -1,21 +0,0 @@
label `
ctx cli web aaa
lex yac gdb log
tcp nfs ssh mdb
`
source ctx/ctx.shy
source cli/cli.shy
source web/web.shy
source aaa/aaa.shy
source lex/lex.shy
source yac/yac.shy
source gdb/gdb.shy
source log/log.shy
source tcp/tcp.shy
source nfs/nfs.shy
source ssh/ssh.shy
source mdb/mdb.shy

View File

@ -72,15 +72,20 @@ const (
CHECK = "check" CHECK = "check"
BENCH = "bench" BENCH = "bench"
PPROF = "pprof" PPROF = "pprof"
CLEAR = "clear"
TIMEOUT = "timeout" TIMEOUT = "timeout"
STATUS = "status" STATUS = "status"
ERROR = "error" ERROR = "error"
START = "start" CLEAR = "clear"
RESTART = "restart"
RELOAD = "reload" RELOAD = "reload"
RESTART = "restart"
START = "start"
STOP = "stop" STOP = "stop"
OPEN = "open"
CLOSE = "close"
BEGIN = "begin"
END = "end"
CODE = "code" CODE = "code"
COST = "cost" COST = "cost"
@ -88,11 +93,6 @@ const (
FROM = "from" FROM = "from"
MAIN = "main" MAIN = "main"
KILL = "kill" KILL = "kill"
OPEN = "open"
CLOSE = "close"
BEGIN = "begin"
END = "end"
) )
const DAEMON = "daemon" const DAEMON = "daemon"

View File

@ -70,9 +70,9 @@ func CmdAction(fields ...string) map[string]*ice.Action {
const ( const (
ACTION = "action" ACTION = "action"
STYLE = "style"
INDEX = "index" INDEX = "index"
ARGS = "args" ARGS = "args"
STYLE = "style"
DISPLAY = "display" DISPLAY = "display"
) )
const COMMAND = "command" const COMMAND = "command"

View File

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

View File

@ -33,7 +33,7 @@ func _route_travel(m *ice.Message, route string) {
} }
func _route_list(m *ice.Message) { func _route_list(m *ice.Message) {
m.Table(func(index int, value map[string]string, field []string) { m.Table(func(index int, value map[string]string, field []string) {
m.PushAnchor(value[ROUTE], _space_link(m, kit.Keys(m.Option(ice.MSG_USERPOD), value[ROUTE]))) m.PushAnchor(value[ROUTE], m.MergePod(value[ROUTE]))
switch value[mdb.TYPE] { switch value[mdb.TYPE] {
case SERVER: case SERVER:

View File

@ -15,9 +15,6 @@ import (
"shylinux.com/x/websocket" "shylinux.com/x/websocket"
) )
func _space_link(m *ice.Message, pod string, arg ...interface{}) string {
return tcp.ReplaceLocalhost(m, kit.MergePOD(m.Option(ice.MSG_USERWEB), pod, arg...))
}
func _space_domain(m *ice.Message) (link string) { func _space_domain(m *ice.Message) (link string) {
if link = m.Config(DOMAIN); link == "" { if link = m.Config(DOMAIN); link == "" {
link = m.Cmd(SPACE, ice.DEV, cli.PWD).Append(mdb.LINK) link = m.Cmd(SPACE, ice.DEV, cli.PWD).Append(mdb.LINK)
@ -201,7 +198,7 @@ func _space_search(m *ice.Message, kind, name, text string, arg ...string) {
case MASTER: case MASTER:
m.PushSearch(mdb.TEXT, m.Cmd(SPIDE, value[mdb.NAME], ice.OptionFields("")).Append("client.url"), value) m.PushSearch(mdb.TEXT, m.Cmd(SPIDE, value[mdb.NAME], ice.OptionFields("")).Append("client.url"), value)
default: default:
m.PushSearch(mdb.TEXT, _space_link(m, kit.Keys(m.Option(ice.MSG_USERPOD), value[mdb.NAME])), value) m.PushSearch(mdb.TEXT, m.MergePod(kit.Format(value[mdb.NAME])), value)
} }
}) })
if name != "" { if name != "" {
@ -309,9 +306,9 @@ func init() {
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
switch value[mdb.TYPE] { switch value[mdb.TYPE] {
case MASTER: case MASTER:
m.PushAnchor(value[mdb.NAME], "http://"+value[mdb.TEXT]) m.PushAnchor(value[mdb.NAME], m.Cmd(SPIDE, value[mdb.NAME], ice.OptionFields("")).Append("client.url"))
default: default:
m.PushAnchor(value[mdb.NAME], _space_link(m, kit.Keys(m.Option(ice.MSG_USERPOD), value[mdb.NAME]))) m.PushAnchor(value[mdb.NAME], m.MergePod(value[mdb.NAME]))
} }
}) })
m.Sort("type,name,text") m.Sort("type,name,text")

View File

@ -64,7 +64,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
return return
} }
msg.Log(ROUTE, "%s <- %s", s.Name, k) msg.Log(ROUTE, "%s <- %s", s.Name, k)
ice.Info.Route[path.Join(list[s], k)] = ice.FileKey(kit.FileLine(x.Hand, 300)) ice.Info.Route[path.Join(list[s], k)] = ice.FileCmd(kit.FileLine(x.Hand, 300))
frame.HandleFunc(k, func(frame http.ResponseWriter, r *http.Request) { frame.HandleFunc(k, func(frame http.ResponseWriter, r *http.Request) {
m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) { m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) {
_serve_handle(k, x, msg, frame, r) _serve_handle(k, x, msg, frame, r)

84
conf.go
View File

@ -14,8 +14,8 @@ const (
FALSE = "false" FALSE = "false"
SUCCESS = "success" SUCCESS = "success"
FAILURE = "failure" FAILURE = "failure"
RESTART = "restart"
PROCESS = "process" PROCESS = "process"
RESTART = "restart"
OF = " of " OF = " of "
INIT = "init" INIT = "init"
@ -201,15 +201,6 @@ const ( // MSG
MSG_STORM = "sess.storm" MSG_STORM = "sess.storm"
MSG_TOAST = "sess.toast" MSG_TOAST = "sess.toast"
MSG_LOCAL = "sess.local" MSG_LOCAL = "sess.local"
CACHE_LIMIT = "cache.limit"
CACHE_BEGIN = "cache.begin"
CACHE_COUNT = "cache.count"
CACHE_OFFEND = "cache.offend"
CACHE_FILTER = "cache.filter"
CACHE_VALUE = "cache.value"
CACHE_FIELD = "cache.field"
CACHE_DETAIL = "detail"
) )
const ( // RENDER const ( // RENDER
RENDER_RAW = "_raw" RENDER_RAW = "_raw"
@ -242,19 +233,30 @@ const ( // PROCESS
FIELD_PREFIX = "_prefix" FIELD_PREFIX = "_prefix"
) )
const ( // Err const ( // CACHE
ErrWarn = "warn: " CACHE_LIMIT = "cache.limit"
ErrPanic = "panic: " CACHE_BEGIN = "cache.begin"
ErrExists = "exists: " CACHE_COUNT = "cache.count"
ErrExpire = "expire: " CACHE_OFFEND = "cache.offend"
ErrTimeout = "timeout: " CACHE_FILTER = "cache.filter"
ErrFailure = "failure: " CACHE_VALUE = "cache.value"
ErrNotLogin = "not login: " CACHE_FIELD = "cache.field"
ErrNotFound = "not found: " CACHE_DETAIL = "detail"
ErrNotRight = "not right: "
ErrNotStart = "not start: "
ErrNotImplement = "not implement: "
) )
const ( // CTX
CTX_FOLLOW = "follow"
CTX_STATUS = "status"
CTX_STREAM = "stream"
CTX_BEGIN = "begin"
CTX_START = "start"
CTX_SERVE = "serve"
CTX_CLOSE = "close"
CTX_INIT = "_init"
CTX_EXIT = "_exit"
)
const ( // LOG const ( // LOG
// 通用 // 通用
LOG_INFO = "info" LOG_INFO = "info"
@ -285,18 +287,18 @@ const ( // LOG
LOG_EXPORT = "export" LOG_EXPORT = "export"
LOG_IMPORT = "import" LOG_IMPORT = "import"
) )
const ( // CTX const ( // Err
CTX_FOLLOW = "follow" ErrWarn = "warn: "
CTX_STATUS = "status" ErrPanic = "panic: "
CTX_STREAM = "stream" ErrExists = "exists: "
ErrExpire = "expire: "
CTX_BEGIN = "begin" ErrTimeout = "timeout: "
CTX_START = "start" ErrFailure = "failure: "
CTX_SERVE = "serve" ErrNotLogin = "not login: "
CTX_CLOSE = "close" ErrNotFound = "not found: "
ErrNotRight = "not right: "
CTX_INIT = "_init" ErrNotStart = "not start: "
CTX_EXIT = "_exit" ErrNotImplement = "not implement: "
) )
const ( const (
@ -313,23 +315,29 @@ const (
SSH = "ssh" SSH = "ssh"
MDB = "mdb" MDB = "mdb"
) )
const ( const ( // ctx
CONFIG = "config"
COMMAND = "command" COMMAND = "command"
ACTION = "action" ACTION = "action"
CONFIG = "config"
STYLE = "style" STYLE = "style"
INDEX = "index" INDEX = "index"
ARGS = "args" ARGS = "args"
INPUTS = "inputs"
FEATURE = "feature"
) )
const ( const ( // web
SERVE = "serve" SERVE = "serve"
SPACE = "space" SPACE = "space"
SPIDE = "spide" SPIDE = "spide"
CACHE = "cache" CACHE = "cache"
) )
const ( const ( // mdb
KEY = "key" KEY = "key"
VALUE = "value" VALUE = "value"
SCRIPT = "script"
LINK = "link"
META = "meta"
HASH = "hash" HASH = "hash"
TIME = "time" TIME = "time"
TYPE = "type" TYPE = "type"

View File

@ -51,11 +51,11 @@ func _website_parse(m *ice.Message, text string, args ...string) (map[string]int
data := kit.Dict() data := kit.Dict()
switch display := ice.DisplayRequire(1, ls[0])[ctx.DISPLAY]; kit.Ext(ls[0]) { switch display := ice.DisplayRequire(1, ls[0])[ctx.DISPLAY]; kit.Ext(ls[0]) {
case nfs.JS: case nfs.JS:
key := ice.GetFileKey(display) key := ice.GetFileCmd(display)
if key == "" { if key == "" {
if ls := strings.Split(display, ice.PS); len(ls) > 4 { if ls := strings.Split(display, ice.PS); len(ls) > 4 {
ls[3] = ice.USR ls[3] = ice.USR
key = ice.GetFileKey(path.Join(ls[3:]...)) key = ice.GetFileCmd(path.Join(ls[3:]...))
} }
} }
if key == "" { if key == "" {
@ -68,7 +68,7 @@ func _website_parse(m *ice.Message, text string, args ...string) (map[string]int
ls[0] = kit.Select("can.code.inner.plugin", key) ls[0] = kit.Select("can.code.inner.plugin", key)
data[ctx.DISPLAY] = display data[ctx.DISPLAY] = display
case nfs.GO: case nfs.GO:
key := ice.GetFileKey(display) key := ice.GetFileCmd(display)
if key == "" { if key == "" {
for k, v := range ice.Info.File { for k, v := range ice.Info.File {
if strings.HasSuffix(k, ls[0]) { if strings.HasSuffix(k, ls[0]) {
@ -78,7 +78,7 @@ func _website_parse(m *ice.Message, text string, args ...string) (map[string]int
} }
ls[0] = key ls[0] = key
case nfs.SH: case nfs.SH:
key := ice.GetFileKey(display) key := ice.GetFileCmd(display)
if key == "" { if key == "" {
key = "cli.system" key = "cli.system"
} }

View File

@ -78,7 +78,7 @@ func init() {
if kit.FileExists(path.Join(ice.USR_VOLCANOS, ice.PROTO_JS)) { if kit.FileExists(path.Join(ice.USR_VOLCANOS, ice.PROTO_JS)) {
m.Cmd(BINPACK, mdb.REMOVE) m.Cmd(BINPACK, mdb.REMOVE)
} else { } else {
ice.Dump = func(w io.Writer, name string, cb func(string)) bool { ice.Info.Dump = func(w io.Writer, name string, cb func(string)) bool {
for _, key := range []string{name, strings.TrimPrefix(name, ice.USR_VOLCANOS)} { for _, key := range []string{name, strings.TrimPrefix(name, ice.USR_VOLCANOS)} {
if b, ok := ice.Info.Pack[key]; ok { if b, ok := ice.Info.Pack[key]; ok {
if cb != nil { if cb != nil {
@ -91,7 +91,7 @@ func init() {
return false return false
} }
web.AddRewrite(func(w http.ResponseWriter, r *http.Request) bool { web.AddRewrite(func(w http.ResponseWriter, r *http.Request) bool {
if ice.Dump(w, r.URL.Path, func(name string) { web.RenderType(w, name, "") }) { if ice.Info.Dump(w, r.URL.Path, func(name string) { web.RenderType(w, name, "") }) {
return true // 打包文件 return true // 打包文件
} }
return false return false
@ -134,18 +134,25 @@ func init() {
fmt.Fprintln(f) fmt.Fprintln(f)
fmt.Fprintln(f, `func init() {`) fmt.Fprintln(f, `func init() {`)
fmt.Fprintln(f, ` ice.Info.Pack = map[string][]byte{`) defer fmt.Fprintln(f, `}`)
// _binpack_dir(m, f, ice.USR_LEARNING) if kit.FileExists(ice.USR_VOLCANOS) && kit.FileExists(ice.USR_INTSHELL) {
fmt.Fprintln(f, ` ice.Info.Pack = map[string][]byte{`)
_binpack_can(m, f, ice.USR_VOLCANOS) _binpack_can(m, f, ice.USR_VOLCANOS)
_binpack_dir(m, f, ice.USR_INTSHELL) _binpack_dir(m, f, ice.USR_INTSHELL)
// _binpack_dir(m, f, ice.USR_ICEBERGS) fmt.Fprintln(f, ` }`)
}
fmt.Fprintln(f, ` pack := map[string][]byte{`)
_binpack_ctx(m, f) _binpack_ctx(m, f)
fmt.Fprintln(f, _binpack_file(m, ice.ETC_INIT_SHY)) fmt.Fprintln(f, _binpack_file(m, ice.ETC_INIT_SHY))
fmt.Fprintln(f, _binpack_file(m, ice.ETC_EXIT_SHY)) fmt.Fprintln(f, _binpack_file(m, ice.ETC_EXIT_SHY))
fmt.Fprintln(f, ` }`)
fmt.Fprintln(f, ` }`) fmt.Fprintln(f, ` }`)
fmt.Fprintln(f, `
for k, v := range pack {
ice.Info.Pack[k] = v
}
`)
} }
}}, }},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {

View File

@ -58,7 +58,7 @@ func _go_grep(m *ice.Message, key string, dir string) {
m.Cmd(nfs.GREP, dir, key).Tables(func(value map[string]string) { m.PushSearch(value) }) m.Cmd(nfs.GREP, dir, key).Tables(func(value map[string]string) { m.PushSearch(value) })
} }
func _go_exec(m *ice.Message, arg ...string) { func _go_exec(m *ice.Message, arg ...string) {
if key := ice.GetFileKey(path.Join(arg[2], arg[1])); key != "" { if key := ice.GetFileCmd(path.Join(arg[2], arg[1])); key != "" {
m.Cmdy(cli.SYSTEM, GO, ice.RUN, ice.SRC_MAIN_GO, key) m.Cmdy(cli.SYSTEM, GO, ice.RUN, ice.SRC_MAIN_GO, key)
} else if m.Option(cli.CMD_DIR, arg[2]); strings.HasSuffix(arg[1], "_test.go") { } else if m.Option(cli.CMD_DIR, arg[2]); strings.HasSuffix(arg[1], "_test.go") {
m.Cmdy(cli.SYSTEM, GO, "test", "-v", nfs.PWD+arg[1]) m.Cmdy(cli.SYSTEM, GO, "test", "-v", nfs.PWD+arg[1])
@ -105,7 +105,7 @@ func _go_show(m *ice.Message, arg ...string) {
} }
}) })
} else { } else {
if key := ice.GetFileKey(path.Join(arg[2], arg[1])); key != "" { if key := ice.GetFileCmd(path.Join(arg[2], arg[1])); key != "" {
m.ProcessCommand(key, kit.Simple()) m.ProcessCommand(key, kit.Simple())
} else { } else {
m.ProcessCommand("web.wiki.word", kit.Simple(strings.ReplaceAll(path.Join(arg[2], arg[1]), ".go", ".shy"))) m.ProcessCommand("web.wiki.word", kit.Simple(strings.ReplaceAll(path.Join(arg[2], arg[1]), ".go", ".shy")))

View File

@ -45,7 +45,7 @@ func init() {
LoadPlug(m, JS) LoadPlug(m, JS)
}}, }},
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) { mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
key := ice.GetFileKey(kit.Replace(path.Join(arg[2], arg[1]), ".js", ".go")) key := ice.GetFileCmd(kit.Replace(path.Join(arg[2], arg[1]), ".js", ".go"))
if key == "" { if key == "" {
for p, k := range ice.Info.File { for p, k := range ice.Info.File {
if strings.HasPrefix(p, path.Dir(path.Join(arg[2], arg[1]))) { if strings.HasPrefix(p, path.Dir(path.Join(arg[2], arg[1]))) {

View File

@ -1,6 +0,0 @@
source chat/chat.shy
source code/code.shy
source mall/mall.shy
source team/team.shy
source wiki/wiki.shy

44
info.go
View File

@ -21,6 +21,8 @@ type MakeInfo struct {
} }
var Info = struct { var Info = struct {
Make MakeInfo
HostName string HostName string
PathName string PathName string
UserName string UserName string
@ -33,12 +35,11 @@ var Info = struct {
CtxShare string CtxShare string
CtxRiver string CtxRiver string
Make MakeInfo
Help string Help string
Pack map[string][]byte Route map[string]string // 路由命令
File map[string]string File map[string]string // 文件命令
Route map[string]string Pack map[string][]byte // 打包文件
Dump func(w io.Writer, name string, cb func(string)) bool
Log func(m *Message, p, l, s string) Log func(m *Message, p, l, s string)
render map[string]func(*Message, string, ...interface{}) string render map[string]func(*Message, string, ...interface{}) string
@ -52,15 +53,17 @@ report: shylinuxc@gmail.com
server: https://shylinux.com server: https://shylinux.com
source: https://shylinux.com/x/icebergs source: https://shylinux.com/x/icebergs
`, `,
Pack: map[string][]byte{},
File: map[string]string{},
Route: map[string]string{}, Route: map[string]string{},
File: map[string]string{},
Pack: map[string][]byte{},
Dump: func(w io.Writer, name string, cb func(string)) bool { return false },
Log: func(m *Message, p, l, s string) {},
render: map[string]func(*Message, string, ...interface{}) string{}, render: map[string]func(*Message, string, ...interface{}) string{},
names: map[string]interface{}{}, names: map[string]interface{}{},
} }
func FileKey(dir string) string { func FileCmd(dir string) string {
dir = strings.Split(dir, DF)[0] dir = strings.Split(dir, DF)[0]
dir = strings.ReplaceAll(dir, ".js", ".go") dir = strings.ReplaceAll(dir, ".js", ".go")
dir = strings.ReplaceAll(dir, ".sh", ".go") dir = strings.ReplaceAll(dir, ".sh", ".go")
@ -71,7 +74,6 @@ func FileKey(dir string) string {
if Info.Make.Path != "" && strings.HasPrefix(dir, Info.Make.Path+PS) { if Info.Make.Path != "" && strings.HasPrefix(dir, Info.Make.Path+PS) {
dir = strings.TrimPrefix(dir, Info.Make.Path+PS) dir = strings.TrimPrefix(dir, Info.Make.Path+PS)
} }
// println("what ", dir, kit.Path(""), Info.Make.Path)
if strings.HasPrefix(dir, kit.Path("")+PS) { if strings.HasPrefix(dir, kit.Path("")+PS) {
dir = strings.TrimPrefix(dir, kit.Path("")+PS) dir = strings.TrimPrefix(dir, kit.Path("")+PS)
} }
@ -83,25 +85,5 @@ func FileKey(dir string) string {
} }
return dir return dir
} }
func AddFileKey(dir, key string) { func AddFileCmd(dir, key string) { Info.File[FileCmd(dir)] = key }
Info.File[FileKey(dir)] = key func GetFileCmd(dir string) string { return Info.File[FileCmd(dir)] }
}
func GetFileKey(dir string) string {
return Info.File[FileKey(dir)]
}
var Dump = func(w io.Writer, name string, cb func(string)) bool { return false }
func name(name string, value interface{}) string {
if s, ok := Info.names[name]; ok {
last := ""
switch s := s.(type) {
case *Context:
last = s.Name
}
panic(kit.Format("%s %s %v", ErrExists, name, last))
}
Info.names[name] = value
return name
}

View File

@ -2,7 +2,6 @@ package ice
import ( import (
"os" "os"
"path"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -133,9 +132,6 @@ func Run(arg ...string) string {
os.Exit(kit.Int(Pulse.Option(EXIT))) os.Exit(kit.Int(Pulse.Option(EXIT)))
} }
default: // 执行命令 default: // 执行命令
if _, ok := Info.names[path.Base(os.Args[0])]; ok {
// arg = kit.Simple(path.Base(os.Args[0]), arg)
}
if len(arg) == 0 { if len(arg) == 0 {
arg = append(arg, HELP) arg = append(arg, HELP)
} }

View File

@ -44,8 +44,8 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
// 长度截断 // 长度截断
switch level { switch level {
case LOG_INFO, LOG_SEND, LOG_RECV: case LOG_INFO, LOG_SEND, LOG_RECV:
if len(str) > 1024 { if len(str) > 2048 {
str = str[:1024] str = str[:2048]
} }
} }

228
meta.go
View File

@ -1,7 +1,6 @@
package ice package ice
import ( import (
"sort"
"strconv" "strconv"
"strings" "strings"
@ -17,8 +16,17 @@ func (m *Message) Set(key string, arg ...string) *Message {
if len(arg) > 0 { if len(arg) > 0 {
for i := 0; i < len(m.meta[KEY]); i++ { for i := 0; i < len(m.meta[KEY]); i++ {
if m.meta[KEY][i] == arg[0] { if m.meta[KEY][i] == arg[0] {
m.meta[KEY][i] = "" if len(arg) > 1 {
m.meta[VALUE][i] = "" m.meta[VALUE][i] = arg[1]
break
}
for ; i < len(m.meta[KEY])-1; i++ {
m.meta[KEY][i] = m.meta[KEY][i+1]
m.meta[VALUE][i] = m.meta[VALUE][i+1]
}
m.meta[KEY] = kit.Slice(m.meta[KEY], 0, -1)
m.meta[VALUE] = kit.Slice(m.meta[VALUE], 0, -1)
break
} }
} }
return m return m
@ -47,7 +55,7 @@ func (m *Message) Set(key string, arg ...string) *Message {
if m.meta[KEY][i] == key { if m.meta[KEY][i] == key {
if len(arg) > 0 { if len(arg) > 0 {
m.meta[VALUE][i] = arg[0] m.meta[VALUE][i] = arg[0]
return m break
} }
for ; i < len(m.meta[KEY])-1; i++ { for ; i < len(m.meta[KEY])-1; i++ {
m.meta[KEY][i] = m.meta[KEY][i+1] m.meta[KEY][i] = m.meta[KEY][i+1]
@ -100,10 +108,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
if len(arg) > 0 { if len(arg) > 0 {
head = kit.Simple(arg[0]) head = kit.Simple(arg[0])
} else { // 键值排序 } else { // 键值排序
for k := range kit.KeyValue(map[string]interface{}{}, "", value) { head = kit.SortedKey(kit.KeyValue(map[string]interface{}{}, "", value))
head = append(head, k)
}
sort.Strings(head)
} }
var val map[string]interface{} var val map[string]interface{}
@ -146,10 +151,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
if len(arg) > 0 { if len(arg) > 0 {
head = kit.Simple(arg[0]) head = kit.Simple(arg[0])
} else { // 键值排序 } else { // 键值排序
for k := range value { head = kit.SortedKey(value)
head = append(head, k)
}
sort.Strings(head)
} }
for _, k := range head { for _, k := range head {
@ -202,100 +204,13 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message {
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], msg.meta[MSG_RESULT]...) m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], msg.meta[MSG_RESULT]...)
return m return m
} }
func (m *Message) Sort(key string, arg ...string) *Message { func (m *Message) Length() (max int) {
ls := kit.Split(key)
key = ls[0]
if m.FieldsIsDetail() && key != KEY {
return m
}
// 排序方法
cmp := "str"
if len(arg) > 0 && arg[0] != "" {
cmp = arg[0]
} else {
cmp = "int"
for _, v := range m.meta[key] {
if _, e := strconv.Atoi(v); e != nil {
cmp = "str"
}
}
}
// 排序因子
number := map[int]int64{}
table := []map[string]string{}
m.Table(func(index int, line map[string]string, head []string) {
switch table = append(table, line); cmp {
case "int":
number[index] = kit.Int64(line[key])
case "int_r":
number[index] = -kit.Int64(line[key])
case "time":
number[index] = int64(kit.Time(line[key]))
case "time_r":
number[index] = -int64(kit.Time(line[key]))
}
})
compare := func(i, j int, op string) bool {
for k := range ls[1:] {
if table[i][ls[k]] == table[j][ls[k]] {
continue
}
if op == ">" && table[i][ls[k]] > table[j][ls[k]] {
return true
}
if op == "<" && table[i][ls[k]] < table[j][ls[k]] {
return true
}
return false
}
return false
}
// 排序数据
for i := 0; i < len(table)-1; i++ {
for j := i + 1; j < len(table); j++ {
result := false
switch cmp {
case "", "str":
if table[i][key] > table[j][key] {
result = true
} else if table[i][key] == table[j][key] && compare(i, j, ">") {
result = true
}
case "str_r":
if table[i][key] < table[j][key] {
result = true
} else if table[i][key] == table[j][key] && compare(i, j, "<") {
result = true
}
default:
if number[i] > number[j] {
result = true
} else if table[i][key] == table[j][key] && compare(i, j, ">") {
result = true
}
}
if result {
table[i], table[j] = table[j], table[i]
number[i], number[j] = number[j], number[i]
}
}
}
// 输出数据
for _, k := range m.meta[MSG_APPEND] { for _, k := range m.meta[MSG_APPEND] {
delete(m.meta, k) if l := len(m.meta[k]); l > max {
} max = l
for _, v := range table {
for _, k := range m.meta[MSG_APPEND] {
m.Add(MSG_APPEND, k, v[k])
} }
} }
return m return max
} }
func (m *Message) Tables(cbs ...func(value map[string]string)) *Message { func (m *Message) Tables(cbs ...func(value map[string]string)) *Message {
return m.Table(func(index int, value map[string]string, head []string) { return m.Table(func(index int, value map[string]string, head []string) {
@ -388,6 +303,106 @@ func (m *Message) Table(cbs ...func(index int, value map[string]string, head []s
} }
return m return m
} }
func (m *Message) Sort(key string, arg ...string) *Message {
ls := kit.Split(key)
if key = ls[0]; m.FieldsIsDetail() && key != KEY {
return m
}
// 排序方法
cmp := "str"
if len(arg) > 0 && arg[0] != "" {
cmp = arg[0]
} else {
cmp = "int"
for _, v := range m.meta[key] {
if _, e := strconv.Atoi(v); e != nil {
cmp = "str"
}
}
}
// 排序因子
number := map[int]int64{}
table := []map[string]string{}
m.Table(func(index int, line map[string]string, head []string) {
switch table = append(table, line); cmp {
case "int":
number[index] = kit.Int64(line[key])
case "int_r":
number[index] = -kit.Int64(line[key])
case "time":
number[index] = int64(kit.Time(line[key]))
case "time_r":
number[index] = -int64(kit.Time(line[key]))
}
})
compare := func(i, j int, op string) bool {
for k := range ls[1:] {
if table[i][ls[k]] == table[j][ls[k]] {
continue
}
if op == ">" && table[i][ls[k]] > table[j][ls[k]] {
return true
}
if op == "<" && table[i][ls[k]] < table[j][ls[k]] {
return true
}
return false
}
return false
}
// 排序数据
for i := 0; i < len(table)-1; i++ {
for j := i + 1; j < len(table); j++ {
result := false
switch cmp {
case "", "str":
if table[i][key] > table[j][key] {
result = true
} else if table[i][key] == table[j][key] && compare(i, j, ">") {
result = true
}
case "str_r":
if table[i][key] < table[j][key] {
result = true
} else if table[i][key] == table[j][key] && compare(i, j, "<") {
result = true
}
default:
if number[i] > number[j] {
result = true
} else if table[i][key] == table[j][key] && compare(i, j, ">") {
result = true
}
}
if result {
table[i], table[j] = table[j], table[i]
number[i], number[j] = number[j], number[i]
}
}
}
// 输出数据
for _, k := range m.meta[MSG_APPEND] {
delete(m.meta, k)
}
for _, v := range table {
for _, k := range m.meta[MSG_APPEND] {
m.Add(MSG_APPEND, k, v[k])
}
}
return m
}
func (m *Message) SortInt(key string) { m.Sort(key, "int") }
func (m *Message) SortIntR(key string) { m.Sort(key, "int_r") }
func (m *Message) SortStr(key string) { m.Sort(key, "str") }
func (m *Message) SortStrR(key string) { m.Sort(key, "str_r") }
func (m *Message) SortTime(key string) { m.Sort(key, "time") }
func (m *Message) SortTimeR(key string) { m.Sort(key, "time_r") }
func (m *Message) Detail(arg ...interface{}) string { func (m *Message) Detail(arg ...interface{}) string {
return kit.Select("", m.meta[MSG_DETAIL], 0) return kit.Select("", m.meta[MSG_DETAIL], 0)
@ -477,10 +492,3 @@ func (m *Message) Result(arg ...interface{}) string {
} }
return strings.Join(m.Resultv(arg...), "") return strings.Join(m.Resultv(arg...), "")
} }
func (m *Message) SortInt(key string) { m.Sort(key, "int") }
func (m *Message) SortIntR(key string) { m.Sort(key, "int_r") }
func (m *Message) SortStr(key string) { m.Sort(key, "str") }
func (m *Message) SortStrR(key string) { m.Sort(key, "str_r") }
func (m *Message) SortTime(key string) { m.Sort(key, "time") }
func (m *Message) SortTimeR(key string) { m.Sort(key, "time_r") }

84
misc.go
View File

@ -3,22 +3,12 @@ package ice
import ( import (
"bytes" "bytes"
"encoding/csv" "encoding/csv"
"net/url"
"path"
"reflect" "reflect"
"strings" "strings"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
func (m *Message) Length() (max int) {
for _, k := range m.meta[MSG_APPEND] {
if l := len(m.meta[k]); l > max {
max = l
}
}
return max
}
func (m *Message) CSV(text string, head ...string) *Message { func (m *Message) CSV(text string, head ...string) *Message {
bio := bytes.NewBufferString(text) bio := bytes.NewBufferString(text)
r := csv.NewReader(bio) r := csv.NewReader(bio)
@ -37,9 +27,6 @@ func (m *Message) CSV(text string, head ...string) *Message {
} }
return m return m
} }
func (m *Message) SplitIndex(str string, arg ...string) *Message {
return m.Split(str, kit.Simple("index", arg)...)
}
func (m *Message) Split(str string, arg ...string) *Message { // field sp nl func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
m.Set(MSG_APPEND).Set(MSG_RESULT) m.Set(MSG_APPEND).Set(MSG_RESULT)
field := kit.Select("", arg, 0) field := kit.Select("", arg, 0)
@ -84,39 +71,19 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
} }
return m return m
} }
func (m *Message) SplitIndex(str string, arg ...string) *Message {
func (m *Message) FieldsIsDetail() bool { return m.Split(str, kit.Simple("index", arg)...)
if m.OptionFields() == CACHE_DETAIL {
return true
} }
if len(m.meta[MSG_APPEND]) == 2 && m.meta[MSG_APPEND][0] == KEY && m.meta[MSG_APPEND][1] == VALUE {
return true
}
return false
}
func (m *Message) PushDetail(value interface{}, arg ...interface{}) *Message { func (m *Message) PushDetail(value interface{}, arg ...interface{}) *Message {
return m.Push(CACHE_DETAIL, value, arg...) return m.Push(CACHE_DETAIL, value, arg...)
} }
func (m *Message) IsErr(arg ...string) bool {
return len(arg) > 0 && m.Result(1) == arg[0] || m.Result(0) == ErrWarn
}
func (m *Message) IsErrNotFound() bool { return m.Result(1) == ErrNotFound }
func (m *Message) OptionCB(key string, cb ...interface{}) interface{} { func (m *Message) OptionCB(key string, cb ...interface{}) interface{} {
if len(cb) > 0 { if len(cb) > 0 {
return m.Optionv(kit.Keycb(key), cb...) return m.Optionv(kit.Keycb(key), cb...)
} }
return m.Optionv(kit.Keycb(key)) return m.Optionv(kit.Keycb(key))
} }
func (m *Message) OptionUserWeb() *url.URL {
return kit.ParseURL(m.Option(MSG_USERWEB))
}
func (m *Message) SetResult(arg ...string) *Message {
return m.Set(MSG_RESULT, arg...)
}
func (m *Message) SetAppend(arg ...string) *Message {
return m.Set(MSG_APPEND, arg...)
}
func (m *Message) ToLowerAppend(arg ...string) *Message { func (m *Message) ToLowerAppend(arg ...string) *Message {
for _, k := range m.meta[MSG_APPEND] { for _, k := range m.meta[MSG_APPEND] {
m.RenameAppend(k, strings.ToLower(k)) m.RenameAppend(k, strings.ToLower(k))
@ -166,30 +133,17 @@ func (m *Message) AppendTrans(cb func(value string, key string, index int) strin
} }
return m return m
} }
func (m *Message) MergeLink(url string, arg ...interface{}) string { func (m *Message) SetAppend(arg ...string) *Message {
return strings.Split(kit.MergeURL2(m.Option(MSG_USERWEB), url, arg...), "?")[0] return m.Set(MSG_APPEND, arg...)
} }
func (m *Message) MergeURL2(url string, arg ...interface{}) string { func (m *Message) SetResult(arg ...string) *Message {
return kit.MergeURL2(m.Option(MSG_USERWEB), url, arg...) return m.Set(MSG_RESULT, arg...)
} }
func (m *Message) MergePod(name string, arg ...interface{}) string {
return kit.MergePOD(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), name, arg...) func (m *Message) IsErr(arg ...string) bool {
} return len(arg) > 0 && m.Result(1) == arg[0] || m.Result(0) == ErrWarn
func (m *Message) MergeCmd(name string, arg ...interface{}) string {
if name == "" {
name = m.PrefixKey()
}
if m.Option(MSG_USERPOD) == "" {
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat/cmd", name))
}
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("cmd", name), arg...)
}
func (m *Message) MergeWebsite(name string, arg ...interface{}) string {
if m.Option(MSG_USERPOD) == "" {
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat/website", name))
}
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("website", name), arg...)
} }
func (m *Message) IsErrNotFound() bool { return m.Result(1) == ErrNotFound }
func (m *Message) cmd(arg ...interface{}) *Message { func (m *Message) cmd(arg ...interface{}) *Message {
opts := map[string]interface{}{} opts := map[string]interface{}{}
@ -199,9 +153,10 @@ func (m *Message) cmd(arg ...interface{}) *Message {
// 解析参数 // 解析参数
for _, v := range arg { for _, v := range arg {
switch val := v.(type) { switch val := v.(type) {
case func(int, map[string]string, []string): case Option:
defer func() { m.Table(val) }() opts[val.Name] = val.Value
case *Option:
opts[val.Name] = val.Value
case map[string]interface{}: case map[string]interface{}:
for k, v := range val { for k, v := range val {
opts[k] = v opts[k] = v
@ -210,14 +165,11 @@ func (m *Message) cmd(arg ...interface{}) *Message {
for k, v := range val { for k, v := range val {
opts[k] = v opts[k] = v
} }
case *Option:
opts[val.Name] = val.Value
case Option:
opts[val.Name] = val.Value
case string: case string:
args = append(args, v) args = append(args, v)
case func(int, map[string]string, []string):
defer func() { m.Table(val) }()
default: default:
if reflect.Func == reflect.TypeOf(val).Kind() { if reflect.Func == reflect.TypeOf(val).Kind() {
cbs = val cbs = val

View File

@ -1,33 +0,0 @@
package app
import (
"shylinux.com/x/ice"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/webview"
)
type app struct {
title string `name:"title text" help:"标题"`
list string `name:"list auto title" help:"应用"`
}
func (app app) Title(m *ice.Message, arg ...string) {
(*ww).SetTitle("contexts")
}
func (app app) List(m *ice.Message, arg ...string) {
}
func init() { ice.Cmd("web.chat.app", app{}) }
var ww *webview.WebView
func Run(arg ...string) {
w := webview.New(true)
defer w.Destroy()
ww = &w
w.SetSize(800, 600, webview.HintNone)
w.SetTitle(kit.Select("contexts", arg, 0))
w.Navigate(kit.Select("http://localhost:9020", arg, 1))
w.Run()
}

View File

@ -1,13 +0,0 @@
source alpha/alpha.shy
source input/input.shy
source chrome/chrome.shy
source zsh/zsh.shy
source tmux/tmux.shy
source git/git.shy
source vim/vim.shy
source lark/lark.shy
source wx/wx.shy
source mp/mp.shy

View File

@ -1,150 +0,0 @@
package fyne
import (
"shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/core/chat"
"shylinux.com/x/toolkits"
"fyne.io/fyne"
"fyne.io/fyne/app"
"fyne.io/fyne/widget"
"os"
"strings"
)
var Index = &ice.Context{Name: "fyne", Help: "fyne",
Configs: map[string]*ice.Config{},
Commands: map[string]*ice.Command{
"field": {Name: "field", Help: "field", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) == 0 {
arg = append(arg, "space")
}
newField(m, kit.Select("contexts", m.Option("title"))).update(m.Cmd(arg))
}},
"hide": {Name: "hide", Help: "hide", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
field := m.Optionv("field").(*Field)
field.w.Hide()
}},
"close": {Name: "close", Help: "close", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
field := m.Optionv("field").(*Field)
field.w.Close()
}},
},
}
type Label struct {
*widget.Label
width int
height int
}
func newLabel(str string, width int, height int) *Label {
return &Label{width: width, height: height, Label: widget.NewLabel(str)}
}
func (label *Label) MinSize() fyne.Size {
return fyne.NewSize(label.width*10, label.height*20)
}
type Board struct {
width int
height int
*widget.ScrollContainer
}
func newBoard(list fyne.CanvasObject, width int, height int) *Board {
return &Board{width: width, height: height, ScrollContainer: widget.NewScrollContainer(list)}
}
func (board *Board) MinSize() fyne.Size {
return fyne.NewSize(board.width*10, board.height*20)
}
type Field struct {
widget.Entry
w fyne.Window
m *ice.Message
}
func newField(m *ice.Message, title string) *Field {
w := win.NewWindow(title)
w.CenterOnScreen()
w.SetMainMenu(fyne.NewMainMenu(
fyne.NewMenu("action",
fyne.NewMenuItem("contexts", func() { win.OpenURL(kit.ParseURL("http://localhost:9020")) }),
fyne.NewMenuItem("fnye", func() { win.OpenURL(kit.ParseURL("https://developer.fyne.io")) }),
fyne.NewMenuItem("quit", func() { os.Exit(0) }),
),
))
return &Field{w: w}
}
func (field *Field) update(m *ice.Message) {
field.ExtendBaseWidget(field)
field.m = m
cols := 0
rows := 0
list := []fyne.CanvasObject{}
width := map[int]int{}
m.Table(func(index int, value map[string]string, head []string) {
if index == 0 {
for i, k := range head {
if len(k) > width[i] {
width[i] = len(k)
}
}
}
for i, k := range head {
if len(value[k]) > width[i] {
width[i] = len(value[k])
}
}
})
m.Table(func(index int, value map[string]string, head []string) {
rows = index + 1
if cols = len(head); index == 0 {
line := []fyne.CanvasObject{}
for i, k := range head {
item := newLabel(k, width[i], 1)
line = append(line, item)
}
list = append(list, widget.NewHBox(line...))
}
line := []fyne.CanvasObject{}
for i, k := range head {
v := value[k]
if len(v) > 40 {
v = v[:40] + "..."
width[i] = 40
}
item := newLabel(v, width[i], 1)
line = append(line, item)
}
list = append(list, widget.NewHBox(line...))
})
table := widget.NewVBox(list...)
count := strings.Count(m.Result(), "\n")
// board := newBoard(newLabel(m.Result(), 20, count), 20, lines)
board := widget.NewScrollContainer(newLabel(m.Result(), 20, count))
w := field.w
w.Resize(fyne.NewSize(kit.Int(kit.Select("600", m.Option("width"))), kit.Int(kit.Select("200", m.Option("height")))))
w.SetContent(widget.NewVBox(field, table, board, widget.NewHBox(
newLabel(m.Time(), 20, 1),
)))
w.Show()
}
func (field *Field) KeyDown(key *fyne.KeyEvent) {
switch m := field.m; key.Name {
case fyne.KeyReturn:
m.Optionv("field", field)
field.update(m.Cmd(kit.Split(field.Text)))
field.Entry.SetText("")
default:
}
}
var win = app.New()
func init() { ice.Loop = win.Run }
func init() { chat.Index.Register(Index, nil) }

View File

@ -1,37 +0,0 @@
package pi
import (
"os"
"path"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/core/chat"
kit "shylinux.com/x/toolkits"
)
var Index = &ice.Context{Name: "pi", Help: "开发板",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
"pi": {Name: "pi", Help: "pi", Value: kit.Data(mdb.SHORT, "name")},
},
Commands: map[string]*ice.Command{
"GPIO": {Name: "GPIO", Help: "GPIO", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
p := kit.Format("/sys/class/gpio/gpio%s", arg[0])
if _, e := os.Stat(p); e != nil {
if m.Warn(!os.IsNotExist(e), "%s", e) {
return
}
m.Cmd("nfs.echo", "/sys/class/gpio/export", arg[0])
}
if len(arg) > 1 {
m.Cmd("nfs.echo", path.Join(p, "direction"), "out")
m.Cmd("nfs.echo", path.Join(p, "value"), arg[1])
}
m.Cmdy("nfs.cat", path.Join(p, "value"))
}},
},
}
func init() { chat.Index.Register(Index, nil) }

View File

@ -1,96 +0,0 @@
package railway
import (
"shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/core/wiki"
"shylinux.com/x/toolkits"
)
var Index = &ice.Context{Name: "railway", Help: "railway",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
"railway": {Name: "railway", Help: "12306", Value: kit.Data("site", "https://kyfw.12306.cn")},
},
Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
web.SpideCreate(m, "12306", m.Conf("railway", "meta.site"))
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save("railway")
}},
"railway": &ice.Command{Name: "railway", Help: "12306", List: kit.List(
kit.MDB_INPUT, "text", "name", "date", "figure", "date",
kit.MDB_INPUT, "text", "name", "from", "value", "北京", "figure", "city",
kit.MDB_INPUT, "text", "name", "to", "value", "曲阜", "figure", "city",
kit.MDB_INPUT, "button", "name", "查询",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if !m.Confs("railway", "meta.place") {
list := strings.Split(strings.TrimPrefix(m.Cmdx(ice.WEB_SPIDE, "12306", "raw", "GET", "/otn/resources/js/framework/station_name.js?station_version=1.9090"), "var statuion_names ='"), "|")
for i := 0; i < len(list)-5; i += 5 {
m.Conf("railway", kit.Keys("meta.place", list[i+1]), list[i+2])
}
}
date := strings.Split(m.Time("24h"), " ")[0]
if len(arg) > 0 {
date, arg = arg[0], arg[1:]
}
date = strings.Split(date, " ")[0]
from := "北京"
if len(arg) > 0 {
from, arg = arg[0], arg[1:]
}
from_code := m.Conf("railway", kit.Keys("meta.place", from))
to := "曲阜"
if len(arg) > 0 {
to, arg = arg[0], arg[1:]
}
to_code := m.Conf("railway", kit.Keys("meta.place", to))
m.Echo("%s->%s %s\n", from, to, date)
if len(arg) > 0 {
m.Cmdy(ice.WEB_SPIDE, "12306", "raw", "GET", fmt.Sprintf("/otn/czxx/queryByTrainNo?train_no=%s&from_station_telecode=%s&to_station_telecode=%s&depart_date=%s",
arg[0], from_code, to_code, date))
return
}
m.Cmd(ice.WEB_SPIDE, "12306", "GET", fmt.Sprintf("/otn/leftTicket/init?linktypeid=dc&fs=%s,%s&ts=%s,%s&date=%s&flag=N,N,Y",
from, from_code, to, to_code, date))
m.Cmd(ice.WEB_SPIDE, "12306", "GET", fmt.Sprintf("/otn/leftTicket/queryZ?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT",
date, from_code, to_code)).Table(func(index int, value map[string]string, head []string) {
kit.Fetch(kit.Value(kit.UnMarshal(value["data"]), "result"), func(index int, value string) {
fields := strings.Split(value, "|")
m.Push("车次", fields[3])
m.Push("出发", fields[8])
m.Push("到站", fields[9])
m.Push("时长", fields[10])
m.Push("二等座", fields[30])
m.Push("一等座", fields[31])
})
})
}},
"passcode": &ice.Command{Name: "passcode", Help: "passcode", Meta: kit.Dict("active", "mall/input"), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
prefix := []string{ice.WEB_SPIDE, "12306"}
if len(arg) == 0 {
m.Cmd(prefix, "raw", "/passport/web/auth/uamtk-static", "form", "appid", "otn")
m.Cmd(prefix, "raw", "GET", "/otn/HttpZF/GetJS")
m.Cmd(prefix, "raw", "/otn/login/conf")
m.Cmdy(prefix, "GET", fmt.Sprintf("/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand"))
return
}
switch arg[0] {
case "check":
m.Cmdy(prefix, "GET", fmt.Sprintf("/passport/captcha/captcha-check?login_site=E&rand=sjrand&answer=%s", arg[1]))
case "login":
m.Cmdy(prefix, "raw", "/passport/web/login", "form", "username", arg[1], "password", arg[2], "answer", arg[3], "appid", "otn")
}
}},
},
}
func init() { wiki.Index.Register(Index, nil) }

View File

@ -1,9 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
"init": function(can, msg, cb, output, action, option) {},
})
Volcanos("onaction", {help: "控件菜单", list: []})
Volcanos("onchoice", {help: "控件交互", list: ["刷新"]
"刷新": function(event, can, value, cmd, target) {},
})
Volcanos("ondetail", {help: "控件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1 +0,0 @@
title "railway"

View File

@ -2,6 +2,7 @@ package ice
import ( import (
"encoding/json" "encoding/json"
"net/url"
"os" "os"
"path" "path"
"strings" "strings"
@ -82,6 +83,15 @@ func (m *Message) OptionTemplate() string {
return kit.Join(res, SP) return kit.Join(res, SP)
} }
func (m *Message) FieldsIsDetail() bool {
if len(m.meta[MSG_APPEND]) == 2 && m.meta[MSG_APPEND][0] == KEY && m.meta[MSG_APPEND][1] == VALUE {
return true
}
if m.OptionFields() == CACHE_DETAIL {
return true
}
return false
}
func (m *Message) Fields(length int, fields ...string) string { func (m *Message) Fields(length int, fields ...string) string {
return m.Option(MSG_FIELDS, kit.Select(kit.Select(CACHE_DETAIL, fields, length), m.Option(MSG_FIELDS))) return m.Option(MSG_FIELDS, kit.Select(kit.Select(CACHE_DETAIL, fields, length), m.Option(MSG_FIELDS)))
} }
@ -127,9 +137,6 @@ func (m *Message) StatusTimeCountTotal(arg ...interface{}) {
m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost()) m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost())
} }
func (m *Message) Confirm(text string) string {
return m.Cmdx(SPACE, m.Option(MSG_DAEMON), "confirm", text)
}
func (m *Message) ToastProcess(arg ...interface{}) func() { func (m *Message) ToastProcess(arg ...interface{}) func() {
if len(arg) == 0 { if len(arg) == 0 {
arg = kit.List("", "-1") arg = kit.List("", "-1")
@ -240,3 +247,31 @@ func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) }
func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) } func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) }
func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) } func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) }
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) } func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
func (m *Message) OptionUserWeb() *url.URL {
return kit.ParseURL(m.Option(MSG_USERWEB))
}
func (m *Message) MergeLink(url string, arg ...interface{}) string {
return strings.Split(m.MergeURL2(url, arg...), "?")[0]
}
func (m *Message) MergeURL2(url string, arg ...interface{}) string {
return kit.MergeURL2(m.Option(MSG_USERWEB), url, arg...)
}
func (m *Message) MergePod(pod string, arg ...interface{}) string {
return kit.MergePOD(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), pod, arg...)
}
func (m *Message) MergeCmd(cmd string, arg ...interface{}) string {
if cmd == "" {
cmd = m.PrefixKey()
}
if m.Option(MSG_USERPOD) == "" {
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat/cmd", cmd))
}
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("cmd", cmd), arg...)
}
func (m *Message) MergeWebsite(web string, arg ...interface{}) string {
if m.Option(MSG_USERPOD) == "" {
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat/website", web))
}
return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("website", web), arg...)
}

105
render.go
View File

@ -29,8 +29,8 @@ func Render(m *Message, cmd string, args ...interface{}) string {
} }
list := []string{} list := []string{}
for _, k := range kit.Split(kit.Join(arg)) { for _, k := range kit.Split(kit.Join(arg)) {
list = append(list, kit.Format(`<input type="button" name="%s" value="%s">`, list = append(list, kit.Format(`<input type="button" name="%s" value="%s">`, k,
k, kit.Select(k, kit.Value(m._cmd.Meta, kit.Keys("_trans", k)), m.Option(MSG_LANGUAGE) != "en"))) kit.Select(k, kit.Value(m._cmd.Meta, kit.Keys("_trans", k)), m.Option(MSG_LANGUAGE) != "en")))
} }
return kit.Join(list, SP) return kit.Join(list, SP)
@ -77,8 +77,7 @@ func (m *Message) RenderDownload(args ...interface{}) *Message {
} }
func (m *Message) RenderWebsite(pod string, dir string, arg ...string) *Message { func (m *Message) RenderWebsite(pod string, dir string, arg ...string) *Message {
m.Cmdy("space", pod, "website", "action", "show", dir, arg) m.Cmdy("space", pod, "website", "action", "show", dir, arg)
m.RenderResult() return m.RenderResult()
return m
} }
func (m *Message) RenderIndex(serve, repos string, file ...string) *Message { func (m *Message) RenderIndex(serve, repos string, file ...string) *Message {
return m.RenderDownload(path.Join(m.Conf(serve, kit.Keym(repos, "path")), kit.Select(m.Conf(serve, kit.Keym(repos, INDEX)), path.Join(file...)))) return m.RenderDownload(path.Join(m.Conf(serve, kit.Keym(repos, "path")), kit.Select(m.Conf(serve, kit.Keym(repos, INDEX)), path.Join(file...))))
@ -89,20 +88,20 @@ func (m *Message) RenderCmd(index string, args ...interface{}) {
msg := m.Cmd(COMMAND, index) msg := m.Cmd(COMMAND, index)
list = kit.Format(kit.List(kit.Dict( list = kit.Format(kit.List(kit.Dict(
INDEX, index, ARGS, kit.Simple(args), INDEX, index, ARGS, kit.Simple(args),
msg.AppendSimple(NAME, "help"), msg.AppendSimple(NAME, HELP),
"feature", kit.UnMarshal(msg.Append("meta")), FEATURE, kit.UnMarshal(msg.Append(META)),
"inputs", kit.UnMarshal(msg.Append("list")), INPUTS, kit.UnMarshal(msg.Append(LIST)),
))) )))
} }
m.RenderResult(kit.Format(`<!DOCTYPE html> m.RenderResult(kit.Format(`<!DOCTYPE html>
<head> <head>
<meta name="viewport" content="width=device-width,initial-scale=0.8,user-scalable=no">
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=0.8,user-scalable=no">
<link rel="stylesheet" type="text/css" href="/page/can.css"> <link rel="stylesheet" type="text/css" href="/page/can.css">
</head>
<body>
<script src="/page/can.js"></script> <script src="/page/can.js"></script>
<script>can(%s)</script> <script>can(%s)</script>
</head>
<body>
</body> </body>
`, list)) `, list))
} }
@ -115,29 +114,27 @@ func (m *Message) IsCliUA() bool {
} }
func (m *Message) PushAnchor(arg ...interface{}) { // [name] link func (m *Message) PushAnchor(arg ...interface{}) { // [name] link
if !m.IsCliUA() { if !m.IsCliUA() {
m.Push("link", Render(m, RENDER_ANCHOR, arg...)) m.Push(LINK, Render(m, RENDER_ANCHOR, arg...))
} }
} }
func (m *Message) PushButton(arg ...interface{}) { // name... func (m *Message) PushButton(arg ...interface{}) { // name...
if !m.IsCliUA() {
if m.FieldsIsDetail() { if m.FieldsIsDetail() {
for i, k := range m.meta["key"] { for i, k := range m.meta[KEY] {
if k == "action" { if k == ACTION {
m.meta["value"][i] = Render(m, RENDER_BUTTON, arg...) m.meta[VALUE][i] = Render(m, RENDER_BUTTON, arg...)
return return
} }
} }
} else if len(m.meta[ACTION]) >= m.Length() {
m.meta[ACTION] = []string{}
} }
if len(m.meta["action"]) >= m.Length() {
m.meta["action"] = []string{}
}
if !m.IsCliUA() {
m.Push(ACTION, Render(m, RENDER_BUTTON, arg...)) m.Push(ACTION, Render(m, RENDER_BUTTON, arg...))
} }
} }
func (m *Message) PushScript(arg ...string) { // [type] text... func (m *Message) PushScript(arg ...string) { // [type] text...
if !m.IsCliUA() { if !m.IsCliUA() {
m.Push("script", Render(m, RENDER_SCRIPT, arg)) m.Push(SCRIPT, Render(m, RENDER_SCRIPT, arg))
} }
} }
func (m *Message) PushQRCode(key string, src string, arg ...string) { // key src [size] func (m *Message) PushQRCode(key string, src string, arg ...string) { // key src [size]
@ -170,11 +167,26 @@ func (m *Message) PushAction(list ...interface{}) *Message {
if len(m.meta[MSG_APPEND]) == 0 { if len(m.meta[MSG_APPEND]) == 0 {
return m return m
} }
m.Set(MSG_APPEND, ACTION) return m.Set(MSG_APPEND, ACTION).Table(func(index int, value map[string]string, head []string) {
m.Table(func(index int, value map[string]string, head []string) {
m.PushButton(list...) m.PushButton(list...)
}) })
return m }
func (m *Message) PushSearch(args ...interface{}) {
data := kit.Dict(args...)
for _, k := range kit.Split(m.OptionFields()) {
switch k {
case POD:
m.Push(k, kit.Select("", data[k]))
case CTX:
m.Push(k, kit.Select(m.Prefix(), data[k]))
case CMD:
m.Push(k, kit.Select(m.CommandKey(), data[k]))
case TIME:
m.Push(k, kit.Select(m.Time(), data[k]))
default:
m.Push(k, kit.Select("", data[k]))
}
}
} }
func (m *Message) PushPodCmd(cmd string, arg ...string) { func (m *Message) PushPodCmd(cmd string, arg ...string) {
if m.Length() > 0 && len(m.Appendv(POD)) == 0 { if m.Length() > 0 && len(m.Appendv(POD)) == 0 {
@ -196,23 +208,6 @@ func (m *Message) PushPodCmd(cmd string, arg ...string) {
} }
}) })
} }
func (m *Message) PushSearch(args ...interface{}) {
data := kit.Dict(args...)
for _, k := range kit.Split(m.OptionFields()) {
switch k {
case POD:
m.Push(k, kit.Select("", data[k]))
case CTX:
m.Push(k, kit.Select(m.Prefix(), data[k]))
case CMD:
m.Push(k, kit.Select(m.CommandKey(), data[k]))
case TIME:
m.Push(k, kit.Select(m.Time(), data[k]))
default:
m.Push(k, kit.Select("", data[k]))
}
}
}
func (m *Message) EchoAnchor(arg ...interface{}) *Message { // [name] link func (m *Message) EchoAnchor(arg ...interface{}) *Message { // [name] link
return m.Echo(Render(m, RENDER_ANCHOR, arg...)) return m.Echo(Render(m, RENDER_ANCHOR, arg...))
@ -246,6 +241,12 @@ func (m *Message) DisplayBase(file string, arg ...interface{}) *Message {
m.Option(MSG_DISPLAY, kit.MergeURL(DisplayBase(file)[DISPLAY], arg...)) m.Option(MSG_DISPLAY, kit.MergeURL(DisplayBase(file)[DISPLAY], arg...))
return m return m
} }
func (m *Message) DisplayStory(file string, arg ...interface{}) *Message {
if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) {
file = path.Join(PLUGIN_STORY, file)
}
return m.DisplayBase(file, arg...)
}
func (m *Message) DisplayLocal(file string, arg ...interface{}) *Message { func (m *Message) DisplayLocal(file string, arg ...interface{}) *Message {
if file == "" { if file == "" {
file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS)) file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS))
@ -255,23 +256,23 @@ func (m *Message) DisplayLocal(file string, arg ...interface{}) *Message {
} }
return m.DisplayBase(file, arg...) return m.DisplayBase(file, arg...)
} }
func (m *Message) DisplayStory(file string, arg ...interface{}) *Message {
if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) {
file = path.Join(PLUGIN_STORY, file)
}
return m.DisplayBase(file, arg...)
}
func (m *Message) DisplayStoryJSON(arg ...interface{}) *Message {
return m.DisplayStory("json", arg...)
}
func (m *Message) Display(file string, arg ...interface{}) *Message { func (m *Message) Display(file string, arg ...interface{}) *Message {
m.Option(MSG_DISPLAY, kit.MergeURL(DisplayRequire(2, file)[DISPLAY], arg...)) m.Option(MSG_DISPLAY, kit.MergeURL(DisplayRequire(2, file)[DISPLAY], arg...))
return m return m
} }
func (m *Message) DisplayStoryJSON(arg ...interface{}) *Message {
return m.DisplayStory("json", arg...)
}
func DisplayBase(file string, arg ...string) map[string]string { func DisplayBase(file string, arg ...string) map[string]string {
return map[string]string{DISPLAY: file, STYLE: kit.Join(arg, SP)} return map[string]string{DISPLAY: file, STYLE: kit.Join(arg, SP)}
} }
func DisplayStory(file string, arg ...string) map[string]string {
if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) {
file = path.Join(PLUGIN_STORY, file)
}
return DisplayBase(file, arg...)
}
func DisplayLocal(file string, arg ...string) map[string]string { func DisplayLocal(file string, arg ...string) map[string]string {
if file == "" { if file == "" {
file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS)) file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS))
@ -281,12 +282,6 @@ func DisplayLocal(file string, arg ...string) map[string]string {
} }
return DisplayBase(file, arg...) return DisplayBase(file, arg...)
} }
func DisplayStory(file string, arg ...string) map[string]string {
if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) {
file = path.Join(PLUGIN_STORY, file)
}
return DisplayBase(file, arg...)
}
func DisplayRequire(n int, file string, arg ...string) map[string]string { func DisplayRequire(n int, file string, arg ...string) map[string]string {
if file == "" { if file == "" {
file = kit.Keys(kit.FileName(n+1), JS) file = kit.Keys(kit.FileName(n+1), JS)

127
type.go
View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"sort"
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -14,8 +13,8 @@ import (
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
type CommandHandler func(m *Message, c *Context, key string, arg ...string)
type ActionHandler func(m *Message, arg ...string) type ActionHandler func(m *Message, arg ...string)
type CommandHandler func(m *Message, c *Context, key string, arg ...string)
type Cache struct { type Cache struct {
Name string Name string
@ -30,7 +29,7 @@ type Config struct {
type Action struct { type Action struct {
Name string Name string
Help string Help string
Hand func(m *Message, arg ...string) Hand ActionHandler
List []interface{} List []interface{}
} }
type Command struct { type Command struct {
@ -58,10 +57,10 @@ type Context struct {
Contexts map[string]*Context Contexts map[string]*Context
context *Context context *Context
root *Context root *Context
server Server
begin *Message begin *Message
start *Message start *Message
server Server
wg *sync.WaitGroup wg *sync.WaitGroup
id int32 id int32
@ -77,7 +76,7 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
return c.Caches[key].Value return c.Caches[key].Value
} }
func (c *Context) Cmd(m *Message, key string, arg ...string) *Message { func (c *Context) Cmd(m *Message, key string, arg ...string) *Message {
return c.cmd(m, m.target.Commands[key], key, arg...) return c.cmd(m, c.Commands[key], key, arg...)
} }
func (c *Context) Server() Server { func (c *Context) Server() Server {
return c.server return c.server
@ -85,7 +84,15 @@ func (c *Context) Server() Server {
func (c *Context) Register(s *Context, x Server, n ...string) *Context { func (c *Context) Register(s *Context, x Server, n ...string) *Context {
for _, n := range n { for _, n := range n {
name(n, s) if s, ok := Info.names[n]; ok {
last := ""
switch s := s.(type) {
case *Context:
last = s.Name
}
panic(kit.Format("%s %s %v", ErrExists, n, last))
}
Info.names[n] = s
} }
if s.Merge(s); c.Contexts == nil { if s.Merge(s); c.Contexts == nil {
@ -95,10 +102,8 @@ func (c *Context) Register(s *Context, x Server, n ...string) *Context {
s.root = c.root s.root = c.root
s.context = c s.context = c
s.server = x s.server = x
s.Merge(s)
return s return s
} }
func (c *Context) Merge(s *Context) *Context { func (c *Context) Merge(s *Context) *Context {
if c.Commands == nil { if c.Commands == nil {
c.Commands = map[string]*Command{} c.Commands = map[string]*Command{}
@ -110,29 +115,6 @@ func (c *Context) Merge(s *Context) *Context {
c.Commands[CTX_EXIT] = &Command{Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.Save() }} c.Commands[CTX_EXIT] = &Command{Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.Save() }}
} }
for key, cmd := range s.Commands {
if p, ok := c.Commands[key]; ok && s != c {
switch last, next := p.Hand, cmd.Hand; key {
case CTX_INIT:
cmd.Hand = func(m *Message, c *Context, key string, arg ...string) {
last(m, c, key, arg...)
next(m, c, key, arg...)
}
case CTX_EXIT:
cmd.Hand = func(m *Message, c *Context, key string, arg ...string) {
next(m, c, key, arg...)
last(m, c, key, arg...)
}
}
}
if cmd.Meta == nil {
cmd.Meta = kit.Dict()
}
if c.Commands[key] = cmd; cmd.List == nil {
cmd.List = c.split(cmd.Name)
}
merge := func(pre *Command, before bool, key string, cmd *Command, cb ...CommandHandler) { merge := func(pre *Command, before bool, key string, cmd *Command, cb ...CommandHandler) {
last := pre.Hand last := pre.Hand
pre.Hand = func(m *Message, c *Context, _key string, arg ...string) { pre.Hand = func(m *Message, c *Context, _key string, arg ...string) {
@ -151,24 +133,37 @@ func (c *Context) Merge(s *Context) *Context {
} }
} }
} }
for key, cmd := range s.Commands {
if p, ok := c.Commands[key]; ok && s != c {
switch hand := cmd.Hand; key {
case CTX_INIT:
merge(p, true, key, cmd, hand)
case CTX_EXIT:
merge(p, false, key, cmd, hand)
}
}
if c.Commands[key] = cmd; cmd.List == nil {
cmd.List = c.split(cmd.Name)
}
if cmd.Meta == nil {
cmd.Meta = kit.Dict()
}
for k, a := range cmd.Action { for k, a := range cmd.Action {
if p, ok := c.Commands[k]; ok { if p, ok := c.Commands[k]; ok {
switch hand := a.Hand; k { switch h := a.Hand; k {
case CTX_INIT: case CTX_INIT:
merge(p, true, key, cmd, func(m *Message, c *Context, _key string, arg ...string) { merge(p, true, key, cmd, func(m *Message, c *Context, key string, arg ...string) { h(m, arg...) })
hand(m, arg...)
})
case CTX_EXIT: case CTX_EXIT:
merge(p, false, key, cmd, func(m *Message, c *Context, _key string, arg ...string) { merge(p, false, key, cmd, func(m *Message, c *Context, key string, arg ...string) { h(m, arg...) })
hand(m, arg...)
})
} }
} }
if s != c { if s != c {
switch k { switch k {
case "search": case "search":
merge(c.Commands[CTX_INIT], true, key, cmd, func(m *Message, c *Context, _key string, arg ...string) { merge(c.Commands[CTX_INIT], true, key, cmd, func(m *Message, c *Context, key string, arg ...string) {
if m.CommandKey() != "search" { if m.CommandKey() != "search" {
m.Cmd("search", "create", m.CommandKey(), m.PrefixKey()) m.Cmd("search", "create", m.CommandKey(), m.PrefixKey())
} }
@ -211,11 +206,10 @@ func (c *Context) Merge(s *Context) *Context {
} }
return c return c
} }
func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context { func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context {
s := &Context{Name: name, Help: help} s := &Context{Name: name, Help: help}
if m.target.server != nil { if c.server != nil {
c.Register(s, m.target.server.Spawn(m, s, arg...)) c.Register(s, c.server.Spawn(m, s, arg...))
} else { } else {
c.Register(s, nil) c.Register(s, nil)
} }
@ -332,6 +326,14 @@ func (m *Message) Spawn(arg ...interface{}) *Message {
json.Unmarshal(val, &msg.meta) json.Unmarshal(val, &msg.meta)
case Option: case Option:
msg.Option(val.Name, val.Value) msg.Option(val.Name, val.Value)
case map[string]interface{}:
for k, v := range val {
msg.Option(k, v)
}
case map[string]string:
for k, v := range val {
msg.Option(k, v)
}
case http.ResponseWriter: case http.ResponseWriter:
msg.W = val msg.W = val
case *http.Request: case *http.Request:
@ -340,14 +342,6 @@ func (m *Message) Spawn(arg ...interface{}) *Message {
msg.target = val msg.target = val
case string: case string:
msg._key = val msg._key = val
case map[string]string:
for k, v := range val {
msg.Option(k, v)
}
case map[string]interface{}:
for k, v := range val {
msg.Option(k, v)
}
} }
} }
return msg return msg
@ -364,41 +358,23 @@ func (m *Message) Travel(cb interface{}) *Message {
cb(list[i].context, list[i]) cb(list[i].context, list[i])
case func(*Context, *Context, string, *Command): case func(*Context, *Context, string, *Command):
ls := []string{}
for k := range list[i].Commands {
ls = append(ls, k)
}
sort.Strings(ls)
target := m.target target := m.target
for _, k := range ls { // 命令列表 for _, k := range kit.SortedKey(list[i].Commands) { // 命令列表
m.target = list[i] m.target = list[i]
cb(list[i].context, list[i], k, list[i].Commands[k]) cb(list[i].context, list[i], k, list[i].Commands[k])
} }
m.target = target m.target = target
case func(*Context, *Context, string, *Config): case func(*Context, *Context, string, *Config):
ls := []string{}
for k := range list[i].Configs {
ls = append(ls, k)
}
sort.Strings(ls)
target := m.target target := m.target
for _, k := range ls { // 配置列表 for _, k := range kit.SortedKey(list[i].Configs) { // 配置列表
m.target = list[i] m.target = list[i]
cb(list[i].context, list[i], k, list[i].Configs[k]) cb(list[i].context, list[i], k, list[i].Configs[k])
} }
m.target = target m.target = target
} }
ls := []string{} for _, k := range kit.SortedKey(list[i].Contexts) { // 遍历递进
for k := range list[i].Contexts {
ls = append(ls, k)
}
sort.Strings(ls)
for _, k := range ls { // 遍历递进
list = append(list, list[i].Contexts[k]) list = append(list, list[i].Contexts[k])
} }
} }
@ -510,11 +486,10 @@ func (m *Message) Cmdx(arg ...interface{}) string {
func (m *Message) Cmdy(arg ...interface{}) *Message { func (m *Message) Cmdy(arg ...interface{}) *Message {
return m.Copy(m.cmd(arg...)) return m.Copy(m.cmd(arg...))
} }
func (m *Message) Confi(key string, sub string) int { func (m *Message) Confi(key string, sub string) int {
return kit.Int(m.Conf(key, sub)) return kit.Int(m.Conf(key, sub))
} }
func (m *Message) Confv(arg ...interface{}) (val interface{}) { func (m *Message) Confv(arg ...interface{}) (val interface{}) { // key sub val
run := func(conf *Config) { run := func(conf *Config) {
if len(arg) == 1 { if len(arg) == 1 {
val = conf.Value val = conf.Value
@ -541,15 +516,15 @@ func (m *Message) Confv(arg ...interface{}) (val interface{}) {
} }
return return
} }
func (m *Message) Confm(key string, chain interface{}, cbs ...interface{}) map[string]interface{} { func (m *Message) Confm(key string, sub interface{}, cbs ...interface{}) map[string]interface{} {
val := m.Confv(key, chain) val := m.Confv(key, sub)
if len(cbs) > 0 { if len(cbs) > 0 {
kit.Fetch(val, cbs[0]) kit.Fetch(val, cbs[0])
} }
value, _ := val.(map[string]interface{}) value, _ := val.(map[string]interface{})
return value return value
} }
func (m *Message) Conf(arg ...interface{}) string { func (m *Message) Conf(arg ...interface{}) string { // key sub val
return kit.Format(m.Confv(arg...)) return kit.Format(m.Confv(arg...))
} }
func (m *Message) Capi(key string, val ...interface{}) int { func (m *Message) Capi(key string, val ...interface{}) int {