1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 08:48:06 +08:00

add kit.shy

This commit is contained in:
shaoying 2019-07-29 01:28:04 +08:00
parent bbb8570de3
commit fc24ba8a6c
18 changed files with 614 additions and 2010 deletions

View File

@ -35,11 +35,13 @@ syn match shyComment "#.*$"
syn match shyContext "^\~[a-zA-Z0-9_\.]\+\>"
syn match shyCommand "\(^\|\t\| \|$(\)[a-zA-Z0-9_\.]\+\>"
call Keys("Operator", ["new"])
syn match shyOperator "option"
call Keys("Statment", ["config", "cache"])
call Keys("Statment", ["return", "source"])
call Keys("Statment", ["let", "var"])
call Keys("Statment", ["if", "else", "else if", "for", "fun", "end"])
call Keys("Statment", ["var", "let"])
call Keys("Statment", ["fun", "kit"])
call Keys("Statment", ["if", "else", "else if", "for", "end"])
call Keys("Statment", ["label", "goto"])
" context nfs
call Keys("SubCommand", ["import", "export", "load", "save"])

View File

@ -40,6 +40,7 @@ func (cli *CLI) schedule(m *ctx.Message) string {
}
func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
c.Configs["_index"] = &ctx.Config{Name: "_index", Value: []interface{}{}, Help: "_index"}
return &CLI{Context: c}
}
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
@ -116,10 +117,10 @@ var Index = &ctx.Context{Name: "test", Help: "测试工具",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"componet_name": "demo", "componet_help": "demo",
"componet_tmpl": "componet", "componet_view": "componet", "componet_init": "",
"componet_type": "public", "componet_ctx": "demo", "componet_cmd": "demo",
"componet_args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "componet", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
@ -141,7 +142,7 @@ func main() {
{init: function(page, pane, field, option, output) {
kit.Log("hello world")
}}
`}, map[string]interface{}{"name": "local.shy", "text": ` `},
`}, map[string]interface{}{"name": "index.shy", "text": ` `}, map[string]interface{}{"name": "local.shy", "text": ` `},
},
}, "script": map[string]interface{}{
"path": "usr/script",
@ -976,10 +977,9 @@ func main() {
m.Cmdy("cli.context")
break
}
fallthrough
default:
if p, e := plugin.Open(path.Join(m.Conf("publish", "path"), arg[0], "index.so")); e == nil {
if s, e := p.Lookup("Index"); m.Assert(e) {
if s, e := p.Lookup("Index"); false && m.Assert(e) {
msg := m.Spawn(c.Register(*(s.(**ctx.Context)), nil, arg[0])).Cmd("_init", arg[1:])
msg.Cap("stream", arg[0])
msg.Confm("_index", func(index int, value map[string]interface{}) {
@ -992,11 +992,32 @@ func main() {
})
m.Table()
}
return e
} else {
m.Log("info", "open %v", e)
}
msg := m.Find(arg[0], false)
if msg == nil {
m.Start(arg[0], "shy")
msg = m
} else {
msg.Target().Configs["_index"].Value = []interface{}{}
}
msg.Optionv("bio.ctx", msg.Target())
if p := msg.Cmdx("nfs.path", path.Join(msg.Conf("publish", "path"), arg[0], "index.shy")); p != "" {
msg.Cmdy("nfs.source", p)
msg.Confv("ssh.componet", arg[0], msg.Confv("_index"))
}
m.Confm("ssh.componet", arg[0], func(index int, value map[string]interface{}) {
m.Push("index", index)
m.Push("name", value["componet_name"])
m.Push("help", value["componet_help"])
m.Push("ctx", value["componet_ctx"])
m.Push("cmd", value["componet_cmd"])
})
m.Table()
default:
restart := false
for _, link := range kit.View([]string{arg[0]}, m.Confm("upgrade")) {
file := kit.Select(link, m.Conf("upgrade", []string{"list", strings.Replace(link, ".", "_", -1)}))

View File

@ -4,5 +4,5 @@ var version = struct {
host string
self int
}{
"2019-07-28 08:54:43", "com", 220,
"2019-07-29 00:09:20", "mac", 237,
}

View File

@ -1,586 +1,87 @@
package ctx
import (
"encoding/json"
"fmt"
"html/template"
"strconv"
"strings"
"toolkit"
)
var CGI = template.FuncMap{
"meta": func(arg ...interface{}) string {
//meta meta [key [index]]
if len(arg) == 0 {
return ""
}
up := ""
list := []string{}
switch data := arg[0].(type) {
case map[string][]string:
if len(arg) == 1 {
list = append(list, fmt.Sprintf("detail: %s\n", data["detail"]))
list = append(list, fmt.Sprintf("option: %s\n", data["option"]))
list = append(list, fmt.Sprintf("result: %s\n", data["result"]))
list = append(list, fmt.Sprintf("append: %s\n", data["append"]))
break
}
if key, ok := arg[1].(string); ok {
if list, ok = data[key]; ok {
arg = arg[1:]
} else {
return up
}
} else {
return fmt.Sprintf("%v", data)
}
case []string:
list = data
default:
if data == nil {
return ""
}
return fmt.Sprintf("%v", data)
}
func index(name string, arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return strings.Join(list, "")
return m.Meta[name]
}
index, ok := arg[1].(int)
if !ok {
return strings.Join(list, "")
}
if index >= len(list) {
return ""
}
return list[index]
},
"sess": func(arg ...interface{}) string {
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
if len(arg) == 1 {
return fmt.Sprintf("%v", m)
switch value := arg[1].(type) {
case int:
if 0 <= value && value < len(m.Meta[name]) {
return m.Meta[name][value]
}
switch which := arg[1].(type) {
case string:
m.Sess(which, arg[2:]...)
return ""
}
}
return ""
},
"ctx": func(arg ...interface{}) string {
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
if len(arg) == 1 {
return fmt.Sprintf("%v", m)
}
switch which := arg[1].(type) {
case string:
switch which {
case "name":
return fmt.Sprintf("%s", m.target.Name)
case "help":
return fmt.Sprintf("%s", m.target.Help)
case "context":
return fmt.Sprintf("%s", m.target.context.Name)
case "contexts":
ctx := []string{}
for _, v := range m.target.contexts {
ctx = append(ctx, fmt.Sprintf("%d", v.Name))
}
return strings.Join(ctx, " ")
case "time":
return m.time.Format("2006-01-02 15:04:05")
case "source":
return m.source.Name
case "target":
return m.target.Name
case "message":
return fmt.Sprintf("%d", m.message.code)
case "messages":
case "sessions":
msg := []string{}
for k, _ := range m.Sessions {
msg = append(msg, fmt.Sprintf("%s", k))
}
return strings.Join(msg, " ")
}
case int:
}
}
return ""
},
"msg": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
if len(arg) == 1 {
return fmt.Sprintf("%v", m.Format())
}
switch which := arg[1].(type) {
case string:
switch which {
case "spawn":
return m.Spawn()
case "code":
return m.code
case "time":
return m.time.Format("2006-01-02 15:04:05")
case "source":
return m.source.Name
case "target":
return m.target.Name
case "message":
return m.message
case "messages":
return m.messages
case "sessions":
return m.Sessions
default:
return m.Sess(which)
}
case int:
ms := []*Message{m}
for i := 0; i < len(ms); i++ {
if ms[i].code == which {
return ms[i]
}
ms = append(ms, ms[i].messages...)
}
}
}
return ""
},
"cap": func(arg ...interface{}) string {
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
if len(arg) == 1 {
return fmt.Sprintf("%v", m)
}
switch which := arg[1].(type) {
case string:
if len(arg) == 2 {
return m.Cap(which)
}
switch value := arg[2].(type) {
case string:
return m.Cap(which, value)
case int:
return fmt.Sprintf("%d", m.Capi(which, value))
case bool:
return fmt.Sprintf("%t", m.Caps(which, value))
default:
return m.Cap(which, fmt.Sprintf("%v", arg[2]))
}
}
}
return ""
},
"conf": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
if m, ok := arg[0].(*Message); ok {
if len(arg) == 1 {
list := []string{}
for k, _ := range m.target.Configs {
list = append(list, k)
}
return list
}
switch which := arg[1].(type) {
case string:
if len(arg) == 2 {
return m.Confv(which)
}
return m.Confv(which, arg[2:]...)
}
}
return ""
},
"cmd": func(m *Message, args ...interface{}) *Message {
if len(args) == 0 {
return m
}
return m.Sess("cli").Put("option", "bench", "").Cmd("source", args)
},
"detail": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return m.Meta["detail"]
}
index := 0
switch value := arg[1].(type) {
case int:
index = value
case string:
i, e := strconv.Atoi(value)
m.Assert(e)
index = i
}
case string:
if len(arg) == 2 {
return m.Detail(index)
return m.Optionv(value)
}
return m.Detail(index, arg[2])
case map[string][]string:
return strings.Join(m["detail"], "")
case []string:
return strings.Join(m, "")
default:
return m
}
return ""
},
"option": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return m.Meta["option"]
}
switch value := arg[1].(type) {
switch val := arg[2].(type) {
case int:
if 0 <= value && value < len(m.Meta["option"]) {
return m.Meta["option"][value]
}
case string:
if len(arg) == 2 {
return m.Optionv(value)
}
switch val := arg[2].(type) {
case int:
if 0 <= val && val < len(m.Meta[value]) {
return m.Meta[value][val]
switch list := m.Optionv(value).(type) {
case []string:
if 0 <= val && val < len(list) {
return list[val]
}
case []interface{}:
if 0 <= val && val < len(list) {
return list[val]
}
}
}
case map[string][]string:
if len(arg) == 1 {
return strings.Join(m["option"], "")
}
case map[string][]string:
if len(arg) == 1 {
return m[name]
}
switch value := arg[1].(type) {
case int:
return m[name][value]
case string:
if len(arg) == 2 {
return m[value]
}
switch value := arg[1].(type) {
case string:
return strings.Join(m[value], "")
switch val := arg[2].(type) {
case int:
return m[value][val]
}
case []string:
return strings.Join(m, "")
default:
}
case []string:
if len(arg) == 1 {
return m
}
return ""
switch value := arg[1].(type) {
case int:
return m[value]
}
default:
return m
}
return ""
}
var CGI = template.FuncMap{
"option": func(arg ...interface{}) interface{} {
return index("option", arg...)
},
"options": func(arg ...interface{}) string {
if len(arg) == 0 {
return ""
}
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return strings.Join(m.Meta["option"], "")
}
switch value := arg[1].(type) {
case int:
if 0 <= value && value < len(m.Meta["option"]) {
return kit.Format(m.Meta["option"][value])
}
case string:
if len(arg) == 2 {
switch v := m.Optionv(value).(type) {
case []string:
return kit.Format(strings.Join(v, ""))
default:
return kit.Format(v)
}
}
switch val := arg[2].(type) {
case int:
if 0 <= val && val < len(m.Meta[value]) {
return kit.Format(m.Meta[value][val])
}
}
}
case map[string][]string:
if len(arg) == 1 {
return strings.Join(m["option"], "")
}
switch value := arg[1].(type) {
case string:
return strings.Join(m[value], "")
}
case []string:
return strings.Join(m, "")
default:
return kit.Format(m)
}
return ""
},
"result": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return m.Meta["result"]
}
index := 0
switch value := arg[1].(type) {
case int:
index = value
case string:
i, e := strconv.Atoi(value)
m.Assert(e)
index = i
}
if len(arg) == 2 {
return m.Result(index)
}
return m.Result(index, arg[2])
case map[string][]string:
return strings.Join(m["result"], "")
case []string:
return strings.Join(m, "")
default:
return m
}
return ""
},
"append": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return m.Meta["append"]
}
switch value := arg[1].(type) {
case int:
if 0 <= value && value < len(m.Meta["append"]) {
return m.Meta["append"][value]
}
case string:
if len(arg) == 2 {
return m.Meta[value]
}
switch val := arg[2].(type) {
case int:
if 0 <= val && val < len(m.Meta[value]) {
return m.Meta[value][val]
}
}
}
case map[string][]string:
if len(arg) == 1 {
return strings.Join(m["append"], "")
}
switch value := arg[1].(type) {
case string:
return strings.Join(m[value], "")
}
case []string:
return strings.Join(m, "")
default:
return m
}
return ""
},
"table": func(arg ...interface{}) []interface{} {
if len(arg) == 0 {
return []interface{}{}
}
switch m := arg[0].(type) {
case *Message:
if len(m.Meta["append"]) == 0 {
return []interface{}{}
}
if len(arg) == 1 {
data := []interface{}{}
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := map[string]string{}
for _, k := range m.Meta["append"] {
line[k] = m.Meta[k][i]
if len(m.Meta[k]) != i {
continue
}
}
data = append(data, line)
}
return data
}
case map[string][]string:
if len(arg) == 1 {
data := []interface{}{}
nrow := len(m[m["append"][0]])
for i := 0; i < nrow; i++ {
line := map[string]string{}
for _, k := range m["append"] {
line[k] = m[k][i]
}
data = append(data, line)
}
return data
}
}
return []interface{}{}
},
"list": func(arg interface{}) interface{} {
n := 0
switch v := arg.(type) {
switch value := index("option", arg...).(type) {
case string:
i, e := strconv.Atoi(v)
if e == nil {
n = i
}
case int:
n = v
return value
case []string:
return strings.Join(value, "")
}
list := make([]int, n)
for i := 1; i <= n; i++ {
list[i-1] = i
}
return list
},
"slice": func(list interface{}, arg ...interface{}) interface{} {
switch l := list.(type) {
case string:
if len(arg) == 0 {
return l
}
if len(arg) == 1 {
return l[arg[0].(int):]
}
if len(arg) == 2 {
return l[arg[0].(int):arg[1].(int)]
}
}
return ""
},
"work": func(m *Message, arg ...interface{}) interface{} {
switch len(arg) {
case 0:
list := map[string]map[string]interface{}{}
m.Cmd("aaa.sess", "bench").Table(func(node map[string]string) {
list[node["key"]] = m.Confm("auth", node["key"])
})
return list
}
return nil
},
"parse": func(m *Message, arg ...interface{}) interface{} {
switch len(arg) {
case 1:
v := m.Parse(kit.Format(arg[0]))
return v
}
return nil
},
"unescape": func(str string) interface{} {
return template.HTML(str)
},
"json": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
b, _ := json.MarshalIndent(arg[0], "", " ")
return string(b)
},
"so": func(arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
cli := Pulse.Sess("cli")
cmd := strings.Join(kit.Trans(arg), " ")
cli.Cmd("source", cmd)
result := []string{}
if len(cli.Meta["append"]) > 0 {
result = append(result, "<table>")
result = append(result, "<caption>", cmd, "</caption>")
cli.Table(func(line int, maps map[string]string) {
if line == 0 {
result = append(result, "<tr>")
for _, v := range cli.Meta["append"] {
result = append(result, "<th>", v, "</th>")
}
result = append(result, "</tr>")
}
result = append(result, "<tr>")
for _, k := range cli.Meta["append"] {
result = append(result, "<td>", maps[k], "</td>")
}
result = append(result, "</tr>")
})
result = append(result, "</table>")
} else {
result = append(result, "<pre><code>")
result = append(result, fmt.Sprintf("%s", cli.Find("shy", false).Conf("prompt")), cmd, "\n")
result = append(result, cli.Meta["result"]...)
result = append(result, "</code></pre>")
}
return template.HTML(strings.Join(result, ""))
},
}

