1
0
forked from x/ContextOS

add spide

Change-Id: I6ef91687d1d91b652159d5ce20667aba3541683a
This commit is contained in:
shaoying 2018-12-25 15:03:54 +08:00
parent b65bacaf72
commit aff272235a
11 changed files with 793 additions and 269 deletions

View File

@ -5,6 +5,7 @@ import (
"contexts/ctx"
"encoding/csv"
"path"
"syscall"
"toolkit"
"fmt"
@ -30,9 +31,23 @@ type CLI struct {
target *ctx.Context
stack []*Frame
*time.Timer
*ctx.Context
}
func (cli *CLI) schedule(m *ctx.Message) string {
first, timer := "", int64(1<<50)
for k, v := range m.Confv("timer").(map[string]interface{}) {
val := v.(map[string]interface{})
if val["action_time"].(int64) < timer && !val["done"].(bool) {
first, timer = k, val["action_time"].(int64)
}
}
cli.Timer.Reset(time.Until(time.Unix(0, timer/int64(m.Confi("time_unit"))*1000000000)))
m.Log("fuck", "what %v %d", first, timer)
return m.Conf("timer_next", first)
}
func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
c.Caches = map[string]*ctx.Cache{
"level": &ctx.Cache{Name: "level", Value: "0", Help: "嵌套层级"},
@ -97,6 +112,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
return s
}
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
cli.target = m.Target()
return cli
}
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
@ -159,6 +175,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
"top": map[string]interface{}{"active": true},
"ls": map[string]interface{}{"arg": []interface{}{"-l"}},
}, Help: "系统命令配置, active: 交互方式, cmd: 命令映射, arg: 命令参数, args: 子命令参数, path: 命令目录, env: 环境变量, dir: 工作目录"},
"timer": &ctx.Config{Name: "timer", Value: map[string]interface{}{}, Help: "定时器"},
"timer_next": &ctx.Config{Name: "timer_next", Value: "", Help: "定时器"},
},
Commands: map[string]*ctx.Command{
"alias": &ctx.Command{Name: "alias [short [long...]]|[delete short]|[import module [command [alias]]]",
@ -275,7 +294,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
execexec = execexec || ctx.Right(detail[i+1])
i++
case "<":
pipe := m.Spawn().Cmd("import", detail[i+1])
pipe := m.Sess("nfs").Cmd("import", detail[i+1])
msg.Copy(pipe, "append")
i++
case ">":
@ -312,8 +331,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
}
detail = args
msg.Set("detail", detail...)
if msg.Cmd(detail); msg.Hand {
if msg.Cmd(); msg.Hand {
m.Cap("ps_target", msg.Cap("module"))
} else {
msg.Copy(m, "target").Copy(m, "result").Detail(-1, "system")
@ -632,8 +652,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
arg = append(args, arg...)
m.Option("current_ctx", "")
} else {
args := []string{"context", m.Source().Name}
arg = append(args, arg...)
if !strings.HasPrefix(arg[0], "context") {
args := []string{"context", m.Source().Name}
arg = append(args, arg...)
}
}
m.Sess("yac").Call(func(msg *ctx.Message) *ctx.Message {
@ -664,87 +686,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.Copy(msg, "append").Copy(msg, "result")
}},
"sleep": &ctx.Command{Name: "sleep time", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if d, e := time.ParseDuration(arg[0]); m.Assert(e) {
m.Log("info", "sleep %v", d)
time.Sleep(d)
m.Log("info", "sleep %v done", d)
}
}},
"time": &ctx.Command{Name: "time when [begin|end|yestoday|tommorow|monday|sunday|first|last|origin|last]",
Help: "查看时间, when: 输入的时间戳, 剩余参数是时间偏移",
Form: map[string]int{"time_format": 1, "time_close": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
t, stamp := time.Now(), true
if len(arg) > 0 {
if i, e := strconv.ParseInt(arg[0], 10, 64); e == nil {
t = time.Unix(int64(i/int64(m.Confi("time_unit"))), 0)
arg = arg[1:]
stamp = false
} else if n, e := time.ParseInLocation(m.Confx("time_format"), arg[0], time.Local); e == nil {
arg = arg[1:]
t = n
}
}
if len(arg) > 0 {
switch arg[0] {
case "begin":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", t.Hour(), t.Minute(), t.Second()))
m.Assert(e)
t = t.Add(-d)
case "end":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds%dns", t.Hour(), t.Minute(), t.Second(), t.Nanosecond()))
m.Assert(e)
t = t.Add(time.Duration(24*time.Hour) - d)
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
case "yestoday":
t = t.Add(-time.Duration(24 * time.Hour))
case "tomorrow":
t = t.Add(time.Duration(24 * time.Hour))
case "monday":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", int((t.Weekday()-time.Monday+7)%7)*24+t.Hour(), t.Minute(), t.Second()))
m.Assert(e)
t = t.Add(-d)
case "sunday":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", int((t.Weekday()-time.Monday+7)%7)*24+t.Hour(), t.Minute(), t.Second()))
m.Assert(e)
t = t.Add(time.Duration(7*24*time.Hour) - d)
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
case "first":
t = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.Local)
case "last":
month, year := t.Month()+1, t.Year()
if month >= 13 {
month, year = 1, year+1
}
t = time.Date(year, month, 1, 0, 0, 0, 0, time.Local)
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
case "origin":
t = time.Date(t.Year(), 1, 1, 0, 0, 0, 0, time.Local)
case "final":
t = time.Date(t.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
}
}
m.Append("datetime", t.Format(m.Confx("time_format")))
m.Append("timestamp", t.Unix()*int64(m.Confi("time_unit")))
if stamp {
m.Echo("%d", t.Unix()*int64(m.Confi("time_unit")))
} else {
m.Echo(t.Format(m.Confx("time_format")))
}
}},
"tmux": &ctx.Command{Name: "tmux buffer", Help: "终端管理, buffer: 查看复制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
switch arg[0] {
case "buffer":
@ -854,8 +795,12 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
}
} else {
if out, e := cmd.Output(); e != nil {
m.Echo("error: ").Echo("%s\n", e)
m.Echo("%s\n", string(out))
if e == exec.ErrNotFound {
m.Echo("error: ").Echo("not found\n")
} else {
m.Echo("error: ").Echo("%s\n", e)
m.Echo("%s\n", string(out))
}
} else {
switch m.Option("cmd_parse") {
case "csv":
@ -911,6 +856,14 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.Append("lookups", mem.Lookups)
m.Append("objects", mem.HeapObjects)
sys := &syscall.Sysinfo_t{}
syscall.Sysinfo(sys)
m.Append("total", kit.FmtSize(uint64(sys.Totalram)))
m.Append("free", kit.FmtSize(uint64(sys.Freeram)))
m.Append("mper", fmt.Sprintf("%d%%", sys.Freeram*100/sys.Totalram))
m.Table()
}},
"windows": &ctx.Command{Name: "windows", Help: "windows", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
@ -1037,6 +990,184 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
}
}
}},
"sleep": &ctx.Command{Name: "sleep time", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if d, e := time.ParseDuration(arg[0]); m.Assert(e) {
m.Log("info", "sleep %v", d)
time.Sleep(d)
m.Log("info", "sleep %v done", d)
}
}},
"time": &ctx.Command{Name: "time when [begin|end|yestoday|tommorow|monday|sunday|first|last|new|eve] [offset]",
Help: "查看时间, when: 输入的时间戳, 剩余参数是时间偏移",
Form: map[string]int{"time_format": 1, "time_close": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
t, stamp := time.Now(), true
if len(arg) > 0 {
if i, e := strconv.ParseInt(arg[0], 10, 64); e == nil {
t, stamp, arg = time.Unix(int64(i/int64(m.Confi("time_unit"))), 0), false, arg[1:]
} else if n, e := time.ParseInLocation(m.Confx("time_format"), arg[0], time.Local); e == nil {
t, arg = n, arg[1:]
} else {
for _, v := range []string{"01-02", "2006-01-02", "15:04:05", "15:04"} {
if n, e := time.ParseInLocation(v, arg[0], time.Local); e == nil {
t, arg = n, arg[1:]
break
}
}
}
}
if len(arg) > 0 {
switch arg[0] {
case "begin":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", t.Hour(), t.Minute(), t.Second()))
m.Assert(e)
t, arg = t.Add(-d), arg[1:]
case "end":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds%dns", t.Hour(), t.Minute(), t.Second(), t.Nanosecond()))
m.Assert(e)
t, arg = t.Add(time.Duration(24*time.Hour)-d), arg[1:]
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
case "yestoday":
t, arg = t.Add(-time.Duration(24*time.Hour)), arg[1:]
case "tomorrow":
t, arg = t.Add(time.Duration(24*time.Hour)), arg[1:]
case "monday":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", int((t.Weekday()-time.Monday+7)%7)*24+t.Hour(), t.Minute(), t.Second()))
m.Assert(e)
t, arg = t.Add(-d), arg[1:]
case "sunday":
d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", int((t.Weekday()-time.Monday+7)%7)*24+t.Hour(), t.Minute(), t.Second()))
m.Assert(e)
t, arg = t.Add(time.Duration(7*24*time.Hour)-d), arg[1:]
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
case "first":
t, arg = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.Local), arg[1:]
case "last":
month, year := t.Month()+1, t.Year()
if month >= 13 {
month, year = 1, year+1
}
t, arg = time.Date(year, month, 1, 0, 0, 0, 0, time.Local), arg[1:]
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
case "new":
t, arg = time.Date(t.Year(), 1, 1, 0, 0, 0, 0, time.Local), arg[1:]
case "eve":
t, arg = time.Date(t.Year()+1, 1, 1, 0, 0, 0, 0, time.Local), arg[1:]
if m.Confx("time_close") == "close" {
t = t.Add(-time.Second)
}
case "":
arg = arg[1:]
}
}
if len(arg) > 0 {
if d, e := time.ParseDuration(arg[0]); e == nil {
t, arg = t.Add(d), arg[1:]
}
}
m.Append("datetime", t.Format(m.Confx("time_format")))
m.Append("timestamp", t.Unix()*int64(m.Confi("time_unit")))
if stamp {
m.Echo("%d", t.Unix()*int64(m.Confi("time_unit")))
} else {
m.Echo(t.Format(m.Confx("time_format")))
}
}},
"timer": &ctx.Command{Name: "timer [begin time] [repeat] [order time] time cmd", Help: "定时任务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if cli, ok := c.Server.(*CLI); m.Assert(ok) {
if len(arg) == 0 { // 查看任务列表
for k, v := range m.Confv("timer").(map[string]interface{}) {
val := v.(map[string]interface{})
m.Add("append", "key", k)
m.Add("append", "action_time", time.Unix(0, val["action_time"].(int64)/int64(m.Confi("time_unit"))*1000000000).Format(m.Conf("time_format")))
m.Add("append", "order", val["order"])
m.Add("append", "time", val["time"])
m.Add("append", "cmd", val["cmd"])
m.Add("append", "msg", val["msg"])
m.Add("append", "results", fmt.Sprintf("%v", val["result"]))
}
m.Table()
return
}
now := int64(m.Spawn().Cmd("time").Appendi("timestamp"))
begin := now
if len(arg) > 0 && arg[0] == "begin" {
begin, arg = int64(m.Spawn().Cmd("time", arg[1]).Appendi("timestamp")), arg[2:]
}
repeat := false
if len(arg) > 0 && arg[0] == "repeat" {
repeat, arg = true, arg[1:]
}
order := ""
if len(arg) > 0 && arg[0] == "order" {
order, arg = arg[1], arg[2:]
}
action := int64(m.Spawn().Cmd("time", begin, order, arg[0]).Appendi("timestamp"))
// 创建任务
hash := m.Sess("aaa").Cmd("md5", arg, now).Result(0)
m.Confv("timer", hash, map[string]interface{}{
"create_time": now,
"begin_time": begin,
"action_time": action,
"repeat": repeat,
"order": order,
"done": false,
"time": arg[0],
"cmd": arg[1:],
"msg": 0,
"result": "",
})
if cli.Timer == nil { // 创建时间队列
cli.Timer = time.NewTimer((time.Duration)((action - now) / int64(m.Confi("time_unit")) * 1000000000))
go func() {
for {
select {
case <-cli.Timer.C:
m.Log("info", "timer %s", m.Conf("timer_next"))
if m.Conf("timer_next") == "" {
break
}
timer := m.Confv("timer", m.Conf("timer_next")).(map[string]interface{})
m.Log("info", "timer %s %v", m.Conf("timer_next"), timer["cmd"])
msg := m.Sess("cli").Cmd("source", timer["cmd"])
timer["result"] = msg.Meta["result"]
timer["msg"] = msg.Code()
if timer["repeat"].(bool) {
timer["action_time"] = int64(m.Spawn().Cmd("time", timer["action_time"], timer["order"], timer["time"]).Appendi("timestamp"))
} else {
timer["done"] = true
}
cli.schedule(m)
}
}
cli.Timer = nil
}()
}
// 调度任务
cli.schedule(m)
m.Echo(hash)
}
}},
},
}

