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) {
m.Richs(ROLE, nil, userrole, func(key string, value 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
})
}
func _role_white(m *ice.Message, userrole, chain string) {
m.Richs(ROLE, nil, userrole, func(key string, value 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
})
}
@ -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) {
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[m.Option(mdb.KEY)] = true
})
}},
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.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{})
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"
BENCH = "bench"
PPROF = "pprof"
CLEAR = "clear"
TIMEOUT = "timeout"
STATUS = "status"
ERROR = "error"
START = "start"
RESTART = "restart"
CLEAR = "clear"
RELOAD = "reload"
STOP = "stop"
RESTART = "restart"
START = "start"
STOP = "stop"
OPEN = "open"
CLOSE = "close"
BEGIN = "begin"
END = "end"
CODE = "code"
COST = "cost"
@ -88,11 +93,6 @@ const (
FROM = "from"
MAIN = "main"
KILL = "kill"
OPEN = "open"
CLOSE = "close"
BEGIN = "begin"
END = "end"
)
const DAEMON = "daemon"

View File

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

View File

@ -39,7 +39,7 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
break
}
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]))
}

View File

@ -33,7 +33,7 @@ func _route_travel(m *ice.Message, route string) {
}
func _route_list(m *ice.Message) {
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] {
case SERVER:

View File

@ -15,9 +15,6 @@ import (
"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) {
if link = m.Config(DOMAIN); 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:
m.PushSearch(mdb.TEXT, m.Cmd(SPIDE, value[mdb.NAME], ice.OptionFields("")).Append("client.url"), value)
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 != "" {
@ -309,9 +306,9 @@ func init() {
m.Table(func(index int, value map[string]string, head []string) {
switch value[mdb.TYPE] {
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:
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")

View File

@ -64,7 +64,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
return
}
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) {
m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) {
_serve_handle(k, x, msg, frame, r)

98
conf.go
View File

@ -14,8 +14,8 @@ const (
FALSE = "false"
SUCCESS = "success"
FAILURE = "failure"
RESTART = "restart"
PROCESS = "process"
RESTART = "restart"
OF = " of "
INIT = "init"
@ -201,15 +201,6 @@ const ( // MSG
MSG_STORM = "sess.storm"
MSG_TOAST = "sess.toast"
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
RENDER_RAW = "_raw"
@ -242,19 +233,30 @@ const ( // PROCESS
FIELD_PREFIX = "_prefix"
)
const ( // Err
ErrWarn = "warn: "
ErrPanic = "panic: "
ErrExists = "exists: "
ErrExpire = "expire: "
ErrTimeout = "timeout: "
ErrFailure = "failure: "
ErrNotLogin = "not login: "
ErrNotFound = "not found: "
ErrNotRight = "not right: "
ErrNotStart = "not start: "
ErrNotImplement = "not implement: "
const ( // CACHE
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 ( // 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
// 通用
LOG_INFO = "info"
@ -285,18 +287,18 @@ const ( // LOG
LOG_EXPORT = "export"
LOG_IMPORT = "import"
)
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 ( // Err
ErrWarn = "warn: "
ErrPanic = "panic: "
ErrExists = "exists: "
ErrExpire = "expire: "
ErrTimeout = "timeout: "
ErrFailure = "failure: "
ErrNotLogin = "not login: "
ErrNotFound = "not found: "
ErrNotRight = "not right: "
ErrNotStart = "not start: "
ErrNotImplement = "not implement: "
)
const (
@ -313,26 +315,32 @@ const (
SSH = "ssh"
MDB = "mdb"
)
const (
CONFIG = "config"
const ( // ctx
COMMAND = "command"
ACTION = "action"
CONFIG = "config"
STYLE = "style"
INDEX = "index"
ARGS = "args"
INPUTS = "inputs"
FEATURE = "feature"
)
const (
const ( // web
SERVE = "serve"
SPACE = "space"
SPIDE = "spide"
CACHE = "cache"
)
const (
KEY = "key"
VALUE = "value"
HASH = "hash"
TIME = "time"
TYPE = "type"
NAME = "name"
TEXT = "text"
const ( // mdb
KEY = "key"
VALUE = "value"
SCRIPT = "script"
LINK = "link"
META = "meta"
HASH = "hash"
TIME = "time"
TYPE = "type"
NAME = "name"
TEXT = "text"
)

View File

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

View File

@ -78,7 +78,7 @@ func init() {
if kit.FileExists(path.Join(ice.USR_VOLCANOS, ice.PROTO_JS)) {
m.Cmd(BINPACK, mdb.REMOVE)
} 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)} {
if b, ok := ice.Info.Pack[key]; ok {
if cb != nil {
@ -91,7 +91,7 @@ func init() {
return false
}
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 false
@ -134,18 +134,25 @@ func init() {
fmt.Fprintln(f)
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)
_binpack_can(m, f, ice.USR_VOLCANOS)
_binpack_dir(m, f, ice.USR_INTSHELL)
// _binpack_dir(m, f, ice.USR_ICEBERGS)
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_dir(m, f, ice.USR_INTSHELL)
fmt.Fprintln(f, ` }`)
}
fmt.Fprintln(f, ` pack := map[string][]byte{`)
_binpack_ctx(m, f)
fmt.Fprintln(f, _binpack_file(m, ice.ETC_INIT_SHY))
fmt.Fprintln(f, _binpack_file(m, ice.ETC_EXIT_SHY))
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) {

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) })
}
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)
} 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])
@ -105,7 +105,7 @@ func _go_show(m *ice.Message, arg ...string) {
}
})
} 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())
} else {
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)
}},
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 == "" {
for p, k := range ice.Info.File {
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 {
Make MakeInfo
HostName string
PathName string
UserName string
@ -33,12 +35,11 @@ var Info = struct {
CtxShare string
CtxRiver string
Make MakeInfo
Help string
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
Log func(m *Message, p, l, s string)
render map[string]func(*Message, string, ...interface{}) string
@ -52,15 +53,17 @@ report: shylinuxc@gmail.com
server: https://shylinux.com
source: https://shylinux.com/x/icebergs
`,
Pack: map[string][]byte{},
File: 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{},
names: map[string]interface{}{},
}
func FileKey(dir string) string {
func FileCmd(dir string) string {
dir = strings.Split(dir, DF)[0]
dir = strings.ReplaceAll(dir, ".js", ".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) {
dir = strings.TrimPrefix(dir, Info.Make.Path+PS)
}
// println("what ", dir, kit.Path(""), Info.Make.Path)
if strings.HasPrefix(dir, kit.Path("")+PS) {
dir = strings.TrimPrefix(dir, kit.Path("")+PS)
}
@ -83,25 +85,5 @@ func FileKey(dir string) string {
}
return dir
}
func AddFileKey(dir, key string) {
Info.File[FileKey(dir)] = key
}
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
}
func AddFileCmd(dir, key string) { Info.File[FileCmd(dir)] = key }
func GetFileCmd(dir string) string { return Info.File[FileCmd(dir)] }

View File

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

View File

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

228
meta.go
View File

@ -1,7 +1,6 @@
package ice
import (
"sort"
"strconv"
"strings"
@ -17,8 +16,17 @@ func (m *Message) Set(key string, arg ...string) *Message {
if len(arg) > 0 {
for i := 0; i < len(m.meta[KEY]); i++ {
if m.meta[KEY][i] == arg[0] {
m.meta[KEY][i] = ""
m.meta[VALUE][i] = ""
if len(arg) > 1 {
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
@ -47,7 +55,7 @@ func (m *Message) Set(key string, arg ...string) *Message {
if m.meta[KEY][i] == key {
if len(arg) > 0 {
m.meta[VALUE][i] = arg[0]
return m
break
}
for ; i < len(m.meta[KEY])-1; i++ {
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 {
head = kit.Simple(arg[0])
} else { // 键值排序
for k := range kit.KeyValue(map[string]interface{}{}, "", value) {
head = append(head, k)
}
sort.Strings(head)
head = kit.SortedKey(kit.KeyValue(map[string]interface{}{}, "", value))
}
var val map[string]interface{}
@ -146,10 +151,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
if len(arg) > 0 {
head = kit.Simple(arg[0])
} else { // 键值排序
for k := range value {
head = append(head, k)
}
sort.Strings(head)
head = kit.SortedKey(value)
}
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]...)
return m
}
func (m *Message) Sort(key string, arg ...string) *Message {
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]
}
}
}
// 输出数据
func (m *Message) Length() (max int) {
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])
if l := len(m.meta[k]); l > max {
max = l
}
}
return m
return max
}
func (m *Message) Tables(cbs ...func(value map[string]string)) *Message {
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
}
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 {
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...), "")
}
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 (
"bytes"
"encoding/csv"
"net/url"
"path"
"reflect"
"strings"
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 {
bio := bytes.NewBufferString(text)
r := csv.NewReader(bio)
@ -37,9 +27,6 @@ func (m *Message) CSV(text string, head ...string) *Message {
}
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
m.Set(MSG_APPEND).Set(MSG_RESULT)
field := kit.Select("", arg, 0)
@ -84,39 +71,19 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
}
return m
}
func (m *Message) FieldsIsDetail() bool {
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) SplitIndex(str string, arg ...string) *Message {
return m.Split(str, kit.Simple("index", arg)...)
}
func (m *Message) PushDetail(value interface{}, arg ...interface{}) *Message {
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{} {
if len(cb) > 0 {
return m.Optionv(kit.Keycb(key), cb...)
}
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 {
for _, k := range m.meta[MSG_APPEND] {
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
}
func (m *Message) MergeLink(url string, arg ...interface{}) string {
return strings.Split(kit.MergeURL2(m.Option(MSG_USERWEB), url, arg...), "?")[0]
func (m *Message) SetAppend(arg ...string) *Message {
return m.Set(MSG_APPEND, arg...)
}
func (m *Message) MergeURL2(url string, arg ...interface{}) string {
return kit.MergeURL2(m.Option(MSG_USERWEB), url, arg...)
func (m *Message) SetResult(arg ...string) *Message {
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) 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) 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) cmd(arg ...interface{}) *Message {
opts := map[string]interface{}{}
@ -199,9 +153,10 @@ func (m *Message) cmd(arg ...interface{}) *Message {
// 解析参数
for _, v := range arg {
switch val := v.(type) {
case func(int, map[string]string, []string):
defer func() { m.Table(val) }()
case Option:
opts[val.Name] = val.Value
case *Option:
opts[val.Name] = val.Value
case map[string]interface{}:
for k, v := range val {
opts[k] = v
@ -210,14 +165,11 @@ func (m *Message) cmd(arg ...interface{}) *Message {
for k, v := range val {
opts[k] = v
}
case *Option:
opts[val.Name] = val.Value
case Option:
opts[val.Name] = val.Value
case string:
args = append(args, v)
case func(int, map[string]string, []string):
defer func() { m.Table(val) }()
default:
if reflect.Func == reflect.TypeOf(val).Kind() {
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 (
"encoding/json"
"net/url"
"os"
"path"
"strings"
@ -82,6 +83,15 @@ func (m *Message) OptionTemplate() string {
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 {
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())
}
func (m *Message) Confirm(text string) string {
return m.Cmdx(SPACE, m.Option(MSG_DAEMON), "confirm", text)
}
func (m *Message) ToastProcess(arg ...interface{}) func() {
if len(arg) == 0 {
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) ProcessHold() { m.Process(PROCESS_HOLD) }
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...)
}

113
render.go
View File

@ -29,8 +29,8 @@ func Render(m *Message, cmd string, args ...interface{}) string {
}
list := []string{}
for _, k := range kit.Split(kit.Join(arg)) {
list = append(list, kit.Format(`<input type="button" name="%s" value="%s">`,
k, kit.Select(k, kit.Value(m._cmd.Meta, kit.Keys("_trans", k)), m.Option(MSG_LANGUAGE) != "en")))
list = append(list, kit.Format(`<input type="button" name="%s" value="%s">`, k,
kit.Select(k, kit.Value(m._cmd.Meta, kit.Keys("_trans", k)), m.Option(MSG_LANGUAGE) != "en")))
}
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 {
m.Cmdy("space", pod, "website", "action", "show", dir, arg)
m.RenderResult()
return m
return m.RenderResult()
}
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...))))
@ -89,20 +88,20 @@ func (m *Message) RenderCmd(index string, args ...interface{}) {
msg := m.Cmd(COMMAND, index)
list = kit.Format(kit.List(kit.Dict(
INDEX, index, ARGS, kit.Simple(args),
msg.AppendSimple(NAME, "help"),
"feature", kit.UnMarshal(msg.Append("meta")),
"inputs", kit.UnMarshal(msg.Append("list")),
msg.AppendSimple(NAME, HELP),
FEATURE, kit.UnMarshal(msg.Append(META)),
INPUTS, kit.UnMarshal(msg.Append(LIST)),
)))
}
m.RenderResult(kit.Format(`<!DOCTYPE html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=0.8,user-scalable=no">
<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">
</head>
<body>
<script src="/page/can.js"></script>
<script>can(%s)</script>
</head>
<body>
</body>
`, list))
}
@ -115,29 +114,27 @@ func (m *Message) IsCliUA() bool {
}
func (m *Message) PushAnchor(arg ...interface{}) { // [name] link
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...
if m.FieldsIsDetail() {
for i, k := range m.meta["key"] {
if k == "action" {
m.meta["value"][i] = Render(m, RENDER_BUTTON, arg...)
return
}
}
}
if len(m.meta["action"]) >= m.Length() {
m.meta["action"] = []string{}
}
if !m.IsCliUA() {
if m.FieldsIsDetail() {
for i, k := range m.meta[KEY] {
if k == ACTION {
m.meta[VALUE][i] = Render(m, RENDER_BUTTON, arg...)
return
}
}
} else if len(m.meta[ACTION]) >= m.Length() {
m.meta[ACTION] = []string{}
}
m.Push(ACTION, Render(m, RENDER_BUTTON, arg...))
}
}
func (m *Message) PushScript(arg ...string) { // [type] text...
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]
@ -170,11 +167,26 @@ func (m *Message) PushAction(list ...interface{}) *Message {
if len(m.meta[MSG_APPEND]) == 0 {
return m
}
m.Set(MSG_APPEND, ACTION)
m.Table(func(index int, value map[string]string, head []string) {
return m.Set(MSG_APPEND, ACTION).Table(func(index int, value map[string]string, head []string) {
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) {
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
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...))
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 {
if file == "" {
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...)
}
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 {
m.Option(MSG_DISPLAY, kit.MergeURL(DisplayRequire(2, file)[DISPLAY], arg...))
return m
}
func (m *Message) DisplayStoryJSON(arg ...interface{}) *Message {
return m.DisplayStory("json", arg...)
}
func DisplayBase(file string, arg ...string) map[string]string {
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 {
if file == "" {
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...)
}
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 {
if file == "" {
file = kit.Keys(kit.FileName(n+1), JS)

145
type.go
View File

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