View File

@ -440,7 +440,9 @@ func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context
context := []*Context{m.target}
for _, v := range kit.Trans(m.Optionv("ctx.chain")) {
if msg := m.Sess(v, false); msg != nil && msg.target != nil {
context = append(context, msg.target)
if msg.target != m.target && msg.target != m.source {
context = append(context, msg.target)
}
}
}
context = append(context, m.source)
@ -510,6 +512,7 @@ func (m *Message) Parse(arg interface{}) string {
return ""
}
func (m *Message) Goshy(input []string, index int, stack *kit.Stack, cb func(*Message)) bool {
m.Optionv("bio.msg", m)
if stack == nil {
stack = &kit.Stack{}
stack.Push("source", true, 0)
@ -522,7 +525,7 @@ func (m *Message) Goshy(input []string, index int, stack *kit.Stack, cb func(*Me
m.Optioni("stack.pos", i)
// 执行语句
msg := m.Cmd("yac.parse", line+"\n")
msg := m.Sess("yac").Cmd("parse", line+"\n")
if cb != nil {
cb(msg)
}

View File

@ -45,8 +45,11 @@ func (ctx *CTX) Begin(m *Message, arg ...string) Server {
}
func (ctx *CTX) Start(m *Message, arg ...string) bool {
if m.Optionv("bio.ctx", Index); len(arg) == 0 {
m.Optionv("bio.msg", m)
m.Optionv("bio.ctx", m.Target())
m.Option("bio.modal", "active")
m.Option("log.disable", false)
m.Option("log.debug", true)
m.Option("gdb.enable", true)
m.Cap("stream", "stdio")
m.Cmd("log._init")
@ -725,11 +728,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
"message": &Command{Name: "message [code] [cmd...]", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m
if ms := m.Find(m.Cap("bio.ctx")); ms != nil {
msg = ms
}
if len(arg) > 0 {
msg = msg.root
if code, e := strconv.Atoi(arg[0]); e == nil {
ms := []*Message{m}
for i := 0; i < len(ms); i++ {
@ -744,8 +744,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
}
if len(arg) == 0 {
m.Format("summary", msg, "deep")
msg.CopyTo(m)
// m.Format("summary", msg, "deep")
// msg.CopyTo(m)
return
}
@ -767,213 +767,86 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
return
}},
"detail": &Command{Name: "detail [index] [value...]", Help: "查看或添加参数", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.message
msg := m.Optionv("bio.msg").(*Message)
if len(arg) == 0 {
for i, v := range msg.Meta["detail"] {
m.Add("append", "index", i)
m.Add("append", "value", v)
m.Push("index", i)
m.Push("value", v)
}
m.Table()
return
}
index := m.Confi("detail_index")
index := 0
if i, e := strconv.Atoi(arg[0]); e == nil {
index, arg = i, arg[1:]
}
m.Echo("%s", msg.Detail(index, arg))
return
}},
"option": &Command{Name: "option [all] [key [index] [value...]]", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
all := false
if len(arg) > 0 && arg[0] == "all" {
all, arg = true, arg[1:]
}
index := -100
if len(arg) > 1 {
if i, e := strconv.Atoi(arg[1]); e == nil {
index = i
for i := 1; i < len(arg)-1; i++ {
arg[i] = arg[i+1]
}
arg = arg[:len(arg)-1]
"copy": &Command{Name: "copy", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.Optionv("bio.msg").(*Message)
msg.Cmdy(arg)
return
}},
"table": &Command{Name: "table", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.Optionv("bio.msg").(*Message)
if len(msg.Meta["append"]) == 0 {
msg.Meta["append"] = arg
} else {
for i, k := range msg.Meta["append"] {
msg.Push(k, kit.Select("", arg, i))
}
}
msg := m.message
keys := map[string]bool{}
for msg = msg; msg != nil; msg = msg.message {
for _, k := range msg.Meta["option"] {
if len(arg) == 0 {
if keys[k] {
continue
}
keys[k] = true
m.Add("append", "key", k)
m.Add("append", "len", len(msg.Meta[k]))
if _, ok := msg.Data[k]; ok {
m.Add("append", "value", kit.Format(msg.Data[k]))
} else {
m.Add("append", "value", kit.Format(msg.Meta[k]))
}
continue
}
if k != arg[0] {
continue
}
if len(arg) > 1 {
msg.Meta[k] = kit.Array(msg.Meta[k], index, arg[1:])
m.Echo("%v", msg.Meta[k])
return
}
if index != -100 {
m.Echo(kit.Array(msg.Meta[k], index)[0])
return
}
if v, ok := msg.Data[k]; ok {
json.MarshalIndent(v, "", " ")
m.Echo(kit.Formats(v))
return e
}
for i, v := range msg.Meta[k] {
m.Add("append", "index", i)
m.Add("append", "value", v)
}
m.Table()
return
}
if !all {
break
}
msg.Log("fuck", "waht %v", msg.Meta)
return
}},
"option": &Command{Name: "option", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.Optionv("bio.msg").(*Message)
switch v := msg.Optionv(arg[0]).(type) {
case []string:
m.Echo(strings.Join(v, ""))
default:
m.Echo(kit.Format(v))
}
m.Sort("key", "str").Table()
return
}},
"append": &Command{Name: "append", Help: "查看或添加附加值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.Optionv("bio.msg").(*Message)
if len(arg) == 0 {
m.Copy(msg, "append")
m.Table()
return
}
if len(arg) == 1 {
for i, v := range msg.Meta[arg[0]] {
m.Push("index", i)
m.Push("value", v)
}
m.Table()
return
}
msg.Push(arg[0], arg[1])
return
}},
"result": &Command{Name: "result [index] [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.message
msg := m.Optionv("bio.msg").(*Message)
if len(arg) == 0 {
for i, v := range msg.Meta["result"] {
m.Add("append", "index", i)
m.Add("append", "value", strings.Replace(v, "\n", "\\n", -1))
m.Push("index", i)
m.Push("value", strings.Replace(v, "\n", "\\n", -1))
}
m.Table()
return
}
index := m.Confi("result_index")
index := -2
if i, e := strconv.Atoi(arg[0]); e == nil {
index, arg = i, arg[1:]
}
m.Echo("%s", msg.Result(index, arg))
return
}},
"append": &Command{Name: "append [all] [key [index] [value...]]", Help: "查看或添加附加值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
all := false
if len(arg) > 0 && arg[0] == "all" {
all, arg = true, arg[1:]
}
index := -100
if len(arg) > 1 {
if i, e := strconv.Atoi(arg[1]); e == nil {
index = i
for i := 1; i < len(arg)-1; i++ {
arg[i] = arg[i+1]
}
arg = arg[:len(arg)-1]
}
}
msg := m.message
for msg = msg; msg != nil; msg = msg.message {
for _, k := range msg.Meta["append"] {
if len(arg) == 0 {
m.Add("append", "key", k)
m.Add("append", "value", fmt.Sprintf("%v", msg.Meta[k]))
continue
}
if k != arg[0] {
continue
}
if len(arg) > 1 {
msg.Meta[k] = kit.Array(msg.Meta[k], index, arg[1:])
m.Echo("%v", msg.Meta[k])
return
}
if index != -100 {
m.Echo(kit.Array(msg.Meta[k], index)[0])
return
}
for i, v := range msg.Meta[k] {
m.Add("append", "index", i)
m.Add("append", "value", v)
}
m.Table()
return
}
if !all {
break
}
}
m.Table()
return
}},
"session": &Command{Name: "session [all] [key [module]]", Help: "查看或添加会话", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
all := false
if len(arg) > 0 && arg[0] == "all" {
all, arg = true, arg[1:]
}
msg := m.message
for msg = msg; msg != nil; msg = msg.message {
for k, v := range msg.Sessions {
if len(arg) > 1 {
msg.Sessions[arg[0]] = msg.Find(arg[1])
return
} else if len(arg) > 0 {
if k == arg[0] {
m.Echo("%d", v.code)
return
}
continue
}
m.Add("append", "key", k)
m.Add("append", "time", v.time.Format("15:04:05"))
m.Add("append", "code", v.code)
m.Add("append", "source", v.source.Name)
m.Add("append", "target", v.target.Name)
m.Add("append", "details", fmt.Sprintf("%v", v.Meta["detail"]))
m.Add("append", "options", fmt.Sprintf("%v", v.Meta["option"]))
}
if len(arg) == 0 && !all {
break
}
}
m.Table()
return
}},
"callback": &Command{Name: "callback", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.message
for msg := msg; msg != nil; msg = msg.message {
m.Add("append", "msg", msg.code)
m.Add("append", "fun", msg.callback)
}
m.Table()
return
}},
"trans": &Command{Name: "trans option [type|data|json] limit 10 [index...]", Help: "数据转换",
Form: map[string]int{"format": 1, "fields": -1},

View File

@ -323,7 +323,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
// 语句堆栈
stack := &kit.Stack{}
stack.Push(m.Option("stack.key", "source"), m.Options("stack.run", true), m.Optioni("stack.pos", 0))
m.Optionv("bio.ctx", m.Target())
input := make([]string, 0, 128)

View File

@ -37,7 +37,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
"company": []interface{}{
map[string]interface{}{"componet_name": "status", "componet_help": "状态",
"componet_tmpl": "componet", "componet_view": "Company", "componet_init": "",
"componet_type": "private", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_type": "protected", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_args": []interface{}{"$$", "context", "cli", "system", "gg"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "select", "name": "sub", "values": []interface{}{"status", ""}},
@ -46,7 +46,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
},
map[string]interface{}{"componet_name": "deploy", "componet_help": "部署",
"componet_tmpl": "componet", "componet_view": "Company", "componet_init": "",
"componet_type": "private", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_type": "protected", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_args": []interface{}{"$$", "context", "cli", "system", "gg"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "select", "name": "sub", "values": []interface{}{"deploygo", "deploy", "status"}},
@ -58,7 +58,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
},
map[string]interface{}{"componet_name": "script", "componet_help": "脚本",
"componet_tmpl": "componet", "componet_view": "Compile", "componet_init": "",
"componet_type": "private", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_type": "protected", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_args": []interface{}{"$$", "context", "cli", "upgrade", "script"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "text", "name": "you", "imports": "plugin_you", "view": "long"},
@ -69,7 +69,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
},
map[string]interface{}{"componet_name": "php", "componet_help": "测试",
"componet_tmpl": "componet", "componet_view": "Company", "componet_init": "",
"componet_type": "private", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_type": "protected", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_args": []interface{}{"$$", "context", "cli", "system", "php", "cmd_parse", "format"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "text", "name": "cmd", "value": "usr/script/test.php", "view": "long"},
@ -78,7 +78,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
},
map[string]interface{}{"componet_name": "grep", "componet_help": "日志",
"componet_tmpl": "componet", "componet_view": "Company", "componet_init": "",
"componet_type": "private", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_type": "protected", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_args": []interface{}{"$$", "context", "nfs", "grep"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "", "imports": "plugin_pod"},
map[string]interface{}{"type": "select", "name": "cmd", "values": []interface{}{"", "hold", "tail", "head"}},
@ -87,7 +87,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
},
map[string]interface{}{"componet_name": "redis", "componet_help": "缓存",
"componet_tmpl": "componet", "componet_view": "Company", "componet_init": "",
"componet_type": "private", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_type": "protected", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_args": []interface{}{"$$", "context", "mdb", "redis"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "select", "name": "cmd", "values": []interface{}{"GET", "SET", "DEL", "HGETALL", "HGET", "HSET"}},
@ -97,7 +97,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
},
map[string]interface{}{"componet_name": "mysql", "componet_help": "存储",
"componet_tmpl": "componet", "componet_view": "Company", "componet_init": "",
"componet_type": "private", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_type": "protected", "componet_ctx": "ssh", "componet_cmd": "_route",
"componet_args": []interface{}{"$$", "context", "$$", "show"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "text", "name": "ctx", "value": "db1"},
@ -199,44 +199,6 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
map[string]interface{}{"type": "button", "value": "计算"},
},
},
map[string]interface{}{"componet_name": "email", "componet_help": "电子邮件",
"componet_tmpl": "componet", "componet_view": "Context", "componet_init": "",
"componet_type": "public", "componet_ctx": "aaa", "componet_cmd": "email",
"componet_args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"label": "收件人", "type": "text", "name": "to", "value": "shylinux@163.com", "view": "long"},
map[string]interface{}{"label": "主题", "type": "text", "name": "title", "view": "long"},
map[string]interface{}{"type": "button", "value": "发送", "view": "clear"},
map[string]interface{}{"type": "textarea", "name": "content", "view": "clear"},
},
},
map[string]interface{}{"componet_name": "location", "componet_help": "地理位置",
"componet_tmpl": "componet", "componet_view": "Context", "componet_init": "",
"componet_type": "public", "componet_ctx": "aaa", "componet_cmd": "location",
"componet_args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "content", "view": "long"},
map[string]interface{}{"type": "button", "value": "位置", "click": "Location"},
map[string]interface{}{"type": "button", "value": "查看"},
},
},
map[string]interface{}{"componet_name": "baidu", "componet_help": "百度地图",
"componet_tmpl": "componet", "componet_view": "Context", "componet_init": "",
"componet_type": "public", "componet_ctx": "aaa", "componet_cmd": "location",
"componet_args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "content", "view": "long"},
map[string]interface{}{"type": "button", "value": "位置", "click": "Location"},
map[string]interface{}{"type": "button", "value": "查看"},
},
"display": map[string]interface{}{"deal": "map"},
},
map[string]interface{}{"componet_name": "draw", "componet_help": "绘图",
"componet_tmpl": "componet", "componet_view": "Context", "componet_init": "",
"componet_type": "public", "componet_ctx": "nfs", "componet_cmd": "draw",
"componet_args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "content", "view": "long"},
map[string]interface{}{"type": "button", "value": "画图"},
},
"display": map[string]interface{}{"deal": "trend"},
},
},
"index": []interface{}{
map[string]interface{}{"componet_name": "pod", "componet_help": "设备",
@ -503,12 +465,12 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
m.Echo("error: %s from %s", name, work)
}
// 共享用户
case "share":
user := m.Conf("runtime", "node.route")
name := kit.Select(m.Conf("runtime", "user.name"), arg, 1)
work := kit.Select(m.Conf("runtime", "work.route"), arg, 2)
if n := m.Cmdx("ssh._route", work, "_check", "work", name, user); n != "" {
if n := m.Cmdx("ssh._route", work, "_check", "work", name, m.Conf("runtime", "node.route")); n != "" {
m.Echo(n)
}
@ -570,21 +532,25 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
default:
m.Confm("componet", arg[0:], func(value map[string]interface{}) {
m.Add("append", "name", value["componet_name"])
m.Add("append", "help", value["componet_help"])
m.Add("append", "view", value["componet_view"])
if kit.Format(value["componet_type"]) == "private" && m.Option("userrole") != "root" {
return
}
m.Push("name", value["componet_name"])
m.Push("help", value["componet_help"])
m.Push("view", value["componet_view"])
if kit.Right(value["componet_init"]) {
script := m.Cmdx("nfs.load", path.Join(m.Conf("cli.publish", "path"), arg[0], kit.Format(value["componet_init"])), -1)
if script == "" {
script = m.Cmdx("nfs.load", path.Join("usr/librarys/plugin", kit.Format(value["componet_init"])), -1)
}
m.Add("append", "init", script)
m.Push("init", script)
} else {
m.Add("append", "init", "")
m.Push("init", "")
}
m.Add("append", "inputs", kit.Format(value["inputs"]))
m.Add("append", "exports", kit.Format(value["exports"]))
m.Add("append", "display", kit.Format(value["display"]))
m.Push("inputs", kit.Format(value["inputs"]))
m.Push("exports", kit.Format(value["exports"]))
m.Push("display", kit.Format(value["display"]))
})
m.Table()
}

View File

@ -219,9 +219,6 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) {
case msg.Has("directory"):
http.ServeFile(w, r, msg.Append("directory"))
case msg.Has("componet"):
msg.Spawn().Add("option", "componet_group", msg.Meta["componet"]).Cmd("/render")
case msg.Has("qrcode"):
if qr, e := qrcode.New(msg.Append("qrcode"), qrcode.Medium); m.Assert(e) {
w.Header().Set("Content-Type", "image/png")
@ -310,7 +307,8 @@ func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server {
web.ServeMux = http.NewServeMux()
web.Template = template.New("render").Funcs(ctx.CGI)
web.Template.ParseGlob(path.Join(m.Cap("directory"), m.Conf("serve", "template_dir"), m.Cap("route"), "/*.tmpl"))
web.Template.ParseGlob(path.Join(m.Conf("route", "template_dir"), "/*.tmpl"))
web.Template.ParseGlob(path.Join(m.Conf("route", "template_dir"), m.Cap("route"), "/*.tmpl"))
return web
}
func (web *WEB) Start(m *ctx.Message, arg ...string) bool {
@ -410,8 +408,8 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}, Help: "服务配置"},
"route": &ctx.Config{Name: "route", Value: map[string]interface{}{
"index": "/render",
"template_dir": "template",
"template_debug": true,
"template_dir": "usr/template",
"template_debug": false,
"componet_index": "index",
"toolkit_view": map[string]interface{}{
"top": 96, "left": 472, "width": 600, "height": 300,
@ -766,7 +764,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}
return
}},
"template": &ctx.Command{Name: "template [file [directory]]|[name [content]]", Help: "添加模板, content: 模板内容, directory: 模板目录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"template": &ctx.Command{Name: "template [name [file...]]", Help: "模板管理, name: 模板名, file: 模板文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
if len(arg) == 0 {
for _, v := range web.Template.Templates() {
@ -776,27 +774,15 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
return
}
if web.Template == nil {
web.Template = template.New("render").Funcs(ctx.CGI)
tmpl := web.Template
if len(arg) > 1 {
tmpl = template.Must(web.Template.Clone())
tmpl = template.Must(tmpl.ParseFiles(arg[1:]...))
}
dir := path.Join(m.Cap("directory"), m.Confx("template_dir", arg, 1), arg[0])
if t, e := web.Template.ParseGlob(dir); e == nil {
web.Template = t
} else {
m.Log("info", "%s", e)
if len(arg) > 1 {
web.Template = template.Must(web.Template.New(arg[0]).Parse(arg[1]))
} else {
tmpl, e := web.Template.Clone()
m.Assert(e)
tmpl.Funcs(ctx.CGI)
buf := bytes.NewBuffer(make([]byte, 1024))
tmpl.ExecuteTemplate(buf, arg[0], m)
m.Echo(string(buf.Bytes()))
}
}
buf := bytes.NewBuffer(make([]byte, 1024))
tmpl.ExecuteTemplate(buf, arg[0], m)
m.Echo(string(buf.Bytes()))
}
return
}},
@ -841,146 +827,101 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}},
"/render": &ctx.Command{Name: "/render template", Help: "渲染模板, template: 模板名称", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if m.Options("toolkit") {
if kit, ok := m.Confv("toolkit", m.Option("toolkit")).(map[string]interface{}); ok {
m.Sess("cli").Cmd(kit["cmd"], m.Option("argument")).CopyTo(m)
}
return
}
// 权限检查
if m.Confs("login", "check") {
if m.Option("username") == "" { // 没有登录
m.Set("option", "componet_group", "login").Set("option", "componet_name", "").Set("option", "bench", "")
} else {
// 创建空间
if bench := m.Option("bench"); m.Option("bench", m.Cmdx("aaa.sess", "bench", "select")) != bench {
m.Append("redirect", merge(m, m.Option("index_url"), "bench", m.Option("bench")))
return
}
m.Optionv("bench_data", m.Confv("auth", []string{m.Option("bench"), "data"}))
if !m.Cmds("aaa.work", "right", m.Confx("componet_group")) { // 没有权限
m.Set("option", "componet_group", "login").Set("option", "componet_name", "").Set("option", "bench", "")
}
if !m.Options("sessid") || !m.Options("username") || !m.Cmds("aaa.role", m.Option("userrole"), "check", m.Confx("group")) {
m.Set("option", "group", "login").Set("option", "name", "")
}
}
// 响应类型
w := m.Optionv("response").(http.ResponseWriter)
accept_json := strings.HasPrefix(m.Option("accept"), "application/json")
w := m.Optionv("response").(http.ResponseWriter)
if accept_json {
// w.Header().Add("Content-Type", "application/json")
} else {
w.Header().Add("Content-Type", "text/html")
w.Header().Set("Content-Type", "text/html")
}
if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
// 响应模板
tmpl := web.Template
if m.Confs("route", "template_debug") {
tmpl = template.New("render").Funcs(ctx.CGI)
tmpl.ParseGlob(path.Join(m.Cap("directory"), m.Conf("route", "template_dir"), "/*.tmpl"))
tmpl.ParseGlob(path.Join(m.Cap("directory"), m.Conf("route", "template_dir"), m.Cap("route"), "/*.tmpl"))
web, ok := m.Target().Server.(*WEB)
m.Assert(ok)
// 响应模板
tmpl := web.Template
if m.Confs("route", "template_debug") {
tmpl = template.New("render").Funcs(ctx.CGI)
tmpl.ParseGlob(path.Join(m.Conf("route", "template_dir"), "/*.tmpl"))
tmpl.ParseGlob(path.Join(m.Conf("route", "template_dir"), m.Cap("route"), "/*.tmpl"))
}
// 响应数据
group, order := m.Option("group", kit.Select(m.Conf("route", "componet_index"), m.Option("group"))), m.Option("name")
list := []interface{}{}
for _, v := range m.Confv("componet", group).([]interface{}) {
val := v.(map[string]interface{})
if order != "" && val["name"].(string) != order {
continue
}
// 响应数据
list := []interface{}{}
// 查找模块
msg := m.Find(kit.Select(m.Cap("module"), val["ctx"]))
// 响应模板
group, order := m.Option("componet_group", kit.Select(m.Conf("route", "componet_index"), m.Option("componet_group"))), m.Option("componet_name")
for _, v := range m.Confv("componet", group).([]interface{}) {
val := v.(map[string]interface{})
if order != "" && val["componet_name"].(string) != order {
continue
// 默认变量
for k, v := range val {
switch value := v.(type) {
case []string:
msg.Set("option", k, value)
case string:
msg.Set("option", k, value)
default:
msg.Put("option", k, value)
}
}
// 查找模块
msg := m.Find(kit.Select(m.Cap("module"), val["componet_ctx"]))
// 默认变量
for k, v := range val {
if msg.Option(k) != "" {
continue
// 添加命令
if kit.Right(val["cmd"]) {
arg = append(arg, kit.Format(val["cmd"]))
}
// 添加参数
if m.Has("cmds") {
arg = append(arg, kit.Trans(m.Optionv("cmds"))...)
} else {
kit.Map(val["args"], "", func(index int, value map[string]interface{}) {
if value["name"] != nil {
arg = append(arg, kit.Select(msg.Option(value["name"].(string)), msg.Parse(value["value"])))
}
switch value := v.(type) {
case []string:
msg.Add("option", k, value)
case string:
msg.Add("option", k, value)
default:
msg.Put("option", k, value)
}
}
// 默认参数
if val["inputs"] != nil {
for _, v := range val["inputs"].([]interface{}) {
value := v.(map[string]interface{})
if value["name"] != nil && msg.Option(value["name"].(string)) == "" {
msg.Add("option", value["name"].(string), m.Parse(value["value"]))
}
}
}
})
}
// 添加设备
arg = arg[:0]
if kit.Right(val["componet_pod"]) {
arg = append(arg, "remote", kit.Format(m.Magic("session", "current.pod")))
}
// 添加命令
if kit.Right(val["componet_cmd"]) {
arg = append(arg, kit.Format(val["componet_cmd"]))
}
if m.Has("cmds") {
arg = append(arg, kit.Trans(m.Optionv("cmds"))...)
}
// 添加参数
for _, v := range kit.Trans(val["componet_args"]) {
arg = append(arg, msg.Parse(v))
}
if len(arg) > 0 {
if len(arg) > 0 {
if order != "" || kit.Right(val["pre_run"]) {
// 权限检查
if m.Options("bench") && m.Option("userrole", m.Cmdx("aaa.work", "right", m.Option("componet_group"), arg[0])) == "" {
if m.Confs("login", "check") && m.Cmds("aaa.role", m.Option("userrole"), "check", m.Option("componet_group"), arg[0]) {
continue
}
m.Option("remote", "true")
// 执行命令
if order != "" || kit.Right(val["pre_run"]) {
if msg.Cmd(arg); m.Options("bench") {
name_alias := "action." + kit.Select(msg.Option("componet_name"), msg.Option("componet_name_alias"))
// 命令历史
msg.Put("option", name_alias, map[string]interface{}{
"cmd": arg, "order": m.Option("componet_name_order"), "action_time": msg.Time(),
}).Cmd("aaa.work", m.Option("bench"), "data", "option", name_alias, "modify_time", msg.Time())
}
}
}
// 添加响应
if msg.Appends("qrcode") {
m.Append("qrcode", msg.Append("qrcode"))
} else if msg.Appends("directory") {
m.Append("download_file", fmt.Sprintf("/download/%s", msg.Append("directory")))
return
} else if accept_json {
list = append(list, msg.Meta)
} else if val["componet_tmpl"] != nil {
m.Assert(tmpl.ExecuteTemplate(w, val["componet_tmpl"].(string), msg))
msg.Cmd(arg)
}
}
// 生成响应
if accept_json {
en := json.NewEncoder(w)
en.SetIndent("", " ")
en.Encode(list)
// 添加响应
if msg.Appends("qrcode") {
m.Append("qrcode", msg.Append("qrcode"))
} else if msg.Appends("directory") {
m.Append("download_file", fmt.Sprintf("/download/%s", msg.Append("directory")))
return
} else if accept_json {
list = append(list, msg.Meta)
} else if val["tmpl"] != nil {
m.Assert(tmpl.ExecuteTemplate(w, val["tmpl"].(string), msg))
}
}
// 生成响应
if accept_json {
en := json.NewEncoder(w)
en.SetIndent("", " ")
en.Encode(list)
}
return
}},
"/upload": &ctx.Command{Name: "/upload", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {

View File

@ -311,6 +311,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
map[string]interface{}{"page": "key", "hash": "key", "word": []interface{}{"[A-Za-z_][A-Za-z_0-9]*"}},
map[string]interface{}{"page": "str", "hash": "str", "word": []interface{}{"mul{", "\"[^\"]*\"", "'[^']*'", "}"}},
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "opt{", "key", "}"}},
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "opt{", "num", "}"}},
// 表达式语句
map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-", "+", "}"}},
@ -332,7 +333,8 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "opt{", "=", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "if", "word": []interface{}{"if", "exp"}},
map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "key", "}"}},
map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "kit", "word": []interface{}{"kit", "rep{", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "else", "word": []interface{}{"else", "opt{", "if", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "end", "word": []interface{}{"end"}},
@ -358,6 +360,12 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
*/
}, Help: "语法集合的最大数量"},
"input": &ctx.Config{Name: "input", Value: map[string]interface{}{
"text": true,
"button": true,
"select": true,
"textarea": true,
}, Help: "控件类型"},
"exec": &ctx.Config{Name: "info", Value: map[string]interface{}{
"disable": map[string]interface{}{
"void": true,
@ -542,23 +550,43 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
case 1:
m.Echo(arg[0])
case 2:
bio := m.Optionv("bio.msg").(*ctx.Message)
msg := m.Spawn(m.Optionv("bio.ctx"))
switch arg[0] {
case "$":
// 局部变量
if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
if v, ok := stack.Hash(arg[1]); ok {
m.Echo("%v", v)
break
}
}
m.Echo(msg.Cap(arg[1]))
// 函数参数
if i, e := strconv.Atoi(arg[1]); e == nil {
m.Echo(bio.Detail(i))
break
}
// 函数选项
m.Echo(kit.Select(msg.Cap(arg[1]), bio.Option(arg[1])))
case "@":
value := msg.Option(arg[1])
if value == "" {
value = msg.Conf(arg[1])
// 局部变量
if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
if v, ok := stack.Hash(arg[1]); ok {
m.Echo("%v", v)
break
}
}
m.Echo(value)
// 函数参数
if i, e := strconv.Atoi(arg[1]); e == nil {
m.Echo(bio.Detail(i))
break
}
// 函数配置
m.Echo(kit.Select(msg.Conf(arg[1]), bio.Option(arg[1])))
default:
m.Echo(arg[0]).Echo(arg[1])
}
@ -1028,15 +1056,76 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
p := m.Optionv("bio.stack").(*kit.Stack).Push(arg[0], false, m.Optioni("stack.pos"))
m.Log("stack", "push %v", p.String("\\"))
if len(arg) > 2 {
m.Cmd("kit", "kit", arg[5], arg[1:5], arg[1], arg[6:])
}
self := &ctx.Command{Name: strings.Join(arg[1:], " "), Help: []string{"pwd", "ls"}}
self.Hand = func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Goshy(self.Help.([]string), 0, nil, nil)
return
}
m.Target().Commands[arg[1]] = self
m.Log("info", "fun: %v %v", arg[1], arg)
p.Data = self
return
}},
"kit": &ctx.Command{Name: "kit type name help view init cmd arg... [input type name value [key val]...]...", Help: "kit", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Log("info", "_index: %v", arg)
args := []interface{}{}
inputs := []interface{}{}
for i := 7; i < len(arg); i++ {
if !m.Confs("input", arg[i]) {
args = append(args, arg[i])
continue
}
for j := i; j < len(arg); j++ {
if j < len(arg)-1 && !m.Confs("input", arg[j+1]) {
continue
}
args := arg[i : j+1]
input := map[string]interface{}{
"type": kit.Select("", args, 0),
"value": kit.Select("", args, 1),
}
for k := 2; k < len(args)-1; k += 2 {
switch val := input[args[k]].(type) {
case nil:
input[args[k]] = args[k+1]
case string:
input[args[k]] = []interface{}{input[args[k]], args[k+1]}
case []interface{}:
input[args[k]] = append(val, args[k+1])
}
}
inputs = append(inputs, input)
i = j
break
}
}
if len(inputs) == 0 {
inputs = []interface{}{
map[string]interface{}{"type": "text", "name": "arg"},
map[string]interface{}{"type": "button", "value": "执行"},
}
}
m.Confv("_index", []interface{}{-2}, map[string]interface{}{
"componet_type": kit.Select("public", arg, 1),
"componet_name": kit.Select("", arg, 2),
"componet_help": kit.Select("", arg, 3),
"componet_view": kit.Select("componet", arg, 4),
"componet_init": kit.Select("", arg, 5),
"componet_ctx": m.Cap("module"),
"componet_cmd": kit.Select("", arg, 6),
"componet_args": args,
"inputs": inputs,
})
return
}},
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Peek()
p.Run = !p.Done && !p.Run && (len(arg) == 1 || kit.Right(arg[2]))