View File

@ -1,7 +1,6 @@
package ctx
import (
"encoding/csv"
"encoding/json"
"errors"
"fmt"
@ -1454,6 +1453,7 @@ func (m *Message) Cmd(args ...interface{}) *Message {
if m == nil {
return m
}
if len(args) > 0 {
m.Set("detail", Trans(args...)...)
}
@ -3050,7 +3050,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
arg, all = arg[1:], true
}
action, which, chain := "", "-1", ""
action, which := "", "-1"
have := map[string]bool{}
if len(arg) > 0 {
switch arg[0] {
@ -3066,8 +3066,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
case "create", "delete":
action, arg = arg[0], arg[1:]
case "parse":
chain, arg = arg[1], arg[2:]
}
}
@ -3149,9 +3147,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
value = m.Confv(arg[0])
}
msg := m.Spawn()
msg.Put("option", "_cache", value)
msg.Cmd("trans", "_cache", chain)
msg := m.Spawn().Put("option", "_cache", value).Cmd("trans", "_cache")
m.Copy(msg, "append").Copy(msg, "result")
}},
"cache": &Command{Name: "cache [all] |key [value]|key = value|key name value help|delete key]",
@ -3188,25 +3184,26 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
}},
"trans": &Command{Name: "trans key index", Help: "数据转换", Hand: func(m *Message, c *Context, key string, arg ...string) {
"trans": &Command{Name: "trans key [index]", Help: "数据转换", Hand: func(m *Message, c *Context, key string, arg ...string) {
value := m.Data[arg[0]]
if arg[1] != "" {
v := Chain(m, value, arg[1])
value = v
if len(arg) > 1 && arg[1] != "" {
value = Chain(m, value, arg[1])
}
switch val := value.(type) {
case map[string]interface{}:
for k, v := range val {
m.Add("append", "key", k)
switch value := v.(type) {
switch val := v.(type) {
case nil:
m.Add("append", "value", "")
case string:
m.Add("append", "value", value)
m.Add("append", "value", val)
case float64:
m.Add("append", "value", fmt.Sprintf("%d", int(value)))
m.Add("append", "value", fmt.Sprintf("%d", int(val)))
default:
b, _ := json.Marshal(value)
m.Add("append", "value", fmt.Sprintf("%v", string(b)))
b, _ := json.Marshal(val)
m.Add("append", "value", fmt.Sprintf("%s", string(b)))
}
}
m.Sort("key", "str").Table()
@ -3218,9 +3215,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
m.Sort("key", "str").Table()
case []interface{}:
for i, v := range val {
switch value := v.(type) {
switch val := v.(type) {
case map[string]interface{}:
for k, v := range value {
for k, v := range val {
switch value := v.(type) {
case string:
m.Add("append", k, value)
@ -3233,13 +3230,16 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
case string:
m.Add("append", "index", i)
m.Add("append", "value", value)
m.Add("append", "value", val)
case float64:
m.Add("append", "index", i)
m.Add("append", "value", fmt.Sprintf("%v", int(value)))
m.Add("append", "value", fmt.Sprintf("%v", int(val)))
case nil:
m.Add("append", "index", i)
m.Add("append", "value", "")
default:
m.Add("append", "index", i)
b, _ := json.Marshal(value)
b, _ := json.Marshal(val)
m.Add("append", "value", fmt.Sprintf("%v", string(b)))
}
}
@ -3472,47 +3472,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
m.Set("result").Table()
}},
"import": &Command{Name: "import filename", Help: "导入数据", Hand: func(m *Message, c *Context, key string, arg ...string) {
f, e := os.Open(arg[0])
m.Assert(e)
defer f.Close()
switch {
case strings.HasSuffix(arg[0], ".json"):
var data interface{}
de := json.NewDecoder(f)
de.Decode(&data)
m.Optionv("data", data)
switch d := data.(type) {
case []interface{}:
for _, value := range d {
switch val := value.(type) {
case map[string]interface{}:
for k, v := range val {
m.Add("append", k, v)
}
}
}
}
case strings.HasSuffix(arg[0], ".csv"):
r := csv.NewReader(f)
l, e := r.Read()
m.Assert(e)
m.Meta["append"] = l
for {
l, e := r.Read()
if e != nil {
break
}
for i, v := range l {
m.Add("append", m.Meta["append"][i], v)
}
}
}
m.Table()
}},
},
}

View File

@ -1084,6 +1084,34 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
m.Set("append").Set("result").Add("append", "directory", name).Echo(name)
}},
"import": &ctx.Command{Name: "import filename [index]", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
_, f, e := open(m, arg[0])
m.Assert(e)
defer f.Close()
switch {
case strings.HasSuffix(arg[0], ".json"):
var data interface{}
de := json.NewDecoder(f)
de.Decode(&data)
msg := m.Spawn().Put("option", "data", data).Cmd("trans", "data", arg[1:])
m.Copy(msg, "append").Copy(msg, "result")
case strings.HasSuffix(arg[0], ".csv"):
r := csv.NewReader(f)
l, e := r.Read()
m.Assert(e)
m.Meta["append"] = l
for l, e = r.Read(); e != nil; l, e = r.Read() {
for i, v := range l {
m.Add("append", m.Meta["append"][i], v)
}
}
m.Table()
}
}},
"pwd": &ctx.Command{Name: "pwd [all] | [[index] path] ", Help: "工作目录all: 查看所有, index path: 设置路径, path: 设置当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if len(arg) > 0 && arg[0] == "all" {

View File

@ -322,6 +322,8 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
"body_response": &ctx.Config{Name: "body_response", Value: "response", Help: "响应缓存"},
"multipart_bsize": &ctx.Config{Name: "multipart_bsize", Value: "102400", Help: "缓存大小"},
"brow_home": &ctx.Config{Name: "brow_home", Value: "http://localhost:9094", Help: "浏览服务"},
"spide": &ctx.Config{Name: "spide", Value: map[string]interface{}{}, Help: "浏览服务"},
"client_timeout": &ctx.Config{Name: "client_timeout", Value: "100s", Help: "浏览服务"},
"directory": &ctx.Config{Name: "directory", Value: "usr", Help: "服务目录"},
"protocol": &ctx.Config{Name: "protocol", Value: "http", Help: "服务协议"},
@ -334,6 +336,12 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
"login_lark": &ctx.Config{Name: "login_lark", Value: "false", Help: "会话认证"},
"cas_url": &ctx.Config{Name: "cas_url", Value: "", Help: "单点登录"},
"toolkit": &ctx.Config{Name: "toolkit", Value: map[string]interface{}{
"time": map[string]interface{}{
"cmd": "time",
},
}, Help: "小工具"},
"library_dir": &ctx.Config{Name: "library_dir", Value: "usr/librarys", Help: "脚本目录"},
"template_dir": &ctx.Config{Name: "template_dir", Value: "usr/template", Help: "模板目录"},
"template_debug": &ctx.Config{Name: "template_debug", Value: "true", Help: "模板调试"},
@ -415,7 +423,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}},
"get": &ctx.Command{Name: "get [method GET|POST] url arg...",
Help: "访问服务, method: 请求方法, url: 请求地址, arg: 请求参数",
Form: map[string]int{"method": 1, "headers": 2, "content_type": 1, "body": 1, "path_value": 1, "body_response": 1, "parse": 1, "save": 1},
Form: map[string]int{"method": 1, "headers": 2, "content_type": 1, "body": 1, "path_value": 1, "body_response": 1, "parse": 1, "sub_parse": 3, "save": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
if m.Has("path_value") {
@ -470,10 +478,13 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}
if web.Client == nil {
web.Client = &http.Client{}
d, e := time.ParseDuration(m.Conf("client_timeout"))
m.Assert(e)
web.Client = &http.Client{Timeout: d}
}
res, e := web.Client.Do(req)
if e != nil {
m.Log("info", "get error %v", e)
return
}
m.Assert(e)
@ -495,7 +506,6 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}()
if m.Has("save") {
p := m.Option("save")
if !strings.Contains(m.Option("save"), "/") {
p = path.Join(m.Sess("nfs").Cmd("pwd").Result(0), m.Option("save"))
@ -512,27 +522,44 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
ct := res.Header.Get("Content-Type")
m.Log("info", "content: %s", ct)
switch {
case strings.HasPrefix(ct, "application/json"):
json.NewDecoder(res.Body).Decode(&result)
if m.Has("parse") {
msg := m.Spawn()
msg.Put("option", "response", result)
msg.Cmd("trans", "response", m.Option("parse"))
msg := m.Spawn().Put("option", "data", result).Cmd("trans", "data", m.Option("parse"))
m.Copy(msg, "append").Copy(msg, "result")
return
}
b, _ := json.MarshalIndent(result, "", " ")
result = string(b)
case strings.HasPrefix(ct, "text/html"):
html, e := goquery.NewDocumentFromReader(res.Body)
page, e := goquery.NewDocumentFromReader(res.Body)
m.Assert(e)
query := html.Find("html")
query := page.Find("html")
if m.Has("parse") {
query = query.Find(m.Option("parse"))
}
query.Each(func(n int, s *goquery.Selection) {
if m.Options("sub_parse") {
for i := 0; i < len(m.Meta["sub_parse"])-2; i += 3 {
item := s.Find(m.Meta["sub_parse"][i+1])
if m.Meta["sub_parse"][i+1] == "" {
item = s
}
if v, ok := item.Attr(m.Meta["sub_parse"][i+2]); ok {
m.Add("append", m.Meta["sub_parse"][i], v)
m.Log("info", "item attr %v", v)
} else {
m.Add("append", m.Meta["sub_parse"][i], strings.Replace(item.Text(), "\n", "", -1))
m.Log("info", "item text %v", item.Text())
}
}
return
}
s.Find("a").Each(func(n int, s *goquery.Selection) {
if attr, ok := s.Attr("href"); ok {
s.SetAttr("href", proxy(m, attr))
@ -551,10 +578,13 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
s.SetAttr("src", proxy(m, attr))
}
})
if html, e := s.Html(); e == nil {
m.Add("append", "html", html)
}
})
m.Table()
result = ""
case strings.HasPrefix(ct, "text"):
buf, e := ioutil.ReadAll(res.Body)
m.Assert(e)
@ -1024,6 +1054,17 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}
}
if m.Options("toolkit") {
m.Log("what", "waht %v", m.Optionv("toolkit"))
m.Log("what", "waht %v", m.Confv("toolkit"))
if kit, ok := m.Confv("toolkit", m.Option("toolkit")).(map[string]interface{}); ok {
m.Log("what", "waht %v", kit)
msg := m.Sess("cli").Cmd(kit["cmd"], m.Option("argument"))
m.Copy(msg, "append").Copy(msg, "result")
}
return
}
bench_share := ""
bench, ok := m.Confv("bench", m.Option("bench")).(map[string]interface{})
if right && !m.Confs("bench_disable") {
@ -1180,6 +1221,101 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
msg := m.Spawn().Cmd("get", strings.TrimPrefix(key, "/proxy/"), arg)
m.Copy(msg, "append").Copy(msg, "result")
}},
"spide": &ctx.Command{Name: "spide", Help: "spide", Form: map[string]int{"fields": 1, "limit": 1, "offset": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if len(arg) == 0 {
for k, v := range m.Confv("spide").(map[string]interface{}) {
val := v.(map[string]interface{})
m.Add("append", "key", k)
m.Add("append", "limit", val["limit"])
m.Add("append", "site", val["site"])
}
m.Sort("key", "str").Table()
return
}
if len(arg) > 0 && arg[0] == "add" {
m.Confv("spide", arg[1], map[string]interface{}{
"site": arg[2],
"narg": strings.Count(arg[2], "%s"),
"parse": arg[3],
"sub_parse": arg[4:],
"fields": m.Option("fields"),
"offset": m.Option("offset"),
"limit": m.Option("limit"),
})
return
}
spide := m.Confv("spide", arg[0]).(map[string]interface{})
arg = arg[1:]
sub_parse := spide["sub_parse"].([]string)
args := []interface{}{}
for i := 0; i < spide["narg"].(int); i++ {
args = append(args, url.QueryEscape(arg[i]))
}
msg := m.Spawn().Cmd("get", fmt.Sprintf(spide["site"].(string), args...),
"parse", spide["parse"], sub_parse)
arg = arg[spide["narg"].(int):]
offset := spide["offset"].(string)
if m.Has("offset") {
offset = m.Option("offset")
}
if len(arg) > 0 {
offset, arg = arg[0], arg[1:]
}
limit := spide["limit"].(string)
if m.Has("limit") {
limit = m.Option("limit")
}
if len(arg) > 0 {
limit, arg = arg[0], arg[1:]
}
fields := spide["fields"].(string)
if m.Has("fields") {
fields = m.Option("fields")
}
if len(arg) > 0 {
fields, arg = arg[0], arg[1:]
}
m.Copy(msg, "append").Copy(msg, "result")
m.Cmd("select", "limit", limit, "offset", offset, "fields", fields)
}},
"12306": &ctx.Command{Name: "12306", Help: "12306", Form: map[string]int{"fields": 1, "limit": 1, "offset": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
date := "2018-12-24"
if len(arg) > 0 {
date, arg = arg[0], arg[1:]
}
to := "QFK"
if len(arg) > 0 {
to, arg = arg[0], arg[1:]
}
from := "BJP"
if len(arg) > 0 {
from, arg = arg[0], arg[1:]
}
m.Echo("%s->%s %s\n", from, to, date)
msg := m.Spawn().Cmd("get", fmt.Sprintf("https://kyfw.12306.cn/otn/leftTicket/queryX?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT", date, from, to), "parse", "data.result")
for _, v := range msg.Meta["value"] {
fields := strings.Split(v, "|")
m.Add("append", "车次--", fields[3])
m.Add("append", "出发----", fields[8])
m.Add("append", "到站----", fields[9])
m.Add("append", "时长----", fields[10])
m.Add("append", "二等座", fields[30])
m.Add("append", "一等座", fields[31])
}
m.Table()
}},
},
}

View File

@ -12,7 +12,16 @@ import (
var Index = &ctx.Context{Name: "chat", Help: "会议中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"chat_msg": &ctx.Config{Name: "chat_msg", Value: []interface{}{}, 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: "聊天记录"},
},
Commands: map[string]*ctx.Command{
"/chat": &ctx.Command{Name: "user", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
@ -34,6 +43,168 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
}
m.Confv("chat_msg", "-1", data)
}},
"talk": &ctx.Command{Name: "talk", Help: "talk", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if m.Confs("default") {
m.Echo(m.Conf("default"))
}
}},
"weather": &ctx.Command{Name: "weather where field", Help: "weather", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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")
}
}},
"calendar": &ctx.Command{Name: "calendar", Help: "calendar", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
msg := m.Spawn().Cmd("get", m.Conf("calendar_site"),
"parse", "div.almanac-hd")
m.Copy(msg, "append").Copy(msg, "result")
}},
"topic": &ctx.Command{Name: "topic", Help: "topic", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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)
}},
"pedia": &ctx.Command{Name: "pedia", Help: "pedia", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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)
}},
"baike": &ctx.Command{Name: "baike", Help: "baike", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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)
}},
"sinas": &ctx.Command{Name: "sinas", Help: "sinas", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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)
}},
"zhihu": &ctx.Command{Name: "zhihu", Help: "zhihu", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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)
}},
"toutiao": &ctx.Command{Name: "toutiao", Help: "toutiao", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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)
}},
},
}

