mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
mac add aaa.right web.render
This commit is contained in:
parent
76fc21dddf
commit
9c90712446
12
etc/init.shy
12
etc/init.shy
@ -1,14 +1,2 @@
|
||||
~aaa
|
||||
# login load var/login.txt
|
||||
~file1
|
||||
history load var/history.txt
|
||||
|
||||
source etc/local.shy
|
||||
|
||||
~shell1
|
||||
alias import nfs
|
||||
alias send send
|
||||
alias open open
|
||||
alias dial dial
|
||||
alias pwd pwd
|
||||
|
||||
|
@ -69,7 +69,9 @@ func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
return time.Unix(int64(n), 0).Format("15:03:04")
|
||||
}},
|
||||
}
|
||||
c.Configs = map[string]*ctx.Config{}
|
||||
c.Configs = map[string]*ctx.Config{
|
||||
"right": &ctx.Config{Name: "right", Value: map[string]interface{}{}, Help: "用户权限"},
|
||||
}
|
||||
|
||||
s := new(AAA)
|
||||
s.Context = c
|
||||
@ -153,6 +155,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
}
|
||||
return true
|
||||
}, c)
|
||||
|
||||
if m.Results(0) {
|
||||
return
|
||||
}
|
||||
@ -173,18 +176,26 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
}
|
||||
return true
|
||||
}, c)
|
||||
|
||||
if m.Results(0) {
|
||||
m.Append("sessid", m.Result(0))
|
||||
return
|
||||
}
|
||||
if arg[0] == "" {
|
||||
return
|
||||
}
|
||||
|
||||
m.Start(fmt.Sprintf("user%d", m.Capi("nuser", 1)), "密码登录", "password", arg[0])
|
||||
m.Cap("password", "password", aaa.Password(arg[1]), "密码登录")
|
||||
m.Append("sessid", m.Cap("sessid"))
|
||||
m.Echo(m.Cap("sessid"))
|
||||
return
|
||||
case 1:
|
||||
m.Sess("login", nil)
|
||||
m.Travel(func(m *ctx.Message, n int) bool {
|
||||
if n > 0 && m.Cap("sessid") == arg[0] {
|
||||
if int64(m.Capi("expire_time")) > time.Now().Unix() {
|
||||
m.Sess("login", m.Target().Message())
|
||||
m.Echo(m.Cap("stream"))
|
||||
} else {
|
||||
m.Target().Close(m)
|
||||
@ -205,6 +216,92 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
}
|
||||
}
|
||||
}},
|
||||
"right": &ctx.Command{Name: "right [user [check|owner|share group [order] [add|del]]]", Form: map[string]int{"from": 1}, Help: "权限管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Travel(func(m *ctx.Message, n int) bool {
|
||||
if n == 0 {
|
||||
return true
|
||||
}
|
||||
if len(arg) == 0 {
|
||||
m.Add("append", "user", m.Cap("stream"))
|
||||
m.Add("append", "right", m.Confv("right"))
|
||||
return true
|
||||
}
|
||||
if m.Cap("stream") == arg[0] {
|
||||
if len(arg) == 1 { //查看所有权
|
||||
for k, v := range m.Confv("right").(map[string]interface{}) {
|
||||
m.Add("append", "group", k)
|
||||
m.Add("append", "right", v)
|
||||
}
|
||||
return true
|
||||
}
|
||||
if arg[1] == "check" { //权限检查
|
||||
if from := m.Confv("right", []interface{}{"right", "role"}); from != nil && from.(string) == "root" {
|
||||
m.Echo("root")
|
||||
}
|
||||
if len(arg) == 2 {
|
||||
return false
|
||||
}
|
||||
if from := m.Confv("right", []interface{}{arg[2], "right", "role"}); from != nil && from.(string) == "owner" {
|
||||
m.Echo("owner")
|
||||
}
|
||||
if len(arg) == 3 {
|
||||
return false
|
||||
}
|
||||
if from := m.Confv("right", []interface{}{arg[2], arg[3], "right", "role"}); from != nil && from.(string) == "share" {
|
||||
m.Echo("share")
|
||||
}
|
||||
return false
|
||||
}
|
||||
if len(arg) == 2 { //分配人事权
|
||||
if m.Option("from") != "root" {
|
||||
return false
|
||||
}
|
||||
switch arg[1] {
|
||||
case "add":
|
||||
m.Confv("right", []interface{}{"right", "role"}, "root")
|
||||
m.Confv("right", []interface{}{"right", "from"}, m.Option("from"))
|
||||
case "del":
|
||||
m.Confv("right", []interface{}{"right", "role"}, "")
|
||||
}
|
||||
return true
|
||||
}
|
||||
if len(arg) == 3 { //查看使用权
|
||||
for k, v := range m.Confv("right", arg[2]).(map[string]interface{}) {
|
||||
m.Add("append", "order", k)
|
||||
m.Add("append", "right", v)
|
||||
}
|
||||
return true
|
||||
}
|
||||
switch arg[1] {
|
||||
case "owner": //分配所有权
|
||||
if m.Cmd("right", m.Option("from"), "check").Result(0) == "" {
|
||||
return false
|
||||
}
|
||||
switch arg[3] {
|
||||
case "add":
|
||||
m.Confv("right", []interface{}{arg[2], "right", "role"}, "owner")
|
||||
m.Confv("right", []interface{}{arg[2], "right", "from"}, m.Option("from"))
|
||||
case "del":
|
||||
m.Confv("right", []interface{}{arg[2], "right", "role"}, "")
|
||||
}
|
||||
case "share": //分配使用权
|
||||
if m.Cmd("right", m.Option("from"), "check", arg[2]).Result(0) == "" {
|
||||
return false
|
||||
}
|
||||
switch arg[4] {
|
||||
case "add":
|
||||
m.Confv("right", []interface{}{arg[2], arg[3], "right", "role"}, "share")
|
||||
m.Confv("right", []interface{}{arg[2], arg[3], "right", "from"}, m.Option("from"))
|
||||
case "del":
|
||||
m.Confv("right", []interface{}{arg[2], arg[3], "right", "role"}, "")
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}, c)
|
||||
m.Table()
|
||||
}},
|
||||
"cert": &ctx.Command{Name: "cert [filename]", Help: "导出证书", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.certificate != nil {
|
||||
certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: aaa.certificate.Raw}))
|
||||
|
@ -1,20 +1,16 @@
|
||||
package cli // {{{
|
||||
// }}}
|
||||
import ( // {{{
|
||||
"contexts/ctx"
|
||||
package cli
|
||||
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
// }}}
|
||||
|
||||
type Frame struct {
|
||||
key string
|
||||
run bool
|
||||
@ -22,7 +18,6 @@ type Frame struct {
|
||||
index int
|
||||
list []string
|
||||
}
|
||||
|
||||
type CLI struct {
|
||||
alias map[string][]string
|
||||
label map[string]string
|
||||
@ -33,7 +28,7 @@ type CLI struct {
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
||||
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: "嵌套层级"},
|
||||
"parse": &ctx.Cache{Name: "parse(true/false)", Value: "true", Help: "命令解析"},
|
||||
@ -43,15 +38,15 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
}
|
||||
c.Configs = map[string]*ctx.Config{
|
||||
"ps_time": &ctx.Config{Name: "ps_time", Value: "[15:04:05]", Help: "当前时间", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||
if len(arg) > 0 { // {{{
|
||||
if len(arg) > 0 {
|
||||
return arg[0]
|
||||
}
|
||||
return time.Now().Format(x.Value.(string))
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"ps_end": &ctx.Config{Name: "ps_end", Value: "> ", Help: "命令行提示符结尾"},
|
||||
"prompt": &ctx.Config{Name: "prompt(ps_count/ps_time/ps_target/ps_end/...)", Value: "ps_count ps_time ps_target ps_end", Help: "命令行提示符, 以空格分隔, 依次显示缓存或配置信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||
if len(arg) > 0 { // {{{
|
||||
if len(arg) > 0 {
|
||||
return arg[0]
|
||||
}
|
||||
|
||||
@ -64,7 +59,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
}
|
||||
}
|
||||
return strings.Join(ps, "")
|
||||
// }}}
|
||||
|
||||
}},
|
||||
}
|
||||
|
||||
@ -83,15 +78,11 @@ 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 { // {{{
|
||||
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
cli.Message = m
|
||||
return cli
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
|
||||
cli.Message = m
|
||||
m.Sess("cli", m)
|
||||
yac := m.Sess("yac")
|
||||
@ -178,9 +169,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||
func (cli *CLI) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch cli.Context {
|
||||
case m.Target():
|
||||
case m.Source():
|
||||
@ -188,8 +177,6 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||
return true
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
var Pulse *ctx.Message
|
||||
var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
Caches: map[string]*ctx.Cache{
|
||||
@ -199,11 +186,11 @@ 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: "启动脚本"},
|
||||
"cli_name": &ctx.Config{Name: "cli_name", Value: "shell", Help: "模块命名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||
if len(arg) > 0 { // {{{
|
||||
if len(arg) > 0 {
|
||||
return arg[0]
|
||||
}
|
||||
return fmt.Sprintf("%s%d", x.Value, m.Capi("nshell", 1))
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"cli_help": &ctx.Config{Name: "cli_help", Value: "shell", Help: "模块文档"},
|
||||
"cmd_timeout": &ctx.Config{Name: "cmd_timeout", Value: "60s", Help: "系统命令超时"},
|
||||
@ -239,28 +226,28 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
}
|
||||
}},
|
||||
"label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if cli.label == nil {
|
||||
cli.label = map[string]string{}
|
||||
}
|
||||
cli.label[arg[1]] = m.Option("file_pos")
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"goto": &ctx.Command{Name: "goto label [exp] condition", Help: "向上跳转到指定位置, label: 跳转位置, condition: 跳转条件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if pos, ok := cli.label[arg[1]]; ok {
|
||||
if !ctx.Right(arg[len(arg)-1]) {
|
||||
return
|
||||
}
|
||||
m.Append("file_pos0", pos)
|
||||
}
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Add("append", "return", arg[1:])
|
||||
}},
|
||||
"target": &ctx.Command{Name: "target module", Help: "设置当前模块, module: 模块全名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if len(arg) == 0 {
|
||||
m.Echo("%s", m.Cap("ps_target"))
|
||||
return
|
||||
@ -269,13 +256,13 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
cli.target = msg.Target()
|
||||
m.Cap("ps_target", cli.target.Name)
|
||||
}
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"alias": &ctx.Command{
|
||||
Name: "alias [short [long...]]|[delete short]|[import module [command [alias]]]",
|
||||
Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名, import导入模块所有命令",
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
for k, v := range cli.alias {
|
||||
@ -318,21 +305,21 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Log("info", "%s: %v", arg[0], cli.alias[arg[0]])
|
||||
}
|
||||
}
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"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) { // {{{
|
||||
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 [time_format format] [parse when] when [begin|end|yestoday|tommorow|monday|sunday|first|last|origin|last]",
|
||||
Form: map[string]int{"time_format": 1, "parse": 1, "time_interval": 1},
|
||||
Help: "查看时间, time_format: 输出或解析的时间格式, parse: 输入的时间字符串, when: 输入的时间戳, 其它是时间偏移",
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
t := time.Now() // {{{
|
||||
t := time.Now()
|
||||
if m.Options("parse") {
|
||||
n, e := time.ParseInLocation(m.Confx("time_format"), m.Option("parse"), time.Local)
|
||||
m.Assert(e)
|
||||
@ -341,7 +328,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
|
||||
if len(arg) > 0 {
|
||||
if i, e := strconv.ParseInt(arg[0], 10, 64); e == nil {
|
||||
m.Option("time_format", m.Conf("time_format"))
|
||||
t = time.Unix(int64(i/int64(m.Confi("time_unit"))), 0)
|
||||
arg = arg[1:]
|
||||
} else if n, e := time.ParseInLocation(m.Confx("time_format"), arg[0], time.Local); e == nil {
|
||||
@ -405,7 +391,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
} else {
|
||||
m.Echo(t.Format(m.Confx("time_format")))
|
||||
}
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"echo": &ctx.Command{Name: "echo arg...", Help: "函数调用, name: 函数名, arg: 参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Echo("%s", strings.Join(arg, ""))
|
||||
@ -415,7 +401,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Echo(arg[0][1 : len(arg[0])-1])
|
||||
}},
|
||||
"exe": &ctx.Command{Name: "exe $ ( cmd )", Help: "解析嵌套命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
switch len(arg) {
|
||||
case 1:
|
||||
m.Echo(arg[0])
|
||||
@ -438,7 +424,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
} //}}}
|
||||
}},
|
||||
"val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
result := "false" // {{{
|
||||
result := "false"
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
result = ""
|
||||
@ -567,7 +553,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
}
|
||||
}
|
||||
m.Echo(result)
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"exp": &ctx.Command{Name: "exp word", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if len(arg) > 0 && arg[0] == "{" {
|
||||
@ -585,7 +571,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
return
|
||||
}
|
||||
|
||||
pre := map[string]int{ // {{{
|
||||
pre := map[string]int{
|
||||
"=": 1,
|
||||
"+": 2, "-": 2,
|
||||
"*": 3, "/": 3, "%": 3,
|
||||
@ -609,10 +595,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
}
|
||||
|
||||
m.Echo("%s", num[0])
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 { // {{{
|
||||
if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 {
|
||||
switch arg[2] {
|
||||
case "=":
|
||||
m.Cap(arg[1], arg[3])
|
||||
@ -621,28 +607,28 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
}
|
||||
}
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式(a {+|-|*|/|%} b)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
switch arg[2] { // {{{
|
||||
switch arg[2] {
|
||||
case "=":
|
||||
m.Cap(arg[1], arg[3])
|
||||
case "<-":
|
||||
m.Cap(arg[1], m.Cap("last_msg"))
|
||||
}
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
run := m.Caps("parse") && ctx.Right(arg[1])
|
||||
cli.stack = append(cli.stack, &Frame{pos: m.Optioni("file_pos"), key: key, run: run})
|
||||
m.Capi("level", 1)
|
||||
m.Caps("parse", run)
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if !m.Caps("parse") {
|
||||
m.Caps("parse", true)
|
||||
} else {
|
||||
@ -653,10 +639,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Caps("parse", !frame.run)
|
||||
}
|
||||
}
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if frame := cli.stack[len(cli.stack)-1]; frame.key == "for" && frame.run {
|
||||
m.Append("file_pos0", frame.pos)
|
||||
return
|
||||
@ -667,13 +653,13 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
} else {
|
||||
m.Caps("parse", true)
|
||||
}
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"for": &ctx.Command{
|
||||
Name: "for [[express ;] condition]|[index message meta value]",
|
||||
Help: "循环语句, express: 每次循环运行的表达式, condition: 循环条件, index: 索引消息, message: 消息编号, meta: value: ",
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
run := m.Caps("parse")
|
||||
defer func() { m.Caps("parse", run) }()
|
||||
|
||||
@ -726,10 +712,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
}
|
||||
m.Cap(arg[3], arg[3], frame.list[0], "临时变量")
|
||||
}
|
||||
} // }}}
|
||||
}
|
||||
}},
|
||||
"cmd": &ctx.Command{Name: "cmd word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
detail := []string{}
|
||||
if a, ok := cli.alias[arg[0]]; ok {
|
||||
detail = append(detail, a...)
|
||||
@ -774,14 +760,14 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Capi("last_msg", 0, msg.Code())
|
||||
m.Capi("ps_count", 1)
|
||||
}
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"system": &ctx.Command{
|
||||
Name: "system [cmd_combine true|false] [cmd_timeout time] word...",
|
||||
Help: "调用系统命令, cmd_combine: 非交互式命令, cmd_timeout: 命令超时, word: 命令",
|
||||
Form: map[string]int{"cmd_combine": 1, "cmd_timeout": 1},
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
system := map[string]bool{"vi": true} // {{{
|
||||
system := map[string]bool{"vi": true}
|
||||
ui, ok := system[arg[0]]
|
||||
if ui = ok && ui; m.Option("cmd_combine") != "" {
|
||||
ui = !m.Options("cmd_combine")
|
||||
@ -816,7 +802,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
case <-wait:
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
}},
|
||||
"login": &ctx.Command{Name: "login username password", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Sess("aaa", false).Cmd("login", arg[0], arg[1])
|
||||
@ -827,6 +813,27 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
"tmux": &ctx.Command{Name: "tmux", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Copy(m.Spawn().Cmd("system", "tmux", arg), "result")
|
||||
}},
|
||||
"buffer": &ctx.Command{Name: "buffer", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
bufs := strings.Split(m.Spawn().Cmd("system", "tmux", "list-buffers").Result(0), "\n")
|
||||
|
||||
n := 3
|
||||
if m.Option("limit") != "" {
|
||||
n = m.Optioni("limit")
|
||||
}
|
||||
|
||||
for i, b := range bufs {
|
||||
if i >= n {
|
||||
break
|
||||
}
|
||||
bs := strings.SplitN(b, ": ", 3)
|
||||
if len(bs) > 1 {
|
||||
m.Add("append", "buffer", bs[0][:len(bs[0])])
|
||||
m.Add("append", "length", bs[1][:len(bs[1])-6])
|
||||
m.Add("append", "string", bs[2][1:len(bs[2])-1])
|
||||
}
|
||||
}
|
||||
m.Echo(m.Append("string"))
|
||||
}},
|
||||
},
|
||||
Index: map[string]*ctx.Context{
|
||||
"void": &ctx.Context{Caches: map[string]*ctx.Cache{"nshell": &ctx.Cache{}}},
|
||||
|
@ -709,7 +709,14 @@ func (m *Message) Search(key string, root ...bool) []*Message {
|
||||
}
|
||||
func (m *Message) Sess(key string, arg ...interface{}) *Message {
|
||||
spawn := true
|
||||
if _, ok := m.Sessions[key]; !ok && len(arg) > 0 {
|
||||
if len(arg) > 0 {
|
||||
switch v := arg[0].(type) {
|
||||
case bool:
|
||||
spawn, arg = v, arg[1:]
|
||||
}
|
||||
}
|
||||
|
||||
if len(arg) > 0 {
|
||||
if m.Sessions == nil {
|
||||
m.Sessions = make(map[string]*Message)
|
||||
}
|
||||
@ -747,13 +754,9 @@ func (m *Message) Sess(key string, arg ...interface{}) *Message {
|
||||
m.Sessions[key] = m.Search(value, root)[0]
|
||||
}
|
||||
return m.Sessions[key]
|
||||
}
|
||||
}
|
||||
|
||||
if len(arg) > 0 {
|
||||
switch v := arg[0].(type) {
|
||||
case bool:
|
||||
spawn = v
|
||||
case nil:
|
||||
m.Sessions[key] = nil
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -1077,6 +1080,14 @@ func (m *Message) Sort(key string, arg ...string) *Message {
|
||||
for j := i + 1; j < len(table); j++ {
|
||||
result := false
|
||||
switch cmp {
|
||||
case "str":
|
||||
if table[i][key] > table[j][key] {
|
||||
result = true
|
||||
}
|
||||
case "str_r":
|
||||
if table[i][key] < table[j][key] {
|
||||
result = true
|
||||
}
|
||||
case "int":
|
||||
a, e := strconv.Atoi(table[i][key])
|
||||
m.Assert(e)
|
||||
@ -1093,14 +1104,6 @@ func (m *Message) Sort(key string, arg ...string) *Message {
|
||||
if a < b {
|
||||
result = true
|
||||
}
|
||||
case "string":
|
||||
if table[i][key] > table[j][key] {
|
||||
result = true
|
||||
}
|
||||
case "string_r":
|
||||
if table[i][key] < table[j][key] {
|
||||
result = true
|
||||
}
|
||||
case "time":
|
||||
ti, e := time.ParseInLocation(m.Confx("time_layout"), table[i][key], time.Local)
|
||||
m.Assert(e)
|
||||
@ -1964,16 +1967,18 @@ var CGI = template.FuncMap{
|
||||
m.Assert(e)
|
||||
index = i
|
||||
}
|
||||
|
||||
if len(arg) == 2 {
|
||||
return m.Detail(index)
|
||||
}
|
||||
|
||||
return m.Detail(index, arg[2])
|
||||
case map[string][]string:
|
||||
return strings.Join(m["detail"], "")
|
||||
case []string:
|
||||
return strings.Join(m, "")
|
||||
default:
|
||||
return fmt.Sprintf("%v", arg[0])
|
||||
return m
|
||||
}
|
||||
return ""
|
||||
},
|
||||
@ -2016,7 +2021,7 @@ var CGI = template.FuncMap{
|
||||
case []string:
|
||||
return strings.Join(m, "")
|
||||
default:
|
||||
return fmt.Sprintf("%v", arg[0])
|
||||
return m
|
||||
}
|
||||
return ""
|
||||
},
|
||||
@ -2040,16 +2045,18 @@ var CGI = template.FuncMap{
|
||||
m.Assert(e)
|
||||
index = i
|
||||
}
|
||||
|
||||
if len(arg) == 2 {
|
||||
return m.Result(index)
|
||||
}
|
||||
|
||||
return m.Result(index, arg[2])
|
||||
case map[string][]string:
|
||||
return strings.Join(m["result"], "")
|
||||
case []string:
|
||||
return strings.Join(m, "")
|
||||
default:
|
||||
return fmt.Sprintf("%v", arg[0])
|
||||
return m
|
||||
}
|
||||
return ""
|
||||
},
|
||||
@ -2092,11 +2099,55 @@ var CGI = template.FuncMap{
|
||||
case []string:
|
||||
return strings.Join(m, "")
|
||||
default:
|
||||
return fmt.Sprintf("%v", arg[0])
|
||||
return m
|
||||
}
|
||||
return ""
|
||||
},
|
||||
"unscaped": func(str string) interface{} {
|
||||
"table": func(arg ...interface{}) []interface{} {
|
||||
if len(arg) == 0 {
|
||||
return []interface{}{}
|
||||
}
|
||||
|
||||
switch m := arg[0].(type) {
|
||||
case *Message:
|
||||
if len(m.Meta["append"]) == 0 {
|
||||
return []interface{}{}
|
||||
}
|
||||
if len(arg) == 1 {
|
||||
data := []interface{}{}
|
||||
nrow := len(m.Meta[m.Meta["append"][0]])
|
||||
for i := 0; i < nrow; i++ {
|
||||
line := map[string]string{}
|
||||
for _, k := range m.Meta["append"] {
|
||||
line[k] = m.Meta[k][i]
|
||||
if len(m.Meta[k]) != i {
|
||||
continue
|
||||
}
|
||||
}
|
||||
data = append(data, line)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
case map[string][]string:
|
||||
if len(arg) == 1 {
|
||||
data := []interface{}{}
|
||||
nrow := len(m[m["append"][0]])
|
||||
|
||||
for i := 0; i < nrow; i++ {
|
||||
line := map[string]string{}
|
||||
for _, k := range m["append"] {
|
||||
line[k] = m[k][i]
|
||||
}
|
||||
data = append(data, line)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
return []interface{}{}
|
||||
},
|
||||
"unescape": func(str string) interface{} {
|
||||
return template.HTML(str)
|
||||
},
|
||||
|
||||
@ -2978,7 +3029,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
"where_field": 1, "where_value": 1,
|
||||
"sort_field": 1, "sort_order": 1,
|
||||
"page_limit": 1, "page_offset": 1,
|
||||
"select": 3,
|
||||
"format_field": 2,
|
||||
"select": 3,
|
||||
},
|
||||
Hand: func(m *Message, c *Context, key string, arg ...string) {
|
||||
offset, e := strconv.Atoi(m.Confx("page_offset"))
|
||||
@ -3022,6 +3074,12 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
de.Decode(&save)
|
||||
}
|
||||
|
||||
format_field := m.Option("format_field")
|
||||
format_str := "%s"
|
||||
if format_field != "" {
|
||||
format_str = m.Meta["format_field"][1]
|
||||
}
|
||||
|
||||
// sort_field := m.Option("sort_field")
|
||||
// sort_order := m.Option("sort_order")
|
||||
m.BackTrace(func(m *Message) bool {
|
||||
@ -3113,7 +3171,11 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
m.Add("append", "index", "0")
|
||||
for k, v := range val {
|
||||
if len(fields) == 0 || fields[k] {
|
||||
m.Add("append", k, v)
|
||||
if k == format_field {
|
||||
m.Add("append", k, fmt.Sprintf(format_str, v))
|
||||
} else {
|
||||
m.Add("append", k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
case []interface{}:
|
||||
@ -3134,7 +3196,11 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
m.Add("append", "index", i)
|
||||
for k, v := range val {
|
||||
if len(fields) == 0 || fields[k] {
|
||||
m.Add("append", k, v)
|
||||
if k == format_field {
|
||||
m.Add("append", k, fmt.Sprintf(format_str, v, v))
|
||||
} else {
|
||||
m.Add("append", k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3142,11 +3208,18 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
case []string:
|
||||
for i, v := range val {
|
||||
m.Add("append", "index", i)
|
||||
m.Add("append", "value", v)
|
||||
if k == format_field {
|
||||
m.Add("append", k, fmt.Sprintf(format_str, v, v))
|
||||
} else {
|
||||
m.Add("append", k, v)
|
||||
}
|
||||
}
|
||||
default:
|
||||
m.Echo("%v", Trans(val)[0])
|
||||
}
|
||||
case 3:
|
||||
m.Echo("%v", m.Confv(arg[0], strings.Split(arg[1], "."), arg[2]))
|
||||
|
||||
default:
|
||||
m.Echo("%v", m.Confv(arg[0], arg[1:]))
|
||||
return false
|
||||
|
@ -68,8 +68,8 @@ func dir(m *ctx.Message, name string, level int, deep bool, fields []string) {
|
||||
switch k {
|
||||
case "filename":
|
||||
m.Add("append", "filename", "..")
|
||||
case "dir":
|
||||
m.Add("append", "dir", "true")
|
||||
case "is_dir":
|
||||
m.Add("append", "is_dir", "true")
|
||||
case "size":
|
||||
m.Add("append", "size", 0)
|
||||
case "line":
|
||||
@ -130,8 +130,8 @@ func dir(m *ctx.Message, name string, level int, deep bool, fields []string) {
|
||||
switch k {
|
||||
case "filename":
|
||||
m.Add("append", "filename", filename)
|
||||
case "dir":
|
||||
m.Add("append", "dir", f.IsDir())
|
||||
case "is_dir":
|
||||
m.Add("append", "is_dir", f.IsDir())
|
||||
case "size":
|
||||
m.Add("append", "size", f.Size())
|
||||
case "line":
|
||||
@ -803,11 +803,12 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
"buf_size": &ctx.Config{Name: "buf_size", Value: "1024", Help: "读取文件的缓存区的大小"},
|
||||
"qr_size": &ctx.Config{Name: "qr_size", Value: "256", Help: "生成二维码的图片的大小"},
|
||||
|
||||
"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: 输出统计信息, 否则输出"},
|
||||
"dir_root": &ctx.Config{Name: "dir_root", Value: "usr", Help: "dir命令输出目录的统计信息, info: 输出统计信息, 否则输出"},
|
||||
"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 line size time", Help: "表格排序字段"},
|
||||
"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: 输出统计信息, 否则输出"},
|
||||
"dir_field": &ctx.Config{Name: "dir_field", Value: "filename is_dir line size time", Help: "表格排序字段"},
|
||||
"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: "表格排序类型"},
|
||||
|
||||
@ -1078,13 +1079,16 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
if len(arg) == 1 {
|
||||
var data interface{}
|
||||
e := json.Unmarshal([]byte(arg[0]), &data)
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
m.Assert(e)
|
||||
|
||||
buf, e := json.MarshalIndent(data, "", " ")
|
||||
m.Assert(e)
|
||||
m.Echo("'")
|
||||
// m.Echo("'")
|
||||
m.Echo(string(buf))
|
||||
m.Echo("'")
|
||||
// m.Echo("'")
|
||||
return
|
||||
}
|
||||
|
||||
@ -1122,10 +1126,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
"pwd": &ctx.Command{Name: "pwd", Help: "查看当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if m.Options("dir") {
|
||||
m.Echo(m.Option("dir"))
|
||||
m.Add("append", "hi", "hello")
|
||||
m.Add("append", "he", "hello")
|
||||
m.Add("append", "hi", "world")
|
||||
m.Add("append", "he", "world")
|
||||
return
|
||||
}
|
||||
if len(arg) > 0 {
|
||||
@ -1134,20 +1134,31 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
wd, e := os.Getwd()
|
||||
m.Assert(e)
|
||||
m.Echo(wd)
|
||||
m.Append("hi", "hello")
|
||||
}},
|
||||
"dir": &ctx.Command{
|
||||
Name: "dir dir [dir_deep yes|no] [dir_info info] [dir_name name|tree|path|full] [dir_type file|dir] [sort_field name] [sort_order type]",
|
||||
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_field": 1, "dir_deep": 1, "dir_info": 1, "dir_name": 1, "dir_type": 1, "sort_field": 1, "sort_order": 1},
|
||||
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,
|
||||
},
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
d := "./" + m.Option("dir")
|
||||
if len(arg) > 0 {
|
||||
d = arg[0]
|
||||
m.Option("dir", arg[0])
|
||||
}
|
||||
m.Option("dir", path.Clean(m.Option("dir")))
|
||||
d := path.Join(m.Confx("dir_root"), m.Option("dir"))
|
||||
if s, e := os.Stat(d); m.Assert(e) && !s.IsDir() {
|
||||
d = path.Dir(d)
|
||||
}
|
||||
|
||||
fields := strings.Split(m.Confx("dir_field"), " ")
|
||||
|
||||
trip := 0
|
||||
@ -1170,22 +1181,30 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
key := m.Meta["append"][i]
|
||||
switch key {
|
||||
case "filename":
|
||||
v = maps[key]
|
||||
if line > -1 && trip > 0 && trip <= len(v) {
|
||||
v = v[trip:]
|
||||
m.Meta["filename"][line] = v
|
||||
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)
|
||||
}
|
||||
}
|
||||
case "dir":
|
||||
continue
|
||||
}
|
||||
m.Echo("%s\t", v)
|
||||
}
|
||||
m.Echo("\n")
|
||||
return true
|
||||
})
|
||||
if !m.Options("dir_link") {
|
||||
m.Table()
|
||||
}
|
||||
for _, v := range info {
|
||||
m.Echo("%s: %s\n", v, m.Option(v))
|
||||
}
|
||||
|
||||
}},
|
||||
"git": &ctx.Command{
|
||||
Name: "git branch|status|diff|log|info arg... [dir path]...",
|
||||
|
@ -27,8 +27,8 @@ type MUX interface {
|
||||
type WEB struct {
|
||||
*http.Client
|
||||
*http.ServeMux
|
||||
*http.Server
|
||||
*template.Template
|
||||
server *http.Server
|
||||
template *template.Template
|
||||
|
||||
*ctx.Context
|
||||
}
|
||||
@ -80,7 +80,9 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) {
|
||||
m.TryCatch(m.Spawn(), true, func(msg *ctx.Message) {
|
||||
msg.Add("option", "method", r.Method).Add("option", "path", r.URL.Path)
|
||||
|
||||
msg.Option("remote_addr", r.RemoteAddr)
|
||||
msg.Option("referer", r.Header.Get("Referer"))
|
||||
msg.Option("accept", r.Header.Get("Accept"))
|
||||
|
||||
if r.ParseForm(); len(r.PostForm) > 0 {
|
||||
for k, v := range r.PostForm {
|
||||
@ -101,11 +103,11 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) {
|
||||
|
||||
switch {
|
||||
case msg.Has("redirect"):
|
||||
http.Redirect(w, r, msg.Append("redirect"), http.StatusFound)
|
||||
http.Redirect(w, r, msg.Append("redirect"), http.StatusTemporaryRedirect)
|
||||
case msg.Has("directory"):
|
||||
http.ServeFile(w, r, msg.Append("directory"))
|
||||
case msg.Has("template"):
|
||||
msg.Spawn().Cmd("/render", msg.Meta["template"])
|
||||
case msg.Has("componet"):
|
||||
msg.Spawn().Add("option", "componet_group", msg.Meta["componet"]).Cmd("/render")
|
||||
case msg.Has("append"):
|
||||
meta := map[string]interface{}{}
|
||||
if len(msg.Meta["result"]) > 0 {
|
||||
@ -208,16 +210,16 @@ func (web *WEB) Start(m *ctx.Message, arg ...string) bool {
|
||||
web.Caches["protocol"] = &ctx.Cache{Name: "protocol", Value: m.Confx("protocol", arg, 2), Help: "服务协议"}
|
||||
web.Caches["address"] = &ctx.Cache{Name: "address", Value: m.Confx("address", arg, 1), Help: "服务地址"}
|
||||
m.Log("info", "%d %s://%s", m.Capi("nserve", 1), m.Cap("protocol"), m.Cap("stream", m.Cap("address")))
|
||||
web.Server = &http.Server{Addr: m.Cap("address"), Handler: web}
|
||||
web.server = &http.Server{Addr: m.Cap("address"), Handler: web}
|
||||
|
||||
if m.Caps("master", true); m.Cap("protocol") == "https" {
|
||||
web.Caches["cert"] = &ctx.Cache{Name: "cert", Value: m.Confx("cert", arg, 3), Help: "服务证书"}
|
||||
web.Caches["key"] = &ctx.Cache{Name: "key", Value: m.Confx("key", arg, 4), Help: "服务密钥"}
|
||||
m.Log("info", "cert [%s]", m.Cap("cert"))
|
||||
m.Log("info", "key [%s]", m.Cap("key"))
|
||||
web.Server.ListenAndServeTLS(m.Cap("cert"), m.Cap("key"))
|
||||
web.server.ListenAndServeTLS(m.Cap("cert"), m.Cap("key"))
|
||||
} else {
|
||||
web.Server.ListenAndServe()
|
||||
web.server.ListenAndServe()
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -244,16 +246,192 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
"cert": &ctx.Config{Name: "cert", Value: "etc/cert.pem", Help: "路由数量"},
|
||||
"key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "路由数量"},
|
||||
|
||||
"template_dir": &ctx.Config{Name: "template_dir", Value: "usr/template", Help: "路由数量"},
|
||||
"template_file": &ctx.Config{Name: "template_file", Value: "usr/template", Help: "路由数量"},
|
||||
"template": &ctx.Config{Name: "template", Value: map[string]interface{}{
|
||||
"index": []interface{}{
|
||||
"web_site": &ctx.Config{Name: "web_site", Value: []interface{}{
|
||||
map[string]interface{}{"_name": "MDN", "site": "https://developer.mozilla.org"},
|
||||
map[string]interface{}{"_name": "github", "site": "https://github.com"},
|
||||
}, Help: "web_site"},
|
||||
"template_dir": &ctx.Config{Name: "template_dir", Value: "usr/template", Help: "模板路径"},
|
||||
|
||||
"componet_context": &ctx.Config{Name: "component_context", Value: "nfs", Help: "默认模块"},
|
||||
"componet_command": &ctx.Config{Name: "component_command", Value: "pwd", Help: "默认命令"},
|
||||
"componet_group": &ctx.Config{Name: "component_group", Value: "index", Help: "默认组件"},
|
||||
"componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
|
||||
"login": []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "message", "title": "message",
|
||||
"context": "nfs", "command": "pwd",
|
||||
"template": "head", "name": "head", "help": "head",
|
||||
"context": "", "command": "", "arguments": []interface{}{},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "componet", "name": "login", "help": "login",
|
||||
"context": "aaa", "command": "login", "arguments": []interface{}{"@username", "@password"},
|
||||
"inputs": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "text", "name": "username",
|
||||
"label": "username", "value": "",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"type": "password", "name": "password",
|
||||
"label": "password", "value": "",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"type": "button", "name": "string",
|
||||
"label": "string", "value": "login",
|
||||
},
|
||||
},
|
||||
"display_append": "",
|
||||
"display_result": "",
|
||||
"result_reload": "10",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "tail", "name": "tail", "help": "tail",
|
||||
"context": "", "command": "", "arguments": []interface{}{},
|
||||
},
|
||||
},
|
||||
}, Help: "路由数量"},
|
||||
"index": []interface{}{
|
||||
map[string]interface{}{
|
||||
"template": "head", "name": "head", "help": "head",
|
||||
"context": "", "command": "", "arguments": []interface{}{},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "clipboard", "name": "clipbaord", "help": "clipbaord",
|
||||
"context": "", "command": "", "arguments": []interface{}{},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "componet", "name": "message", "help": "message",
|
||||
"context": "cli", "command": "buffer", "arguments": []interface{}{},
|
||||
"inputs": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "text", "name": "limit",
|
||||
"label": "limit", "value": "3",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"type": "button", "name": "string",
|
||||
"label": "string", "value": "refresh",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "componet", "name": "time", "help": "time",
|
||||
"context": "cli", "command": "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", "value": "",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"type": "button", "name": "button",
|
||||
"label": "string", "value": "refresh",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "componet", "name": "json", "help": "json",
|
||||
"context": "nfs", "command": "json",
|
||||
"arguments": []interface{}{"@string"},
|
||||
"inputs": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "text", "name": "string",
|
||||
"label": "string", "value": "",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"type": "button", "name": "button",
|
||||
"label": "string", "value": "refresh",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "componet", "name": "dir", "help": "dir",
|
||||
"context": "nfs", "command": "dir",
|
||||
"arguments": []interface{}{"@dir",
|
||||
"dir_deep", "no",
|
||||
"dir_name", "name",
|
||||
"dir_link", "<a class='download' data-type='%s'>%s<a>",
|
||||
"dir_info", "",
|
||||
},
|
||||
"inputs": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "text", "name": "dir",
|
||||
"label": "dir", "value": "",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"type": "choice", "name": "dir_type",
|
||||
"label": "dir_type", "value": "both",
|
||||
"choice": []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "both", "value": "both",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "file", "value": "file",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "dir", "value": "dir",
|
||||
},
|
||||
},
|
||||
},
|
||||
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": "line", "value": "line",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "size", "value": "size",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "time", "value": "time",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"type": "choice", "name": "sort_order",
|
||||
"label": "sort_order", "value": "time",
|
||||
"choice": []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "str", "value": "str",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "str_r", "value": "str_r",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "int", "value": "int",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "int_r", "value": "int_r",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "time", "value": "time",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "time_r", "value": "time_r",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "componet", "name": "web_site", "help": "web_site",
|
||||
"context": "web", "command": "config",
|
||||
"arguments": []interface{}{
|
||||
"web_site",
|
||||
"format_field", "site", "<a href='%s'>%s<a>",
|
||||
},
|
||||
"display_result": "",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"template": "tail", "name": "tail", "help": "tail",
|
||||
"context": "", "command": "", "arguments": []interface{}{},
|
||||
},
|
||||
},
|
||||
}, Help: "组件列表"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"client": &ctx.Command{Name: "client address [output [editor]]", Help: "添加浏览器配置, address: 默认地址, output: 输出路径, editor: 编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
@ -517,55 +695,248 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
}
|
||||
}
|
||||
}},
|
||||
"/demo": &ctx.Command{Name: "/demo template", Help: "渲染模板, template: 模板名称", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Append("template", "index")
|
||||
}},
|
||||
"template": &ctx.Command{Name: "template [file directory]|[name content]", Help: "添加模块, content: 模板内容, directory: 模板目录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"template": &ctx.Command{Name: "template [file [directory]]|[name [content]]", Help: "添加模板, content: 模板内容, directory: 模板目录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
|
||||
if len(arg) == 0 {
|
||||
for _, v := range web.Template.Templates() {
|
||||
for _, v := range web.template.Templates() {
|
||||
m.Add("append", "name", v.Name())
|
||||
}
|
||||
m.Sort("name").Table()
|
||||
return
|
||||
}
|
||||
|
||||
if web.Template == nil {
|
||||
web.Template = template.New("render").Funcs(ctx.CGI)
|
||||
if web.template == nil {
|
||||
web.template = template.New("render").Funcs(ctx.CGI)
|
||||
}
|
||||
|
||||
dir := path.Join(m.Confx("template_dir", arg, 1), arg[0])
|
||||
if t, e := web.Template.ParseGlob(dir); e == nil {
|
||||
web.Template = t
|
||||
if t, e := web.template.ParseGlob(dir); e == nil {
|
||||
web.template = t
|
||||
} else {
|
||||
m.Log("info", "%s", e)
|
||||
if len(arg) > 1 {
|
||||
web.Template = template.Must(web.Template.New(arg[0]).Parse(arg[1]))
|
||||
web.template = template.Must(web.template.New(arg[0]).Parse(arg[1]))
|
||||
} else {
|
||||
buf := bytes.NewBuffer(make([]byte, 1024))
|
||||
tmpl, e := web.Template.Clone()
|
||||
tmpl, e := web.template.Clone()
|
||||
m.Assert(e)
|
||||
tmpl.Funcs(ctx.CGI)
|
||||
|
||||
buf := bytes.NewBuffer(make([]byte, 1024))
|
||||
tmpl.ExecuteTemplate(buf, arg[0], m)
|
||||
m.Echo(string(buf.Bytes()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
"/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) {
|
||||
w := m.Optionv("response").(http.ResponseWriter)
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
tmpl, e := web.Template.Clone()
|
||||
m.Assert(e)
|
||||
|
||||
for _, v := range m.Confv("template", arg[0]).([]interface{}) {
|
||||
//执行命令
|
||||
val := v.(map[string]interface{})
|
||||
if _, ok := val["command"]; ok {
|
||||
msg := m.Find(val["context"].(string)).Cmd(val["command"], val["argument"])
|
||||
msg.Option("title", val["title"])
|
||||
m.Assert(tmpl.ExecuteTemplate(w, val["name"].(string), msg))
|
||||
"componet": &ctx.Command{Name: "componet [group [order [arg...]]]", Help: "添加组件, group: 组件分组, arg...: 组件参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
for k, v := range m.Confv("componet").(map[string]interface{}) {
|
||||
for i, val := range v.([]interface{}) {
|
||||
value := val.(map[string]interface{})
|
||||
m.Add("append", "group", k)
|
||||
m.Add("append", "order", i)
|
||||
m.Add("append", "name", value["name"])
|
||||
m.Add("append", "help", value["help"])
|
||||
m.Add("append", "context", value["context"])
|
||||
m.Add("append", "command", value["command"])
|
||||
}
|
||||
}
|
||||
m.Sort("group").Table()
|
||||
case 1:
|
||||
for i, val := range m.Confv("componet", arg[0]).([]interface{}) {
|
||||
value := val.(map[string]interface{})
|
||||
m.Add("append", "order", i)
|
||||
m.Add("append", "name", value["name"])
|
||||
m.Add("append", "help", value["help"])
|
||||
m.Add("append", "context", value["context"])
|
||||
m.Add("append", "command", value["command"])
|
||||
}
|
||||
m.Table()
|
||||
case 2:
|
||||
value := m.Confv("componet", []interface{}{arg[0], arg[1]}).(map[string]interface{})
|
||||
for k, v := range value {
|
||||
m.Add("append", k, v)
|
||||
}
|
||||
m.Table()
|
||||
default:
|
||||
if com, ok := m.Confv("componet", []interface{}{arg[0], arg[1]}).(map[string]interface{}); ok {
|
||||
for i := 2; i < len(arg)-1; i += 2 {
|
||||
com[arg[i]] = arg[i+1]
|
||||
}
|
||||
} else {
|
||||
m.Confv("componet", []interface{}{arg[0], arg[1]}, map[string]interface{}{
|
||||
"name": arg[2], "help": arg[3],
|
||||
"context": m.Confx("componet_context", arg, 4),
|
||||
"command": m.Confx("componet_command", arg, 5),
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}},
|
||||
"session": &ctx.Command{Name: "session", Help: "用户登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
sessid := m.Option("sessid")
|
||||
if sessid == "" && m.Options("username") && m.Options("password") {
|
||||
sessid = m.Sess("aaa").Cmd("login", m.Option("username"), m.Option("password")).Result(0)
|
||||
}
|
||||
if sessid == "" && m.Options("remote_addr") {
|
||||
sessid = m.Sess("aaa").Cmd("login", "ip", m.Option("remote_addr")).Result(0)
|
||||
}
|
||||
|
||||
login := m.Sess("aaa").Cmd("login", sessid).Sess("login", false)
|
||||
m.Appendv("login", login)
|
||||
m.Echo(sessid)
|
||||
}},
|
||||
"/render": &ctx.Command{Name: "/render template", Help: "渲染模板, template: 模板名称", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Target().Server.(*WEB); m.Assert(ok) {
|
||||
accept_json := strings.HasPrefix(m.Option("accept"), "application/json")
|
||||
list := []interface{}{}
|
||||
|
||||
// tmpl, e := web.template.Clone()
|
||||
// m.Assert(e)
|
||||
// tmpl.Funcs(ctx.CGI)
|
||||
//
|
||||
|
||||
tmpl := template.New("render").Funcs(ctx.CGI)
|
||||
tmpl.ParseGlob("/Users/shaoying/context/usr/template/common/base.tmpl")
|
||||
|
||||
w := m.Optionv("response").(http.ResponseWriter)
|
||||
if accept_json {
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
} else {
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
}
|
||||
|
||||
if m.Option("componet_group") == "" {
|
||||
m.Option("componet_group", m.Conf("componet_group"))
|
||||
}
|
||||
group := m.Option("componet_group")
|
||||
|
||||
right := false
|
||||
if group == "login" {
|
||||
right = true
|
||||
}
|
||||
|
||||
login := m
|
||||
login = nil
|
||||
|
||||
for count := 0; count == 0; {
|
||||
order := -1
|
||||
if m.Option("componet_order") != "" {
|
||||
order = m.Optioni("componet_order")
|
||||
}
|
||||
|
||||
if !right {
|
||||
login = m.Spawn().Cmd("session").Appendv("login").(*ctx.Message)
|
||||
}
|
||||
if !right && login != nil {
|
||||
if role := login.Confv("right", []interface{}{"right", "role"}); role != nil && role.(string) == "root" {
|
||||
right = true
|
||||
}
|
||||
}
|
||||
if !right && login != nil {
|
||||
if role := login.Confv("right", []interface{}{group, "right", "role"}); role != nil && role.(string) == "owner" {
|
||||
right = true
|
||||
}
|
||||
}
|
||||
|
||||
for i, v := range m.Confv("componet", group).([]interface{}) {
|
||||
if order != -1 && i != order {
|
||||
continue
|
||||
}
|
||||
|
||||
val := v.(map[string]interface{})
|
||||
|
||||
order_right := right
|
||||
if !order_right && login != nil {
|
||||
if role := login.Confv("right", []interface{}{group, val["name"], "right", "role"}); role != nil && role.(string) == "share" {
|
||||
order_right = true
|
||||
}
|
||||
}
|
||||
if !order_right {
|
||||
continue
|
||||
}
|
||||
|
||||
msg := m.Find(val["context"].(string))
|
||||
if msg == nil {
|
||||
if !accept_json {
|
||||
m.Assert(tmpl.ExecuteTemplate(w, val["template"].(string), m))
|
||||
}
|
||||
continue
|
||||
}
|
||||
count++
|
||||
|
||||
msg.Option("componet_order", i)
|
||||
|
||||
for k, v := range val {
|
||||
if msg.Option(k) != "" {
|
||||
continue
|
||||
}
|
||||
switch value := v.(type) {
|
||||
case []string:
|
||||
msg.Add("option", k, value)
|
||||
case string:
|
||||
msg.Add("option", k, value)
|
||||
default:
|
||||
msg.Put("option", k, value)
|
||||
}
|
||||
}
|
||||
|
||||
args := []string{}
|
||||
if val["arguments"] != nil {
|
||||
for _, v := range val["arguments"].([]interface{}) {
|
||||
switch value := v.(type) {
|
||||
case string:
|
||||
if len(value) > 1 && value[0] == '$' {
|
||||
args = append(args, msg.Cap(value[1:]))
|
||||
} else if len(value) > 1 && value[0] == '@' {
|
||||
args = append(args, msg.Confx(value[1:]))
|
||||
} else {
|
||||
args = append(args, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if val["inputs"] != nil {
|
||||
for _, v := range val["inputs"].([]interface{}) {
|
||||
value := v.(map[string]interface{})
|
||||
if msg.Option(value["name"].(string)) == "" {
|
||||
msg.Add("option", value["name"].(string), value["value"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if msg.Cmd(val["command"], args); accept_json {
|
||||
list = append(list, msg.Meta)
|
||||
} else {
|
||||
m.Assert(tmpl.ExecuteTemplate(w, val["template"].(string), msg))
|
||||
}
|
||||
|
||||
if msg.Appends("sessid") {
|
||||
http.SetCookie(w, &http.Cookie{Name: "sessid", Value: msg.Append("sessid")})
|
||||
m.Append("page_redirect", fmt.Sprintf("/render?componet_group=%s&componet_order=%s",
|
||||
m.Option("componet_group", m.Option("last_componet_group")),
|
||||
m.Option("componet_order", m.Option("last_componet_order"))))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
m.Option("last_componet_group", m.Option("componet_group"))
|
||||
m.Option("last_componet_order", m.Option("componet_order"))
|
||||
m.Option("componet_group", "login")
|
||||
m.Option("componet_order", "-1")
|
||||
group = m.Option("componet_group")
|
||||
order = -1
|
||||
right = true
|
||||
}
|
||||
}
|
||||
|
||||
if accept_json {
|
||||
en := json.NewEncoder(w)
|
||||
en.SetIndent("", " ")
|
||||
en.Encode(list)
|
||||
}
|
||||
}
|
||||
}},
|
||||
},
|
||||
|
@ -1,59 +1,194 @@
|
||||
|
||||
function update(event, module, details, key) {
|
||||
if (event) {
|
||||
window[key+"timer"] = !window[key+"timer"];
|
||||
}
|
||||
if (!window[key+"timer"]) {
|
||||
return
|
||||
}
|
||||
console.log("update "+key)
|
||||
setTimeout(function() {
|
||||
action(event, module, details, key);
|
||||
update(null, module, details, key);
|
||||
}, refresh_time);
|
||||
function insert_child(parent, element, html, position) {
|
||||
var elm = document.createElement(element)
|
||||
html && (elm.innerHTML = html)
|
||||
return parent.insertBefore(elm, position || parent.firstElementChild)
|
||||
}
|
||||
function append_child(parent, element, html) {
|
||||
var elm = document.createElement(element)
|
||||
html && (elm.innerHTML = html)
|
||||
parent.append(elm)
|
||||
return elm
|
||||
}
|
||||
function insert_before(self, element, html) {
|
||||
var elm = document.createElement(element)
|
||||
html && (elm.innerHTML = html)
|
||||
return self.parentElement.insertBefore(elm, self)
|
||||
}
|
||||
|
||||
function input(event, module, details, key) {
|
||||
if (event.code == "Enter") {
|
||||
action(event, module, details, key);
|
||||
}
|
||||
function copy_to_clipboard(text) {
|
||||
var clipboard = document.querySelector("#clipboard")
|
||||
clipboard.value = text
|
||||
clipboard.select()
|
||||
document.execCommand("copy")
|
||||
clipboard.blur()
|
||||
|
||||
var clipstack = document.querySelector("#clipstack")
|
||||
insert_child(clipstack, "option").value = clipboard.value
|
||||
clipstack.childElementCount > 3 && clipstack.removeChild(clipstack.lastElementChild)
|
||||
}
|
||||
function action(event, module, details, key) {
|
||||
var input = document.getElementsByClassName(key+"_input");
|
||||
for (var i = 0; i < input.length; i++ ){
|
||||
if (input[i].value != "") {
|
||||
details.push(input[i].value)
|
||||
}
|
||||
}
|
||||
ctx.POST("", {module:module, details:details}, function(msg) {
|
||||
if (msg && msg.result) {
|
||||
var result = document.getElementsByClassName(key+"_result")[0];
|
||||
result.innerHTML = msg.result;
|
||||
}
|
||||
if (!msg || !msg.append || msg.append.length < 1) {
|
||||
return
|
||||
}
|
||||
function send_command(form, cb) {
|
||||
var data = {}
|
||||
for (var key in form.dataset) {
|
||||
data[key] = form.dataset[key]
|
||||
}
|
||||
for (var i = 0; i < form.length; i++) {
|
||||
data[form[i].name] = form[i].value
|
||||
}
|
||||
|
||||
var append = document.getElementsByClassName(key+"_append")[0];
|
||||
if (append.rows.length == msg[msg.append[0]].length+1) {
|
||||
return
|
||||
}
|
||||
append.innerHTML = '';
|
||||
var tr = append.insertRow(0);
|
||||
for (var i in msg.append) {
|
||||
var th = tr.appendChild(document.createElement("th"));
|
||||
th.appendChild(document.createTextNode(msg.append[i]));
|
||||
}
|
||||
context.GET("", data, function(msg) {
|
||||
msg = msg[0]
|
||||
|
||||
for (var i = 0; i < msg[msg.append[0]].length; i++) {
|
||||
var tr = append.insertRow(1);
|
||||
for (var j in msg.append) {
|
||||
var td = tr.appendChild(document.createElement("td"));
|
||||
td.appendChild(document.createTextNode(msg[msg.append[j]][i]));
|
||||
}
|
||||
}
|
||||
var div = append.parent;
|
||||
var result = document.querySelector("code.result."+data["componet_name"]+" pre")
|
||||
result && (result.innerHTML = (msg.result || []).join(""))
|
||||
|
||||
})
|
||||
return false;
|
||||
var append = document.querySelector("table.append."+data["componet_name"])
|
||||
append && (append.innerHTML = "")
|
||||
|
||||
if (append && msg.append) {
|
||||
var tr = append_child(append, "tr")
|
||||
for (var i in msg.append) {
|
||||
append_child(tr, "th", msg.append[i])
|
||||
}
|
||||
|
||||
var ncol = msg.append.length
|
||||
var nrow = msg[msg.append[0]].length
|
||||
for (var i = 0; i < nrow; i ++) {
|
||||
var tr = append_child(append, "tr")
|
||||
for (var k in msg.append) {
|
||||
append_child(tr, "td", msg[msg.append[k]][i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typeof(cb) == "function" && cb(msg)
|
||||
})
|
||||
}
|
||||
function onaction(event, action) {
|
||||
switch (action) {
|
||||
case "command":
|
||||
send_command(event.target.form)
|
||||
break
|
||||
case "input":
|
||||
switch (event.key) {
|
||||
case "Enter":
|
||||
var form = event.target.form
|
||||
for (var i = 0; i < form.length; i++) {
|
||||
if (form[i] == event.target) {
|
||||
continue
|
||||
}
|
||||
(i == form.length-1)? send_command(form): form[i+1].focus()
|
||||
}
|
||||
break
|
||||
case "Escape":
|
||||
event.target.value = ""
|
||||
event.target.blur()
|
||||
break
|
||||
}
|
||||
break
|
||||
case "keymap":
|
||||
switch (event.key) {
|
||||
case "g":
|
||||
document.querySelectorAll("form.option label.keymap").forEach(function(item) {
|
||||
item.className = (item.className == "keymap show")? "keymap hide": "keymap show"
|
||||
})
|
||||
break
|
||||
default:
|
||||
if (inputs[event.key]) {
|
||||
inputs[event.key].focus()
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
case "copy":
|
||||
copy_to_clipboard(event.target.innerText)
|
||||
break
|
||||
}
|
||||
}
|
||||
var inputs = {}
|
||||
var ninput = 0
|
||||
var keymap = ['a', 'b', 'c']
|
||||
function init_option() {
|
||||
inputs = {}
|
||||
ninput = 0
|
||||
keymap =[]
|
||||
for (var i = 97; i < 123; i++) {
|
||||
if (i == 103) {
|
||||
continue
|
||||
}
|
||||
keymap.push(String.fromCharCode(i))
|
||||
}
|
||||
|
||||
document.querySelectorAll("form.option input").forEach(function(input) {
|
||||
if (ninput < keymap.length && input.style.display != "none") {
|
||||
input.title = "keymap: "+keymap[ninput]
|
||||
input.dataset["keymap"] = keymap[ninput]
|
||||
insert_before(input, "label", "("+keymap[ninput]+")").className = "keymap"
|
||||
inputs[keymap[ninput++]] = input
|
||||
}
|
||||
})
|
||||
}
|
||||
function init_append(event) {
|
||||
var append = document.querySelectorAll("table.append").forEach(function(item) {
|
||||
item.onclick = function(event) {
|
||||
if (event.target.tagName == "TD") {
|
||||
copy_to_clipboard(event.target.innerText)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
function init_result(event) {
|
||||
var result = document.querySelectorAll("code.result pre").forEach(function(item) {
|
||||
item.onclick = function(event) {
|
||||
copy_to_clipboard(event.target.innerText)
|
||||
}
|
||||
})
|
||||
}
|
||||
function init_download(event) {
|
||||
var option = document.querySelector("form.option.dir")
|
||||
if (!option) {
|
||||
return
|
||||
}
|
||||
option["dir"].value && send_command(option)
|
||||
|
||||
var append = document.querySelector("table.append.dir")
|
||||
append.onclick = function(event) {
|
||||
if (event.target.tagName == "A") {
|
||||
if (event.target.dataset.type != "true") {
|
||||
location.href = option["dir"].value+"/"+event.target.innerText
|
||||
return
|
||||
}
|
||||
|
||||
option["dir"].value = option["dir"].value+"/"+event.target.innerText
|
||||
send_command(option, function(msg) {
|
||||
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
|
||||
|
||||
var sort_order = option["sort_order"]
|
||||
switch (event.target.innerText) {
|
||||
case "filename":
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
init_option()
|
||||
init_append()
|
||||
init_result()
|
||||
init_download()
|
||||
}
|
||||
|
@ -1,202 +1,47 @@
|
||||
ctx = {
|
||||
Cookie: function(key, value) {//{{{
|
||||
if (value == undefined) {
|
||||
var pattern = new RegExp(key+"=([^;]*);?");
|
||||
var result = pattern.exec(document.cookie);
|
||||
if (result && result.length > 0) {
|
||||
return result[1];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
context = {
|
||||
GET: function(url, form, cb) {
|
||||
form = form || {}
|
||||
|
||||
document.cookie = key+"="+value;
|
||||
return this.Cookie(key);
|
||||
},//}}}
|
||||
Search: function(key, value) {//{{{
|
||||
var args = {};
|
||||
var search = location.search.split("?");
|
||||
if (search.length > 1) {
|
||||
var searchs = search[1].split("&");
|
||||
for (var i = 0; i < searchs.length; i++) {
|
||||
var keys = searchs[i].split("=");
|
||||
args[keys[0]] = decodeURIComponent(keys[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof key == "object") {
|
||||
for (var k in key) {
|
||||
if (key[k] != undefined) {
|
||||
args[k] = key[k];
|
||||
}
|
||||
}
|
||||
} else if (value == undefined) {
|
||||
return args[key] || "";
|
||||
} else {
|
||||
args[key] = value;
|
||||
}
|
||||
|
||||
var arg = [];
|
||||
for (var k in args) {
|
||||
arg.push(k+"="+encodeURIComponent(args[k]));
|
||||
}
|
||||
location.search = arg.join("&");
|
||||
},//}}}
|
||||
GET: function(url, form, cb) {//{{{
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function() {
|
||||
switch (xhr.readyState) {
|
||||
case 4:
|
||||
switch (xhr.status) {
|
||||
case 200:
|
||||
try {
|
||||
var msg = JSON.parse(xhr.responseText||'{"result":[]}');
|
||||
} catch (e) {
|
||||
msg = {"result": [xhr.responseText]}
|
||||
}
|
||||
|
||||
msg && console.log(msg)
|
||||
msg.result && console.log(msg.result.join(""));
|
||||
typeof cb == "function" && cb(msg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
form = form || {}
|
||||
form["dir"] = form["dir"] || this.Search("dir") || undefined
|
||||
form["module"] = form["module"] || this.Search("module") || undefined
|
||||
form["domain"] = form["domain"] || this.Search("domain") || undefined
|
||||
|
||||
var args = [];
|
||||
for (k in form) {
|
||||
if (form[k] instanceof Array) {
|
||||
for (i in form[k]) {
|
||||
args.push(k+"="+encodeURIComponent(form[k][i]));
|
||||
}
|
||||
} else if (form[k] != undefined) {
|
||||
args.push(k+"="+encodeURIComponent(form[k]));
|
||||
}
|
||||
}
|
||||
|
||||
var arg = args.join("&");
|
||||
if (arg) {
|
||||
url += "?"+arg
|
||||
var args = [];
|
||||
for (var k in form) {
|
||||
if (form[k] instanceof Array) {
|
||||
for (i in form[k]) {
|
||||
args.push(k+"="+encodeURIComponent(form[k][i]));
|
||||
}
|
||||
} else if (form[k] != undefined) {
|
||||
args.push(k+"="+encodeURIComponent(form[k]));
|
||||
}
|
||||
}
|
||||
|
||||
xhr.open("GET", url);
|
||||
console.log("GET: "+url+"?"+arg);
|
||||
xhr.send();
|
||||
},//}}}
|
||||
POST: function(url, form, cb) {//{{{
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function() {
|
||||
switch (xhr.readyState) {
|
||||
case 4:
|
||||
switch (xhr.status) {
|
||||
case 200:
|
||||
try {
|
||||
var msg = JSON.parse(xhr.responseText||'{"result":[]}');
|
||||
} catch (e) {
|
||||
msg = {"result": [xhr.responseText]}
|
||||
}
|
||||
var arg = args.join("&");
|
||||
arg && (url += ((url.indexOf("?")>-1)? "&": "?") + arg)
|
||||
console.log("GET: "+url);
|
||||
|
||||
msg && console.log(msg)
|
||||
msg.result && console.log(msg.result.join(""));
|
||||
typeof cb == "function" && cb(msg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", url);
|
||||
xhr.setRequestHeader("Accept", "application/json")
|
||||
|
||||
xhr.open("POST", url);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState != 4) {
|
||||
return
|
||||
}
|
||||
if (xhr.status != 200) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
var msg = JSON.parse(xhr.responseText||'{"result":[]}');
|
||||
} catch (e) {
|
||||
var msg = {"result": [xhr.responseText]}
|
||||
}
|
||||
|
||||
form = form || {}
|
||||
form["dir"] = form["dir"] || this.Search("dir") || undefined
|
||||
form["module"] = form["module"] || this.Search("module") || undefined
|
||||
form["domain"] = form["domain"] || this.Search("domain") || undefined
|
||||
|
||||
var args = [];
|
||||
for (k in form) {
|
||||
if (form[k] instanceof Array) {
|
||||
for (i in form[k]) {
|
||||
args.push(k+"="+encodeURIComponent(form[k][i]));
|
||||
}
|
||||
} else if (form[k] != undefined) {
|
||||
args.push(k+"="+encodeURIComponent(form[k]));
|
||||
}
|
||||
}
|
||||
|
||||
var arg = args.join("&");
|
||||
console.log("POST: "+url+"?"+arg);
|
||||
xhr.send(arg);
|
||||
},//}}}
|
||||
Refresh: function() {//{{{
|
||||
location.assign(location.href);
|
||||
},//}}}
|
||||
|
||||
Cap: function(cap, cb) {//{{{
|
||||
if (typeof cap == "function") {
|
||||
cb = cap;
|
||||
cap = undefined;
|
||||
}
|
||||
|
||||
var args = {ccc:"cache"};
|
||||
if (cap != undefined) {
|
||||
args.name = cap;
|
||||
}
|
||||
|
||||
this.POST("", args, function(msg) {
|
||||
var value = msg.result.join("");
|
||||
typeof cb == "function" && cb(value);
|
||||
});
|
||||
},//}}}
|
||||
Conf: function(name, value, cb) {//{{{
|
||||
if (typeof name == "function") {
|
||||
value = name;
|
||||
name = undefined;
|
||||
}
|
||||
if (typeof value == "function") {
|
||||
cb = value;
|
||||
value = undefined;
|
||||
}
|
||||
|
||||
var args = {ccc:"config"};
|
||||
if (name != undefined) {
|
||||
args.name = name
|
||||
}
|
||||
if (value != undefined) {
|
||||
args.value = value
|
||||
}
|
||||
|
||||
this.POST("", args, function(msg) {
|
||||
var value = msg.result.join("");
|
||||
typeof cb == "function" && cb(value);
|
||||
});
|
||||
},//}}}
|
||||
Cmd: function(cmd, value, cb) {//{{{
|
||||
if (typeof cmd == "function") {
|
||||
value = cmd;
|
||||
cmd = undefined;
|
||||
}
|
||||
if (typeof value == "function") {
|
||||
cb = value;
|
||||
value = undefined;
|
||||
}
|
||||
|
||||
var args = {ccc:"command"};
|
||||
if (cmd != undefined) {
|
||||
args.name = cmd
|
||||
}
|
||||
if (value != undefined) {
|
||||
args.value = JSON.stringify(value)
|
||||
}
|
||||
|
||||
this.POST("", args, cb);
|
||||
},//}}}
|
||||
Module: function(module, domain) {//{{{
|
||||
this.Search({module:module, domain:domain})
|
||||
},//}}}
|
||||
};
|
||||
|
||||
console.log(msg)
|
||||
msg.result && console.log(msg.result.join(""));
|
||||
if (msg.page_redirect) {
|
||||
location.href = msg.page_redirect.join("")
|
||||
}
|
||||
typeof cb == "function" && cb(msg)
|
||||
}
|
||||
xhr.send();
|
||||
},
|
||||
}
|
||||
|
@ -1,211 +0,0 @@
|
||||
function jumpto(url) {
|
||||
if (url == "..") {
|
||||
var ps = locaiton.href.split();
|
||||
}
|
||||
location.href=url;
|
||||
}
|
||||
|
||||
function keyup(event) {
|
||||
console.log(event);
|
||||
if (typeof window.control == "function") {
|
||||
control(event);
|
||||
}
|
||||
if (event.key == "z") {
|
||||
var input = document.getElementsByClassName("query_input")[0];
|
||||
if (!window.query_show) {
|
||||
window.query_show = true;
|
||||
var query = document.getElementsByClassName("query_menu")[0];
|
||||
var input = query.getElementsByTagName("input")[0];
|
||||
input.style.visibility = "visible";
|
||||
input.style.width = "80px";
|
||||
input.focus();
|
||||
}
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
document.onkeyup = keyup;
|
||||
function toggle(side) {
|
||||
if (side == "left") {
|
||||
window.left_list_hide = !window.left_list_hide;
|
||||
var list = document.getElementsByClassName("list")[0];
|
||||
var content = document.getElementsByClassName("content")[0];
|
||||
if (left_list_hide) {
|
||||
list.style.visibility = "hidden";
|
||||
list.style.width="0px";
|
||||
list.style.height="0px";
|
||||
list.style["min-width"]="0px";
|
||||
content.style.width="100%";
|
||||
} else {
|
||||
list.style.visibility = "visible";
|
||||
list.style.width="15%";
|
||||
list.style.height="100%";
|
||||
list.style["min-width"]="180px";
|
||||
content.style.width="85%";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function menu() {
|
||||
var max = 0;
|
||||
var min = 1000;
|
||||
var list = [];
|
||||
var hs = ["h2", "h3", "h4"];
|
||||
for (var i = 0; i < hs.length; i++) {
|
||||
var head = document.getElementsByTagName(hs[i]);
|
||||
for (var j = 0; j < head.length; j++) {
|
||||
head[j].id = "head"+head[j].offsetTop;
|
||||
head[j].onclick = function(event) {}
|
||||
list.push({"level": hs[i], "position": head[j].offsetTop, "title": head[j].innerText, "hash": head[j].id})
|
||||
if (head[j].offsetTop > max) {
|
||||
max = head[j].offsetTop;
|
||||
}
|
||||
if (head[j].offsetTop < min) {
|
||||
min = head[j].offsetTop;
|
||||
}
|
||||
}
|
||||
}
|
||||
max = max - min;
|
||||
|
||||
var link = [];
|
||||
var a = document.getElementsByTagName("a");
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
link.push({href: a[i].href, title: a[i].innerText});
|
||||
}
|
||||
|
||||
for (var i = 0; i < list.length-1; i++) {
|
||||
for (var j = i+1; j < list.length; j++) {
|
||||
if (list[j].position < list[i].position) {
|
||||
var a = list[i];
|
||||
list[i] = list[j];
|
||||
list[j] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var index = [-1, 0, 0]
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i].level == "h2") {
|
||||
index[0]++;
|
||||
index[1]=0;
|
||||
index[2]=0;
|
||||
} else if (list[i].level == "h3") {
|
||||
index[1]++;
|
||||
index[2]=0;
|
||||
} else {
|
||||
index[2]++;
|
||||
}
|
||||
|
||||
list[i].index4 = index[2];
|
||||
list[i].index3 = index[1];
|
||||
list[i].index2 = index[0];
|
||||
}
|
||||
|
||||
var m = document.getElementsByClassName("menu");
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
var text = list[j].index2+"."
|
||||
if (list[j].level == "h3") {
|
||||
text += list[j].index3
|
||||
} else if (list[j].level == "h4") {
|
||||
text += list[j].index3+"."+list[j].index4
|
||||
}
|
||||
|
||||
text += " "
|
||||
text += list[j].title;
|
||||
|
||||
var h = document.getElementById(list[j].hash)
|
||||
h.innerText = text
|
||||
|
||||
var one = m[i].appendChild(document.createElement("div"));
|
||||
var a = one.appendChild(document.createElement("a"));
|
||||
a.href = "#"+list[j].hash;
|
||||
a.innerText = text+" ("+parseInt((list[j].position-min)/max*100)+"%)";
|
||||
|
||||
one.className = list[j].level;
|
||||
}
|
||||
}
|
||||
|
||||
var m = document.getElementsByClassName("link");
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
var one = m[i].appendChild(document.createElement("div"));
|
||||
var a = one.appendChild(document.createTextNode("相关链接: "));
|
||||
|
||||
for (var j = 0; j < link.length; j++) {
|
||||
var one = m[i].appendChild(document.createElement("div"));
|
||||
var a = one.appendChild(document.createTextNode(link[j].title+": "));
|
||||
var a = one.appendChild(document.createElement("a"));
|
||||
a.href = link[j].href
|
||||
a.innerText = a.href
|
||||
}
|
||||
}
|
||||
|
||||
var m = document.getElementsByTagName("pre");
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
var line = (m[i].clientHeight-10)/15
|
||||
// if (line < 3) {
|
||||
// continue
|
||||
// }
|
||||
console.log(m[i].clientHeight)
|
||||
var nu = m[i].parentElement.insertBefore(document.createElement("div"), m[i]);
|
||||
nu.className = "number1"
|
||||
|
||||
for (var j = 1; j <= line; j++) {
|
||||
console.log(j)
|
||||
var li = nu.appendChild(document.createElement("div"));
|
||||
li.appendChild(document.createTextNode(""+j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function query(event) {
|
||||
if (event) {
|
||||
if (event.code == "Enter") {
|
||||
jumpto("/wiki/?query="+encodeURIComponent(event.target.value));
|
||||
}
|
||||
console.log("what")
|
||||
return true
|
||||
}
|
||||
window.query_show = !window.query_show;
|
||||
var query = document.getElementsByClassName("query_menu")[0];
|
||||
var input = query.getElementsByTagName("input")[0];
|
||||
if (window.query_show) {
|
||||
input.style.visibility = "visible";
|
||||
input.style.width = "80px";
|
||||
|
||||
} else {
|
||||
input.style.visibility = "hidden";
|
||||
input.style.width = "0px";
|
||||
}
|
||||
}
|
||||
|
||||
var tags_list = {};
|
||||
ctx.GET("/wiki/define.json", undefined, function(msg){
|
||||
tags_list = msg["define"];
|
||||
})
|
||||
|
||||
function tags(event) {
|
||||
console.log(event);
|
||||
|
||||
if (event.srcElement.tagName == "CODE") {
|
||||
var tag = document.getSelection().toString();
|
||||
console.log(tag);
|
||||
if (tag && tag.length > 0 && tags_list[tag]) {
|
||||
var position = tags_list[tag].position;
|
||||
if (position.length == 1) {
|
||||
jumpto("/wiki/src/"+position[0].file+"#hash_"+position[0].line);
|
||||
} else {
|
||||
jumpto("/wiki/?query="+encodeURIComponent(tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.onmouseup = tags;
|
||||
window.onload = function() {
|
||||
toggle();
|
||||
if (location.href.endsWith(".md")) {
|
||||
menu();
|
||||
}
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
{{define "head"}}
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{option .Meta "page_title"}}</title>
|
||||
<style>
|
||||
fieldset {
|
||||
margin-top:8px;
|
||||
}
|
||||
legend {
|
||||
font-size:16px;
|
||||
font-weight:bold;
|
||||
font-family:monospace;
|
||||
}
|
||||
th {
|
||||
cursor:pointer;
|
||||
background-color:lightgreen;
|
||||
}
|
||||
td {
|
||||
padding-left: 10px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
pre {
|
||||
color:white;
|
||||
font-size:14px;
|
||||
background-color:#272822;
|
||||
padding:5px;
|
||||
border:solid 2px green;
|
||||
border-left:solid 4px green;
|
||||
overflow:scroll;
|
||||
}
|
||||
.command {
|
||||
font-size:14px;
|
||||
font-family:monospace;
|
||||
}
|
||||
html, body {
|
||||
height:100%;
|
||||
width:100%;
|
||||
margin:0px;
|
||||
background-color:#d8d8d8;
|
||||
}
|
||||
h4 {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
</style>
|
||||
<script src="/library/context.js"></script>
|
||||
<script src="/library/base.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
{{end}}
|
||||
|
||||
{{define "code"}}
|
||||
<pre><code>{{.}}</code></pre>
|
||||
{{end}}
|
||||
|
||||
{{define "notice"}}
|
||||
<fieldset class="notice"><legend>[notice]</legend>
|
||||
{{template "code" result .Meta}}
|
||||
</fieldset>
|
||||
<style>
|
||||
.notice {color:red}
|
||||
</style>
|
||||
{{end}}
|
||||
|
||||
{{define "detail"}}
|
||||
{{$msg := .}}
|
||||
{{$key := append . "title"|meta}}
|
||||
<fieldset><legend><a onclick="return action(event, '{{option .Meta "module"}}', ['{{detail .Meta}}'], '{{$key}}')" href="/">{{option . "title"}}</a></legend>
|
||||
{{range option . "ninput"|meta|list}}
|
||||
<input type="text" class="{{$key}}_input" value="" onkeyup="return input(event, '{{option $msg.Meta "module"}}', ['{{detail $msg.Meta}}'], '{{$key}}')"></input>
|
||||
{{end}}
|
||||
{{if option . "refresh"}}
|
||||
<input type="button" class="{{$key}}_button" value="update" onclick="return update(event, '{{option $msg.Meta "module"}}', ['{{detail $msg.Meta}}'], '{{$key}}')"></input>
|
||||
<input type="button" class="{{$key}}_button" value="cancel" onclick="return update(event, '{{option $msg.Meta "module"}}', ['{{detail $msg.Meta}}'], '{{$key}}')"></input>
|
||||
{{end}}
|
||||
<pre><code class="{{$key}}_result"></code></pre>
|
||||
<div style="max-height:150px;overflow:auto">
|
||||
<table class="{{$key}}_append"></table>
|
||||
</div>
|
||||
</fieldset>
|
||||
<script>
|
||||
var refresh_time = parseInt({{conf . "refresh_time"}});
|
||||
{{if option . "auto_refresh"}}
|
||||
update(true, '{{option $msg.Meta "module"}}', ['{{detail $msg.Meta}}'], '{{$key}}');
|
||||
{{end}}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "result"}}
|
||||
<fieldset><legend>{{option . "title"}}</legend>
|
||||
{{template "code" result .Meta|unscaped}}
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "append_link"}}
|
||||
<a onclick="return jump('{{.}}')" href="{{.}}">{{.}}</a>
|
||||
<script>
|
||||
function jump(to) {
|
||||
location.href = location.href + "/" +to;
|
||||
return false
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "append"}}
|
||||
<fieldset><legend>{{option . "title"}}</legend>
|
||||
<table class="append">
|
||||
{{$msg := .}}
|
||||
{{$ncol := append . |len}}
|
||||
{{$nrow := append . 0|append .|len}}
|
||||
<tr>{{range append .}}<th><code onclick="sort_table('{{.}}')">{{.}}</code></th>{{end}}</tr>
|
||||
{{range $row, $val := append . 0|append .}}
|
||||
<tr>
|
||||
{{range append $msg}}
|
||||
{{$value := append $msg . $row}}
|
||||
<td><code>
|
||||
{{if eq . "filename"}}
|
||||
{{template "append_link" $value}}
|
||||
{{else}}
|
||||
{{$value}}
|
||||
{{end}}
|
||||
</code></td>
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
<script>
|
||||
var sort_field="";
|
||||
function sort_table(field) {
|
||||
sort_field = field;
|
||||
console.log(sort_field);
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
welcome to context world!
|
||||
{{end}}
|
||||
|
||||
{{define "tail"}}
|
||||
</body>
|
||||
{{end}}
|
138
usr/template/common/base.tmpl
Normal file
138
usr/template/common/base.tmpl
Normal file
@ -0,0 +1,138 @@
|
||||
{{define "head"}}
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{option .Meta "page_title"}}</title>
|
||||
<style>
|
||||
html, body {
|
||||
height:100%;
|
||||
width:100%;
|
||||
margin:0px;
|
||||
background-color:#d8d8d8;
|
||||
}
|
||||
fieldset {
|
||||
margin-top:8px;
|
||||
}
|
||||
legend {
|
||||
font-size:16px;
|
||||
font-weight:bold;
|
||||
font-family:monospace;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
form.option div {
|
||||
float:left;
|
||||
}
|
||||
form.option hr {
|
||||
clear:both;
|
||||
}
|
||||
form.option label.keymap {
|
||||
display:none;
|
||||
color:red;
|
||||
}
|
||||
form.option label.keymap.show {
|
||||
display:inline;
|
||||
}
|
||||
table.append th {
|
||||
cursor:pointer;
|
||||
background-color:lightgreen;
|
||||
}
|
||||
table.append th.order {
|
||||
cursor:pointer;
|
||||
background-color:red;
|
||||
}
|
||||
table.append td {
|
||||
padding-left: 10px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
code.result pre {
|
||||
color:white;
|
||||
font-size:14px;
|
||||
background-color:#272822;
|
||||
padding:5px;
|
||||
border:solid 2px green;
|
||||
border-left:solid 4px green;
|
||||
overflow:scroll;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body onkeyup="return onaction(event, 'keymap')">
|
||||
{{end}}
|
||||
|
||||
{{define "detail"}}{{detail .}}{{end}}
|
||||
{{define "option"}}{{option .}}{{end}}
|
||||
{{define "append"}}{{append .}}{{end}}
|
||||
{{define "result"}}{{result .}}{{end}}
|
||||
|
||||
{{define "clipboard"}}
|
||||
<fieldset><legend>clipboard</legend>
|
||||
<datalist id="clipstack"></datalist>
|
||||
<input id="clipboard">
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "componet"}}
|
||||
<fieldset><legend title="{{option .Meta "help"}}">{{option .Meta "context"}}.{{option .Meta "command"}}</legend>
|
||||
<form class="option {{option .Meta "name"}}"
|
||||
data-last_componet_group="{{option . "last_componet_group"|meta}}"
|
||||
data-last_componet_order="{{option . "last_componet_order"|meta}}"
|
||||
data-componet_group="{{option . "componet_group"|meta}}"
|
||||
data-componet_order="{{option . "componet_order"|meta}}"
|
||||
data-componet_name="{{option . "name"|meta}}"
|
||||
data-componet_help="{{option . "help"|meta}}"
|
||||
>
|
||||
<input style="display:none"></input>
|
||||
{{range $index, $input := option . "inputs"}}
|
||||
<div>
|
||||
{{$type := index $input "type"}}
|
||||
{{if eq $type "button"}}
|
||||
<input type="button" name="{{index $input "name"}}" value="{{index $input "value"}}" onclick="return onaction(event, 'command')">
|
||||
{{else if eq $type "choice"}}
|
||||
{{$default_value := index $input "value"}}
|
||||
<label>{{index $input "label"}} : </label>
|
||||
<select name="{{index $input "name"}}" onchange="return onaction(event, 'command')">
|
||||
{{range $index, $value := index $input "choice"}}
|
||||
{{$val := index $value "value"}}
|
||||
{{if eq $default_value $val}}
|
||||
<option value="{{index $value "value"}}" selected>{{index $value "name"}}</option>
|
||||
{{else}}
|
||||
<option value="{{index $value "value"}}">{{index $value "name"}}</option>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</select>
|
||||
{{else}}
|
||||
<label>{{index $input "label"}} : </label>
|
||||
<input name="{{index $input "name"}}" value="{{index $input "value"}}" onkeyup="return onaction(event, 'input')" list="clipstack">
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<hr/>
|
||||
</form>
|
||||
|
||||
{{if index .Meta "display_append"}}
|
||||
{{option .Meta "display_append"}}
|
||||
{{else}}
|
||||
<table class="append {{option .Meta "name"}}">
|
||||
{{$msg := .}}
|
||||
<tr>{{range $field := append .}}<th>{{$field}}</th>{{end}}</tr>
|
||||
{{range $line := table .}}
|
||||
<tr>{{range $field := append $msg}}<td>{{index $line $field|unescape}}</td>{{end}}</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
{{end}}
|
||||
|
||||
{{if index .Meta "display_result"}}
|
||||
{{option .Meta "display_result"}}
|
||||
{{else}}
|
||||
<code class="result {{option .Meta "name"}}"><pre>{{result .Meta}}</pre></code>
|
||||
{{end}}
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "tail"}}
|
||||
<script src="/library/context.js"></script>
|
||||
<script src="/library/base.js"></script>
|
||||
</body>
|
||||
{{end}}
|
@ -1,94 +0,0 @@
|
||||
{{define "login"}}
|
||||
<fieldset><legend>login</legend>
|
||||
<form method="POST" action="/login">
|
||||
<label>username:</label><input type="text" name="username" required autofocus>
|
||||
<label>password:</label><input type="password" name="password" required>
|
||||
<input type="submit">
|
||||
</form>
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "userinfo"}}
|
||||
<fieldset><legend>userinfo</legend>
|
||||
welcome <span class="username">{{option . "username"}}</span> to context world
|
||||
<button onclick="return logout(event)">logout</button>
|
||||
</fieldset>
|
||||
<style>
|
||||
.username {
|
||||
color:red;
|
||||
font-weight:bold;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function logout(event) {
|
||||
ctx.Cookie("sessid", ";path=/");
|
||||
ctx.Refresh();
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "share"}}
|
||||
<fieldset><legend>share</legend>
|
||||
<table>
|
||||
{{$msg := .}}
|
||||
{{$ncol := append . |len}}
|
||||
{{$nrow := append . 0|append .|len}}
|
||||
<tr>{{range append .}}<th><code onclick="sort_table('{{.}}')">{{.}}</code></th>{{end}}</tr>
|
||||
{{range $row, $val := append . 0|append .}}
|
||||
<tr>
|
||||
{{range append $msg}}
|
||||
{{$value := append $msg . $row}}
|
||||
<td><code>
|
||||
{{if eq . "to"}}
|
||||
{{if eq $value ""}}
|
||||
<input type="text" onkeyup="return share_input(event, '{{append $msg "template" $row}}', '{{append $msg "titles" $row}}', 'add')">
|
||||
{{else}}
|
||||
<code><a href="/" title="点击取消共享" onclick="return shareto('{{append $msg "template" $row}}', '{{append $msg "titles" $row}}', '{{$value}}','del')">{{$value}}</a></code>
|
||||
{{end}}
|
||||
{{else if eq . "value"}}
|
||||
<code><a title="点击删除" href="/" onclick="deleteshare(event, '{{append $msg "friend" $row}}', '{{$value}}')">{{$value}}</a></code>
|
||||
{{else}}
|
||||
{{$value}}
|
||||
{{end}}
|
||||
</code></td>
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
<script>
|
||||
function share_input(event, template, title, action) {
|
||||
if (event.code == "Enter") {
|
||||
shareto(template, title, event.target.value, action);
|
||||
}
|
||||
console.log(event.code)
|
||||
console.log(event.key)
|
||||
console.log(event)
|
||||
}
|
||||
|
||||
function shareto(template, title, friend, action) {
|
||||
ctx.POST("/share", {
|
||||
module: "web",
|
||||
template: template,
|
||||
title: title,
|
||||
friend: friend,
|
||||
action: action,
|
||||
share: ["command", "/index/"],
|
||||
}, function(msg) {
|
||||
ctx.Refresh();
|
||||
})
|
||||
return false
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{$msg := .}}
|
||||
{{$meta := .Meta}}
|
||||
|
||||
{{template "head" $meta}}
|
||||
{{if meta $meta.notice}}
|
||||
{{template "notice" $meta}}
|
||||
{{end}}
|
||||
{{template "login" $meta}}
|
||||
{{template "tail" $meta}}
|
@ -1,9 +0,0 @@
|
||||
{{$msg := .}}
|
||||
{{$meta := .Meta}}
|
||||
|
||||
{{template "head" $meta}}
|
||||
{{if meta $meta.message}}
|
||||
{{template "message" $meta}}
|
||||
{{end}}
|
||||
{{template "main" $msg}}
|
||||
{{template "tail" $meta}}
|
@ -1,222 +0,0 @@
|
||||
{{define "wiki_head"}}
|
||||
{{end}}
|
||||
|
||||
{{define "wiki_menu"}}
|
||||
{{end}}
|
||||
|
||||
{{define "wiki_list"}}
|
||||
<style>
|
||||
p {
|
||||
text-indent:2em;
|
||||
}
|
||||
.container {
|
||||
height:100%;
|
||||
min-width:300px;
|
||||
}
|
||||
.head {
|
||||
color:white;
|
||||
font-size:20px;
|
||||
font-weight:bold;
|
||||
background-color:#222;
|
||||
text-align:center;
|
||||
vertical-align:middle;
|
||||
padding:10px;
|
||||
width:100%;
|
||||
height:27px;
|
||||
}
|
||||
.title {
|
||||
font-style:italic;
|
||||
}
|
||||
.toggle_menu {
|
||||
cursor:pointer;
|
||||
float:left;
|
||||
}
|
||||
.query_menu {
|
||||
cursor:pointer;
|
||||
margin-right:20px;
|
||||
float:right;
|
||||
}
|
||||
.query_button {
|
||||
cursor:pointer;
|
||||
float:right;
|
||||
margin-left:10px;
|
||||
}
|
||||
.query_input {
|
||||
visibility:hidden;
|
||||
width:0px;
|
||||
position:absolute;
|
||||
right:40px;
|
||||
top:12px;
|
||||
}
|
||||
.list {
|
||||
width:15%;
|
||||
min-width:140px;
|
||||
float:left;
|
||||
max-height:1000px;
|
||||
overflow:scroll;
|
||||
}
|
||||
.list_item {
|
||||
padding-top:10px;
|
||||
padding-left:30px;
|
||||
min-height:30px;
|
||||
margin-left:-30px;
|
||||
}
|
||||
.list_item:hover, .list_item:active {
|
||||
background-color:green;
|
||||
}
|
||||
</style>
|
||||
<div class="container">
|
||||
<div class="head">
|
||||
<div class="toggle_menu" onclick="toggle()">三</div>
|
||||
<div class="query_menu">
|
||||
<input class="query_input" type="text" onkeyup="return query(event)">
|
||||
<div class="query_button" onclick="return query()"> Q</div>
|
||||
</div>
|
||||
<div class="title" onclick="return jumpto('/wiki/')">shylinux</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
{{$msg := .}}
|
||||
{{$ncol := append . |len}}
|
||||
{{$nrow := append . 0|append .|len}}
|
||||
<ul>
|
||||
<li>
|
||||
<div class="list_item" onclick="return jumpto('/wiki/{{option $msg "parent"|meta}}')">返回上一层</div>
|
||||
</li>
|
||||
{{range $row, $val := append . 0|append .}}
|
||||
<li>
|
||||
<div class="list_item" onclick="return jumpto('/wiki/{{option $msg "dir"|meta}}/{{append $msg "name" $row}}')">
|
||||
{{append $msg "name" $row}}
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{define "wiki_body"}}
|
||||
<style>
|
||||
.content {
|
||||
width:85%;
|
||||
height:100%;
|
||||
float:left;
|
||||
min-width:400px;
|
||||
}
|
||||
.toggle {
|
||||
background-color:green;
|
||||
width:2%;
|
||||
height:100%;
|
||||
float:left;
|
||||
}
|
||||
.toggle1 {
|
||||
background-color:green;
|
||||
width:2%;
|
||||
height:100%;
|
||||
float:right;
|
||||
}
|
||||
.texts {
|
||||
max-width:800px;
|
||||
width:94%;
|
||||
float:left;
|
||||
margin-left:2%;
|
||||
}
|
||||
.li_link {
|
||||
font-size:18px;
|
||||
}
|
||||
.number {
|
||||
float:left;
|
||||
position:relative;
|
||||
left:-6px;
|
||||
top:18px;
|
||||
text-align:right;
|
||||
}
|
||||
.number div {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
height:16px;
|
||||
}
|
||||
.record {
|
||||
margin: 10px 10px;
|
||||
float:left;
|
||||
}
|
||||
.menu {
|
||||
}
|
||||
.menu a {
|
||||
text-decoration:none;
|
||||
}
|
||||
.menu .h3 {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.menu .h4 {
|
||||
padding-left: 40px;
|
||||
}
|
||||
.link {
|
||||
margin-top:10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.link div:first-child {
|
||||
margin-left:-10px;
|
||||
}
|
||||
.link div {
|
||||
padding-left:10px;
|
||||
}
|
||||
.number1 {
|
||||
color:#271ace;
|
||||
font-size:14px;
|
||||
font-family:monospace;
|
||||
background-color:#77b724;
|
||||
padding:5px;
|
||||
border:solid 2px green;
|
||||
margin-left:0px;
|
||||
float:left;
|
||||
}
|
||||
.number1 div {
|
||||
text-align:right;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
</style>
|
||||
<div class="content">
|
||||
<div class="toggle" title="点击,显示或隐藏目录" onclick="toggle('left')"></div>
|
||||
<div class="toggle1" title="点击,显示或隐藏目录" onclick="toggle('right')"></div>
|
||||
{{if option . "modify_time"|meta}}
|
||||
<div class="record">上次修订时间: {{option . "modify_time"|meta}} 修订次数: {{option . "modify_count"|meta}}</div>
|
||||
{{end}}
|
||||
<div class="record">上次阅读时间: {{option . "last_record_time"|meta}} 总访问量: {{option . "record_count"|meta}}</div>
|
||||
<div class="texts">
|
||||
<div class="menu"></div>
|
||||
<div class="link"></div>
|
||||
<div class="number">
|
||||
{{range option . "nline"|meta|list}}
|
||||
<div id="hash_{{.}}" style="margin-top:-1px"><code>{{.}}</code></div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{$msg := .}}
|
||||
{{if append . "name"}}
|
||||
{{$l := append . "name"|len}}
|
||||
{{if eq $l 1}}
|
||||
<script>
|
||||
location.replace("/wiki/{{option $msg "dir"|meta|unscaped}}/{{append . "name"|meta|unscaped}}");
|
||||
</script>
|
||||
{{else}}
|
||||
<ul>
|
||||
{{range $i, $v := append . "name"}}
|
||||
<li class="li_link">
|
||||
<div>
|
||||
<code>{{option $msg "time" $i}} </code>
|
||||
<a href="/wiki/{{option $msg "dir"|meta}}/{{$v}}{{option $msg "pend" $i}}">{{$v}}{{option $msg "pend" $i}}</a>
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
<ul>
|
||||
{{end}}
|
||||
{{else if append . "code"|meta}}
|
||||
<p><pre><code>{{append . "code"|meta}}</code></pre><p>
|
||||
{{else}}
|
||||
<p>{{append . "body"|meta|unscaped}}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="/library/wiki.js"></script>
|
||||
{{end}}
|
@ -1,431 +0,0 @@
|
||||
{{define "head"}}
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
legend {
|
||||
font-size:16px;
|
||||
font-weight:bold;
|
||||
}
|
||||
th {
|
||||
cursor:pointer;
|
||||
background-color:lightgray;
|
||||
}
|
||||
.name {
|
||||
padding-left:10px;
|
||||
text-align:left;
|
||||
}
|
||||
.help {
|
||||
padding-left:10px;
|
||||
text-align:left;
|
||||
}
|
||||
.status {
|
||||
padding-left:10px;
|
||||
text-align:left;
|
||||
}
|
||||
.stream {
|
||||
padding-left:10px;
|
||||
text-align:left;
|
||||
}
|
||||
.result {
|
||||
background-color:black;
|
||||
color:white;
|
||||
padding:10px;
|
||||
margin:0px;
|
||||
}
|
||||
code {
|
||||
font-size:14px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{end}}
|
||||
|
||||
{{define "cache"}}
|
||||
{{$meta := .}}
|
||||
<fieldset><legend>cache</legend>
|
||||
<table>
|
||||
<colgroup>{{range .append}}<col class="{{.}}">{{end}}</colgroup>
|
||||
<tr>{{range .append}}<th class="{{.}}" onclick="list('{{.}}')">{{.}}</th>{{end}}</tr>
|
||||
{{$l := index .append|len}}
|
||||
{{if gt $l 0}}
|
||||
{{$first := index .append 0}}
|
||||
{{range $i, $k := index . $first}}
|
||||
<tr>
|
||||
{{range $key := index $meta "append"}}
|
||||
{{$content := index $meta $key $i}}
|
||||
<td class="{{$key}}">
|
||||
<code>{{$content}}</code>
|
||||
</td>
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
<script>
|
||||
function cache(event, key, value) {
|
||||
console.log(event);
|
||||
switch (event.type) {
|
||||
case "keydown":
|
||||
if (event.key != "Enter") {
|
||||
return true;
|
||||
}
|
||||
|
||||
value = event.target.value;
|
||||
ctx.Cap(key, value);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "config"}}
|
||||
<fieldset><legend>config</legend>
|
||||
<table>
|
||||
<colgroup>{{range .append}}<col class="{{.}}">{{end}}</colgroup>
|
||||
<tr>{{range .append}}<th class="{{.}}" onclick="list('{{.}}')">{{.}}</th>{{end}}</tr>
|
||||
{{$l := index .append|len}}
|
||||
{{if gt $l 0}}
|
||||
{{$meta := .}} {{$first := index .append 0}}
|
||||
{{range $i, $k := index . $first}}
|
||||
<tr>{{$config := index $meta "key" $i}}
|
||||
{{range $key := index $meta "append"}}
|
||||
{{if eq $key "value"}}
|
||||
<td class="{{$key}}">
|
||||
<input type="text" value="{{index $meta $key $i}}" onkeydown="return Config(event, '{{$config}}')">
|
||||
</td>
|
||||
{{else}}
|
||||
<td class="{{$key}}">
|
||||
<code>{{index $meta $key $i}}</code>
|
||||
</td>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
<script>
|
||||
function Config(event, name) {
|
||||
if (event.type=="keydown" && event.key == "Enter") {
|
||||
ctx.Conf(name, event.target.value, function(msg) {alert("ok")});
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "command2"}}
|
||||
{{$meta := .}}
|
||||
<fieldset><legend>command</legend>
|
||||
<div>
|
||||
{{$l := index .append|len}}
|
||||
{{if gt $l 0}}
|
||||
{{$first := index .append 0}}
|
||||
{{range $i, $k := index . $first}}
|
||||
{{$command := index $meta "key" $i}}
|
||||
<div>
|
||||
<div>
|
||||
<code>
|
||||
{{$command}}: {{index $meta "help" $i}}<br/>
|
||||
<a href="" onclick="return shell(event, '{{$command}}')">{{index $meta "name" $i}}</a>
|
||||
</code>
|
||||
</div>
|
||||
<div id="argument_{{$command}}">
|
||||
<button onclick="return Argument(event, 'add', '{{$command}}')">add</button>
|
||||
<button onclick="return Argument(event, 'del', '{{$command}}')">del</button>
|
||||
</div>
|
||||
<pre class="result" hidden><code id="result_{{$command}}"></code></pre>
|
||||
<table id="append_{{$command}}" hidden></table>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset><legend><input id="direct" type="text" onkeydown="return shell(event)"></legend>
|
||||
<pre class="result"><code id="result2"></code></pre>
|
||||
</fieldset>
|
||||
<script>
|
||||
function show(msg, command) {
|
||||
console.log(msg);
|
||||
if (msg.result) {
|
||||
var result = document.getElementById("result_"+command);
|
||||
if (!result) {
|
||||
var result = document.getElementById("result2");
|
||||
}
|
||||
result.innerHTML = msg.result.join("");
|
||||
}
|
||||
|
||||
var append = document.getElementById("append_"+command);
|
||||
append.innerHTML = "";
|
||||
if (msg.append) {
|
||||
append.hidden = false;
|
||||
|
||||
var tr = document.createElement("tr");
|
||||
append.appendChild(tr)
|
||||
for (var k in msg.append) {
|
||||
var th = document.createElement("th");
|
||||
th.innerHTML = msg.append[k];
|
||||
tr.appendChild(th)
|
||||
}
|
||||
|
||||
for (var i in msg[msg.append[0]]) {
|
||||
var tr = document.createElement("tr");
|
||||
append.appendChild(tr)
|
||||
for (var k in msg.append) {
|
||||
var td = document.createElement("td");
|
||||
var pre = document.createElement("pre");
|
||||
var code = document.createElement("code");
|
||||
code.innerHTML = msg[msg.append[k]][i];
|
||||
pre.appendChild(code)
|
||||
td.appendChild(pre)
|
||||
tr.appendChild(td);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Argument(event, action, command) {
|
||||
var argument = document.getElementById("argument_"+command);
|
||||
switch (action) {
|
||||
case "add":
|
||||
var arg = document.createElement("input");
|
||||
arg.type = "text";
|
||||
argument.appendChild(arg);
|
||||
break;
|
||||
case "del":
|
||||
var arg = argument.lastElementChild;
|
||||
if (arg.type == "text") {
|
||||
argument.removeChild(arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function shell(event, command) {
|
||||
console.log(event);
|
||||
switch (event.type) {
|
||||
case "keydown":
|
||||
if (event.key != "Enter") {
|
||||
return true;
|
||||
}
|
||||
command = event.target.value
|
||||
// no break
|
||||
case "click":
|
||||
var detail = [];
|
||||
var result = document.getElementById("result_"+command);
|
||||
var append = document.getElementById("append_"+command);
|
||||
if (!result) {
|
||||
var result = document.getElementById("result2");
|
||||
} else {
|
||||
var div = document.getElementById("argument_"+command);
|
||||
var input = div.getElementsByTagName("input");
|
||||
for (var i in input) {
|
||||
if (input[i].value) {
|
||||
detail.push(input[i].value);
|
||||
}
|
||||
}
|
||||
result = result.parentElement;
|
||||
result.hidden = !result.hidden;
|
||||
append.hidden = result.hidden;
|
||||
}
|
||||
if (!result.hidden) {
|
||||
ctx.Cmd(command, detail, function(msg) {
|
||||
show(msg, command);
|
||||
if (!msg.result) {
|
||||
}
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function Direct(event, name, value) {
|
||||
debugger;
|
||||
console.log(event)
|
||||
if (!name) {
|
||||
name = event.currentTarget.value;
|
||||
}
|
||||
|
||||
var direct = document.getElementById("direct");
|
||||
direct.value = name;
|
||||
ctx.Cmd(name, value, function(msg){
|
||||
Result(msg, name);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "command"}}
|
||||
<fieldset><legend>command</legend>
|
||||
<table>
|
||||
<colgroup>{{range .append}}<col class="{{.}}">{{end}}</colgroup>
|
||||
<tr>{{range .append}}<th class="{{.}}" onclick="list('{{.}}')">{{.}}</th>{{end}}</tr>
|
||||
{{$l := index .append|len}}
|
||||
{{if gt $l 0}}
|
||||
{{$meta := .}} {{$first := index .append 0}}
|
||||
{{range $i, $k := index . $first}}
|
||||
<tr>{{$command := index $meta "key" $i}}
|
||||
{{range $key := index $meta "append"}}
|
||||
<td class="{{$key}}">
|
||||
{{if eq $key "input"}}
|
||||
<input type="text" name="{{$command}}" onkeydown="return Command(event, '{{$command}}')">
|
||||
{{else if eq $key "key"}}
|
||||
<code><a href="" onclick="return Direct(event, '{{$command}}')">{{index $meta $key $i}}</a></code>
|
||||
{{else}}
|
||||
<code>{{index $meta $key $i}}</code>
|
||||
{{end}}
|
||||
</td>
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
<fieldset><legend><input id="direct" type="text" onkeydown="return Command(event)"></legend>
|
||||
<table id="append"></table>
|
||||
<pre class="result"><code id="result"></code></pre>
|
||||
</fieldset>
|
||||
<script>
|
||||
function Result(msg) {
|
||||
var result = document.getElementById("result");
|
||||
result.innerHTML = msg.result.join("");
|
||||
|
||||
var append = document.getElementById("append");
|
||||
var tr = document.createElement("tr");
|
||||
append.appendChild(tr)
|
||||
for (var k in msg.append) {
|
||||
var th = document.createElement("th");
|
||||
th.innerHTML = k;
|
||||
}
|
||||
}
|
||||
|
||||
function Command(event, name) {
|
||||
if (event.keyCode == 13) {
|
||||
var direct = document.getElementById("direct");
|
||||
if (name) {
|
||||
direct.value = name;
|
||||
ctx.Cmd(name, event.currentTarget.value, Result);
|
||||
} else {
|
||||
ctx.Cmd(event.currentTarget.value, "", Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Direct(event, name, value) {
|
||||
console.log(event)
|
||||
if (!name) {
|
||||
name = event.currentTarget.value;
|
||||
}
|
||||
|
||||
var direct = document.getElementById("direct");
|
||||
direct.value = name;
|
||||
ctx.Cmd(name, value, Result);
|
||||
return false;
|
||||
}
|
||||
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "module"}}
|
||||
<fieldset><legend><input type="text" id="module" value="{{index .current_module 0}}" onkeydown="return Change(event, 'dir')"></legend>
|
||||
<table>
|
||||
<colgroup>{{range .append}}<col class="{{.}}">{{end}}</colgroup>
|
||||
<tr>{{range .append}}<th class="{{.}}" onclick="list('{{.}}')">{{.}}</th>{{end}}</tr>
|
||||
{{$l := index .append|len}}
|
||||
{{if gt $l 0}}
|
||||
{{$meta := .}} {{$first := index .append 0}}
|
||||
{{range $i, $k := index . $first}}
|
||||
<tr>
|
||||
{{range $key := index $meta "append"}}
|
||||
{{if eq $key "name"}}
|
||||
<td class="{{$key}}">
|
||||
<code><a href="" onclick="ctx.Search('dir', '{{index $meta "module" $i}}'); return false">{{index $meta $key $i}}</a></code>
|
||||
</td>
|
||||
{{else}}
|
||||
<td class="{{$key}}">
|
||||
<code>{{index $meta $key $i}}</code>
|
||||
</td>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "domain"}}
|
||||
<fieldset><legend><input type="text" id="domain" value="{{index . "current_domain" 0}}" onkeydown="return Change(event, 'dir')"></legend>
|
||||
<table>
|
||||
<colgroup>{{range .append}}<col class="{{.}}">{{end}}</colgroup>
|
||||
<tr>{{range .append}}<th class="{{.}}" onclick="list('{{.}}')">{{.}}</th>{{end}}</tr>
|
||||
{{$l := index .append|len}}
|
||||
{{if gt $l 0}}
|
||||
{{$meta := .}} {{$first := index .append 0}}
|
||||
{{range $i, $k := index . $first}}
|
||||
<tr>
|
||||
{{range $key := index $meta "append"}}
|
||||
{{if eq $key "name"}}
|
||||
<td class="{{$key}}">
|
||||
<code><a href="" onclick="ctx.Search('domain', '{{index $meta "domain" $i}}'); return false">{{index $meta $key $i}}</a></code>
|
||||
</td>
|
||||
{{else}}
|
||||
<td class="{{$key}}">
|
||||
<code>{{index $meta $key $i}}</code>
|
||||
</td>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "tail"}}
|
||||
<script src="library/context.js"></script>
|
||||
<script>
|
||||
function Change(event, key) {
|
||||
if (event.keyCode == 13) {
|
||||
ctx.Search(key, event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
function list(what) {
|
||||
ctx.Cookie("list", what);
|
||||
ctx.Cookie("sort_order", ctx.Cookie("sort_order")*1 + 1);
|
||||
location.assign(location.href);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
{{$msg := .}}
|
||||
{{$meta := .Meta}}
|
||||
{{$sess := $msg.Sessions}}
|
||||
{{range .Meta.tmpl}}
|
||||
{{if eq . "login"}}
|
||||
{{template "login" $meta}}
|
||||
{{else if eq . "userinfo"}}
|
||||
{{template "userinfo" $msg}}
|
||||
{{else if eq . "share"}}
|
||||
{{template "share" $sess.share}}
|
||||
{{else if eq . "cache"}}
|
||||
{{template "cache" $sess.cache.Meta}}
|
||||
{{else if eq . "config"}}
|
||||
{{template "config" $sess.config.Meta}}
|
||||
{{else if eq . "command"}}
|
||||
{{template "command" $sess.command.Meta}}
|
||||
{{template "command2" $sess.command.Meta}}
|
||||
{{else if eq . "module"}}
|
||||
{{template "module" $sess.module.Meta}}
|
||||
{{else if eq . "domain"}}
|
||||
{{template "domain" $sess.domain.Meta}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
@ -1,163 +0,0 @@
|
||||
{{define "list"}}
|
||||
<fieldset><legend><input type="text" id="dir" value="{{meta .dir}}" onkeydown="return Change(event)"></legend>
|
||||
<table>
|
||||
<colgroup>{{range .append}}<col class="{{.}}">{{end}}</colgroup>
|
||||
|
||||
<tr>
|
||||
{{$sort := meta .sort}}
|
||||
{{$reverse := meta .reverse}}
|
||||
{{range .append}}
|
||||
{{if eq $sort .}}
|
||||
<th class="{{.}} sort" onclick="list('{{.}}')">{{.}}</th>
|
||||
{{else if eq $reverse .}}
|
||||
<th class="{{.}} reverse" onclick="list('{{.}}')">{{.}}</th>
|
||||
{{else if eq . "path"}}
|
||||
{{else}}
|
||||
<th class="{{.}}" onclick="list('{{.}}')">{{.}}</th>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tr>
|
||||
|
||||
{{if .append}}
|
||||
{{$meta := .}}
|
||||
{{$first := index .append 0}}
|
||||
{{range $i, $k := index . $first}}
|
||||
<tr>
|
||||
{{range $key := index $meta "append"}}
|
||||
{{if eq $key "name"}}
|
||||
{{$type := index $meta "type" $i}}
|
||||
<td class="{{$key}}">
|
||||
<a {{if eq $type "file"}} download="{{index $meta $key $i}}" {{end}}
|
||||
href="/upload?dir={{index $meta "path" $i}}"><code>{{index $meta $key $i}}</code></a>
|
||||
</td>
|
||||
{{else if eq $key "path"}}
|
||||
{{else}}
|
||||
<td class="{{$key}}">
|
||||
<code>{{index $meta $key $i}}</code>
|
||||
</td>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</fieldset>
|
||||
<style>
|
||||
.time {
|
||||
padding-right:20px;
|
||||
}
|
||||
.size {
|
||||
text-align:right;
|
||||
padding-right:20px;
|
||||
}
|
||||
.name {
|
||||
padding-left:10px;
|
||||
text-align:left;
|
||||
}
|
||||
.sort {
|
||||
color:red;
|
||||
}
|
||||
.reverse {
|
||||
color:green;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function Change(event) {
|
||||
if (event.keyCode == 13) {
|
||||
ctx.Search("dir", event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
function list(what) {
|
||||
ctx.Cookie("list_order", ctx.Cookie("list_order")*1 + 1);
|
||||
ctx.Cookie("list", what);
|
||||
ctx.Refresh();
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "git"}}
|
||||
<fieldset><legend>branch</legend>
|
||||
<pre>{{index . "result"}}</pre>
|
||||
</fieldset>
|
||||
<fieldset><legend>status</legend>
|
||||
<pre>{{index . "result"}}</pre>
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "tmux"}}
|
||||
{{$meta := .}}
|
||||
{{range $index, $value := index $meta "append"}}
|
||||
<fieldset><legend>{{$value}}</legend>
|
||||
{{if eq $value "buffer"}}
|
||||
<button onclick="copy_tmux_buffer('copy')">copy</button>
|
||||
<button onclick="send_tmux_buffer('paste')">send</button>
|
||||
<textarea rows="5" cols="60" name="tmux_buffer">{{meta . "buffer" 0}}</textarea>
|
||||
<script>
|
||||
var buffer = document.getElementsByName("tmux_buffer")[0];
|
||||
function copy_tmux_buffer(action) {
|
||||
buffer.select();
|
||||
document.execCommand(action);
|
||||
}
|
||||
function send_tmux_buffer(action) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "/paste?content="+encodeURIComponent(buffer.value));
|
||||
xhr.send()
|
||||
}
|
||||
</script>
|
||||
{{else}}
|
||||
<pre>{{meta $meta $value}}</pre>
|
||||
{{end}}
|
||||
</fieldset>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{define "upload"}}
|
||||
<fieldset><legend>upload</legend>
|
||||
<form method="POST" action="/create?dir={{option . "dir"|meta|unscaped}}" enctype="multipart/form-data">
|
||||
<input type="file" name="file"><input type="submit">
|
||||
</form>
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "create"}}
|
||||
<fieldset><legend>create</legend>
|
||||
<form method="POST" action="/create?dir={{option . "dir"|meta|unscaped}}">
|
||||
<table>
|
||||
<tr><td>filename:</td><td><input type="text" name="filename" required><input type="submit"></td></tr>
|
||||
<tr><td>content:</td><td><textarea rows="5" cols="60" name="content"></textarea></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
</fieldset>
|
||||
{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
{{$msg := .}}
|
||||
{{$meta := .Meta}}
|
||||
{{$sess := .Sessions}}
|
||||
{{range .Meta.tmpl}}
|
||||
{{$tmpl := index $sess .}}
|
||||
|
||||
{{if eq . "login"}}
|
||||
{{template "login" $meta}}
|
||||
{{else if eq . "userinfo"}}
|
||||
{{template "userinfo" $msg}}
|
||||
{{else if eq . "share"}}
|
||||
{{template "share" $sess.share}}
|
||||
{{else if eq . "list"}}
|
||||
{{template "list" $msg.Sessions.list.Meta}}
|
||||
{{else if eq . "tmux"}}
|
||||
{{template "tmux" $msg.Sessions.tmux.Meta}}
|
||||
{{else if eq . "git"}}
|
||||
{{if $msg.Sessions.git}}
|
||||
{{template "git" $msg.Sessions.git.Meta}}
|
||||
{{end}}
|
||||
{{else if eq . "upload"}}
|
||||
{{template "upload" $msg}}
|
||||
{{else if eq . "create"}}
|
||||
{{template "create" $msg}}
|
||||
{{else}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user