View File

@ -3,165 +3,96 @@ package chat
import (
"contexts/ctx"
"contexts/web"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"encoding/xml"
"fmt"
"net/http"
"net/url"
"sort"
"strings"
"time"
"toolkit"
)
func Marshal(m *ctx.Message, meta string) string {
b, e := xml.Marshal(struct {
CreateTime int64
FromUserName string
ToUserName string
MsgType string
Content string
XMLName xml.Name `xml:"xml"`
}{
time.Now().Unix(),
m.Option("selfname"), m.Option("username"),
meta, strings.Join(m.Meta["result"], ""), xml.Name{},
})
m.Assert(e)
m.Set("append").Set("result").Echo(string(b))
return string(b)
}
var Index = &ctx.Context{Name: "chat", Help: "会议中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": "false"}, Help: "默认组件"},
"componet_group": &ctx.Config{Name: "component_group", Value: "index", Help: "默认组件"},
"login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": "false"}, Help: "默认组件"},
"componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
"index": []interface{}{
map[string]interface{}{"componet_name": "chat", "componet_tmpl": "head", "metas": []interface{}{
map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"},
}, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "chat.css"}},
map[string]interface{}{"componet_name": "header", "componet_tmpl": "fieldset",
"componet_view": "Header", "componet_init": "initHeader",
map[string]interface{}{"name": "chat",
"tmpl": "head", "metas": []interface{}{map[string]interface{}{
"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no",
}}, "favicon": "favicon.ico", "styles": []interface{}{
"example.css", "chat.css",
}},
map[string]interface{}{"name": "header",
"tmpl": "fieldset", "view": "Header", "init": "initHeader",
"title": "shylinux 天行健,君子以自强不息",
},
map[string]interface{}{"componet_name": "login", "componet_help": "login", "componet_tmpl": "fieldset",
"componet_view": "Login dialog", "componet_init": "initLogin",
"componet_ctx": "web.chat", "componet_cmd": "login",
map[string]interface{}{"name": "login",
"tmpl": "fieldset", "view": "Login dialog", "init": "initLogin",
"ctx": "web.chat", "cmd": "login",
},
map[string]interface{}{"componet_name": "ocean", "componet_tmpl": "fieldset",
"componet_view": "Ocean dialog", "componet_init": "initOcean",
"componet_ctx": "web.chat", "componet_cmd": "ocean",
map[string]interface{}{"name": "ocean",
"tmpl": "fieldset", "view": "Ocean dialog", "init": "initOcean",
"ctx": "web.chat", "cmd": "ocean",
},
map[string]interface{}{"componet_name": "steam", "componet_tmpl": "fieldset",
"componet_view": "Steam dialog", "componet_init": "initSteam",
"componet_ctx": "web.chat", "componet_cmd": "steam",
map[string]interface{}{"name": "steam",
"tmpl": "fieldset", "view": "Steam dialog", "init": "initSteam",
"ctx": "web.chat", "cmd": "steam",
},
map[string]interface{}{"componet_name": "river", "componet_tmpl": "fieldset",
"componet_view": "River", "componet_init": "initRiver",
"componet_ctx": "web.chat", "componet_cmd": "river",
map[string]interface{}{"name": "river",
"tmpl": "fieldset", "view": "River", "init": "initRiver",
"ctx": "web.chat", "cmd": "river",
},
map[string]interface{}{"componet_name": "storm", "componet_tmpl": "fieldset",
"componet_view": "Storm", "componet_init": "initStorm",
"componet_ctx": "web.chat", "componet_cmd": "storm",
map[string]interface{}{"name": "storm",
"tmpl": "fieldset", "view": "Storm", "init": "initStorm",
"ctx": "web.chat", "cmd": "storm",
},
map[string]interface{}{"componet_name": "target", "componet_tmpl": "fieldset",
"componet_view": "Target", "componet_init": "initTarget",
"componet_ctx": "web.chat", "componet_cmd": "river",
map[string]interface{}{"name": "target",
"tmpl": "fieldset", "view": "Target", "init": "initTarget",
"ctx": "web.chat", "cmd": "river",
},
map[string]interface{}{"componet_name": "source", "componet_tmpl": "fieldset",
"componet_view": "Source", "componet_init": "initSource",
"componet_ctx": "web.chat", "componet_cmd": "storm",
map[string]interface{}{"name": "source",
"tmpl": "fieldset", "view": "Source", "init": "initSource",
"ctx": "web.chat", "cmd": "storm",
},
map[string]interface{}{"componet_name": "action", "componet_tmpl": "fieldset",
"componet_view": "Action", "componet_init": "initAction",
"componet_ctx": "web.chat", "componet_cmd": "storm",
map[string]interface{}{"name": "action",
"tmpl": "fieldset", "view": "Action", "init": "initAction",
"ctx": "web.chat", "cmd": "storm",
},
map[string]interface{}{"componet_name": "footer", "componet_tmpl": "fieldset",
"componet_view": "Footer", "componet_init": "initFooter",
map[string]interface{}{"name": "footer",
"tmpl": "fieldset", "view": "Footer", "init": "initFooter",
"title": "shycontext 地势坤,君子以厚德载物",
},
map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail",
"scripts": []interface{}{"toolkit.js", "context.js", "example.js", "chat.js"},
map[string]interface{}{"name": "tail",
"tmpl": "tail", "scripts": []interface{}{
"toolkit.js", "context.js", "example.js", "chat.js",
},
},
},
}, Help: "组件列表"},
"salary": &ctx.Config{Name: "salary", Value: map[string]interface{}{
"公基金": 120, "养老": 80, "医疗": 20, "失业": 2,
"个税": []interface{}{
85000, 45,
60000, 35,
40000, 30,
30000, 25,
17000, 20,
8000, 10,
5000, 3,
},
}, Help: "聊天记录"},
"chat_msg": &ctx.Config{Name: "chat_msg", Value: []interface{}{}, Help: "聊天记录"},
"default": &ctx.Config{Name: "default", Value: "", Help: "聊天记录"},
"weather_site": &ctx.Config{Name: "weather_site", Value: "http://weather.sina.com.cn", Help: "聊天记录"},
"calendar_site": &ctx.Config{Name: "calendar_site", Value: "http://tools.2345.com/rili.htm", Help: "聊天记录"},
"topic_site": &ctx.Config{Name: "topic_site", Value: "https://s.weibo.com/top/summary?cate=realtimehot", Help: "聊天记录"},
"pedia_site": &ctx.Config{Name: "pedia_site", Value: "https://zh.wikipedia.org/wiki", Help: "聊天记录"},
"baike_site": &ctx.Config{Name: "baike_site", Value: "https://baike.baidu.com/item", Help: "聊天记录"},
"sinas_site": &ctx.Config{Name: "sinas_site", Value: "http://www.sina.com.cn/mid/search.shtml?range=all&c=news&q=%s&from=home&ie=utf-8", Help: "聊天记录"},
"zhihu_site": &ctx.Config{Name: "zhihu_site", Value: "https://www.zhihu.com/search?type=content&q=%s", Help: "聊天记录"},
"toutiao_site": &ctx.Config{Name: "toutiao_site", Value: "https://www.toutiao.com/search/?keyword=%s", Help: "聊天记录"},
"chat": &ctx.Config{Name: "chat", Value: map[string]interface{}{
"appid": "", "appmm": "", "token": "", "site": "https://shylinux.com",
"auth": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STATE#wechat_redirect",
"access": map[string]interface{}{"token": "", "expire": 0, "url": "/cgi-bin/token?grant_type=client_credential"},
"ticket": map[string]interface{}{"value": "", "expire": 0, "url": "/cgi-bin/ticket/getticket?type=jsapi"},
}, Help: "聊天记录"},
"mp": &ctx.Config{Name: "chat", Value: map[string]interface{}{
"appid": "", "appmm": "", "token": "", "site": "https://shylinux.com",
"auth": "/sns/jscode2session?grant_type=authorization_code",
"tool_path": "/Applications/wechatwebdevtools.app/Contents/MacOS/cli",
"project_path": "/Users/shaoying/context/usr/client/mp",
}, Help: "聊天记录"},
},
Commands: map[string]*ctx.Command{
"/qrcode": &ctx.Command{Name: "qrcode text", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Append("qrcode", m.Option("text"))
return
}},
"login": &ctx.Command{Name: "login [username password]", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 { // 非登录态
switch arg[0] {
case "weixin":
m.Cmdy(".js_token")
case "qrcode":
m.Append("qrcode", kit.Select(m.Option("index_url"), arg, 1))
case "rename":
default:
// 非登录态
if !m.Options("sessid") || !m.Options("username") {
if len(arg) > 0 {
// 用户登录
if m.Cmds("ssh.work", "share", arg[0]) {
if m.Cmds("aaa.auth", "username", arg[0], "password", arg[1]) {
m.Option("username", arg[0])
m.Copy(m.Cmd("aaa.user", "session", "select"), "result")
m.Option("sessid", m.Result(0))
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
if !m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") {
m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default", m.Spawn().Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name")))
m.Cmd("aaa.auth", "username", arg[0], "data", "chat.default",
m.Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name"), m.Option("username")))
}
m.Echo(m.Option("sessid"))
}
}
}
}
// 登录检查
if !m.Options("sessid") && !m.Options("username") {
return
}
if len(arg) > 0 {
switch arg[0] {
// 用户昵称
case "rename":
m.Cmd("aaa.auth", "username", m.Option("username"), "data", "nickname", arg[1])
}
@ -175,45 +106,57 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
m.Echo(m.Option("username"))
return
}},
"ocean": &ctx.Command{Name: "ocean", Help: "海洋", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"ocean": &ctx.Command{Name: "ocean [search [name]]|[spawn hash name user...]", Help: "海洋, search [name]: 搜索员工, spawn hash name user...: 创建群聊", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
if !m.Options("sessid") || !m.Options("username") {
return
}
if len(arg) == 0 {
m.Cmdy("ssh.work", "search")
return
arg = append(arg, "search")
}
switch arg[0] {
case "spawn":
arg = append(arg, m.Option("username"))
arg = append(arg, m.Conf("runtime", "work.name"))
// 搜索员工
case "search":
m.Cmdy("ssh.work", "search")
h := kit.Select(kit.Hashs("uniq"), arg, 1)
// 创建群聊
case "spawn":
// 用户列表
user := map[string]interface{}{}
for _, v := range arg[3:] {
u := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", v)
if u != "" {
user[v] = map[string]interface{}{"user": u}
if len(arg) > 3 {
arg = append(arg, m.Option("username"))
arg = append(arg, m.Conf("runtime", "work.name"))
for _, v := range arg[3:] {
if p := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", v); p != "" {
user[v] = map[string]interface{}{"user": p}
}
}
}
// 添加群聊
h := kit.Select(kit.Hashs("uniq"), arg, 1)
m.Conf("flow", h, map[string]interface{}{
"conf": map[string]interface{}{
"create_user": m.Option("username"),
"create_time": m.Time(),
"update_time": m.Time(),
"name": kit.Select("what", arg, 2),
"nick": kit.Select("what", arg, 2),
"route": kit.Select(m.Conf("runtime", "node.route"), m.Option("node.route"), arg[1] != ""),
},
"user": user,
"text": map[string]interface{}{},
"tool": map[string]interface{}{},
"text": map[string]interface{}{},
})
m.Echo(h)
return
m.Option("username", m.Conf("runtime", "user.name"))
if m.Echo(h); arg[1] != "" {
return
}
m.Cmdx(".steam", h, "spawn", "favor")
// 分发群聊
m.Confm("flow", []string{h, "user"}, func(key string, value map[string]interface{}) {
if kit.Right(value["user"]) && kit.Format(value["user"]) != m.Conf("runtime", "node.route") {
m.Cmd("ssh._route", value["user"], "context", "chat", "ocean", "spawn", h, arg[2])
@ -222,11 +165,13 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
}
return
}},
"river": &ctx.Command{Name: "river", Help: "河流", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"river": &ctx.Command{Name: "river hash [brow begin]|[flow type text [index]]|[wave route group index args...]", Help: "河流", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
if !m.Options("sessid") || !m.Options("username") {
return
}
// 自动入群
if m.Options("river") {
if m.Confs("flow", m.Option("river")) && !m.Confs("flow", []string{m.Option("river"), "user", m.Option("username")}) {
u := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", m.Option("username"))
@ -234,532 +179,218 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
}
}
// 群聊列表
if len(arg) == 0 {
m.Confm("flow", func(key string, value map[string]interface{}) {
if kit.Chain(value, []string{"user", m.Option("username")}) == nil {
return
}
m.Add("append", "key", key)
m.Add("append", "name", kit.Chains(value, "conf.name"))
m.Add("append", "create_user", kit.Chains(value, "conf.create_user"))
m.Add("append", "create_time", kit.Chains(value, "conf.create_time"))
m.Add("append", "update_time", kit.Chains(value, "conf.update_time"))
m.Push("key", key)
m.Push("nick", kit.Chains(value, "conf.nick"))
m.Push("create_user", kit.Chains(value, "conf.create_user"))
m.Push("create_time", kit.Chains(value, "conf.create_time"))
m.Push("update_time", kit.Chains(value, "conf.update_time"))
if list, ok := kit.Chain(value, "text.list").([]interface{}); ok {
m.Add("append", "count", len(list))
m.Push("count", len(list))
} else {
m.Add("append", "count", 0)
m.Push("count", 0)
}
})
m.Sort("name").Sort("update_time", "time_r").Table()
return
}
rid := m.Option("river")
if m.Confs("flow", arg[0]) {
rid, arg = arg[0], arg[1:]
}
switch arg[0] {
// 消息列表
case "brow":
m.Option("page.begin", kit.Select("0", arg, 2))
m.Confm("flow", []string{arg[1], "text.list"}, func(index int, value map[string]interface{}) {
m.Add("append", "index", index)
m.Add("append", "type", value["type"])
m.Add("append", "text", value["text"])
m.Add("append", "create_time", value["create_time"])
m.Add("append", "create_user", value["create_user"])
m.Add("append", "create_nick", value["create_nick"])
begin := kit.Int(kit.Select("0", arg, 1))
m.Confm("flow", []string{rid, "text.list"}, func(index int, value map[string]interface{}) {
if index < begin {
return
}
m.Push("index", index)
m.Push("type", value["type"])
m.Push("text", value["text"])
m.Push("create_time", value["create_time"])
m.Push("create_user", value["create_user"])
m.Push("create_nick", value["create_nick"])
})
m.Table()
return
// 推送消息
case "flow":
if kit.Right(m.Conf("flow", []string{arg[1], "conf.route"})) && m.Conf("flow", []string{arg[1], "conf.route"}) != m.Conf("runtime", "node.route") && len(arg) == 4 {
m.Cmdy("ssh._route", m.Conf("flow", []string{arg[1], "conf.route"}),
"context", "chat", "river", "flow", arg[1], arg[2], arg[3])
m.Log("info", "upstream")
up := m.Conf("flow", []string{rid, "conf.route"})
// 上传消息
if len(arg) == 3 && up != m.Conf("runtime", "node.route") {
m.Cmdy("ssh._route", up, "context", "chat", "river", rid, "flow", arg[1], arg[2])
return
}
m.Conf("flow", []string{arg[1], "text.list.-2"}, map[string]interface{}{
"create_user": m.Option("username"),
// 保存消息
m.Conf("flow", []string{rid, "text.list.-2"}, map[string]interface{}{
"create_nick": m.Option("nickname"),
"create_user": m.Option("username"),
"create_time": m.Time(),
"type": arg[2],
"text": arg[3],
"type": arg[1],
"text": arg[2],
})
m.Conf("flow", []string{rid, "conf.update_time"}, m.Time())
count := m.Confi("flow", []string{rid, "text.count"}) + 1
m.Confi("flow", []string{rid, "text.count"}, count)
m.Conf("flow", []string{arg[1], "conf.update_time"}, m.Time())
count := m.Confi("flow", []string{arg[1], "text.count"}) + 1
m.Confi("flow", []string{arg[1], "text.count"}, count)
m.Append("create_user", m.Option("username"))
m.Echo("%d", count)
m.Option("username", m.Conf("runtime", "user.name"))
m.Confm("flow", []string{arg[1], "user"}, func(key string, value map[string]interface{}) {
if kit.Right(value["user"]) && kit.Format(value["user"]) != m.Conf("runtime", "node.route") {
m.Cmd("ssh._route", value["user"], "context", "chat", "river", "flow", arg[1], arg[2], arg[3], "sync")
}
})
// 分发消息
if up == m.Conf("runtime", "node.route") {
m.Confm("flow", []string{rid, "user"}, func(key string, value map[string]interface{}) {
if kit.Right(value["user"]) && kit.Format(value["user"]) != m.Conf("runtime", "node.route") {
m.Cmd("ssh._route", value["user"], "context", "chat", "river", rid, "flow", arg[1], arg[2], count, "sync")
}
})
}
// 推送命令
case "wave":
m.Cmdy("ssh._route", arg[2], "tool", "run", arg[3], arg[4], arg[1], arg[5:])
m.Cmdy("ssh._route", arg[1], "tool", "run", arg[2], arg[3], rid, arg[4:])
}
return
}},
"storm": &ctx.Command{Name: "storm", Help: "风雨", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 1 {
m.Confm("flow", []string{arg[0], "tool"}, func(key string, value map[string]interface{}) {
m.Add("append", "key", key)
m.Add("append", "count", len(value["list"].([]interface{})))
"storm": &ctx.Command{Name: "storm [rid] [[delete] group [index [arg...]]]", Help: "风雨", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
if !m.Options("sessid") || !m.Options("username") {
return
}
rid := m.Option("river")
if m.Confs("flow", arg[0]) {
rid, arg = arg[0], arg[1:]
}
// 命令列表
if len(arg) == 0 {
m.Confm("flow", []string{rid, "tool"}, func(key string, value map[string]interface{}) {
m.Push("key", key)
m.Push("count", len(value["list"].([]interface{})))
})
m.Sort("key").Table()
return
}
switch arg[1] {
switch arg[0] {
// 删除命令
case "delete":
str := m.Conf("flow", []string{arg[0], "tool", arg[2]})
m.Log("info", "delete %v %v %v", arg[0], arg[2], str)
m.Conf("flow", []string{arg[0], "tool", arg[2]}, "")
str := m.Conf("flow", []string{rid, "tool", arg[1]})
m.Log("info", "delete %v %v %v", rid, arg[1], str)
m.Conf("flow", []string{rid, "tool", arg[1]}, "")
m.Echo(str)
default:
if len(arg) == 2 {
m.Confm("flow", []string{arg[0], "tool", arg[1], "list"}, func(index int, tool map[string]interface{}) {
m.Add("append", "river", arg[0])
m.Add("append", "storm", arg[1])
m.Add("append", "action", index)
// 命令列表
m.Set("option", "name")
if len(arg) == 1 {
m.Confm("flow", []string{rid, "tool", arg[0], "list"}, func(index int, tool map[string]interface{}) {
m.Push("river", rid)
m.Push("storm", arg[0])
m.Push("action", index)
m.Add("append", "node", tool["node"])
m.Add("append", "group", tool["group"])
m.Add("append", "index", tool["index"])
m.Push("node", tool["node"])
m.Push("group", tool["group"])
m.Push("index", tool["index"])
msg := m.Cmd("ssh._route", tool["node"], "tool", tool["group"], tool["index"])
m.Add("append", "name", msg.Append("name"))
m.Add("append", "help", msg.Append("help"))
m.Add("append", "view", msg.Append("view"))
m.Add("append", "init", msg.Append("init"))
m.Add("append", "inputs", msg.Append("inputs"))
m.Add("append", "exports", msg.Append("exports"))
m.Add("append", "display", msg.Append("display"))
m.Push("name", msg.Append("name"))
m.Push("help", msg.Append("help"))
m.Push("view", msg.Append("view"))
m.Push("init", msg.Append("init"))
m.Push("inputs", msg.Append("inputs"))
m.Push("exports", msg.Append("exports"))
m.Push("display", msg.Append("display"))
})
m.Table()
break
}
} else if tool := m.Confm("flow", []string{arg[0], "tool", arg[1], "list", arg[2]}); tool != nil {
m.Cmdy("ssh._route", tool["node"], "tool", "run", tool["group"], tool["index"], arg[0], arg[3:])
// 推送命令
if tool := m.Confm("flow", []string{rid, "tool", arg[0], "list", arg[1]}); tool != nil {
m.Cmdy("ssh._route", tool["node"], "tool", "run", tool["group"], tool["index"], rid, arg[2:])
}
}
return
}},
"steam": &ctx.Command{Name: "steam", Help: "天空", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if m.Conf("flow", []string{arg[0], "conf.route"}) != m.Conf("runtime", "node.route") {
m.Cmdy("ssh._remote", m.Conf("flow", []string{arg[0], "conf.route"}), "context", "chat", "steam", arg)
m.Log("info", "upstream")
"steam": &ctx.Command{Name: "steam rid [user node]|[spawn name [route group index name]...]", Help: "天空", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
if !m.Options("sessid") || !m.Options("username") {
return
}
if len(arg) == 1 {
m.Confm("flow", []string{arg[0], "user"}, func(key string, value map[string]interface{}) {
m.Add("append", "user", key)
m.Add("append", "node", value["user"])
rid := m.Option("river")
if m.Confs("flow", arg[0]) {
rid, arg = arg[0], arg[1:]
}
// 上传请求
if up := m.Conf("flow", []string{rid, "conf.route"}); up != m.Conf("runtime", "node.route") {
m.Cmdy("ssh._remote", up, "context", "chat", "steam", rid, arg)
return
}
// 设备列表
if len(arg) == 0 {
m.Confm("flow", []string{rid, "user"}, func(key string, value map[string]interface{}) {
m.Push("user", key)
m.Push("node", value["user"])
})
m.Confm("ssh.node", func(key string, value map[string]interface{}) {
m.Add("append", "user", "")
m.Add("append", "node", value["name"])
m.Push("user", "")
m.Push("node", value["name"])
})
m.Table()
return
}
switch arg[1] {
switch arg[0] {
// 创建命令
case "spawn":
list := []interface{}{}
for i := 3; i < len(arg)-3; i += 4 {
self := m.Conf("runtime", "node.route")
m.Confm("ssh.componet", arg[1], func(index int, value map[string]interface{}) {
arg = append(arg, self, arg[1], kit.Format(index), kit.Format(value["name"]))
})
for i := 2; i < len(arg)-3; i += 4 {
list = append(list, map[string]interface{}{
"node": arg[i], "group": arg[i+1], "index": arg[i+2], "name": arg[i+3],
})
}
m.Conf("flow", []string{arg[0], "tool", arg[2]}, map[string]interface{}{
m.Conf("flow", []string{rid, "tool", arg[1]}, map[string]interface{}{
"create_user": m.Option("username"),
"create_time": m.Time(),
"list": list,
})
// 命令列表
default:
if m.Option("username") != arg[1] && arg[1] != "" {
m.Option("username", arg[1])
m.Option("userrole", m.Cmd("aaa.user", "role").Append("meta"))
}
m.Cmdy("ssh._route", arg[2], "tool")
// m.Cmdy("ssh._route", m.Conf("flow", []string{arg[0], "user", arg[1], "user"}), "tool")
m.Cmdy("ssh._route", arg[1], "tool")
}
return
}},
"salary": &ctx.Command{Name: "salary", Help: "天空", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
arg[0] = kit.Select(arg[1], arg, 0)
total := kit.Int64(kit.Select(arg[0], arg, 1))
base := kit.Int64(arg[0]) - m.Appendi("公基金", total*kit.Int64(m.Conf("salary", "公基金"))/1000) -
m.Appendi("养老", total*kit.Int64(m.Conf("salary", "养老"))/1000) -
m.Appendi("医疗", total*kit.Int64(m.Conf("salary", "医疗"))/1000) -
m.Appendi("失业", total*kit.Int64(m.Conf("salary", "失业"))/1000)
list := kit.Trans(m.Confv("salary", "个税"))
calc, tax := base, int64(0)
for i := 0; i < len(list); i += 2 {
if calc > kit.Int64(list[i]) {
tax += (calc - kit.Int64(list[i])) * kit.Int64(list[i+1])
calc = kit.Int64(list[i])
}
}
m.Append("个税", tax/100)
m.Append("结余", (base*100-tax)/100)
m.Table()
return
}},
"/chat": &ctx.Command{Name: "user", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 信息验证
nonce := []string{m.Option("timestamp"), m.Option("nonce"), m.Conf("chat", "token")}
sort.Strings(nonce)
h := sha1.Sum([]byte(strings.Join(nonce, "")))
if hex.EncodeToString(h[:]) == m.Option("signature") {
// m.Echo(m.Option("echostr"))
} else {
return
}
// 解析数据
var data struct {
MsgId int64
CreateTime int64
ToUserName string
FromUserName string
MsgType string
Content string
}
r := m.Optionv("request").(*http.Request)
m.Assert(xml.NewDecoder(r.Body).Decode(&data))
m.Option("username", data.FromUserName)
m.Option("selfname", data.ToUserName)
// 创建会话
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
m.Option("bench", m.Cmdx("aaa.sess", "bench", "select"))
m.Option("current_ctx", kit.Select("chat", m.Magic("bench", "current_ctx")))
switch data.MsgType {
case "text":
m.Echo(web.Merge(m, map[string]interface{}{"path": "chat"}, m.Conf("chat", "site"), "sessid", m.Option("sessid")))
if !m.Cmds("aaa.auth", "username", m.Option("usernmae"), "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") {
if m.Cmds("ssh.work", "share", m.Option("username")) {
m.Cmd("aaa.auth", "username", m.Option("username"), "data", "nickname", "someone")
m.Cmds("aaa.auth", "username", m.Option("username"), "data", "chat.default", m.Spawn().Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name")))
}
}
Marshal(m, "text")
return
// 执行命令
cmd := strings.Split(data.Content, " ")
if !m.Cmds("aaa.work", m.Option("bench"), "right", data.FromUserName, "chat", cmd[0]) {
m.Echo("no right %s %s", "chat", cmd[0])
} else if m.Cmdy("cli.source", data.Content); m.Appends("redirect") {
}
Marshal(m, "text")
}
return
}},
"access": &ctx.Command{Name: "access", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("format", "object")
now := kit.Int(time.Now().Unix())
access := m.Confm("chat", "access")
if kit.Int(access["expire"]) < now {
msg := m.Cmd("web.get", "wexin", access["url"], "appid", m.Conf("chat", "appid"), "secret", m.Conf("chat", "appmm"), "temp", "data")
access["token"] = msg.Append("access_token")
access["expire"] = int(msg.Appendi("expires_in")) + now
}
m.Echo("%v", access["token"])
return
}},
"ticket": &ctx.Command{Name: "ticket", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("format", "object")
now := kit.Int(time.Now().Unix())
ticket := m.Confm("chat", "ticket")
if kit.Int(ticket["expire"]) < now {
msg := m.Cmd("web.get", "wexin", ticket["url"], "access_token", m.Cmdx(".access"), "temp", "data")
ticket["value"] = msg.Append("ticket")
ticket["expire"] = int(msg.Appendi("expires_in")) + now
}
m.Echo("%v", ticket["value"])
return
}},
"js_token": &ctx.Command{Name: "js_token", Help: "zhihu", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
nonce := []string{
"jsapi_ticket=" + m.Cmdx(".ticket"),
"noncestr=" + m.Append("nonce", "what"),
"timestamp=" + m.Append("timestamp", kit.Int(time.Now())),
"url=" + m.Append("url", m.Conf("chat", "site")+m.Option("index_url")),
}
sort.Strings(nonce)
h := sha1.Sum([]byte(strings.Join(nonce, "&")))
m.Append("signature", hex.EncodeToString(h[:]))
m.Append("appid", m.Conf("chat", "appid"))
m.Append("remote_ip", m.Option("remote_ip"))
m.Append("auth2.0", fmt.Sprintf(m.Conf("chat", "auth"), m.Conf("chat", "appid"),
url.QueryEscape(fmt.Sprintf("%s%s", m.Conf("chat", "site"), m.Option("index_url"))), kit.Select("snsapi_base", m.Option("scope"))))
return
}},
"share": &ctx.Command{Name: "share", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo("%s?bench=%s&sessid=%s", m.Conf("chat", "site"), m.Option("bench"), m.Option("sessid"))
return
}},
"check": &ctx.Command{Name: "check", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
sort.Strings(arg)
h := sha1.Sum([]byte(strings.Join(arg, "")))
if hex.EncodeToString(h[:]) == m.Option("signature") {
m.Echo("true")
}
return
}},
"/mp": &ctx.Command{Name: "/mp", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 用户登录
if m.Options("code") {
m.Option("format", "object")
msg := m.Cmd("web.get", "wexin", m.Conf("mp", "auth"), "js_code", m.Option("code"), "appid", m.Conf("mp", "appid"), "secret", m.Conf("mp", "appmm"), "parse", "json", "temp", "data")
// 创建会话
if !m.Options("sessid") {
m.Cmd("aaa.sess", m.Option("sessid", m.Cmdx("aaa.sess", "mp", "ip", "what")), msg.Append("openid"), "ppid", "what")
defer func() {
m.Set("result").Echo(m.Option("sessid"))
}()
}
m.Magic("session", "user.openid", msg.Append("openid"))
m.Magic("session", "user.expires_in", kit.Int(msg.Append("expires_in"), time.Now()))
m.Magic("session", "user.session_key", msg.Append("session_key"))
}
// 用户信息
if m.Options("userInfo") && m.Options("rawData") {
h := sha1.Sum([]byte(strings.Join([]string{m.Option("rawData"), kit.Format(m.Magic("session", "user.session_key"))}, "")))
if hex.EncodeToString(h[:]) == m.Option("signature") {
var info interface{}
json.Unmarshal([]byte(m.Option("userInfo")), &info)
m.Log("info", "user %v %v", m.Option("sessid"), info)
m.Magic("session", "user.info", info)
m.Magic("session", "user.encryptedData", m.Option("encryptedData"))
m.Magic("session", "user.iv", m.Option("iv"))
}
}
if m.Option("username", m.Magic("session", "user.openid")) == "" || m.Option("cmd") == "" {
return
}
if m.Option("username") == "o978M0XIrcmco28CU1UbPgNxIL78" {
m.Option("username", "shy")
}
if m.Option("username") == "o978M0ff_Y76hFu1FPLif6hFfmsM" {
m.Option("username", "shy")
}
// 创建空间
if !m.Options("bench") && m.Option("bench", m.Cmd("aaa.sess", m.Option("sessid"), "bench").Append("key")) == "" {
m.Option("bench", m.Cmdx("aaa.work", m.Option("sessid"), "mp"))
}
m.Option("current_ctx", kit.Select("chat", m.Magic("bench", "current_ctx")))
// 执行命令
cmd := kit.Trans(m.Optionv("cmd"))
if !m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("username"), "mp", cmd[0]) {
m.Echo("no right %s %s", "chat", cmd[0])
} else if m.Cmdy(cmd); m.Appends("redirect") {
}
return
}},
"mp": &ctx.Command{Name: "mp", Help: "talk", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy("cli.system", m.Conf("mp", "tool_path"), arg, m.Conf("mp", "project_path"), "cmd_active", "true")
return
}},
"weather": &ctx.Command{Name: "weather where field", Help: "weather", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
where := "beijing"
if len(arg) > 0 {
where, arg = arg[0], arg[1:]
}
msg := m.Spawn().Cmd("get", fmt.Sprintf("%s/%s", m.Conf("weather_site"), where),
"parse", "div.blk_fc_c0_i",
"sub_parse", "date", "p.wt_fc_c0_i_date", "text",
"sub_parse", "day", "p.wt_fc_c0_i_day", "text",
"sub_parse", "weather", "p.wt_fc_c0_i_icons.clearfix img", "title",
"sub_parse", "temp", "p.wt_fc_c0_i_temp", "text",
"sub_parse", "wind", "p.wt_fc_c0_i_tip", "text",
"sub_parse", "pm", "ul.wt_fc_c0_i_level li.l", "text",
"sub_parse", "env", "ul.wt_fc_c0_i_level li.r", "text",
)
m.Copy(msg, "append").Copy(msg, "result")
if len(arg) == 0 {
arg = append(arg, "temp")
}
switch arg[0] {
case "all":
case "temp":
m.Cmd("select", "fields", "date day weather temp")
case "wind":
m.Cmd("select", "fields", "date day weather wind")
case "env":
m.Cmd("select", "fields", "date day weather pm env")
default:
m.Cmd("select", "date", arg[0], "vertical")
}
return
}},
"calendar": &ctx.Command{Name: "calendar", Help: "calendar", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
msg := m.Spawn().Cmd("get", m.Conf("calendar_site"),
"parse", "div.almanac-hd")
m.Copy(msg, "append").Copy(msg, "result")
return
}},
"topic": &ctx.Command{Name: "topic", Help: "topic", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
limit := "10"
if len(arg) > 0 {
limit, arg = arg[0], arg[1:]
}
msg := m.Spawn().Cmd("get", m.Conf("topic_site"),
"parse", "table tr",
"sub_parse", "mark", "td.td-03", "text",
"sub_parse", "count", "td.td-02 span", "text",
"sub_parse", "rank", "td.td-01", "text",
"sub_parse", "topic", "td.td-02 a", "text",
)
m.Copy(msg, "append").Copy(msg, "result")
m.Cmd("select", "limit", limit)
return
}},
"pedia": &ctx.Command{Name: "pedia", Help: "pedia", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
msg := m.Spawn().Cmd("get", fmt.Sprintf("%s/%s", m.Conf("pedia_site"), arg[0]),
"parse", "div.mw-parser-output>p,div.mw-parser-output>ul",
"sub_parse", "content", "", "text",
)
arg = arg[1:]
offset := "0"
if len(arg) > 0 {
offset, arg = arg[0], arg[1:]
}
limit := "3"
if len(arg) > 0 {
limit, arg = arg[0], arg[1:]
}
m.Copy(msg, "append").Copy(msg, "result")
m.Cmd("select", "limit", limit, "offset", offset)
return
}},
"baike": &ctx.Command{Name: "baike", Help: "baike", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
msg := m.Spawn().Cmd("get", fmt.Sprintf("%s/%s", m.Conf("baike_site"), arg[0]),
"parse", "div.mw-body",
"sub_parse", "content", "p", "text",
)
arg = arg[1:]
offset := "0"
if len(arg) > 0 {
offset, arg = arg[0], arg[1:]
}
limit := "3"
if len(arg) > 0 {
limit, arg = arg[0], arg[1:]
}
m.Copy(msg, "append").Copy(msg, "result")
m.Cmd("select", "limit", limit, "offset", offset)
return
}},
"sinas": &ctx.Command{Name: "sinas", Help: "sinas", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
msg := m.Spawn().Cmd("get", fmt.Sprintf(m.Conf("sinas_site"), arg[0]),
"parse", "div.box-result.clearfix",
"sub_parse", "title", "h2", "text",
)
arg = arg[1:]
offset := "0"
if len(arg) > 0 {
offset, arg = arg[0], arg[1:]
}
limit := "3"
if len(arg) > 0 {
limit, arg = arg[0], arg[1:]
}
m.Copy(msg, "append").Copy(msg, "result")
m.Cmd("select", "limit", limit, "offset", offset)
return
}},
"zhihu": &ctx.Command{Name: "zhihu", Help: "zhihu", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
msg := m.Spawn().Cmd("get", fmt.Sprintf(m.Conf("zhihu_site"), arg[0]),
"parse", "div.SearchMain div.Card.SearchResult-Card",
"sub_parse", "title", "", "text",
)
arg = arg[1:]
offset := "0"
if len(arg) > 0 {
offset, arg = arg[0], arg[1:]
}
limit := "3"
if len(arg) > 0 {
limit, arg = arg[0], arg[1:]
}
m.Copy(msg, "append").Copy(msg, "result")
m.Cmd("select", "limit", limit, "offset", offset)
return
}},
"toutiao": &ctx.Command{Name: "toutiao", Help: "toutiao", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
msg := m.Spawn().Cmd("get", fmt.Sprintf(m.Conf("toutiao_site"), arg[0]),
"parse", "div.articleCard",
"sub_parse", "title", "", "text",
)
arg = arg[1:]
offset := "0"
if len(arg) > 0 {
offset, arg = arg[0], arg[1:]
}
limit := "3"
if len(arg) > 0 {
limit, arg = arg[0], arg[1:]
}
m.Copy(msg, "append").Copy(msg, "result")
m.Cmd("select", "limit", limit, "offset", offset)
return
}},
},
}
func init() {
chat := &web.WEB{}
chat.Context = Index
web.Index.Register(Index, chat)
web.Index.Register(Index, &web.WEB{Context: Index})
}

View File

@ -7,475 +7,65 @@ import (
"contexts/web"
"toolkit"
"bufio"
"bytes"
"encoding/xml"
"fmt"
"html/template"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
)
var Index = &ctx.Context{Name: "wiki", Help: "文档中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": "false"}, Help: "默认组件"},
"componet_group": &ctx.Config{Name: "component_group", Value: "index", Help: "默认组件"},
"login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": "false"}, Help: "用户登录"},
"componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
"index": []interface{}{
map[string]interface{}{"componet_name": "wiki", "componet_tmpl": "head", "metas": []interface{}{
map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"},
}, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "wiki.css"}},
map[string]interface{}{"componet_name": "header", "componet_tmpl": "fieldset",
"componet_view": "Header", "componet_init": "initHeader",
"title": "shylinux 天行健,君子以自强不息",
map[string]interface{}{"name": "wiki",
"tmpl": "head", "metas": []interface{}{map[string]interface{}{
"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no",
}}, "favicon": "favicon.ico", "styles": []interface{}{
"example.css", "wiki.css",
}},
map[string]interface{}{"name": "header",
"tmpl": "fieldset", "view": "Header", "init": "initHeader",
},
map[string]interface{}{"componet_name": "tree", "componet_tmpl": "fieldset",
"componet_view": "Tree", "componet_init": "initTree",
"componet_ctx": "web.wiki", "componet_cmd": "wiki_tree", "arguments": []interface{}{"@wiki_class"},
map[string]interface{}{"name": "tree",
"tmpl": "fieldset", "view": "Tree", "init": "initTree",
"ctx": "web.wiki", "cmd": "tree",
},
map[string]interface{}{"componet_name": "text", "componet_tmpl": "fieldset",
"componet_view": "Text", "componet_init": "initText",
"componet_ctx": "web.wiki", "componet_cmd": "wiki_text", "arguments": []interface{}{"@wiki_favor"},
map[string]interface{}{"name": "text",
"tmpl": "fieldset", "view": "Text", "init": "initText",
"ctx": "web.wiki", "cmd": "text",
},
map[string]interface{}{"componet_name": "footer", "componet_tmpl": "fieldset",
"componet_view": "Footer", "componet_init": "initFooter",
"title": "shycontext 地势坤,君子以厚德载物",
map[string]interface{}{"name": "footer",
"tmpl": "fieldset", "view": "Footer", "init": "initFooter",
},
map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail",
"scripts": []interface{}{"toolkit.js", "context.js", "example.js", "wiki.js"},
map[string]interface{}{"name": "tail",
"tmpl": "tail", "scripts": []interface{}{
"toolkit.js", "context.js", "example.js", "wiki.js",
},
},
},
}, Help: "组件列表"},
"wiki_level": &ctx.Config{Name: "wiki_level", Value: "local/wiki/自然/编程", Help: "路由数量"},
"wiki_favor": &ctx.Config{Name: "wiki_favor", Value: "index.md", Help: "路由数量"},
"wiki_visit": &ctx.Config{Name: "wiki_visit", Value: map[string]interface{}{}, Help: "路由数量"},
"wiki_dir": &ctx.Config{Name: "wiki_dir", Value: "usr/local/wiki", Help: "路由数量"},
"wiki_list": &ctx.Config{Name: "wiki_list", Value: []interface{}{}, Help: "路由数量"},
"wiki_list_show": &ctx.Config{Name: "wiki_list_show", Value: map[string]interface{}{
"md": true,
}, Help: "路由数量"},
"level": &ctx.Config{Name: "level", Value: "local/wiki/自然/编程", Help: "路由数量"},
"favor": &ctx.Config{Name: "favor", Value: "index.md", Help: "路由数量"},
},
Commands: map[string]*ctx.Command{
"wiki_tree": &ctx.Command{Name: "wiki_tree", Help: "wiki_tree", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy("nfs.dir", path.Join(m.Confx("wiki_level"), kit.Select(m.Option("wiki_class"), arg, 0)),
"time", "line", "size", "file", "dir_sort", "time", "time_r")
"tree": &ctx.Command{Name: "tree", Help: "目录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy("nfs.dir", path.Join(m.Confx("level"), kit.Select(m.Option("class"), arg, 0)),
"time", "size", "line", "file", "dir_sort", "time", "time_r")
return
}},
"wiki_text": &ctx.Command{Name: "wiki_text", Help: "wiki_text", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
which := m.Cmdx("nfs.path", path.Join(m.Confx("wiki_level"), m.Option("wiki_class"), m.Confx("wiki_favor", arg, 0)),
"time", "line", "size", "file")
"text": &ctx.Command{Name: "text", Help: "文章", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
which := m.Cmdx("nfs.path", path.Join(m.Confx("level"), m.Option("class"), m.Confx("favor", arg, 0)))
if ls, e := ioutil.ReadFile(which); e == nil {
m.Conf("wiki_visit", []string{which, m.Option("access")},
m.Confi("wiki_visit", []string{which, m.Option("access")})+1)
m.Append("visit_count", m.Confi("wiki_visit", []string{which, m.Option("access")}))
m.Append("visit_total", len(m.Confm("wiki_visit", []string{which})))
buffer := bytes.NewBuffer([]byte{})
temp, e := template.New("temp").Funcs(ctx.CGI).Parse(string(ls))
if e != nil {
m.Log("info", "parse %s %s", which, e)
}
temp.Execute(buffer, m)
ls = buffer.Bytes()
ls = markdown.ToHTML(ls, nil, nil)
m.Echo(string(ls))
} else {
msg := m.Cmd("nfs.dir", path.Join(m.Confx("wiki_level"), m.Option("wiki_class")),
"dir_deep", "dir_type", "dir", "time", "path")
msg.Table(func(index int, value map[string]string) {
msg.Meta["path"][index] = strings.TrimPrefix(value["path"], path.Join("usr", m.Confx("wiki_level")))
})
m.Echo(msg.ToHTML("wiki_list"))
}
return
}},
"wiki_list": &ctx.Command{Name: "wiki_list sort_field sort_order", Help: "wiki_list", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
sort_field, sort_order := "time", "time_r"
if len(arg) > 0 {
sort_field, arg = arg[0], arg[1:]
}
if len(arg) > 0 {
sort_order, arg = arg[0], arg[1:]
}
dir := path.Join(m.Conf("wiki_dir"), m.Option("wiki_class"))
md, e := ioutil.ReadDir(dir)
m.Assert(e)
for _, v := range md {
if strings.HasSuffix(v.Name(), ".md") {
f, e := os.Open(path.Join(dir, v.Name()))
m.Assert(e)
defer f.Close()
title := ""
nline, ncode := 0, 0
h2, h3, h4 := 0, 0, 0
for bio := bufio.NewScanner(f); bio.Scan(); {
line := bio.Text()
nline++
if strings.HasPrefix(line, "## ") {
h2++
if title == "" {
title = line[3:]
}
} else if strings.HasPrefix(line, "### ") {
h3++
} else if strings.HasPrefix(line, "#### ") {
h4++
} else if strings.HasPrefix(line, "```") {
ncode++
}
}
m.Add("append", "time", v.ModTime().Format("2006/01/02"))
m.Add("append", "file", v.Name())
m.Add("append", "size", v.Size())
m.Add("append", "line", nline)
m.Add("append", "code", ncode/2)
m.Add("append", "h4", h4)
m.Add("append", "h3", h3)
m.Add("append", "h2", h2)
m.Add("append", "title", title)
}
}
m.Sort(sort_field, sort_order).Table()
m.Target().Configs["wiki_list"].Value = []interface{}{}
m.Table(func(line int, maps map[string]string) {
if line > 1 {
m.Confv("wiki_list", -2, maps)
}
})
return
}},
"/wiki_tags": &ctx.Command{Name: "/wiki_tags ", Help: "博客", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 {
m.Option("dir", arg[0])
}
yac := m.Find("yac.parse4", true)
msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), "src", m.Option("dir")), "dir_name", "path")
for _, v := range msg.Meta["filename"] {
name := strings.TrimSpace(v)
es := strings.Split(name, ".")
switch es[len(es)-1] {
case "pyc", "o", "gz", "tar":
continue
case "c":
case "py":
case "h":
default:
continue
}
f, e := os.Open(name)
m.Assert(e)
defer f.Close()
bio := bufio.NewScanner(f)
for line := 1; bio.Scan(); line++ {
yac.Options("silent", true)
l := yac.Cmd("parse", "code", "void", bio.Text())
key := ""
switch l.Result(1) {
case "struct":
switch l.Result(2) {
case "struct", "}":
key = l.Result(3)
case "typedef":
if l.Result(3) == "struct" {
key = l.Result(5)
}
}
case "function":
switch l.Result(3) {
case "*":
key = l.Result(4)
default:
key = l.Result(3)
}
case "variable":
switch l.Result(2) {
case "struct":
key = l.Result(4)
}
case "define":
key = l.Result(3)
}
if key != "" {
m.Confv("define", strings.Join([]string{key, "position", "-2"}, "."), map[string]interface{}{
"file": strings.TrimPrefix(name, m.Confx("wiki_dir")+"/src"),
"line": line,
"type": l.Result(1),
})
}
yac.Meta = nil
}
}
return
}},
"/wiki_body": &ctx.Command{Name: "/wiki_body", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
which := path.Join(m.Conf("wiki_dir"), m.Confx("which"))
st, _ := os.Stat(which)
if ls, e := ioutil.ReadFile(which); e == nil {
pre := false
es := strings.Split(m.Confx("which"), ".")
if len(es) > 0 {
switch es[len(es)-1] {
case "md":
m.Option("modify_count", 1)
m.Option("modify_time", st.ModTime().Format("2006/01/02 15:03:04"))
switch v := m.Confv("record", []interface{}{m.Option("path"), "local", "modify_count"}).(type) {
case int:
if m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}).(string) != m.Option("modify_time") {
m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}, m.Option("modify_time"))
m.Confv("record", []interface{}{m.Option("path"), "local", "modify_count"}, v+1)
}
m.Option("modify_count", v+1)
case float64:
if m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}).(string) != m.Option("modify_time") {
m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}, m.Option("modify_time"))
m.Confv("record", []interface{}{m.Option("path"), "local", "modify_count"}, v+1)
}
m.Option("modify_count", v+1)
case nil:
m.Confv("record", []interface{}{m.Option("path"), "local"}, map[string]interface{}{
"modify_count": m.Optioni("modify_count"),
"modify_time": m.Option("modify_time"),
})
default:
}
ls = markdown.ToHTML(ls, nil, nil)
default:
pre = true
}
}
if pre {
m.Option("nline", bytes.Count(ls, []byte("\n")))
m.Option("nbyte", len(ls))
m.Add("append", "code", string(ls))
m.Add("append", "body", "")
} else {
m.Add("append", "body", string(ls))
m.Add("append", "code", "")
}
return e
}
if m.Options("query") {
if v, ok := m.Confv("define", m.Option("query")).(map[string]interface{}); ok {
for _, val := range v["position"].([]interface{}) {
value := val.(map[string]interface{})
m.Add("append", "name", fmt.Sprintf("src/%v#hash_%v", value["file"], value["line"]))
}
return
}
msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), m.Option("dir")), "dir_name", "path")
for _, v := range msg.Meta["filename"] {
name := strings.TrimPrefix(strings.TrimSpace(v), m.Conf("wiki_dir"))
es := strings.Split(name, ".")
switch es[len(es)-1] {
case "pyc", "o", "gz", "tar":
continue
}
if strings.Contains(name, m.Option("query")) {
m.Add("append", "name", name)
}
}
return
}
msg := m.Spawn().Cmd("/wiki_list")
m.Copy(msg, "append").Copy(msg, "option")
return
}},
"/wiki_list": &ctx.Command{Name: "/wiki_list", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
ls, e := ioutil.ReadDir(path.Join(m.Conf("wiki_dir"), m.Option("which")))
m.Option("dir", m.Option("which"))
if e != nil {
dir, _ := path.Split(m.Option("which"))
m.Option("dir", dir)
ls, e = ioutil.ReadDir(path.Join(m.Conf("wiki_dir"), dir))
}
parent, _ := path.Split(strings.TrimSuffix(m.Option("dir"), "/"))
m.Option("parent", parent)
for _, l := range ls {
if l.Name()[0] == '.' {
continue
}
if !l.IsDir() {
es := strings.Split(l.Name(), ".")
if len(es) > 0 {
if show, ok := m.Confv("wiki_list_show", es[len(es)-1]).(bool); !ok || !show {
continue
}
}
}
m.Add("append", "name", l.Name())
m.Add("append", "time", l.ModTime().Format("2006-01-02 15:04:05"))
if l.IsDir() {
m.Add("append", "pend", "/")
} else {
m.Add("append", "pend", "")
}
m.Option("time_format", "2006-01-02 15:04:05")
m.Sort("time", "time_r")
}
return
}},
"/wiki/": &ctx.Command{Name: "/wiki", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("which", strings.TrimPrefix(key, "/wiki/"))
if f, e := os.Stat(path.Join(m.Conf("wiki_dir"), m.Option("which"))); e == nil && !f.IsDir() && (strings.HasSuffix(m.Option("which"), ".json") || strings.HasSuffix(m.Option("which"), ".js") || strings.HasSuffix(m.Option("which"), ".css")) {
m.Append("directory", path.Join(m.Conf("wiki_dir"), m.Option("which")))
return e
}
m.Append("template", "wiki")
return
}},
"/wx/": &ctx.Command{Name: "/wx/", Help: "微信", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if !m.Sess("aaa").Cmds("wx") {
return
}
if m.Has("echostr") {
m.Echo(m.Option("echostr"))
return
}
r := m.Optionv("request").(*http.Request)
switch r.Header.Get("Content-Type") {
case "text/xml":
type Article struct {
XMLName xml.Name `xml:"item"`
PicUrl string
Title string
Description string
Url string
}
type WXMsg struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime int32
MsgId int64
MsgType string
Event string
EventKey string
Content string
Format string
Recognition string
PicUrl string
MediaId string
Location_X float64
Location_Y float64
Scale int64
Label string
ArticleCount int
Articles struct {
XMLName xml.Name `xml:"Articles"`
Articles []*Article
}
}
var data WXMsg
b, e := ioutil.ReadAll(r.Body)
e = xml.Unmarshal(b, &data)
// de := xml.NewDecoder(r.Body)
// e := de.Decode(&data)
m.Assert(e)
var echo WXMsg
echo.FromUserName = data.ToUserName
echo.ToUserName = data.FromUserName
echo.CreateTime = data.CreateTime
fs, e := ioutil.ReadDir("usr/wiki")
m.Assert(e)
msg := m.Spawn()
for _, f := range fs {
if !strings.HasSuffix(f.Name(), ".md") {
continue
}
msg.Add("append", "name", f.Name())
msg.Add("append", "title", strings.TrimSuffix(f.Name(), ".md")+"源码解析")
msg.Add("append", "time", f.ModTime().Format("01/02 15:03"))
}
msg.Option("time_format", "01/02 15:03")
msg.Sort("time", "time_r")
articles := []*Article{}
articles = append(articles, &Article{PicUrl: "http://mmbiz.qpic.cn/mmbiz_jpg/sCJZHmp0V0doWEFBe6gS2HjgB0abiaK7H5WjkXGTvAI0CkCFrVJDEBBbJX8Kz0VegZ54ZoCo4We0sKJUOTuf1Tw/0",
Title: "wiki首页", Description: "技术文章", Url: "https://shylinux.com/wiki/"})
for i, v := range msg.Meta["title"] {
if i > 6 {
continue
}
articles = append(articles, &Article{PicUrl: "http://mmbiz.qpic.cn/mmbiz_jpg/sCJZHmp0V0doWEFBe6gS2HjgB0abiaK7H5WjkXGTvAI0CkCFrVJDEBBbJX8Kz0VegZ54ZoCo4We0sKJUOTuf1Tw/0",
Title: msg.Meta["time"][i] + " " + v, Description: "技术文章", Url: "https://shylinux.com/wiki/" + msg.Meta["name"][i]})
}
switch data.MsgType {
case "event":
echo.MsgType = "news"
echo.Articles.Articles = articles
echo.ArticleCount = len(echo.Articles.Articles)
case "text":
echo.MsgType = "news"
echo.Articles.Articles = articles
echo.ArticleCount = len(echo.Articles.Articles)
case "voice":
echo.MsgType = "text"
echo.Content = "你好"
case "image":
echo.MsgType = "text"
echo.Content = "你好"
case "location":
echo.MsgType = "text"
echo.Content = "你好"
}
b, e = xml.Marshal(echo)
m.Echo(string(b))
}
buffer := bytes.NewBuffer([]byte{})
template.Must(template.ParseFiles(which)).Funcs(ctx.CGI).Execute(buffer, m)
m.Echo(string(markdown.ToHTML(buffer.Bytes(), nil, nil)))
return
}},
},
}
func init() {
wiki := &web.WEB{}
wiki.Context = Index
web.Index.Register(Index, wiki)
web.Index.Register(Index, &web.WEB{Context: Index})
}