View File

@ -37,19 +37,19 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
"index": []interface{}{
map[string]interface{}{"componet_name": "head", "template": "head"},
map[string]interface{}{"componet_name": "docker", "componet_help": "docker", "template": "docker"},
map[string]interface{}{"componet_name": "login", "componet_help": "login", "template": "componet",
"componet_ctx": "aaa", "componet_cmd": "login", "arguments": []interface{}{"@username", "@password"},
"inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "username", "label": "username"},
map[string]interface{}{"type": "password", "name": "password", "label": "password"},
map[string]interface{}{"type": "button", "value": "login"},
},
"display_append": "", "display_result": "",
},
map[string]interface{}{"componet_name": "userinfo", "componet_help": "userinfo", "template": "componet",
"componet_ctx": "aaa", "componet_cmd": "login", "arguments": []interface{}{"@sessid"},
"pre_run": true,
},
// map[string]interface{}{"componet_name": "login", "componet_help": "login", "template": "componet",
// "componet_ctx": "aaa", "componet_cmd": "login", "arguments": []interface{}{"@username", "@password"},
// "inputs": []interface{}{
// map[string]interface{}{"type": "text", "name": "username", "label": "username"},
// map[string]interface{}{"type": "password", "name": "password", "label": "password"},
// map[string]interface{}{"type": "button", "value": "login"},
// },
// "display_append": "", "display_result": "",
// },
// map[string]interface{}{"componet_name": "userinfo", "componet_help": "userinfo", "template": "componet",
// "componet_ctx": "aaa", "componet_cmd": "login", "arguments": []interface{}{"@sessid"},
// "pre_run": true,
// },
map[string]interface{}{"componet_name": "clipboard", "componet_help": "clipboard", "template": "clipboard"},
map[string]interface{}{"componet_name": "buffer", "componet_help": "buffer", "template": "componet",
"componet_ctx": "cli", "componet_cmd": "tmux", "arguments": []interface{}{"buffer"}, "inputs": []interface{}{
@ -59,23 +59,23 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
},
"pre_run": true,
},
map[string]interface{}{"componet_name": "time", "componet_help": "time", "template": "componet",
"componet_ctx": "cli", "componet_cmd": "time", "arguments": []interface{}{"@string"},
"inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "time_format",
"label": "format", "value": "2006-01-02 15:04:05",
},
map[string]interface{}{"type": "text", "name": "string", "label": "string"},
map[string]interface{}{"type": "button", "value": "refresh"},
},
},
map[string]interface{}{"componet_name": "json", "componet_help": "json", "template": "componet",
"componet_ctx": "nfs", "componet_cmd": "json", "arguments": []interface{}{"@string"},
"inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "string", "label": "string"},
map[string]interface{}{"type": "button", "value": "refresh"},
},
},
// map[string]interface{}{"componet_name": "time", "componet_help": "time", "template": "componet",
// "componet_ctx": "cli", "componet_cmd": "time", "arguments": []interface{}{"@string"},
// "inputs": []interface{}{
// map[string]interface{}{"type": "text", "name": "time_format",
// "label": "format", "value": "2006-01-02 15:04:05",
// },
// map[string]interface{}{"type": "text", "name": "string", "label": "string"},
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// },
// map[string]interface{}{"componet_name": "json", "componet_help": "json", "template": "componet",
// "componet_ctx": "nfs", "componet_cmd": "json", "arguments": []interface{}{"@string"},
// "inputs": []interface{}{
// map[string]interface{}{"type": "text", "name": "string", "label": "string"},
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// },
map[string]interface{}{"componet_name": "dir", "componet_help": "dir", "template": "componet",
"componet_ctx": "nfs", "componet_cmd": "dir", "arguments": []interface{}{"@dir", "dir_sort", "@sort_order", "@sort_field"},
"pre_run": true, "display_result": "",
@ -117,16 +117,16 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
},
"display_result": "",
},
map[string]interface{}{"componet_name": "download", "componet_help": "download", "template": "componet",
"componet_ctx": "cli.shy", "componet_cmd": "source", "arguments": []interface{}{"@cmds"},
"display_result": "", "download_file": "",
"inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "download_file", "value": "data_2006_0102_1504.txt", "class": "file_name"},
map[string]interface{}{"type": "text", "name": "cmds", "value": "",
"class": "file_cmd", "clipstack": "clistack",
},
},
},
// map[string]interface{}{"componet_name": "download", "componet_help": "download", "template": "componet",
// "componet_ctx": "cli.shy", "componet_cmd": "source", "arguments": []interface{}{"@cmds"},
// "display_result": "", "download_file": "",
// "inputs": []interface{}{
// map[string]interface{}{"type": "text", "name": "download_file", "value": "data_2006_0102_1504.txt", "class": "file_name"},
// map[string]interface{}{"type": "text", "name": "cmds", "value": "",
// "class": "file_cmd", "clipstack": "clistack",
// },
// },
// },
map[string]interface{}{"componet_name": "command", "componet_help": "command", "template": "componet",
"componet_ctx": "cli.shy", "componet_cmd": "source", "arguments": []interface{}{"@cmd"},
"inputs": []interface{}{
@ -143,50 +143,50 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
map[string]interface{}{"type": "button", "value": "refresh"},
},
},
map[string]interface{}{"componet_name": "ccc", "componet_help": "ccc", "template": "componet",
"componet_ctx": "cli.shy", "componet_cmd": "context", "arguments": []interface{}{"@current_ctx", "@ccc"},
"display_result": "",
"inputs": []interface{}{
map[string]interface{}{"type": "choice", "name": "ccc",
"label": "ccc", "value": "command", "choice": []interface{}{
map[string]interface{}{"name": "command", "value": "command"},
map[string]interface{}{"name": "config", "value": "config"},
map[string]interface{}{"name": "cache", "value": "cache"},
},
},
map[string]interface{}{"type": "button", "value": "refresh"},
},
},
map[string]interface{}{"componet_name": "cmd", "componet_help": "cmd", "template": "componet",
"componet_ctx": "cli.shy", "componet_cmd": "context", "arguments": []interface{}{"@current_ctx", "command", "list"},
"pre_run": true, "display_result": "",
"inputs": []interface{}{
map[string]interface{}{"type": "button", "value": "refresh"},
},
},
map[string]interface{}{"componet_name": "history", "componet_help": "history", "template": "componet",
"componet_ctx": "cli", "componet_cmd": "config", "arguments": []interface{}{"source_list"},
"pre_run": true, "display_result": "",
"inputs": []interface{}{
map[string]interface{}{"type": "button", "value": "refresh"},
},
},
map[string]interface{}{"componet_name": "develop", "componet_help": "develop", "template": "componet",
"componet_ctx": "web.code", "componet_cmd": "config", "arguments": []interface{}{"counter"},
"inputs": []interface{}{
map[string]interface{}{"type": "button", "value": "refresh"},
},
"pre_run": true,
"display_result": "",
},
map[string]interface{}{"componet_name": "windows", "componet_help": "windows", "template": "componet",
"componet_ctx": "cli", "componet_cmd": "windows",
"inputs": []interface{}{
map[string]interface{}{"type": "button", "value": "refresh"},
},
"pre_run": true,
"display_result": "",
},
// map[string]interface{}{"componet_name": "ccc", "componet_help": "ccc", "template": "componet",
// "componet_ctx": "cli.shy", "componet_cmd": "context", "arguments": []interface{}{"@current_ctx", "@ccc"},
// "display_result": "",
// "inputs": []interface{}{
// map[string]interface{}{"type": "choice", "name": "ccc",
// "label": "ccc", "value": "command", "choice": []interface{}{
// map[string]interface{}{"name": "command", "value": "command"},
// map[string]interface{}{"name": "config", "value": "config"},
// map[string]interface{}{"name": "cache", "value": "cache"},
// },
// },
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// },
// map[string]interface{}{"componet_name": "cmd", "componet_help": "cmd", "template": "componet",
// "componet_ctx": "cli.shy", "componet_cmd": "context", "arguments": []interface{}{"@current_ctx", "command", "list"},
// "pre_run": true, "display_result": "",
// "inputs": []interface{}{
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// },
// map[string]interface{}{"componet_name": "history", "componet_help": "history", "template": "componet",
// "componet_ctx": "cli", "componet_cmd": "config", "arguments": []interface{}{"source_list"},
// "pre_run": true, "display_result": "",
// "inputs": []interface{}{
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// },
// map[string]interface{}{"componet_name": "develop", "componet_help": "develop", "template": "componet",
// "componet_ctx": "web.code", "componet_cmd": "config", "arguments": []interface{}{"counter"},
// "inputs": []interface{}{
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// "pre_run": true,
// "display_result": "",
// },
// map[string]interface{}{"componet_name": "windows", "componet_help": "windows", "template": "componet",
// "componet_ctx": "cli", "componet_cmd": "windows",
// "inputs": []interface{}{
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// "pre_run": true,
// "display_result": "",
// },
map[string]interface{}{"componet_name": "runtime", "componet_help": "runtime", "template": "componet",
"componet_ctx": "cli", "componet_cmd": "runtime",
"inputs": []interface{}{
@ -195,14 +195,14 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
"pre_run": true,
"display_result": "",
},
map[string]interface{}{"componet_name": "sysinfo", "componet_help": "sysinfo", "template": "componet",
"componet_ctx": "cli", "componet_cmd": "sysinfo",
"inputs": []interface{}{
map[string]interface{}{"type": "button", "value": "refresh"},
},
"pre_run": true,
"display_result": "",
},
// map[string]interface{}{"componet_name": "sysinfo", "componet_help": "sysinfo", "template": "componet",
// "componet_ctx": "cli", "componet_cmd": "sysinfo",
// "inputs": []interface{}{
// map[string]interface{}{"type": "button", "value": "refresh"},
// },
// "pre_run": true,
// "display_result": "",
// },
map[string]interface{}{"componet_name": "tail", "template": "tail"},
},
}, Help: "组件列表"},

