From e167d1522c9c137b9a002e0a191509bb2814532e Mon Sep 17 00:00:00 2001 From: shaoying Date: Sun, 11 Nov 2018 09:14:37 +0800 Subject: [PATCH] mac opt nfs.dir --- etc/dotsfile/git_hooks/post-commit | 1 - src/contexts/cli/cli.go | 7 +- src/contexts/ctx/ctx.go | 72 +++++++- src/contexts/log/log.go | 2 +- src/contexts/nfs/nfs.go | 255 ++++++++++++----------------- src/contexts/web/web.go | 16 ++ src/examples/code/code.go | 127 ++++++++------ src/examples/wiki/wiki.go | 4 +- usr/librarys/code.js | 90 ++++++---- usr/librarys/context.js | 14 +- usr/template/code/code.tmpl | 9 + 11 files changed, 355 insertions(+), 242 deletions(-) diff --git a/etc/dotsfile/git_hooks/post-commit b/etc/dotsfile/git_hooks/post-commit index 7ae21a4d..f1f641af 100755 --- a/etc/dotsfile/git_hooks/post-commit +++ b/etc/dotsfile/git_hooks/post-commit @@ -1,2 +1 @@ #!/usr/bin/env bash -echo $* diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index bbfc7e12..ba5ad9e9 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -83,8 +83,10 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server "!": []string{"message"}, ":": []string{"command"}, "::": []string{"command", "list"}, - "@": []string{"config"}, - "$": []string{"cache"}, + + "pwd": []string{"nfs.pwd"}, + "dir": []string{"nfs.dir"}, + "git": []string{"nfs.git"}, } return s @@ -137,7 +139,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "init.shy": &ctx.Config{Name: "init.shy", Value: "etc/init.shy", Help: "启动脚本"}, "exit.shy": &ctx.Config{Name: "exit.shy", Value: "etc/exit.shy", Help: "启动脚本"}, - "time_format": &ctx.Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"}, "time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"}, "time_close": &ctx.Config{Name: "time_close(open/close)", Value: "open", Help: "时间区间"}, diff --git a/src/contexts/ctx/ctx.go b/src/contexts/ctx/ctx.go index 77a64437..288e5591 100644 --- a/src/contexts/ctx/ctx.go +++ b/src/contexts/ctx/ctx.go @@ -1197,17 +1197,17 @@ func (m *Message) Sort(key string, arg ...string) *Message { result = true } case "time": - ti, e := time.ParseInLocation(m.Confx("time_layout"), table[i][key], time.Local) + ti, e := time.ParseInLocation(m.Confx("time_format"), table[i][key], time.Local) m.Assert(e) - tj, e := time.ParseInLocation(m.Confx("time_layout"), table[j][key], time.Local) + tj, e := time.ParseInLocation(m.Confx("time_format"), table[j][key], time.Local) m.Assert(e) if tj.Before(ti) { result = true } case "time_r": - ti, e := time.ParseInLocation(m.Confx("time_layout"), table[i][key], time.Local) + ti, e := time.ParseInLocation(m.Confx("time_format"), table[i][key], time.Local) m.Assert(e) - tj, e := time.ParseInLocation(m.Confx("time_layout"), table[j][key], time.Local) + tj, e := time.ParseInLocation(m.Confx("time_format"), table[j][key], time.Local) m.Assert(e) if ti.Before(tj) { result = true @@ -2300,9 +2300,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心", "table_row_sep": &Config{Name: "table_row_sep", Value: "\n", Help: "命令列表帮助"}, "page_offset": &Config{Name: "page_offset", Value: "0", Help: "列表偏移"}, - "page_limit": &Config{Name: "page_limit", Value: "10", Help: "列表大小"}, + "page_limit": &Config{Name: "page_limit", Value: "100", Help: "列表大小"}, - "time_layout": &Config{Name: "time_layout", Value: "2006/01/02 15:04:05", Help: "默认时间格式"}, + "time_format": &Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"}, }, Commands: map[string]*Command{ "help": &Command{Name: "help topic", Help: "帮助", Hand: func(m *Message, c *Context, key string, arg ...string) { @@ -3203,7 +3203,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } }}, "select": &Command{Name: "select key value field", - Form: map[string]int{"parse": 2, "order": 2, "limit": 1, "offset": 1, "fields": 1, "format": 2, "trans_map": 3, "vertical": 0}, + Form: map[string]int{"parse": 2, "group": 1, "order": 2, "limit": 1, "offset": 1, "fields": 1, "format": 2, "trans_map": 3, "vertical": 0}, Help: "选取数据", Hand: func(m *Message, c *Context, key string, arg ...string) { msg := m.Spawn() @@ -3233,12 +3233,66 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } } - if m.Set("append").Copy(msg, "append"); m.Has("order") { + if m.Set("append"); m.Has("group") { + + group := m.Option("group") + + nrow := len(msg.Meta[msg.Meta["append"][0]]) + + for i := 0; i < nrow; i++ { + count := 1 + + if group != "" && msg.Meta[group][i] == "" { + msg.Add("append", "count", 0) + continue + } + + for j := i + 1; j < nrow; j++ { + if group == "" || msg.Meta[group][i] == msg.Meta[group][j] { + count++ + for _, k := range msg.Meta["append"] { + if k == "count" { + continue + } + if k == group { + continue + } + m, e := strconv.Atoi(msg.Meta[k][i]) + if e != nil { + continue + } + n, e := strconv.Atoi(msg.Meta[k][j]) + if e != nil { + continue + } + msg.Meta[k][i] = fmt.Sprintf("%d", m+n) + + } + + if group != "" { + msg.Meta[group][j] = "" + } + } + } + + msg.Add("append", "count", count) + for _, k := range msg.Meta["append"] { + m.Add("append", k, msg.Meta[k][i]) + } + if group == "" { + break + } + } + } else { + m.Copy(msg, "append") + } + + if m.Has("order") { m.Sort(m.Meta["order"][1], m.Option("order")) } offset := 0 - limit := 10 + limit := m.Confi("page_limit") if m.Has("limit") { limit = m.Optioni("limit") } diff --git a/src/contexts/log/log.go b/src/contexts/log/log.go index d6ab3a44..03e43095 100644 --- a/src/contexts/log/log.go +++ b/src/contexts/log/log.go @@ -24,7 +24,7 @@ func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server { log.Configs["flag_color"] = &ctx.Config{Name: "flag_color", Value: "true", Help: "模块日志输出颜色"} log.Configs["flag_time"] = &ctx.Config{Name: "flag_time", Value: "2006/01/02 15:04:05 ", Help: "模块日志输出颜色"} - log.Configs["bench.log"] = &ctx.Config{Name: "bench.log", Value: "var/bench.log", Help: "模块日志输出的文件"} + log.Configs["bench.log"] = &ctx.Config{Name: "bench.log", Value: "bench.log", Help: "模块日志输出的文件"} return log } func (log *LOG) Start(m *ctx.Message, arg ...string) bool { diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index cadddd3a..c6961bee 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -3,7 +3,9 @@ package nfs import ( "bufio" "contexts/ctx" + "crypto/sha1" "encoding/csv" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -16,8 +18,10 @@ import ( "os/exec" "path" "runtime" + "sort" "strconv" "strings" + "time" "unicode" ) @@ -68,27 +72,11 @@ func open(m *ctx.Message, name string, arg ...int) (string, *os.File, error) { f, e := os.OpenFile(name, flag, os.ModePerm) return name, f, e } - -func dir(m *ctx.Message, name string, level int, deep bool, fields []string) { +func dir(m *ctx.Message, name string, level int, deep bool, trip int, fields []string) { back, e := os.Getwd() m.Assert(e) os.Chdir(name) defer os.Chdir(back) - s, e := os.Stat(".") - for _, k := range fields { - switch k { - case "filename": - m.Add("append", "filename", "..") - case "is_dir": - m.Add("append", "is_dir", "true") - case "size": - m.Add("append", "size", 0) - case "line": - m.Add("append", "line", 0) - case "time": - m.Add("append", "time", s.ModTime().Format("2006-01-02 15:04:05")) - } - } if fs, e := ioutil.ReadDir("."); m.Assert(e) { for _, f := range fs { @@ -96,70 +84,83 @@ func dir(m *ctx.Message, name string, level int, deep bool, fields []string) { continue } - if f.IsDir() { - if m.Has("dirs") { - m.Optioni("dirs", m.Optioni("dirs")+1) - } - } else { - if m.Has("files") { - m.Optioni("files", m.Optioni("files")+1) - } - } - - if m.Has("sizes") { - m.Optioni("sizes", m.Optioni("sizes")+int(f.Size())) - } - - line := 0 - if m.Has("lines") { - if !f.IsDir() { - f, e := os.Open(path.Join(back, name, f.Name())) - m.Assert(e) - defer f.Close() - bio := bufio.NewScanner(f) - for bio.Scan() { - bio.Text() - line++ - } - m.Optioni("lines", m.Optioni("lines")+line) - } - } - - filename := "" - switch m.Confx("dir_name") { - case "name": - filename = f.Name() - case "tree": - filename = strings.Repeat(" ", level) + f.Name() - default: - filename = path.Join(back, name, f.Name()) - } - if !(m.Confx("dir_type") == "file" && f.IsDir() || m.Confx("dir_type") == "dir" && !f.IsDir()) { - for _, k := range fields { - switch k { + for _, field := range fields { + switch field { + case "time": + m.Add("append", "time", f.ModTime().Format(m.Conf("time_format"))) + case "type": + if m.Assert(e) && f.IsDir() { + m.Add("append", "type", "dir") + } else { + m.Add("append", "type", "file") + } + case "full": + m.Add("append", "full", path.Join(back, name, f.Name())) + case "path": + m.Add("append", "path", path.Join(back, name, f.Name())[trip:]) + case "tree": + if level == 0 { + m.Add("append", "tree", f.Name()) + } else { + m.Add("append", "tree", strings.Repeat("| ", level-1)+"|-"+f.Name()) + } case "filename": - m.Add("append", "filename", filename) - case "is_dir": - f, e := os.Stat(filename) - m.Assert(e) - m.Add("append", "is_dir", f.IsDir()) + if f.IsDir() { + m.Add("append", "filename", f.Name()+"/") + } else { + m.Add("append", "filename", f.Name()) + } case "size": m.Add("append", "size", f.Size()) case "line": - m.Add("append", "line", line) - case "time": - m.Add("append", "time", f.ModTime().Format("2006-01-02 15:04:05")) + nline := 0 + if f.IsDir() { + d, e := ioutil.ReadDir(f.Name()) + m.Assert(e) + nline = len(d) + } else { + f, e := os.Open(f.Name()) + m.Assert(e) + defer f.Close() + + bio := bufio.NewScanner(f) + for bio.Scan() { + bio.Text() + nline++ + } + } + m.Add("append", "line", nline) + case "hash": + if f.IsDir() { + d, e := ioutil.ReadDir(f.Name()) + m.Assert(e) + meta := []string{} + for _, v := range d { + meta = append(meta, fmt.Sprintf("%s%d%s", v.Name(), v.Size(), v.ModTime())) + } + sort.Strings(meta) + + h := sha1.Sum([]byte(strings.Join(meta, ""))) + m.Add("append", "hash", hex.EncodeToString(h[:])) + break + } + + f, e := ioutil.ReadFile(f.Name()) + m.Assert(e) + h := sha1.Sum(f) + m.Add("append", "hash", hex.EncodeToString(h[:])) } } } if f.IsDir() && deep { - dir(m, f.Name(), level+1, deep, fields) + dir(m, f.Name(), level+1, deep, trip, fields) } } } } + func (nfs *NFS) insert(rest []rune, letters []rune) []rune { n := len(rest) l := len(letters) @@ -824,17 +825,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", "dir_root": "usr", }, Help: "读取文件的缓存区的大小"}, - "dir_deep": &ctx.Config{Name: "dir_deep(yes/no)", Value: "yes", Help: "dir命令输出目录的统计信息, info: 输出统计信息, 否则输出"}, - "dir_type": &ctx.Config{Name: "dir_type(file/dir)", Value: "file", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"}, - "dir_field": &ctx.Config{Name: "dir_field", Value: "filename is_dir line size time", Help: "表格排序字段"}, + "dir_type": &ctx.Config{Name: "dir_type(file/dir/all)", Value: "all", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"}, "dir_name": &ctx.Config{Name: "dir_name(name/tree/path/full)", Value: "name", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"}, - "dir_info": &ctx.Config{Name: "dir_info(sizes/lines/files/dirs)", Value: "sizes lines files dirs", Help: "dir命令输出目录的统计信息, info: 输出统计信息, 否则输出"}, - "sort_field": &ctx.Config{Name: "sort_field", Value: "line", Help: "表格排序字段"}, - "sort_order": &ctx.Config{Name: "sort_order(int/int_r/string/string_r/time/time_r)", Value: "int", Help: "表格排序类型"}, - - "git_conf": &ctx.Config{Name: "git_conf", Value: map[string]interface{}{ - "dir_root": "usr", - }, Help: "读取文件的缓存区的大小"}, + "dir_fields": &ctx.Config{Name: "dir_fields(time/type/name/size/line/hash)", Value: "time size line filename", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"}, "git_branch": &ctx.Config{Name: "git_branch", Value: "--list", Help: "版本控制状态参数"}, "git_status": &ctx.Config{Name: "git_status", Value: "-sb", Help: "版本控制状态参数"}, @@ -846,7 +839,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", "git_path": &ctx.Config{Name: "git_path", Value: ".", Help: "版本控制默认路径"}, "git_info": &ctx.Config{Name: "git_info", Value: "branch status diff log", Help: "命令集合"}, - "paths": &ctx.Config{Name: "paths", Value: []interface{}{""}, Help: "文件路径"}, + "paths": &ctx.Config{Name: "paths", Value: []interface{}{"var", ""}, Help: "文件路径"}, }, Commands: map[string]*ctx.Command{ "listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -898,7 +891,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", return } - if p, f, e := open(m, arg[0], os.O_RDWR); m.Assert(e) { + if p, f, e := open(m, arg[0]); m.Assert(e) { m.Optionv("in", f) m.Start(m.Confx("nfs_name", arg, 1), help, key, p) } @@ -1038,9 +1031,12 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } }}, "export": &ctx.Command{Name: "export filename", Help: "导出数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - _, f, e := open(m, arg[0], os.O_WRONLY|os.O_CREATE|os.O_TRUNC) + 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() + m.Log("fuck", "what %v", name) + m.Log("fuck", "what %v", m.Meta) switch { case strings.HasSuffix(arg[0], ".json"): @@ -1081,6 +1077,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", f.WriteString(v) } } + m.Log("fuck", "what %v", name) + m.Log("fuck", "what %v", m.Meta) + m.Set("append").Set("result").Echo(name) }}, "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) { @@ -1169,80 +1168,44 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } }}, - "dir": &ctx.Command{ - Name: "dir dir [dir_deep yes|no] [dir_info info] [dir_name name|tree|path|full] [dir_type both|file|dir] [sort_field name] [sort_order type]", - Help: "查看目录, dir: 目录名, dir_info: 显示统计信息, dir_name: 文件名类型, dir_type: 文件类型, sort_field: 排序字段, sort_order: 排序类型", - Form: map[string]int{ - "dir_root": 1, - "dir_deep": 1, - "dir_type": 1, - "dir_name": 1, - "dir_info": 1, - "dir_link": 1, - "dir_field": 1, - "sort_field": 1, - "sort_order": 1, - }, + "dir": &ctx.Command{Name: "dir dir [dir_type both|file|dir] [dir_name name|tree|path|full] [dir_deep] fields...", + Help: "查看目录, dir: 目录名, dir_type: 文件类型, dir_name: 文件名类型, dir_deep: 递归查询, fields: 查询字段", + Form: map[string]int{"dir_type": 1, "dir_name": 1, "dir_deep": 0, "dir_sort": 2}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - conf := m.Confv("dir_conf") + wd, e := os.Getwd() + m.Assert(e) + trip := len(wd) + 1 - m.Log("info", "option %s", m.Option("dir")) - if len(arg) > 0 { - m.Log("info", "arg0 %s", arg[0]) + if len(arg) == 0 { + arg = append(arg, "") } - m.Log("info", "elect %s", ctx.Elect(m.Option("dir"), arg, 0)) - - m.Option("dir", path.Clean(ctx.Elect(m.Option("dir"), arg, 0))) - d := path.Join(m.Confx("dir_root", conf), m.Option("dir")) - if s, e := os.Stat(d); m.Assert(e) && !s.IsDir() { - d = path.Dir(d) + dirs := arg[0] + if m.Options("dir_root") { + dirs = path.Join(m.Option("dir_root"), dirs) } - fields := strings.Split(m.Confx("dir_field"), " ") - - trip := 0 - if m.Confx("dir_name") == "path" { - wd, e := os.Getwd() - m.Assert(e) - trip = len(wd) + 1 - } - - info := strings.Split(m.Confx("dir_info"), " ") - for _, v := range info { - m.Option(v, 0) - } - - m.Option("time_layout", "2006-01-02 15:04:05") - dir(m, d, 0, ctx.Right(m.Confx("dir_deep")), fields) - m.Sort(m.Confx("sort_field"), m.Confx("sort_order")) - m.Table(func(maps map[string]string, list []string, line int) bool { - for i, v := range list { - key := m.Meta["append"][i] - switch key { - case "filename": - v = maps[key] - if line > -1 && trip > 0 && trip <= len(v) { - v = v[trip:] - if m.Options("dir_link") { - m.Meta["filename"][line] = fmt.Sprintf(m.Option("dir_link"), maps["is_dir"], v) - } else { - m.Meta["filename"][line] = v - } - } - if line > -1 { - if m.Options("dir_link") { - m.Meta["filename"][line] = fmt.Sprintf(m.Option("dir_link"), maps["is_dir"], v) - } - } + for _, v := range m.Confv("paths").([]interface{}) { + d := path.Join(v.(string), dirs) + if s, e := os.Stat(d); e == nil { + if s.IsDir() { + dir(m, d, 0, ctx.Right(m.Has("dir_deep")), trip, strings.Split(m.Confx("dir_fields", strings.Join(arg[1:], " ")), " ")) + } else { + m.Append("directory", d) + return } + break } - return true - }) - if !m.Options("dir_link") { - m.Table() } - for _, v := range info { - m.Echo("%s: %s\n", v, m.Option(v)) + if m.Has("dir_sort") { + m.Sort(m.Meta["dir_sort"][1], m.Meta["dir_sort"][0]) + } + + if len(m.Meta["append"]) == 1 { + for _, v := range m.Meta[m.Meta["append"][0]] { + m.Echo(v).Echo(" ") + } + } else { + m.Table() } }}, "git": &ctx.Command{ diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index b6b1a5c7..4319a098 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -83,6 +83,7 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { msg.Add("option", "method", r.Method).Add("option", "path", r.URL.Path) msg.Option("remote_addr", r.RemoteAddr) + msg.Option("dir_root", m.Cap("directory")) msg.Option("referer", r.Header.Get("Referer")) msg.Option("accept", r.Header.Get("Accept")) @@ -682,6 +683,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Log("upload", "file(%d): %s", h.Size, p) m.Append("redirect", m.Option("referer")) }}, + "/download/": &ctx.Command{Name: "/download/", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + r := m.Optionv("request").(*http.Request) + w := m.Optionv("response").(http.ResponseWriter) + http.ServeFile(w, r, m.Sess("nfs").Cmd("path", strings.TrimPrefix(m.Option("path"), "/download/")).Result(0)) + }}, "/render": &ctx.Command{Name: "/render template", Help: "渲染模板, template: 模板名称", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if web, ok := m.Target().Server.(*WEB); m.Assert(ok) { accept_json := strings.HasPrefix(m.Option("accept"), "application/json") @@ -802,6 +808,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", if order != "" || (val["pre_run"] != nil && val["pre_run"].(bool)) { if val["command"] != nil { msg.Cmd(val["command"], args) + if msg.Options("file_name") { + m.Append("page_redirect", fmt.Sprintf("/download/%s", + msg.Sess("nfs").Copy(msg, "append").Copy(msg, "result").Cmd("export", msg.Option("file_name")).Result(0))) + return + } } } @@ -811,6 +822,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Assert(tmpl.ExecuteTemplate(w, val["template"].(string), msg)) } + if msg.Appends("directory") { + m.Append("page_redirect", fmt.Sprintf("/download?file=%s", msg.Append("directory"))) + return + } + if msg.Detail(0) == "login" && msg.Appends("sessid") { http.SetCookie(w, &http.Cookie{Name: "sessid", Value: msg.Append("sessid")}) m.Append("page_refresh", "10") diff --git a/src/examples/code/code.go b/src/examples/code/code.go index e0803119..77464062 100644 --- a/src/examples/code/code.go +++ b/src/examples/code/code.go @@ -39,38 +39,6 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", }, "index": []interface{}{ map[string]interface{}{"name": "head", "template": "head"}, - map[string]interface{}{"name": "sysinfo", "help": "sysinfo", "template": "componet", - "context": "cli", "command": "sysinfo", - "inputs": []interface{}{ - map[string]interface{}{"type": "button", "label": "refresh"}, - }, - "pre_run": true, - "display_result": "", - }, - map[string]interface{}{"name": "runtime", "help": "runtime", "template": "componet", - "context": "cli", "command": "runtime", - "inputs": []interface{}{ - map[string]interface{}{"type": "button", "label": "refresh"}, - }, - "pre_run": true, - "display_result": "", - }, - map[string]interface{}{"name": "windows", "help": "windows", "template": "componet", - "context": "cli", "command": "windows", - "inputs": []interface{}{ - map[string]interface{}{"type": "button", "label": "refresh"}, - }, - "pre_run": true, - "display_result": "", - }, - map[string]interface{}{"name": "develop", "help": "develop", "template": "componet", - "context": "web.code", "command": "config", "arguments": []interface{}{"counter"}, - "inputs": []interface{}{ - map[string]interface{}{"type": "button", "label": "refresh"}, - }, - "pre_run": true, - "display_result": "", - }, map[string]interface{}{"name": "clipbaord", "help": "clipbaord", "template": "clipboard"}, map[string]interface{}{"name": "buffer", "help": "buffer", "template": "componet", "context": "cli", "command": "tmux", "arguments": []interface{}{"buffer"}, "inputs": []interface{}{ @@ -80,16 +48,19 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", }, "pre_run": true, }, - map[string]interface{}{"name": "command", "help": "command", "template": "componet", - "context": "cli.shy", "command": "source", "arguments": []interface{}{"@cmd"}, + map[string]interface{}{"name": "time", "help": "time", "template": "componet", + "context": "cli", "command": "time", "arguments": []interface{}{"@string"}, "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "cmd", "value": "", - "class": "cmd", "clipstack": "clistack", + 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", "label": "refresh"}, }, }, map[string]interface{}{"name": "time", "help": "time", "template": "componet", "context": "cli", "command": "time", "arguments": []interface{}{"@string"}, + "file_name": "nice-2006-01-02_1504.txt", "inputs": []interface{}{ map[string]interface{}{"type": "text", "name": "time_format", "label": "format", "value": "2006-01-02 15:04:05", @@ -105,20 +76,9 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", map[string]interface{}{"type": "button", "label": "refresh"}, }, }, - map[string]interface{}{"name": "upload", "help": "upload", "template": "componet", - "context": "web", "command": "upload", "form_type": "upload", - "inputs": []interface{}{ - map[string]interface{}{"type": "file", "name": "upload"}, - map[string]interface{}{"type": "submit", "value": "submit"}, - }, - "display_result": "", - }, map[string]interface{}{"name": "dir", "help": "dir", "template": "componet", - "context": "nfs", "command": "dir", "arguments": []interface{}{"@dir", - "dir_deep", "no", "dir_name", "name", "dir_info", "", - "dir_link", "%s", - }, - "pre_run": true, + "context": "nfs", "command": "dir", "arguments": []interface{}{"@dir", "dir_sort", "@sort_order", "@sort_field"}, + "pre_run": true, "display_result": "", "inputs": []interface{}{ map[string]interface{}{"type": "choice", "name": "dir_type", "label": "dir_type", "value": "both", "choice": []interface{}{ @@ -130,7 +90,7 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", map[string]interface{}{"type": "choice", "name": "sort_field", "label": "sort_field", "value": "time", "choice": []interface{}{ map[string]interface{}{"name": "filename", "value": "filename"}, - map[string]interface{}{"name": "is_dir", "value": "is_dir"}, + map[string]interface{}{"name": "is_dir", "value": "type"}, map[string]interface{}{"name": "line", "value": "line"}, map[string]interface{}{"name": "size", "value": "size"}, map[string]interface{}{"name": "time", "value": "time"}, @@ -149,6 +109,73 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", map[string]interface{}{"type": "text", "name": "dir", "label": "dir"}, }, }, + map[string]interface{}{"name": "upload", "help": "upload", "template": "componet", + "context": "web", "command": "upload", "form_type": "upload", + "inputs": []interface{}{ + map[string]interface{}{"type": "file", "name": "upload"}, + map[string]interface{}{"type": "submit", "value": "submit"}, + }, + "display_result": "", + }, + map[string]interface{}{"name": "command", "help": "command", "template": "componet", + "context": "cli.shy", "command": "source", "arguments": []interface{}{"@cmd"}, + "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "cmd", "value": "", + "class": "cmd", "clipstack": "clistack", + }, + }, + }, + map[string]interface{}{"name": "command_result", "help": "command_result", "template": "componet", + "context": "cli.shy", "command": "source", "arguments": []interface{}{"@cmd"}, + "display_result": "", "file_name": "result_2006_0102_1504.txt", + "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "cmd", "value": "", + "class": "cmd", "clipstack": "clistack", + }, + }, + }, + map[string]interface{}{"name": "command_append", "help": "command_append", "template": "componet", + "context": "cli.shy", "command": "source", "arguments": []interface{}{"@cmd"}, + "display_result": "", "file_name": "", + "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "file_name", "value": "data_2006_0102_1504.txt", "class": "file_name"}, + map[string]interface{}{"type": "text", "name": "cmd", "value": "", + "class": "file_cmd", "clipstack": "clistack", + }, + }, + }, + map[string]interface{}{"name": "develop", "help": "develop", "template": "componet", + "context": "web.code", "command": "config", "arguments": []interface{}{"counter"}, + "inputs": []interface{}{ + map[string]interface{}{"type": "button", "label": "refresh"}, + }, + "pre_run": true, + "display_result": "", + }, + map[string]interface{}{"name": "windows", "help": "windows", "template": "componet", + "context": "cli", "command": "windows", + "inputs": []interface{}{ + map[string]interface{}{"type": "button", "label": "refresh"}, + }, + "pre_run": true, + "display_result": "", + }, + map[string]interface{}{"name": "runtime", "help": "runtime", "template": "componet", + "context": "cli", "command": "runtime", + "inputs": []interface{}{ + map[string]interface{}{"type": "button", "label": "refresh"}, + }, + "pre_run": true, + "display_result": "", + }, + map[string]interface{}{"name": "sysinfo", "help": "sysinfo", "template": "componet", + "context": "cli", "command": "sysinfo", + "inputs": []interface{}{ + map[string]interface{}{"type": "button", "label": "refresh"}, + }, + "pre_run": true, + "display_result": "", + }, map[string]interface{}{"name": "tail", "template": "tail"}, }, }, Help: "组件列表"}, diff --git a/src/examples/wiki/wiki.go b/src/examples/wiki/wiki.go index 2b753531..d3c055f7 100644 --- a/src/examples/wiki/wiki.go +++ b/src/examples/wiki/wiki.go @@ -291,7 +291,7 @@ var Index = &ctx.Context{Name: "wiki", Help: "文档中心", } else { m.Add("append", "pend", "") } - m.Option("time_layout", "2006-01-02 15:04:05") + m.Option("time_format", "2006-01-02 15:04:05") m.Sort("time", "time_r") } }}, @@ -379,7 +379,7 @@ var Index = &ctx.Context{Name: "wiki", Help: "文档中心", msg.Add("append", "title", strings.TrimSuffix(f.Name(), ".md")+"源码解析") msg.Add("append", "time", f.ModTime().Format("01/02 15:03")) } - msg.Option("time_layout", "01/02 15:03") + msg.Option("time_format", "01/02 15:03") msg.Sort("time", "time_r") articles := []*Article{} diff --git a/usr/librarys/code.js b/usr/librarys/code.js index b244c2ff..a304b7e5 100644 --- a/usr/librarys/code.js +++ b/usr/librarys/code.js @@ -18,10 +18,6 @@ function send_command(form, cb) { data[form[i].name] = form[i].value } - if (data["dir"]) { - context.Cookie("dir", data["dir"]) - } - context.GET("", data, function(msg) { msg = msg[0] @@ -228,38 +224,76 @@ function init_result(event) { }) } function init_download(event) { + var append = document.querySelector("table.append.dir") + insert_before(append, "input", { + "type": "button", + "value": "root", + "onclick": function(event) { + option["dir"].value = "" + context.Cookie("download_dir", option["dir"].value) + send_command(option) + return true + } + }) + insert_before(append, "input", { + "type": "button", + "value": "back", + "onclick": function(event) { + var path = option["dir"].value.split("/") + while (path.pop() == "") {} + option["dir"].value = path.join("/")+(path.length? "/": "") + context.Cookie("download_dir", option["dir"].value) + send_command(option) + return true + } + }) + var option = document.querySelector("form.option.dir") - if (!option) { - return + var sort_order = option["sort_order"] + var sort_field = option["sort_field"] + sort_field.innerHTML = "" + sort_field.onchange = function(event) { + switch (event.target.selectedOptions[0].value) { + case "filename": + case "type": + sort_order.value = (sort_order.value == "str")? "str_r": "str" + break + case "line": + case "size": + sort_order.value = (sort_order.value == "int")? "int_r": "int" + break + case "time": + sort_order.value = (sort_order.value == "time")? "time_r": "time" + break + } + send_command(option) } - document.querySelector("form.option.dir input[name=dir]").value = context.Search("download_dir") + var th = append.querySelectorAll("th") + for (var i = 0; i < th.length; i++) { + var value = th[i].innerText.trim() + var opt = append_child(sort_field, "option", { + "value": value, "innerText": value, + }) + } - option["dir"].value && option["dir"].value != context.Cookie("dir") && send_command(option) + (option["dir"].value = context.Search("download_dir")) && send_command(option) - var append = document.querySelector("table.append.dir") - append.onchange = - append.onclick = function(event) { + append.onchange = append.onclick = function(event) { console.log(event) - if (event.target.tagName == "A") { - if (event.target.dataset.type != "true") { - location.href = option["dir"].value+"/"+event.target.innerText - return + if (event.target.tagName == "TD") { + copy_to_clipboard(event.target.innerText.trim()) + var name = event.target.innerText.trim() + option["dir"].value += name + if (name.endsWith("/")) { + context.Cookie("download_dir", option["dir"].value) } - - option["dir"].value = option["dir"].value+"/"+event.target.innerText - send_command(option, function(msg) { - context.Cookie("download_dir", option["dir"].value = msg.dir.join("")) - }) - } else if (event.target.tagName == "TD") { - copy_to_clipboard(event.target.innerText) } else if (event.target.tagName == "TH") { - option["sort_field"].value = event.target.innerText + option["sort_field"].value = event.target.innerText.trim() - var sort_order = option["sort_order"] - switch (event.target.innerText) { + switch (event.target.innerText.trim()) { case "filename": - case "is_dir": + case "type": sort_order.value = (sort_order.value == "str")? "str_r": "str" break case "line": @@ -270,9 +304,9 @@ function init_download(event) { sort_order.value = (sort_order.value == "time")? "time_r": "time" break } - - send_command(option) } + + send_command(option) } } diff --git a/usr/librarys/context.js b/usr/librarys/context.js index 53d822ea..f4e94d14 100644 --- a/usr/librarys/context.js +++ b/usr/librarys/context.js @@ -136,13 +136,23 @@ function insert_child(parent, element, html, position) { } function append_child(parent, element, html) { var elm = document.createElement(element) - html && (elm.innerHTML = html) + html && typeof html == "string" && (elm.innerHTML = html) + if (typeof html == "object") { + for (var k in html) { + elm[k] = html[k] + } + } parent.append(elm) return elm } function insert_before(self, element, html) { var elm = document.createElement(element) - html && (elm.innerHTML = html) + html && typeof html == "string" && (elm.innerHTML = html) + if (typeof html == "object") { + for (var k in html) { + elm[k] = html[k] + } + } return self.parentElement.insertBefore(elm, self) } diff --git a/usr/template/code/code.tmpl b/usr/template/code/code.tmpl index a2cf9ffd..4ae36986 100644 --- a/usr/template/code/code.tmpl +++ b/usr/template/code/code.tmpl @@ -48,6 +48,15 @@ padding-left:10px; width:600px; } + form.option input.file_cmd { + color:white; + background-color:#272822; + padding-left:10px; + width:400px; + } + form.option input.file_name { + width:200px; + } form.option.exec input { color:white; background-color:#272822;