View File

@ -168,7 +168,7 @@ page = Page({
initRiver: function(page, field, option, output) {
return {
Show: function() {
this.Update([], "text", ["name", "count"], "key", ctx.Search("river")||true)
this.Update([], "text", ["nick", "count"], "key", ctx.Search("river")||true)
},
Action: {
"创建": function(event) {
@ -196,7 +196,7 @@ page = Page({
Show: function(i) {
field.Pane.Back(river, output)
var pane = this, foot = page.footer.Pane
var cmds = ["brow", river, i||which[river]||0]
var cmds = [river, "brow", i||which[river]||0]
cmds[2] || (output.innerHTML = ""), pane.Times(page.conf.refresh, cmds, function(line, index, msg) {
pane.Append("", line, ["text"], "index", function(line, index, event, args, cbs) {
var text = JSON.parse(line.text)
@ -209,7 +209,7 @@ page = Page({
},
Send: function(type, text, cb) {
var pane = this
pane.Run(["flow", river, type, text], function(msg) {
pane.Run([river, "flow", type, text], function(msg) {
pane.Show(), typeof cb == "function" && cb(msg)
})
},

View File

@ -106,8 +106,8 @@ ctx = context = {
Current: function(key, value) {
context.GET("", {
"componet_group": "index",
"componet_name": "cmd",
"group": "index",
"name": "cmd",
"cmds": ["sess", "current", key, value],
})
return value

View File

@ -84,6 +84,9 @@ function Page(page) {
var text = JSON.parse(line.text)
case "plugin":
if (!text.name) {
return {}
}
var id = "plugin"+page.ID()
list.push({view: [text.view+" item", "fieldset", "", "field"], data: {id: id, Run: cb}, list: [
{text: [text.name+"("+text.help+")", "legend"]},
@ -378,7 +381,6 @@ function Page(page) {
})
}]},
{type: "br"},
{type: "img", data: {"src": "/chat/qrcode?text=hi"}}
])
return {
Exit: function() {
@ -420,7 +422,7 @@ function Pane(page, field) {
var timer = ""
var list = [], last = -1
var conf = {}, conf_cb = {}
var name = option.dataset.componet_name
var name = option.dataset.name
var pane = (page[field.dataset.init] || function() {
})(page, field, option, output) || {}; pane.__proto__ = {
__proto__: page,
@ -520,8 +522,8 @@ function Pane(page, field) {
},
Share: function(objs) {
objs = objs || {}
objs.componet_name = option.dataset.componet_name
objs.componet_group = option.dataset.componet_group
objs.name = option.dataset.name
objs.group = option.dataset.group
return ctx.Share(objs)
},
Save: function(name, output) {

View File

@ -480,7 +480,7 @@ kit = toolkit = {
text.querySelectorAll("table.wiki_list").forEach(function(value, index, array) {
kit.OrderTable(value, "path", function(event) {
var text = event.target.innerText
ctx.Search({"wiki_class": text})
ctx.Search({"class": text})
})
})
},
@ -655,7 +655,7 @@ kit = toolkit = {
if (document.referrer) {
location.href = document.referrer
} else {
ctx.Search("componet_group", "")
ctx.Search("group", "")
}
})
return

View File

@ -55,22 +55,22 @@ var page = Page({
ctx.Runs(page, form, function(msg) {
ui.back.innerHTML = "", kit.AppendChild(ui.back, [
{"button": ["知识", function(event) {
ctx.Search({"wiki_level": "", "wiki_class": "", "wiki_favor": ""})
ctx.Search({"level": "", "class": "", "favor": ""})
}]},
].concat(ctx.Search("wiki_class").split("/").map(function(value, index, array) {
].concat(ctx.Search("class").split("/").map(function(value, index, array) {
return value && {"button": [value, function(event) {
location.hash = "", ctx.Search({"wiki_class": array.slice(0, index+1).join("/")+"/", "wiki_favor":""})
location.hash = "", ctx.Search({"class": array.slice(0, index+1).join("/")+"/", "favor":""})
}]}
})))
ui.tree.innerHTML = "", kit.AppendChild(ui.tree, ctx.Table(msg, function(value, index) {
return value.file.endsWith("/") && {"text": [value.file, "div"], click: function(event, target) {
location.hash = "", ctx.Search({"wiki_class": ctx.Search("wiki_class")+value.file, "wiki_favor": ""})
location.hash = "", ctx.Search({"class": ctx.Search("class")+value.file, "favor": ""})
}}
}))
ui.list.innerHTML = "", kit.AppendChild(ui.list, ctx.Table(msg, function(value, index) {
return !value.file.endsWith("/") && {"text": [value.time.substr(5, 5)+" "+value.file, "div"], click: function(event, target) {
location.hash = "", ctx.Search("wiki_favor", value.file)
location.hash = "", ctx.Search("favor", value.file)
}}
}))
})

View File

@ -6,37 +6,24 @@
<meta name="{{index $meta "name"}}" content="{{index $meta "content"}}">
{{end}}
<title>{{option . "componet_name" 0}}</title>
<link rel="shortcut icon" type="image/ico" href="/static/librarys/{{option . "favicon" 0}}">
<title>{{options . "name"}}</title>
<link rel="shortcut icon" type="image/ico" href="/static/librarys/{{options . "favicon"}}">
{{range $index, $lib := option . "styles"}}
<link rel="stylesheet" type="text/css" href="/static/librarys/{{$lib}}"></link>
{{end}}
</head>
<body>
<script>
var conf = {
toolkit_view: {{conf . "route" "toolkit_view"}},
bench_data: {{option . "bench_data"}},
}
</script>
<fieldset class="toast"><legend></legend>
<form class="option" data-componet_name="toast"></form>
<form class="option" data-name="toast"></form>
<div class="output"></div>
</fieldset>
{{end}}
{{define "banner"}}
<fieldset class="{{option . "componet_view" 0}}" data-init="{{option . "componet_init" 0}}">
<ul>{{range $key, $item := conf . "componet"}}<li>{{$key}}</li>{{end}}</ul>
</fieldset>
{{end}}
{{define "fieldset"}}
<fieldset class="{{option . "componet_view" 0}}" data-init="{{option . "componet_init" 0}}">
<form class="option {{option . "componet_name" 0}}"
data-componet_name="{{options . "componet_name"}}"
data-componet_group="{{options . "componet_group"}}">
<fieldset class="{{options . "view"}}" data-init="{{options . "init"}}">
<form class="option" data-name="{{options . "name"}}" data-group="{{options . "group"}}">
<input style="display:none"></input>
</form>
<div class="output {{option . "componet_name" 0}}"></div>
<div class="output"></div>
</fieldset>
{{end}}
{{define "tail"}}
@ -46,4 +33,3 @@
</body>
{{end}}