View File

@ -10,7 +10,7 @@ var code = {
ncommand: 1,
current_cmd: "",
show_result: true,
show_result: false,
show_height: "30px",
hide_height: "14px",
scroll_x: 50,
@ -105,15 +105,19 @@ function add_sort(append, field, cb) {
typeof cb == "function" && cb(event)
}
var text = window.getSelection().toString()
if (!text) {
var has = document.querySelector("td.clip")
has && (has.className = "")
target.className = "clip"
text = target.innerText
var has = document.querySelector("td.clip")
has && (has.className = "")
target.className = "clip"
if (event.shiftKey) {
copy_to_clipboard(target.innerText, false, false)
return
}
copy_to_clipboard(text, true, !event.shiftKey)
var text = window.getSelection().toString()
if (text) {
copy_to_clipboard(text, true, !event.shiftKey)
}
}
}
}
@ -222,13 +226,6 @@ function send_command(form, cb) {
var result = document.querySelector("code.result."+name+" pre")
var append = document.querySelector("table.append."+name)
if (result && msg) {
if (msg["Content-Type"] && msg["Content-Type"].join("") == "text/html") {
append_child(result, "iframe").innerHTML = (msg.result || []).join("")
} else {
result.innerHTML = (msg.result || []).join("")
}
}
if (append && msg) {
append.innerHTML = ""
if (msg.append) {
@ -245,9 +242,20 @@ function send_command(form, cb) {
append_child(tr, "td", msg[msg.append[k]][i])
}
}
result && ( result.style.height = code.show_result? "": code.show_height)
}
}
if (result && msg) {
if (msg["Content-Type"] && msg["Content-Type"].join("") == "text/html") {
append_child(result, "iframe").innerHTML = (msg.result || []).join("")
} else {
result.innerHTML = (msg.result || []).join("")
}
init_result()
}
typeof(cb) == "function" && cb(msg)
})
}
@ -363,6 +371,8 @@ function onaction(event, action, arg) {
break
case "z":
shrink_command_result()
var target = document.querySelector("div.workflow>ul>li>ul>li[data-action=shrink_cmd]")
target.className = code.show_result? "": "stick"
break
case "r":
location.reload()
@ -568,6 +578,14 @@ function onaction(event, action, arg) {
case "command":
check_option(target.form, target)
break
case "toolkit":
if (event.key == "Enter") {
context.GET("", {"toolkit": dataset["cmd"], "argument": target.value}, function(msg) {
target.nextElementSibling.innerText = msg.result
event
})
}
break
}
}
@ -814,10 +832,13 @@ function init_docker() {
save_clipboard(item)
return
case "create_txt":
copy_to_clipboard(prompt("text"))
var text = prompt("text")
text && copy_to_clipboard(text)
return
case "shrink_cmd":
shrink_command_result()
var target = document.querySelector("div.workflow>ul>li>ul>li[data-action=shrink_cmd]")
target.className = code.show_result? "": "stick"
return
case "create_cmd":
add_command()

View File

@ -297,4 +297,51 @@ function add_sort(append, field, cb) {
}
}
}
function scroll_page(event, page) {
var body = document.querySelector("body")
switch (event.key) {
case "h":
if (event.ctrlKey) {
window.scrollBy(-page.scroll_x*10, 0)
} else {
window.scrollBy(-page.scroll_x, 0)
}
break
case "H":
window.scrollBy(-body.scrollWidth, 0)
break
case "l":
if (event.ctrlKey) {
window.scrollBy(page.scroll_x*10, 0)
} else {
window.scrollBy(page.scroll_x, 0)
}
break
case "L":
window.scrollBy(body.scrollWidth, 0)
break
case "j":
if (event.ctrlKey) {
window.scrollBy(0, page.scroll_y*10)
} else {
window.scrollBy(0, page.scroll_y)
}
break
case "J":
window.scrollBy(0, body.scrollHeight)
break
case "k":
if (event.ctrlKey) {
window.scrollBy(0, -page.scroll_y*10)
} else {
window.scrollBy(0, -page.scroll_y)
}
break
case "K":
window.scrollBy(0, -body.scrollHeight)
break
}
return
}

