1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-26 01:04:06 +08:00
This commit is contained in:
shaoying 2019-01-08 15:17:02 +08:00
parent b965e0c78a
commit 5c3a4d5eb4
8 changed files with 332 additions and 221 deletions

View File

@ -77,7 +77,11 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
m.Target().Close(m)
}
m.Optionv("ps_target", cmd.Optionv("ps_target"))
v := cmd.Optionv("ps_target")
if v != nil {
m.Optionv("ps_target", v)
}
m.Set("append").Copy(cmd, "append")
m.Set("result").Copy(cmd, "result")
return nil
@ -203,7 +207,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if e := cmd.Run(); e != nil {
m.Echo("error: ").Echo("%s\n", e).Echo(err.String())
m.Log("trace", "%s\n", e)
} else {
switch m.Option("cmd_parse") {
case "json":
@ -312,8 +315,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
detail = append(detail, arg...)
// 目标切换
target := m.Optionv("ps_target")
if detail[0] != "context" {
target := m.Optionv("ps_target")
defer func() { m.Optionv("ps_target", target) }()
}
@ -401,6 +404,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if msg.Set("detail", args).Cmd(); !msg.Hand {
msg.Cmd("system", args)
}
if msg.Appends("ps_target1") {
target = msg.Target()
}
// 管道命令
if len(rest) > 0 {

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"fmt"
"html/template"
"io/ioutil"
"regexp"
"runtime"
"strconv"
"strings"
@ -13,7 +13,6 @@ import (
"io"
"math/rand"
"os"
"runtime/debug"
"sort"
"time"
"toolkit"
@ -171,7 +170,7 @@ func (c *Context) Close(m *Message, arg ...string) bool {
return true
}
m.Log("close", "%d:%d %v", len(c.requests), len(c.sessions), arg)
m.Log("close", "before %d:%d %v", len(c.requests), len(c.sessions), arg)
if m.target == c {
for i := len(c.requests) - 1; i >= 0; i-- {
if msg := c.requests[i]; msg.code == m.code {
@ -185,7 +184,7 @@ func (c *Context) Close(m *Message, arg ...string) bool {
}
}
m.Log("close", "%d:%d %v", len(c.requests), len(c.sessions), arg)
m.Log("close", "after %d:%d %v", len(c.requests), len(c.sessions), arg)
if len(c.requests) > 0 {
return false
}
@ -307,17 +306,21 @@ func (m *Message) Log(action string, str string, arg ...interface{}) *Message {
if l := m.Sess("log", false); l != nil {
if log, ok := l.target.Server.(LOGGER); ok {
if action == "error" {
log.Log(m, "error", "chain: %s", m.Format("chain"))
}
log.Log(m, action, str, arg...)
if action == "error" {
log.Log(m, "error", "%s", m.Format("full"))
log.Log(m, "error", "%s\n\n", string(debug.Stack()))
log.Log(m, "error", "stack: %s", m.Format("stack"))
}
return m
}
}
if action == "error" {
kit.Log("error", fmt.Sprintf("chain: %s", m.Format("chain")))
kit.Log("error", fmt.Sprintf("%s %s %s", m.Format(), action, fmt.Sprintf(str, arg...)))
kit.Log("error", fmt.Sprintf("stack: %s", m.Format("stack")))
}
return m
@ -406,25 +409,56 @@ func (m *Message) Format(arg ...string) string {
case "result":
meta = append(meta, fmt.Sprintf("%v", m.Meta["result"]))
case "full":
meta = append(meta, fmt.Sprintf("%s\n", m.Format("time", "ship")))
meta = append(meta, fmt.Sprintf("detail: %d %v\n", len(m.Meta["detail"]), m.Meta["detail"]))
meta = append(meta, fmt.Sprintf("option: %d %v\n", len(m.Meta["option"]), m.Meta["option"]))
for _, k := range m.Meta["option"] {
if v, ok := m.Data[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
} else if v, ok := m.Meta[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
case "chain":
ms := []*Message{}
if v == "full" {
ms = append(ms, m)
} else {
for msg := m; msg != nil; msg = msg.message {
ms = append(ms, msg)
}
}
meta = append(meta, fmt.Sprintf("append: %d %v\n", len(m.Meta["append"]), m.Meta["append"]))
for _, k := range m.Meta["append"] {
if v, ok := m.Data[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
} else if v, ok := m.Meta[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
for i := len(ms) - 1; i >= 0; i-- {
msg := ms[i]
meta = append(meta, fmt.Sprintf("\n%s\n", msg.Format("time", "ship")))
meta = append(meta, fmt.Sprintf(" detail: %d %v\n", len(msg.Meta["detail"]), msg.Meta["detail"]))
meta = append(meta, fmt.Sprintf(" option: %d %v\n", len(msg.Meta["option"]), msg.Meta["option"]))
for _, k := range msg.Meta["option"] {
if v, ok := msg.Data[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
} else if v, ok := msg.Meta[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
}
}
meta = append(meta, fmt.Sprintf(" append: %d %v\n", len(msg.Meta["append"]), msg.Meta["append"]))
for _, k := range msg.Meta["append"] {
if v, ok := msg.Data[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
} else if v, ok := msg.Meta[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
}
}
meta = append(meta, fmt.Sprintf(" result: %d %v\n", len(msg.Meta["result"]), msg.Meta["result"]))
}
case "stack":
pc := make([]uintptr, 100)
pc = pc[:runtime.Callers(2, pc)]
frames := runtime.CallersFrames(pc)
for {
frame, more := frames.Next()
file := strings.Split(frame.File, "/")
name := strings.Split(frame.Function, "/")
meta = append(meta, fmt.Sprintf("\n%s:%d\t%s", file[len(file)-1], frame.Line, name[len(name)-1]))
if !more {
break
}
}
meta = append(meta, fmt.Sprintf("result: %d %v\n", len(m.Meta["result"]), m.Meta["result"]))
default:
meta = append(meta, kit.FileName(v, "time"))
}
}
return strings.Join(meta, " ")
@ -1140,9 +1174,11 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message))
case io.EOF:
case nil:
default:
m.Log("stack", "m: %s", m.Format("full"))
m.Log("stack", "msg: %s", msg.Format("full"))
m.Log("stack", "%s\n%s\n", e, string(debug.Stack()))
m.Log("bench", "chain: %s", msg.Format("chain"))
m.Log("bench", "catch: %s", e)
m.Log("bench", "stack: %s", msg.Format("stack"))
m.Log("error", "catch: %s", e)
if len(hand) > 1 {
m.TryCatch(msg, safe, hand[1:]...)
@ -1619,6 +1655,19 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
}
}
if len(arg) > 0 {
switch arg[0] {
case "full":
m.Echo(m.Format("full"))
return
case "back":
m.Echo(m.Format("back"))
return
case "stack":
m.Echo(m.Format("stack"))
return
}
}
if len(arg) > 0 && arg[0] == "spawn" {
sub := msg.Spawn()
m.Echo("%d", sub.code)
@ -1986,7 +2035,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
msg.target.Start(msg, arg...)
m.Copy(msg, "append").Copy(msg, "result").Copy(msg, "target")
case "close":
msg.target.Close(msg, arg...)
msg := m.Spawn()
m.target = msg.target.context
msg.target.Close(msg.target.message, arg...)
}
}
@ -3227,8 +3278,6 @@ func Start(args ...string) bool {
args = append(args, os.Args[1:]...)
}
ioutil.WriteFile(fmt.Sprintf("bench.pid"), []byte(kit.Format(os.Getpid())), 0666)
Index.Begin(Pulse, args...)
Index.Start(Pulse, args...)
Index.Close(Pulse, args...)

View File

@ -4,8 +4,6 @@ import (
"contexts/ctx"
"toolkit"
"fmt"
"io/ioutil"
"os"
"os/signal"
"syscall"
@ -84,10 +82,7 @@ func (gdb *GDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
func (gdb *GDB) Start(m *ctx.Message, arg ...string) bool {
gdb.goon = make(chan os.Signal, 10)
gdb.wait = make(chan interface{}, 10)
m.Log("error", "pid %d", os.Getpid())
kit.Log("error", "pid %d", os.Getpid())
signal.Notify(gdb.goon, syscall.Signal(19))
ioutil.WriteFile(fmt.Sprintf("%s.pid", gdb.Name), []byte(kit.Format(os.Getpid())), 0666)
for {
select {
case sig := <-gdb.goon:

View File

@ -0,0 +1,28 @@
package gdb
import (
"contexts/ctx"
"testing"
"time"
)
func TestLog(t *testing.T) {
m := ctx.Pulse.Spawn(Index)
m.Sess("gdb", m)
m.Target().Begin(m).Start(m)
go func() {
t.Logf("%s", m.Cmd("wait", "config", "demo").Result(0))
// t.Logf("%s", m.Cmd("demo", "what").Result(0))
}()
time.Sleep(time.Second * 3)
m.Spawn().Cmd("goon", "nice")
// gdb := m.Target().Server.(*GDB)
// gdb.Goon("yes", "command", "demo")
//
time.Sleep(time.Second * 3)
}

View File

@ -2,6 +2,7 @@ package log
import (
"contexts/ctx"
"io/ioutil"
"path"
"toolkit"
@ -68,8 +69,16 @@ func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
return s
}
func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server {
os.Mkdir(m.Conf("logdir"), 0770)
log.file = map[string]*os.File{}
os.Mkdir(m.Conf("logdir"), 0770)
kit.Log("error", "make log dir %s", m.Conf("logdir"))
ioutil.WriteFile(m.Conf("logpid"), []byte(kit.Format(os.Getpid())), 0666)
kit.Log("error", "save log file %s", m.Conf("logpid"))
for _, v := range []string{"error", "bench", "debug"} {
log.Log(m, v, "hello world\n")
log.Log(m, v, "hello world")
}
return log
}
func (log *LOG) Start(m *ctx.Message, arg ...string) bool {
@ -90,16 +99,25 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
},
Configs: map[string]*ctx.Config{
"logdir": &ctx.Config{Name: "logdir", Value: "var/log", Help: ""},
"logpid": &ctx.Config{Name: "logpid", Value: "var/log/bench.pid", Help: ""},
"output": &ctx.Config{Name: "output", Value: map[string]interface{}{
"error": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
"debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
"error": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
"debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
"search": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
"cbs": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
"bench": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}},
"begin": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"start": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"close": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"cmd": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"},
"lex": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
"yac": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
"cli": map[string]interface{}{
"cmd": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
},
},
}, Help: "日志输出配置"},
},

View File

@ -0,0 +1,19 @@
package log
import (
"contexts/ctx"
"testing"
)
func TestLog(t *testing.T) {
m := ctx.Pulse.Spawn(Index)
m.Target().Begin(m)
m.Sess("log", m)
m.Log("error", "what %v", 123)
m.Log("debug", "what %v", 123)
m.Log("info", "what %v", 123)
m.Log("cmd", "what %v", 123)
m.Log("begin", "what %v", 123)
m.Log("search", "what %v", 123)
m.Cmd("log", "search", "what %v", 123)
}

View File

@ -18,9 +18,9 @@ import (
"os/exec"
"path"
"regexp"
// "runtime"
"sort"
"strconv"
"strings"
"time"
"toolkit"
@ -50,31 +50,6 @@ type NFS struct {
*ctx.Context
}
func open(m *ctx.Message, name string, arg ...int) (string, *os.File, error) {
if !path.IsAbs(name) {
paths := m.Confv("paths").([]interface{})
for _, v := range paths {
p := path.Join(v.(string), name)
if len(arg) > 0 {
name = p
break
}
if s, e := os.Stat(p); e == nil && !s.IsDir() {
name = p
break
}
}
}
flag := os.O_RDONLY
if len(arg) > 0 {
flag = arg[0]
}
m.Log("info", "open %s", name)
f, e := os.OpenFile(name, flag, 0660)
return name, f, e
}
func dir(m *ctx.Message, name string, level int, deep bool, dir_type string, trip int, dir_reg *regexp.Regexp, fields []string, format string) {
back, e := os.Getwd()
m.Assert(e)
@ -167,6 +142,31 @@ func dir(m *ctx.Message, name string, level int, deep bool, dir_type string, tri
}
}
}
func open(m *ctx.Message, name string, arg ...int) (string, *os.File, error) {
if !path.IsAbs(name) {
paths := m.Confv("paths").([]interface{})
for _, v := range paths {
p := path.Join(v.(string), name)
if len(arg) > 0 {
name = p
break
}
if s, e := os.Stat(p); e == nil && !s.IsDir() {
name = p
break
}
}
}
flag := os.O_RDONLY
if len(arg) > 0 {
flag = arg[0]
}
m.Log("info", "open %s", name)
f, e := os.OpenFile(name, flag, 0660)
return name, f, e
}
func (nfs *NFS) insert(rest []rune, letters []rune) []rune {
n := len(rest)
@ -530,8 +530,9 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
func (nfs *NFS) prompt(arg ...string) string {
m := nfs.Context.Message()
target := m.Optionv("ps_target").(*ctx.Context)
target, _ := m.Optionv("ps_target").(*ctx.Context)
nfs.out.WriteString(fmt.Sprintf("%d[%s]%s> ", m.Capi("ninput"), time.Now().Format("15:04:05"), target.Name))
return ""
return "> "
ps := nfs.Option("prompt")
@ -583,11 +584,8 @@ func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
"size": &ctx.Cache{Name: "size", Value: "0", Help: "size"},
"nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"},
"nwrite": &ctx.Cache{Name: "nwrite", Value: "0", Help: "nwrite"},
"nline": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"},
}
c.Configs = map[string]*ctx.Config{
"history": &ctx.Config{Name: "history", Value: []interface{}{}, Help: "读取记录"},
}
c.Configs = map[string]*ctx.Config{}
} else {
c.Caches = map[string]*ctx.Cache{
"nsend": &ctx.Cache{Name: "消息发送数量", Value: "0", Help: "消息发送数量"},
@ -605,7 +603,6 @@ func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
}
func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server {
nfs.Message = m
nfs.width, nfs.height = 1, 1
return nfs
}
func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
@ -700,6 +697,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
if m.Cap("stream", arg[1]) == "stdio" {
nfs.out = m.Optionv("out").(*os.File)
nfs.width, nfs.height = 1, 1
// if !m.Caps("windows", runtime.GOOS == "windows") {
// termbox.Init()
// defer termbox.Close()
@ -836,10 +834,12 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool {
switch nfs.Context {
case m.Target():
if nfs.in != nil {
m.Log("info", "close in %s", m.Cap("stream"))
nfs.in.Close()
nfs.in = nil
}
if nfs.out != nil {
m.Log("info", "close out %s", m.Cap("stream"))
nfs.out.Close()
nfs.out = nil
}
@ -946,7 +946,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
return
}},
"git": &ctx.Command{Name: "git", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"git": &ctx.Command{Name: "git sum", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 && arg[0] == "sum" {
if out, e := exec.Command("git", "log", "--shortstat", "--pretty=commit: %ad", "--date=format:%Y-%m-%d").CombinedOutput(); m.Assert(e) {
for _, v := range strings.Split(string(out), "commit: ") {
@ -1008,29 +1008,23 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}},
"path": &ctx.Command{Name: "path file", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
for _, v := range m.Confv("paths").([]interface{}) {
p := path.Join(v.(string), arg[0])
m.Confm("paths", func(index int, value string) bool {
p := path.Join(value, arg[0])
if _, e := os.Stat(p); e == nil {
m.Echo(p)
break
return true
}
}
return false
})
return
}},
"load": &ctx.Command{Name: "load file [buf_size [pos]]", Help: "加载文件, buf_size: 加载大小, pos: 加载位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if p, f, e := open(m, arg[0]); m.Assert(e) {
defer f.Close()
pos := 0
if len(arg) > 2 {
i, e := strconv.Atoi(arg[2])
m.Assert(e)
pos = i
}
s, e := strconv.Atoi(m.Confx("buf_size", arg, 1))
m.Assert(e)
buf := make([]byte, s)
pos := kit.Int(kit.Select("0", arg, 2))
size := kit.Int(m.Confx("buf_size", arg, 1))
buf := make([]byte, size)
if l, e := f.ReadAt(buf, int64(pos)); e == io.EOF || m.Assert(e) {
m.Log("info", "load %s %d %d", p, l, pos)
@ -1043,7 +1037,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
if len(arg) == 1 && m.Has("data") {
arg = append(arg, m.Option("data"))
}
if p, f, e := open(m, arg[0], os.O_WRONLY|os.O_CREATE|os.O_TRUNC); m.Assert(e) {
if p, f, e := open(m, m.Format(arg[0]), os.O_WRONLY|os.O_CREATE|os.O_TRUNC); m.Assert(e) {
defer f.Close()
m.Append("directory", p)
m.Echo(p)
@ -1056,67 +1050,24 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
return
}},
"export": &ctx.Command{Name: "export filename", Help: "导出数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
name := time.Now().Format(arg[0])
_, f, e := open(m, name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
m.Assert(e)
defer f.Close()
switch {
case strings.HasSuffix(arg[0], ".json") && len(m.Meta["append"]) > 0:
data := []interface{}{}
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := map[string]interface{}{}
for _, k := range m.Meta["append"] {
line[k] = m.Meta[k][i]
}
data = append(data, line)
}
en := json.NewEncoder(f)
en.SetIndent("", " ")
en.Encode(data)
case strings.HasSuffix(arg[0], ".csv") && len(m.Meta["append"]) > 0:
w := csv.NewWriter(f)
line := []string{}
for _, v := range m.Meta["append"] {
line = append(line, v)
}
w.Write(line)
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := []string{}
for _, k := range m.Meta["append"] {
line = append(line, m.Meta[k][i])
}
w.Write(line)
}
w.Flush()
default:
for _, v := range m.Meta["result"] {
f.WriteString(v)
}
}
m.Set("append").Set("result").Add("append", "directory", name).Echo(name)
return
}},
"import": &ctx.Command{Name: "import filename [index]", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
_, f, e := open(m, arg[0])
p, f, e := open(m, arg[0])
m.Assert(e)
defer f.Close()
s, e := f.Stat()
m.Option("filepath", p)
m.Option("filename", s.Name())
m.Option("filesize", s.Size())
m.Option("filetime", s.ModTime().Format(m.Conf("time_format")))
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")
m.Put("option", "filedata", data).Cmdy("ctx.trans", "filedata", arg[1:]).CopyTo(m)
case strings.HasSuffix(arg[0], ".csv"):
r := csv.NewReader(f)
@ -1130,9 +1081,96 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
}
m.Table()
default:
b, e := ioutil.ReadAll(f)
m.Assert(e)
m.Echo(string(b))
}
return
}},
"export": &ctx.Command{Name: "export filename", Help: "导出数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
tp := false
if len(arg) > 0 && arg[0] == "time" {
tp, arg = true, arg[1:]
}
p, f, e := open(m, kit.Select(arg[0], m.Format(arg[0]), tp), os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
m.Assert(e)
defer f.Close()
m.Option("hi", "hello world")
m.Option("he", "hello", "world")
m.Append("he", "hello", "world")
m.Append("hi", "nice", "job")
data := m.Optionv(kit.Select("data", arg, 1))
if len(arg) > 0 && arg[0] == "all" {
data, arg = m.Meta, arg[1:]
}
switch {
case strings.HasSuffix(arg[0], ".json"):
if data == nil && len(m.Meta["append"]) > 0 {
lines := []interface{}{}
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := map[string]interface{}{}
for _, k := range m.Meta["append"] {
line[k] = m.Meta[k][i]
}
lines = append(lines, line)
data = lines
}
}
en := json.NewEncoder(f)
en.SetIndent("", " ")
en.Encode(data)
case strings.HasSuffix(arg[0], ".csv"):
fields := m.Meta["append"]
if m.Options("fields") {
fields = m.Meta["fields"]
}
if data == nil && len(m.Meta["append"]) > 0 {
lines := []interface{}{}
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := []string{}
for _, k := range fields {
line = append(line, m.Meta[k][i])
}
lines = append(lines, line)
data = lines
}
}
if data, ok := data.([]interface{}); ok {
w := csv.NewWriter(f)
w.Write(fields)
for _, v := range data {
w.Write(kit.Trans(v))
}
w.Flush()
}
case strings.HasSuffix(arg[0], ".png"):
if data == nil {
data = kit.Format(arg[1:])
}
qr, e := qrcode.New(kit.Format(data), qrcode.Medium)
m.Assert(e)
m.Assert(qr.Write(256, f))
default:
f.WriteString(kit.Format(m.Meta["result"]))
}
m.Set("append").Add("append", "directory", p)
m.Set("result").Echo(p)
return
}},
"open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if m.Has("io") {
@ -1144,7 +1182,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
m.Start(fmt.Sprintf("file%d", m.Capi("nfile")), fmt.Sprintf("file %s", arg[0]), "open", arg[0])
m.Echo(arg[0])
m.Append("ps_target1", m.Cap("module"))
m.Echo(m.Cap("module"))
return
}},
"read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -1213,6 +1252,23 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
return
}},
"exec": &ctx.Command{Name: "exec cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
nfs.prompt()
for _, v := range arg {
nfs.out.WriteString(v)
}
nfs.out.WriteString("\n")
msg := m.Find("cli.shell1").Cmd("source", arg)
for _, v := range msg.Meta["result"] {
nfs.out.WriteString(v)
m.Echo(v)
}
nfs.out.WriteString("\n")
}
return
}},
"listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{
@ -1253,88 +1309,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
return
}},
"exec": &ctx.Command{Name: "exec cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
nfs.prompt()
for _, v := range arg {
nfs.out.WriteString(v)
}
nfs.out.WriteString("\n")
msg := m.Find("cli.shell1").Cmd("source", arg)
for _, v := range msg.Meta["result"] {
nfs.out.WriteString(v)
m.Echo(v)
}
nfs.out.WriteString("\n")
}
return
}},
"print": &ctx.Command{Name: "print file string...", Help: "输出文件, file: 输出的文件, string: 输出的内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if p, f, e := open(m, arg[0], os.O_WRONLY|os.O_CREATE|os.O_APPEND); m.Assert(e) {
defer f.Close()
for _, v := range arg[1:] {
n, e := fmt.Fprint(f, v)
m.Assert(e)
m.Log("info", "print %s %d", p, n)
}
}
return
}},
"json": &ctx.Command{Name: "json [key value]...", Help: "生成格式化内容, key: 参数名, value: 参数值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 1 {
var data interface{}
json.Unmarshal([]byte(arg[0]), &data)
buf, e := json.MarshalIndent(data, "", " ")
m.Assert(e)
m.Echo(string(buf))
return e
}
if len(arg) > 1 && arg[0] == "file" {
var data interface{}
f, e := os.Open(arg[1])
m.Assert(e)
d := json.NewDecoder(f)
d.Decode(&data)
buf, e := json.MarshalIndent(data, "", " ")
m.Assert(e)
m.Echo(string(buf))
return e
}
data := map[string]interface{}{}
for _, k := range m.Meta["option"] {
if v, ok := m.Data[k]; ok {
data[k] = v
continue
}
data[k] = m.Meta[k]
}
for i := 1; i < len(arg)-1; i += 2 {
data[arg[i]] = arg[i+1]
}
buf, e := json.Marshal(data)
m.Assert(e)
m.Echo(string(buf))
return
}},
"genqr": &ctx.Command{Name: "genqr [qr_size size] filename string...", Help: "生成二维码图片, qr_size: 图片大小, filename: 文件名, string: 输出内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if size, e := strconv.Atoi(m.Confx("qr_size")); m.Assert(e) {
p := path.Join(m.Confv("paths", 0).(string), arg[0])
qrcode.WriteFile(strings.Join(arg[1:], ""), qrcode.Medium, size, p)
m.Log("info", "genqr %s", p)
m.Append("directory", p)
}
return
}},
},
}

View File

@ -286,6 +286,7 @@ func Select(value string, args ...interface{}) string {
if b && arg != "" {
return arg
}
return value
}
}
if arg != "" {
@ -458,6 +459,27 @@ func Hash(arg ...interface{}) (string, []string) {
h := md5.Sum([]byte(strings.Join(meta, "")))
return hex.EncodeToString(h[:]), meta
}
func FileName(name string, meta ...string) string {
result, app := strings.Split(name, "."), ""
if len(result) > 1 {
app, result = result[len(result)-1], result[:len(result)-1]
}
for _, v := range meta {
switch v {
case "year":
result = append(result, "_", time.Now().Format("2006"))
case "date":
result = append(result, "_", time.Now().Format("0102"))
case "time":
result = append(result, "_", time.Now().Format("2006_0102_1504"))
}
}
if app != "" {
result = append(result, ".", app)
}
return strings.Join(result, "")
}
func Action(cmd string, arg ...interface{}) string {
switch cmd {