1
0
forked from x/icebergs
This commit is contained in:
shaoying 2020-06-19 21:28:30 +08:00
parent 46759d6795
commit b383b945fd
13 changed files with 394 additions and 317 deletions

View File

@ -120,8 +120,8 @@ var Index = &ice.Context{Name: "log", Help: "日志模块",
// 日志文件
if f, p, e := kit.Create(kit.Format(value["path"])); m.Assert(e) {
m.Cap(ice.CTX_STREAM, path.Base(p))
m.Log("create", "%s: %s", key, p)
value["file"] = bufio.NewWriter(f)
m.Log_CREATE(kit.MDB_FILE, p)
}
})
}

View File

@ -4,17 +4,18 @@ import (
"github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/toolkits"
"github.com/shylinux/toolkits/task"
"encoding/csv"
"encoding/json"
"os"
"sort"
"strings"
)
func _list_import(m *ice.Message, prefix, key, file string) {
f, e := os.Open(file)
m.Assert(e)
defer m.Cmdy(web.STORY, web.CATCH, CSV, file)
defer f.Close()
r := csv.NewReader(f)
@ -43,10 +44,10 @@ func _list_import(m *ice.Message, prefix, key, file string) {
m.Log_IMPORT(kit.MDB_KEY, kit.Keys(prefix, key), kit.MDB_COUNT, count)
}
func _list_export(m *ice.Message, prefix, key, file string) {
f, p, e := kit.Create(kit.Keys(file, "csv"))
f, p, e := kit.Create(kit.Keys(file, CSV))
m.Assert(e)
defer m.Cmdy(web.STORY, web.CATCH, CSV, p)
defer f.Close()
defer m.Cmdy(web.STORY, "catch", "csv", p)
w := csv.NewWriter(f)
defer w.Flush()
@ -73,54 +74,101 @@ func _list_export(m *ice.Message, prefix, key, file string) {
})
m.Log_EXPORT(kit.MDB_FILE, p, kit.MDB_COUNT, count)
}
func _list_select(m *ice.Message, prefix, key, limit, offend, field, value string) {
m.Option("cache.limit", limit)
m.Option("cache.offend", offend)
m.Grows(prefix, key, field, value, func(index int, value map[string]interface{}) {
m.Push("", value)
})
}
func _list_search(m *ice.Message, prefix, key, field, value string) {
list := []interface{}{}
files := map[string]bool{}
m.Richs(prefix, key, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
kit.Fetch(kit.Value(value, "meta.record"), func(index int, value map[string]interface{}) {
file := value["file"].(string)
if _, ok := files[file]; ok {
list = append(list, file)
} else {
files[file] = true
}
})
})
defer m.Cost("search")
task.Sync(list, func(task *task.Task, lock *task.Lock) error {
kit.CSV(kit.Format(task.Arg), 100000, func(index int, line map[string]string, head []string) {
if line[field] != value {
return
}
defer lock.WLock()()
m.Push("", line)
})
return nil
})
}
func _hash_search(m *ice.Message, prefix, key, field, value string) {
m.Richs(prefix, key, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
if field != "" && value != val[field] {
return
}
m.Push(key, value)
})
}
func _hash_import(m *ice.Message, prefix, key, file string) {
f, e := os.Open(file)
m.Assert(e)
defer m.Cmdy(web.STORY, web.CATCH, JSON, file)
defer f.Close()
defer m.Log_IMPORT(kit.MDB_FILE, file)
data := map[string]interface{}{}
list := map[string]interface{}{}
de := json.NewDecoder(f)
de.Decode(&data)
de.Decode(&list)
for k, v := range data {
m.Log_MODIFY(kit.MDB_KEY, kit.Keys(prefix, key, kit.MDB_HASH), "k", k, "v", v)
m.Conf(prefix, kit.Keys(key, k), v)
count := 0
for _, data := range list {
// 导入数据
m.Rich(prefix, key, data)
count++
}
m.Log_IMPORT(kit.MDB_KEY, kit.Keys(prefix, key), kit.MDB_COUNT, count)
}
func _hash_export(m *ice.Message, prefix, key, file string) {
f, p, e := kit.Create(kit.Keys(file, "json"))
f, p, e := kit.Create(kit.Keys(file, JSON))
m.Assert(e)
defer m.Cmdy(web.STORY, web.CATCH, JSON, p)
defer f.Close()
defer m.Cmdy(web.STORY, "catch", "json", p)
en := json.NewEncoder(f)
en.SetIndent("", " ")
en.Encode(m.Confv(prefix, kit.Keys(key, kit.MDB_HASH)))
en.Encode(m.Confv(prefix, kit.Keys(key, HASH)))
m.Log_EXPORT(kit.MDB_FILE, p)
}
func _dict_import(m *ice.Message, prefix, key, file string) {
f, e := os.Open(file)
m.Assert(e)
m.Cmdy(web.STORY, web.CATCH, JSON, file)
defer f.Close()
defer m.Log_IMPORT(kit.MDB_FILE, file)
data := map[string]interface{}{}
de := json.NewDecoder(f)
de.Decode(&data)
count := 0
for k, v := range data {
m.Log_MODIFY(kit.MDB_KEY, kit.Keys(prefix, key), "k", k, "v", v)
m.Conf(prefix, kit.Keys(key, k), v)
count++
}
m.Log_EXPORT(kit.MDB_FILE, file, kit.MDB_COUNT, count)
}
func _dict_export(m *ice.Message, prefix, key, file string) {
f, p, e := kit.Create(kit.Keys(file, "json"))
f, p, e := kit.Create(kit.Keys(file, JSON))
m.Assert(e)
defer m.Cmdy(web.STORY, web.CATCH, JSON, p)
defer f.Close()
defer m.Cmdy(web.STORY, "catch", "json", p)
en := json.NewEncoder(f)
en.SetIndent("", " ")
@ -128,72 +176,66 @@ func _dict_export(m *ice.Message, prefix, key, file string) {
m.Log_EXPORT(kit.MDB_FILE, p)
}
const IMPORT = "import"
const EXPORT = "export"
const (
CSV = "csv"
JSON = "json"
)
const (
DICT = "dict"
META = "meta"
HASH = "hash"
LIST = "list"
)
const (
IMPORT = "import"
EXPORT = "export"
SELECT = "select"
SEARCH = "search"
)
var Index = &ice.Context{Name: "mdb", Help: "数据模块",
Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
kit.MDB_IMPORT: {Name: "import conf key type file", Help: "导入数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
IMPORT: {Name: "import conf key type file", Help: "导入数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case kit.MDB_LIST:
case LIST:
_list_import(m, arg[0], arg[1], arg[3])
case kit.MDB_HASH:
case HASH:
_hash_import(m, arg[0], arg[1], arg[3])
case kit.MDB_DICT:
case DICT:
_dict_import(m, arg[0], arg[1], arg[3])
}
}},
kit.MDB_EXPORT: {Name: "export conf key type [name]", Help: "导出数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
EXPORT: {Name: "export conf key type [name]", Help: "导出数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch file := kit.Select(kit.Select(arg[0], arg[0]+":"+arg[1], arg[1] != ""), arg, 3); arg[2] {
case kit.MDB_LIST:
case LIST:
_list_export(m, arg[0], arg[1], file)
case kit.MDB_HASH:
case HASH:
_hash_export(m, arg[0], arg[1], file)
case kit.MDB_DICT:
case DICT:
_dict_export(m, arg[0], arg[1], file)
}
}},
"update": {Name: "update config table index key value", Help: "修改数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
meta := m.Confm(arg[0], arg[1]+".meta")
index := kit.Int(arg[2]) - kit.Int(meta["offset"]) - 1
data := m.Confm(arg[0], arg[1]+".list."+kit.Format(index))
for i := 3; i < len(arg)-1; i += 2 {
kit.Value(data, arg[i], arg[i+1])
}
}},
"select": {Name: "select config table index offend limit match value", Help: "修改数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 3 {
meta := m.Confm(arg[0], arg[1]+".meta")
index := kit.Int(arg[2]) - kit.Int(meta["offset"]) - 1
data := m.Confm(arg[0], arg[1]+".list."+kit.Format(index))
m.Push(arg[2], data)
} else {
m.Option("cache.offend", kit.Select("0", arg, 3))
m.Option("cache.limit", kit.Select("10", arg, 4))
fields := strings.Split(arg[7], " ")
m.Grows(arg[0], arg[1], kit.Select("", arg, 5), kit.Select("", arg, 6), func(index int, value map[string]interface{}) {
m.Push("id", value, fields)
})
}
}},
ice.MDB_DELETE: {Name: "delete conf key type", Help: "删除", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
SELECT: {Name: "select conf key type [limit [offend [key value]]]", Help: "数据查询", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case kit.MDB_DICT:
m.Log(ice.LOG_DELETE, "%s: %s", arg[1], m.Conf(arg[0], arg[1]))
m.Echo("%s", m.Conf(arg[0], arg[1]))
m.Conf(arg[0], arg[1], "")
case kit.MDB_META:
case kit.MDB_LIST:
case kit.MDB_HASH:
case LIST:
_list_select(m, arg[0], arg[1], kit.Select("10", arg, 3), kit.Select("0", arg, 4), kit.Select("", arg, 5), kit.Select("", arg, 6))
}
}},
SEARCH: {Name: "search conf key type key value", Help: "数据查询", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] {
case LIST:
_list_search(m, arg[0], arg[1], arg[3], arg[4])
case HASH:
_hash_search(m, arg[0], arg[1], arg[3], arg[4])
}
}},
},
}
func init() { ice.Index.Register(Index, nil, IMPORT, EXPORT) }
func init() {
ice.Index.Register(Index, nil, IMPORT, EXPORT, SELECT, SEARCH)
}