View File

@ -13,6 +13,12 @@ var wiki = {
height: 40,
},
},
show_result: false,
show_height: "30px",
hide_height: "14px",
scroll_x: 50,
scroll_y: 50,
}
function set_layout() {
@ -30,6 +36,9 @@ function set_layout() {
}
function action(event, cmd) {
var target = event.target
var dataset = target.dataset
switch (cmd) {
case "toggle_nav":
var nav = document.querySelector("nav")
@ -40,6 +49,11 @@ function action(event, cmd) {
var list = event.target.nextElementSibling
list.hidden = !list.hidden
break
case "scroll":
if (target.tagName == "BODY") {
scroll_page(event, wiki)
}
break
}
}
function init_layout() {

View File

@ -45,6 +45,16 @@
div.workflow div.stick, div.workflow li li.stick {
background-color:red;
}
div.workflow li>label.result{
background-color:rgba(0,0,0,0.2);
padding:0 5px;
border:2px solid green;
margin-left: 10px;
}
div.workflow li>input {
background-color:rgba(0,0,0,0.2);
}
form.option div {
float:left;
@ -168,7 +178,11 @@
</li>
<li><div>命令行</div>
<ul class="cmd">
<li data-action="shrink_cmd">+ 折叠命令行(Ctrl+Z)</li>
{{range $name, $cmd := conf . "toolkit"}}
<li>{{$name}} <input type="text" data-cmd="{{$name}}" onkeyup="onaction(event, 'toolkit')"><label class="result"></label></li>
{{end}}
<li class="stick" data-action="shrink_cmd">+ 折叠命令行(Ctrl+Z)</li>
<li data-action="create_cmd">+ 添加命令行(Ctrl+M)</li>
{{if $bench}}
{{range $index, $cmd := index $bench "commands"}}

View File

@ -83,6 +83,7 @@ nav>ul>li>ul>li .mono {
article {
float:right;
max-width:calc(100% - 40px);
}
article h2 {
cursor:alias;
@ -96,6 +97,7 @@ article h4 {
article table {
border-collapse:collapse;
margin-bottom:10px;
}
article table caption {
font-weight:bold;
@ -129,9 +131,9 @@ article pre {
overflow:scroll;
padding:5px;
border:solid 2px green;
border-left:solid 4px green;
max-width:800px;
margin:0;
margin-bottom:10px;
font-size:14px;
line-height:16px;
}
@ -142,6 +144,7 @@ article div.number1 {
text-align:right;
padding:5px 0;
border:solid green 2px;
margin-bottom:10px;
float:left;
}
article div.number1 div {
@ -167,7 +170,7 @@ footer .title {
}
</style>
</head>
<body>
<body onkeydown="action(event, 'scroll')">
{{end}}
{{define "header"}}