View File

@ -2,6 +2,8 @@ package nfs
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"bufio"
@ -19,7 +21,6 @@ import (
const (
FILE = "file"
TRASH = "trash"
)
func _file_list(m *ice.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string) {
@ -141,12 +142,12 @@ func _file_list(m *ice.Message, root string, name string, level int, deep bool,
}
}
func _file_show(m *ice.Message, name string) {
if f, e := os.OpenFile(name, os.O_RDONLY, 0777); m.Assert(e) {
if f, e := os.OpenFile(name, os.O_RDONLY, 0640); m.Assert(e) {
defer f.Close()
if s, e := f.Stat(); m.Assert(e) {
buf := make([]byte, s.Size())
if n, e := f.Read(buf); m.Assert(e) {
m.Log_IMPORT("file", name, "size", n)
m.Log_IMPORT(kit.MDB_FILE, name, kit.MDB_SIZE, n)
m.Echo(string(buf[:n]))
}
}
@ -157,7 +158,7 @@ func _file_save(m *ice.Message, name string, text ...string) {
defer f.Close()
for _, v := range text {
if n, e := f.WriteString(v); m.Assert(e) {
m.Log_EXPORT("file", p, "size", n)
m.Log_IMPORT(kit.MDB_FILE, p, kit.MDB_SIZE, n)
}
}
m.Echo(p)
@ -170,7 +171,7 @@ func _file_copy(m *ice.Message, name string, from ...string) {
if s, e := os.Open(v); !m.Warn(e != nil, "%s", e) {
defer s.Close()
if n, e := io.Copy(f, s); !m.Warn(e != nil, "%s", e) {
m.Log_IMPORT("file", p, "size", n)
m.Log_IMPORT(kit.MDB_FILE, p, kit.MDB_SIZE, n)
}
}
}
@ -178,14 +179,14 @@ func _file_copy(m *ice.Message, name string, from ...string) {
}
func _file_link(m *ice.Message, name string, from string) {
m.Cmd("nfs.trash", name)
os.MkdirAll(path.Dir(name), 0777)
os.MkdirAll(path.Dir(name), 0760)
os.Link(from, name)
}
func _file_trash(m *ice.Message, name string, from ...string) {
if s, e := os.Stat(name); e == nil {
if s.IsDir() {
name := path.Base(name) + ".tar.gz"
m.Cmd(ice.CLI_SYSTEM, "tar", "zcf", name, name)
m.Cmd(cli.SYSTEM, "tar", "zcf", name, name)
}
if f, e := os.Open(name); m.Assert(e) {
@ -196,36 +197,41 @@ func _file_trash(m *ice.Message, name string, from ...string) {
os.MkdirAll(path.Dir(p), 0777)
os.Rename(name, p)
m.Cmd(ice.WEB_FAVOR, "trash", "bin", name, p)
m.Cmd(web.FAVOR, "trash", "bin", name, p)
}
}
}
func FileSave(m *ice.Message, file string, text ...string) {
_file_save(m, file, text...)
}
const (
DIR = "dir"
CAT = "cat"
SAVE = "save"
COPY = "copy"
LINK = "link"
TRASH = "trash"
)
var Index = &ice.Context{Name: "nfs", Help: "存储模块",
Configs: map[string]*ice.Config{
TRASH: {Name: "trash", Help: "删除", Value: kit.Data("path", "var/trash")},
},
Commands: map[string]*ice.Command{
"dir": {Name: "dir path field...", Help: "目录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
DIR: {Name: "dir path field...", Help: "目录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
rg, _ := regexp.Compile(m.Option("dir_reg"))
_file_list(m, kit.Select("./", m.Option("dir_root")), kit.Select("", arg, 0),
0, m.Options("dir_deep"), kit.Select("both", m.Option("dir_type")), rg,
strings.Split(kit.Select("time size line path", strings.Join(arg[1:], " ")), " "))
}},
"cat": {Name: "cat file", Help: "查看", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
CAT: {Name: "cat file", Help: "查看", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_file_show(m, arg[0])
}},
"save": {Name: "save file text...", Help: "保存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
SAVE: {Name: "save file text...", Help: "保存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_file_save(m, arg[0], arg[1:]...)
}},
"copy": {Name: "copy file from...", Help: "复制", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
COPY: {Name: "copy file from...", Help: "复制", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_file_copy(m, arg[0], arg[1:]...)
}},
"link": {Name: "link file from", Help: "链接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
LINK: {Name: "link file from", Help: "链接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_file_link(m, arg[0], arg[1])
}},

View File

@ -3,6 +3,8 @@ package ssh
import (
"github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/toolkits"
"bufio"
@ -17,15 +19,20 @@ import (
)
type Frame struct {
in io.ReadCloser
out io.Writer
source string
target *ice.Context
stdout io.Writer
count int
ps1 []string
ps2 []string
exit bool
}
func Render(msg *ice.Message, cmd string, args ...interface{}) {
msg.Log(ice.LOG_EXPORT, "%s: %v", cmd, args)
defer func() { msg.Log_EXPORT(kit.MDB_RENDER, cmd, kit.MDB_TEXT, args) }()
switch arg := kit.Simple(args...); cmd {
case ice.RENDER_OUTPUT:
@ -49,6 +56,7 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
if res == "" {
res = msg.Table().Result()
}
args = append(args, "length:", len(res))
// 输出结果
if fmt.Fprintf(msg.O, res); !strings.HasSuffix(res, "\n") {
@ -58,40 +66,92 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
msg.Append(ice.MSG_OUTPUT, ice.RENDER_OUTPUT)
}
func (f *Frame) prompt(m *ice.Message) *Frame {
if f.out == os.Stdout {
fmt.Fprintf(f.out, "\r")
for _, v := range kit.Simple(m.Optionv(ice.MSG_PROMPT)) {
switch v {
case "count":
fmt.Fprintf(f.out, "%d", kit.Int(m.Conf("history", "meta.count"))+1)
case "time":
fmt.Fprintf(f.out, time.Now().Format("15:04:05"))
case "target":
fmt.Fprintf(f.out, f.target.Name)
default:
fmt.Fprintf(f.out, v)
func (f *Frame) history(m *ice.Message, line string) string {
favor := m.Conf(SOURCE, kit.Keys(kit.MDB_META, web.FAVOR))
if strings.HasPrefix(strings.TrimSpace(line), "!!") {
if len(line) == 2 {
line = m.Cmd(web.FAVOR, favor).Append(kit.MDB_TEXT)
}
} else if strings.HasPrefix(strings.TrimSpace(line), "!") {
if len(line) == 1 {
// 历史记录
msg := m.Cmd(web.FAVOR, favor)
msg.Sort(kit.MDB_ID)
msg.Appendv(ice.MSG_APPEND, kit.MDB_TIME, kit.MDB_ID, kit.MDB_TEXT)
f.printf(m, msg.Table().Result())
return ""
}
if i, e := strconv.Atoi(line[1:]); e == nil {
// 历史命令
line = kit.Format(kit.Value(m.Cmd(web.FAVOR, favor, i).Optionv("value"), kit.MDB_TEXT))
} else {
f.printf(m, m.Cmd("history", "search", line[1:]).Table().Result())
return ""
}
return f
} else if strings.TrimSpace(line) != "" && f.source == STDIO {
// 记录历史
m.Cmd(web.FAVOR, favor, "cmd", f.source, line)
}
return line
}
func (f *Frame) printf(m *ice.Message, res string, arg ...interface{}) *Frame {
if len(arg) > 0 {
fmt.Fprintf(f.out, res, arg...)
fmt.Fprintf(f.stdout, res, arg...)
} else {
fmt.Fprint(f.out, res)
fmt.Fprint(f.stdout, res)
}
// if !strings.HasSuffix(res, "\n") {
// fmt.Fprint(f.out, "\n")
// }
return f
}
func (f *Frame) parse(m *ice.Message, line string) *Frame {
for _, one := range kit.Split(line, ";", ";", ";") {
ls := kit.Split(one)
m.Log(ice.LOG_IMPORT, "stdin: %d %v", len(ls), ls)
func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
if f.stdout != os.Stdout {
return f
}
if len(list) == 0 {
list = append(list, f.ps1...)
}
fmt.Fprintf(f.stdout, "\r")
for _, v := range list {
switch v {
case "count":
fmt.Fprintf(f.stdout, "%d", kit.Int(m.Conf("history", "meta.count"))+1)
case "time":
fmt.Fprintf(f.stdout, time.Now().Format("15:04:05"))
case "target":
fmt.Fprintf(f.stdout, f.target.Name)
default:
fmt.Fprintf(f.stdout, v)
}
}
return f
}
func (f *Frame) option(m *ice.Message, ls []string) []string {
// 解析选项
ln := []string{}
m.Option("cache.limit", 10)
for i := 0; i < len(ls); i++ {
if ls[i] == "--" {
ln = append(ln, ls[i+1:]...)
break
} else if strings.HasPrefix(ls[i], "-") {
for j := i; j < len(ls); j++ {
if j == len(ls)-1 || strings.HasPrefix(ls[j+1], "-") {
if i == j {
m.Option(ls[i][1:], "true")
} else {
m.Option(ls[i][1:], ls[i+1:j+1])
}
i = j
break
}
}
} else {
ln = append(ln, ls[i])
}
}
return ln
}
func (f *Frame) change(m *ice.Message, ls []string) []string {
if len(ls) == 1 && ls[0] == "~" {
// 模块列表
ls = []string{"context"}
@ -109,9 +169,22 @@ func (f *Frame) parse(m *ice.Message, line string) *Frame {
f.target = s
})
}
if len(ls) == 0 {
continue
return ls
}
func (f *Frame) alias(m *ice.Message, ls []string) []string {
// 命令替换
if alias, ok := m.Optionv(ice.MSG_ALIAS).(map[string]interface{}); ok {
if a := kit.Simple(alias[ls[0]]); len(a) > 0 {
ls = append(append([]string{}, a...), ls[1:]...)
}
}
return ls
}
func (f *Frame) parse(m *ice.Message, line string) string {
for _, one := range kit.Split(line, ";", ";", ";") {
m.Log_IMPORT("stdin", one, "length", len(one))
ls := kit.Split(one)
if m.Option("scan_mode") == "scan" {
f.printf(m, ls[0])
f.printf(m, "`")
@ -121,104 +194,47 @@ func (f *Frame) parse(m *ice.Message, line string) *Frame {
continue
}
// 命令替换
if alias, ok := m.Optionv(ice.MSG_ALIAS).(map[string]interface{}); ok {
if a := kit.Simple(alias[ls[0]]); len(a) > 0 {
ls = append(append([]string{}, a...), ls[1:]...)
}
}
// 解析选项
ln := []string{}
// 解析引擎
msg := m.Spawns(f.target)
msg.Option("cache.limit", 10)
for i := 0; i < len(ls); i++ {
if ls[i] == "--" {
ln = append(ln, ls[i+1:]...)
break
} else if strings.HasPrefix(ls[i], "-") {
for j := i; j < len(ls); j++ {
if j == len(ls)-1 || strings.HasPrefix(ls[j+1], "-") {
if i == j {
msg.Option(ls[i][1:], "true")
} else {
msg.Option(ls[i][1:], ls[i+1:j+1])
}
i = j
break
}
}
} else {
ln = append(ln, ls[i])
}
}
if ln[0] == "qrcode" {
msg.Option(ice.MSG_OUTPUT, ice.RENDER_QRCODE)
ln = ln[1:]
}
msg.Option("_cmd", one)
ls = f.alias(msg, ls)
ls = f.change(msg, ls)
ls = f.option(msg, ls)
if len(ls) == 0 {
continue
}
// 执行命令
msg.Cmdy(ln[0], ln[1:])
msg.Cmdy(ls[0], ls[1:])
// 渲染引擎
_args, _ := msg.Optionv(ice.MSG_ARGS).([]interface{})
Render(msg, msg.Option(ice.MSG_OUTPUT), _args...)
}
return ""
}
func (f *Frame) scan(m *ice.Message, file, line string, r io.Reader) *Frame {
f.ps1 = kit.Simple(m.Confv("prompt", "meta.PS1"))
f.ps2 = kit.Simple(m.Confv("prompt", "meta.PS2"))
ps := f.ps1
}
return f
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}
}
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
return f
}
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS1"))
f.target = m.Source()
aaa.UserRoot(m)
switch kit.Select("stdio", arg, 0) {
case "stdio":
// 解析终端
f.in, f.out = os.Stdin, os.Stdout
m.Cap(ice.CTX_STREAM, "stdio")
f.target = m.Target()
default:
if s, e := os.Open(arg[0]); m.Warn(e != nil, "%s", e) {
// 打开失败
return true
} else {
// 解析脚本
defer s.Close()
if f.in, f.out = s, os.Stdout; m.Optionv(ice.MSG_STDOUT) != nil {
f.out = m.Optionv(ice.MSG_STDOUT).(io.Writer)
}
m.Cap(ice.CTX_STREAM, arg[0])
}
}
m.I, m.O = f.in, f.out
line := ""
bio := bufio.NewScanner(f.in)
for f.prompt(m); bio.Scan() && !f.exit; f.prompt(m) {
m.I, m.O = r, f.stdout
bio := bufio.NewScanner(r)
for f.prompt(m, ps...); bio.Scan() && !f.exit; f.prompt(m, ps...) {
if len(bio.Text()) == 0 {
// 空行
continue
}
if strings.HasSuffix(bio.Text(), "\\") {
// 续行
m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS2"))
line += bio.Text()[:len(bio.Text())-1]
ps = f.ps2
continue
}
if line += bio.Text(); strings.Count(line, "`")%2 == 1 {
// 多行
m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS2"))
line += "\n"
ps = f.ps2
continue
}
if strings.HasPrefix(strings.TrimSpace(line), "#") {
@ -226,127 +242,127 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
line = ""
continue
}
if strings.HasPrefix(strings.TrimSpace(line), "!") {
if len(line) == 1 {
// 历史记录
f.printf(m, m.Cmd("history").Table().Result())
line = ""
continue
}
if i, e := strconv.Atoi(line[1:]); e == nil {
if line = f.history(m, line); line == "" {
// 历史命令
m.Grows("history", nil, "id", kit.Format(i), func(index int, value map[string]interface{}) {
line = kit.Format(value["line"])
})
} else {
f.printf(m, m.Cmd("history", "search", line[1:]).Table().Result())
line = ""
continue
}
} else {
// 记录历史
m.Grow("history", nil, kit.Dict("line", line))
}
if ps = f.ps1; f.stdout == os.Stdout {
// 清空格式
if m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS1")); f.out == os.Stdout {
f.printf(m, "\033[0m")
}
if m.Cap(ice.CTX_STREAM) == "stdio" {
m.Cmd(ice.WEB_FAVOR, "cmd.history", "cmd", kit.Select("stdio", arg, 0), line)
line = f.parse(m, line)
}
return f
}
// 解析命令
f.parse(m, line)
m.Cost("stdin: %v", line)
line = ""
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
return f
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}
}
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
var r io.Reader
switch kit.Select(STDIO, arg, 0) {
case STDIO:
// 终端交互
f.source = STDIO
r, f.stdout = os.Stdin, os.Stdout
m.Cap(ice.CTX_STREAM, STDIO)
f.target = m.Target()
aaa.UserRoot(m)
default:
if s, e := os.Open(arg[0]); !m.Warn(e != nil, "%s", e) {
defer s.Close()
buf := bytes.NewBuffer(make([]byte, 0, 4096))
defer m.Echo(buf.String())
// 脚本解析
f.source = arg[0]
r, f.stdout = s, buf
m.Cap(ice.CTX_STREAM, arg[0])
f.target = m.Source()
break
}
return true
}
f.scan(m, kit.Select(STDIO, arg, 0), "", r)
return true
}
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
return true
}
const (
SOURCE = "source"
TARGET = "target"
PROMPT = "prompt"
QRCODE = "qrcode"
RETURN = "return"
REMOTE = "remote"
)
const (
STDIO = "stdio"
)
var Index = &ice.Context{Name: "ssh", Help: "终端模块",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
"history": {Name: "history", Help: "history", Value: kit.Data("limit", "200", "least", "100")},
"prompt": {Name: "prompt", Help: "prompt", Value: kit.Data(
SOURCE: {Name: "prompt", Help: "命令提示", Value: kit.Data(
web.FAVOR, "cmd.history",
)},
PROMPT: {Name: "prompt", Help: "命令提示", Value: kit.Data(
"PS1", []interface{}{"\033[33;44m", "count", "[", "time", "]", "\033[5m", "target", "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"},
"PS2", []interface{}{"count", " ", "target", "> "},
)},
"super": {Name: "super", Help: "super", Value: kit.Data()},
REMOTE: {Name: "remote", Help: "远程连接", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
}},
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save("history")
if f, ok := m.Target().Server().(*Frame); ok {
// 关闭终端
f.in.Close()
if _, ok := m.Target().Server().(*Frame); ok {
m.Done()
}
}},
"history": {Name: "history", Help: "历史", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Grows("history", nil, "", "", func(index int, value map[string]interface{}) {
m.Push("", value, []string{"id", "time", "line"})
})
return
}
switch arg[0] {
case "search":
m.Grows("history", nil, "", "", func(index int, value map[string]interface{}) {
if strings.Contains(kit.Format(value["line"]), arg[1]) {
m.Push("", value, []string{"id", "time", "line"})
}
})
default:
m.Grows("history", nil, "id", arg[0], func(index int, value map[string]interface{}) {
m.Push("", value, []string{"id", "time", "line"})
})
}
SOURCE: {Name: "source file", Help: "脚本解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Starts(strings.Replace(arg[0], ".", "_", -1), arg[0], arg[0:]...)
}},
"return": {Name: "return", Help: "解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS1"))
TARGET: {Name: "target name", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Search(arg[0], func(p *ice.Context, s *ice.Context, key string) {
f := m.Target().Server().(*Frame)
f.target = s
f.prompt(m)
})
}},
PROMPT: {Name: "prompt arg...", Help: "命令提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)
f.ps1 = arg
f.prompt(m)
}},
QRCODE: {Name: "qrcode arg...", Help: "命令提示", Action: map[string]*ice.Action{
"json": {Name: "json [key val]...", Help: "json", Hand: func(m *ice.Message, arg ...string) {
val := map[string]interface{}{}
for i := 0; i < len(arg)-1; i += 2 {
kit.Value(val, arg[i], arg[i+1])
}
f := m.Target().Server().(*Frame)
f.printf(m, m.Cmdx(cli.PYTHON, "qrcode", kit.Format(val)))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)
f.printf(m, m.Cmdx(cli.PYTHON, "qrcode", strings.Join(arg, "")))
}},
RETURN: {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)
f.exit = true
}},
"target": {Name: "target", Help: "目标", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)
m.Search(arg[0], func(p *ice.Context, s *ice.Context, key string) {
f.target = s
})
f.prompt(m)
}},
"source": {Name: "source file", Help: "解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
buf := bytes.NewBuffer(make([]byte, 0, 4096))
m.Optionv(ice.MSG_STDOUT, buf)
m.Starts(strings.Replace(arg[0], ".", "_", -1), arg[0], arg[0:]...)
m.Echo(buf.String())
}},
"show": {Name: "show", Help: "解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f, e := os.Open("usr/local/what/hi.shy")
m.Assert(e)
bio := bufio.NewScanner(f)
for bio.Scan() {
ls := kit.Split(bio.Text())
m.Echo("%d: %v\n", len(ls), ls)
m.Info("%v", ls)
}
}},
"super": {Name: "super user remote port local", Help: "上位机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
key := m.Rich("super", nil, kit.Dict(
REMOTE: {Name: "remote user remote port local", Help: "远程连接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
key := m.Rich(REMOTE, nil, kit.Dict(
"user", arg[0], "remote", arg[1], "port", arg[2], "local", arg[3],
))
m.Echo(key)
@ -354,17 +370,13 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块",
m.Gos(m, func(m *ice.Message) {
for {
m.Cmd(ice.CLI_SYSTEM, "ssh", "-CNR", kit.Format("%s:%s:22", arg[2], arg[3]), kit.Format("%s@%s", arg[0], arg[1]))
m.Cmd(cli.SYSTEM, "ssh", "-CNR", kit.Format("%s:%s:22", arg[2], kit.Select("localhost", arg, 3)),
kit.Format("%s@%s", arg[0], arg[1]))
m.Info("reconnect after 10s")
time.Sleep(time.Second * 10)
}
})
}},
"what": {Name: "what", Help: "上位机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
ls := kit.Split("window:=auto", " ", ":=")
m.Echo("%v %v", len(ls), ls)
}},
},
}

View File

@ -384,6 +384,9 @@ func StoryAdd(m *ice.Message, mime string, name string, text string, arg ...stri
}
const STORY = "story"
const (
CATCH = "catch"
)
func init() {
Index.Merge(&ice.Context{

View File

@ -2,7 +2,6 @@ package wiki
import (
"github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/toolkits"
"path"
@ -36,7 +35,7 @@ func init() {
"display", "/plugin/local/wiki/draw.js",
), Action: map[string]*ice.Action{
"save": {Name: "save path text", Help: "保存", Hand: func(m *ice.Message, arg ...string) {
nfs.FileSave(m, path.Join(m.Conf(DRAW, "meta.path"), kit.Select("hi.svg", arg, 0)), kit.Select(m.Option("content"), arg, 1))
m.Cmd("nfs.save", path.Join(m.Conf(DRAW, "meta.path"), kit.Select("hi.svg", arg, 0)), kit.Select(m.Option("content"), arg, 1))
}},
"run": {Name: "show path text", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
_draw_show(m, arg[0], arg[1], arg[2], arg[3], arg[4:]...)

View File

@ -342,7 +342,7 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin
order := 0
if begin < current {
// 读取文件
m.Log(LOG_INFO, "%s.%v read %v-%v from %v-%v", key, chain, begin, end, current, current+len(list))
// m.Log(LOG_INFO, "%s.%v read %v-%v from %v-%v", key, chain, begin, end, current, current+len(list))
store, _ := meta["record"].([]interface{})
for s := len(store) - 1; s > -1; s-- {
item, _ := store[s].(map[string]interface{})

View File

@ -9,6 +9,7 @@ import (
"time"
kit "github.com/shylinux/toolkits"
"github.com/shylinux/toolkits/task"
)
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
@ -112,6 +113,10 @@ func (m *Message) Back(res *Message) *Message {
return m
}
func (m *Message) Gos(msg *Message, cb func(*Message)) *Message {
go func() { msg.TryCatch(msg, true, func(msg *Message) { cb(msg) }) }()
task.Put(nil, func(task *task.Task) error {
msg.Optionv("_task", task)
msg.TryCatch(msg, true, func(msg *Message) { cb(msg) })
return nil
})
return m
}

View File

View File

@ -52,6 +52,11 @@ func (m *Message) Set(key string, arg ...string) *Message {
}
func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Message {
switch value := value.(type) {
case map[string]string:
for k, v := range value {
m.Push(k, v)
}
return m
case map[string]interface{}:
if key == "detail" {
// 格式转换
@ -452,6 +457,10 @@ func (m *Message) Append(key string, arg ...interface{}) string {
return kit.Select("", m.Appendv(key, arg...), 0)
}
func (m *Message) Appendv(key string, arg ...interface{}) []string {
if key == MSG_APPEND {
m.meta[MSG_APPEND] = kit.Simple(arg)
return m.meta[key]
}
if key == "_index" {
max := 0
for _, k := range m.meta[MSG_APPEND] {

View File

@ -47,7 +47,7 @@ func _alpha_find2(m *ice.Message, method, word string) {
}
var mu sync.Mutex
task.Sync(args, func(task *task.Task) error {
task.Sync(args, func(task *task.Task, lock *task.Lock) error {
info := task.Arg.(os.FileInfo)
file := path.Join(p, info.Name())
kit.CSV(file, 100000, func(index int, value map[string]string, head []string) {

View File

@ -90,7 +90,7 @@ func _input_find2(m *ice.Message, method, word, limit string) {
defer m.Cost("some")
var mu sync.Mutex
task.Sync(list, func(task *task.Task) error {
task.Sync(list, func(task *task.Task, lock *task.Lock) error {
kit.CSV(kit.Format(task.Arg), 100000, func(index int, value map[string]string, head []string) {
if value["code"] != word {
return
@ -181,7 +181,7 @@ var Index = &ice.Context{Name: "input", Help: "输入法",
Configs: map[string]*ice.Config{
INPUT: {Name: "input", Help: "输入法", Value: kit.Data(
"repos", "wubi-dict", "local", "person",
kit.MDB_STORE, "var/data/input", kit.MDB_FSIZE, "200000",
kit.MDB_STORE, "usr/export/input", kit.MDB_FSIZE, "200000",
kit.MDB_LIMIT, "5000", kit.MDB_LEAST, "1000",
kit.MDB_SHORT, "zone",
)},

19
type.go
View File

@ -78,6 +78,9 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
return c.Caches[key].Value
}
func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message {
if cmd == nil {
return m
}
m.meta[MSG_DETAIL] = kit.Simple(key, arg)
m.Hand = true
@ -100,7 +103,7 @@ func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Mess
}
}
}
if len(arg) > 0 {
if len(arg) > 0 && cmd.Action != nil {
if h, ok := cmd.Action[arg[0]]; ok {
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg, kit.FileLine(h.Hand, 3))
h.Hand(m, arg[1:]...)
@ -499,7 +502,9 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
// 查找模块
p := m.target.root
if strings.Contains(key, ":") {
if ctx, ok := names[key].(*Context); ok {
p = ctx
} else if strings.Contains(key, ":") {
} else if key == "." {
if m.target.context != nil {
@ -597,14 +602,10 @@ func (m *Message) Cmd(arg ...interface{}) *Message {
return m
}
if ctx, ok := names[list[0]].(*Context); ok {
m.Hand = true
return ctx.Run(m.Spawns(ctx), ctx.Commands[list[0]], list[0], list[1:]...)
}
m.Search(list[0], func(p *Context, c *Context, key string, cmd *Command) {
m = p.Run(m.Spawns(c), cmd, key, list[1:]...)
m.Hand = true
m.TryCatch(m.Spawns(c), true, func(msg *Message) {
m = p.Run(msg, cmd, key, list[1:]...)
})
})
if m.Warn(m.Hand == false, "not found %v", list) {