1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00

add eachField

This commit is contained in:
shaoying 2019-05-13 19:01:07 +08:00
parent 3631a04bc5
commit 29f3442ac0
9 changed files with 237 additions and 198 deletions

View File

@ -99,7 +99,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
},
Configs: map[string]*ctx.Config{
"runtime": &ctx.Config{Name: "runtime", Value: map[string]interface{}{
"init_env": []interface{}{"ctx_cas", "ctx_dev", "ctx_box", "ctx_root", "ctx_home", "USER"},
"init_env": []interface{}{"ctx_cas", "ctx_dev", "ctx_box", "ctx_root", "ctx_home", "web_port", "ssh_port", "USER"},
"boot": map[string]interface{}{"web_port": ":9094", "ssh_port": ":9090"},
}, Help: "运行环境"},
@ -146,20 +146,35 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
return
}},
"runtime": &ctx.Command{Name: "runtime", Help: "runtime", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
mem := &runtime.MemStats{}
runtime.ReadMemStats(mem)
m.Append("NumCPU", runtime.NumCPU())
m.Append("NumGo", runtime.NumGoroutine())
m.Append("NumGC", mem.NumGC)
m.Append("other", kit.FmtSize(mem.OtherSys))
m.Append("stack", kit.FmtSize(mem.StackSys))
m.Append("heapsys", kit.FmtSize(mem.HeapSys))
m.Append("heapidle", kit.FmtSize(mem.HeapIdle))
m.Append("heapinuse", kit.FmtSize(mem.HeapInuse))
m.Append("heapalloc", kit.FmtSize(mem.HeapAlloc))
m.Append("objects", mem.HeapObjects)
m.Append("lookups", mem.Lookups)
m.Table()
if len(arg) == 0 {
m.Cmdy("ctx.config", "runtime")
return
}
switch arg[0] {
case "system":
mem := &runtime.MemStats{}
runtime.ReadMemStats(mem)
m.Append("NumCPU", runtime.NumCPU())
m.Append("NumGo", runtime.NumGoroutine())
m.Append("NumGC", mem.NumGC)
m.Append("other", kit.FmtSize(mem.OtherSys))
m.Append("stack", kit.FmtSize(mem.StackSys))
m.Append("heapsys", kit.FmtSize(mem.HeapSys))
m.Append("heapidle", kit.FmtSize(mem.HeapIdle))
m.Append("heapinuse", kit.FmtSize(mem.HeapInuse))
m.Append("heapalloc", kit.FmtSize(mem.HeapAlloc))
m.Append("objects", mem.HeapObjects)
m.Append("lookups", mem.Lookups)
m.Table()
default:
if len(arg) == 1 {
m.Cmdy("ctx.config", "runtime", arg[0])
return
}
m.Conf("runtime", arg[0], arg[1])
m.Echo(arg[1])
}
return
}},
"system": &ctx.Command{Name: "system word...", Help: []string{"调用系统命令, word: 命令",
@ -664,7 +679,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.Conf("runtime", "boot.pathname", file)
}
m.Confm("runtime", "init_env", func(index int, key string) {
m.Conf("runtime", "boot."+key, os.Getenv(key))
if value := os.Getenv(key); value != "" {
m.Conf("runtime", "boot."+key, kit.Select("", value, value != "-"))
}
})
return
}},

View File

@ -49,7 +49,6 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
}
m.Conf("runtime", "node.route", m.Conf("runtime", "node.name"))
m.Conf("runtime", "user.name", m.Conf("runtime", "boot.USER"))
m.Conf("runtime", "work.name", m.Conf("runtime", "boot.USER"))
return
}},
"node": &ctx.Command{Name: "node [create|delete [name [type module]]]", Help: "节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -192,12 +191,27 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
switch arg[1] {
case "create": // 创建证书
if name := m.Cmdx("ssh.remote", arg[2], "check", "work", arg[3], m.Conf("runtime", "user.route"), m.Conf("runtime", "user.cert")); name != "" {
m.Conf("runtime", "work.route", arg[2])
m.Conf("runtime", "work.name", name)
m.Echo(name)
user := m.Conf("runtime", "user.route")
if user == "" {
m.Echo("error: no user.route")
return
}
name := kit.Select(m.Conf("runtime", "user.name"), arg, 2)
work := kit.Select(m.Conf("runtime", "work.route"), arg, 3)
if n := m.Cmdx("ssh.remote", work, "check", "work", name, user); n != "" {
m.Conf("runtime", "work.route", work)
m.Conf("runtime", "work.name", n)
m.Echo(n)
} else {
m.Echo("error: %s from %s", name, work)
}
case "search":
work := kit.Select(m.Conf("runtime", "work.route"), arg, 3)
m.Cmdy("ssh.remote", work, "check", "work", "search")
case "check": // 数字验签
if m.Option("user.route") != m.Cmdx("ssh.remote", arg[2], "check", "work", arg[3]) {
m.Log("warn", "work error")
@ -227,17 +241,28 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
}
}
case "work": // 工作验签
if cert := m.Confm("cert", arg[1]); len(arg) == 2 {
if cert != nil {
m.Echo("%s", cert["user"])
switch arg[1] {
case "search":
m.Confm("cert", func(key string, value map[string]interface{}) {
m.Add("append", "key", key)
m.Add("append", "user.route", value["user"])
m.Add("append", "create_time", value["create_time"])
})
m.Table()
default:
if cert := m.Confm("cert", arg[1]); len(arg) == 2 {
if cert != nil {
m.Echo("%s", cert["user"])
}
} else { // 工作签证
if cert == nil {
m.Conf("cert", arg[1], map[string]interface{}{"create_time": m.Time(), "user": arg[2]})
} else if cert["user"] != arg[2] {
return // 签证失败
}
m.Echo(arg[1])
}
} else { // 工作签证
if cert == nil {
m.Conf("cert", arg[1], map[string]interface{}{"create_time": m.Time(), "user": arg[2]})
} else if cert["user"] != arg[2] {
return // 签证失败
}
m.Echo(arg[1])
}
}
return
@ -364,15 +389,20 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
})
// 本机路由
m.Conf("runtime", "node.route", node.Append("node.route")+"."+node.Result(0))
m.Cmd("cli.runtime", "node.route", node.Append("node.route")+"."+node.Result(0))
// 用户路由
if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") {
m.Conf("runtime", "user.route", m.Conf("runtime", "node.route"))
m.Cmd("cli.runtime", "user.route", m.Conf("runtime", "node.route"))
} else if node.Appends("user.route") && !m.Confs("runtime", "user.route") {
m.Cmd("ssh.node", "share", "root", node.Append("user.route"))
}
// 工作路由
if node.Appends("work.route") && !m.Confs("runtime", "work.route") {
m.Cmd("cli.runtime", "work.route", node.Append("work.route"))
}
return nil
}, "send", "add", m.Conf("runtime", "node.name"), m.Conf("runtime", "node.type"), m.Conf("runtime", "node.cert"))
return nil
@ -397,9 +427,10 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
// 同步信息
m.Append("node.name", m.Conf("runtime", "node.name"))
m.Append("user.name", m.Conf("runtime", "user.name"))
m.Append("node.route", m.Conf("runtime", "node.route"))
m.Append("user.route", m.Conf("runtime", "user.route"))
m.Append("user.name", m.Conf("runtime", "user.name"))
m.Append("work.route", m.Conf("runtime", "work.route"))
m.Echo(name).Back(m)
default:
@ -464,7 +495,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
// 路由转发
for _, p := range ps {
m.Find(p, true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
return m.CopyFuck(sub, "append").CopyFuck(sub, "result").Echo("\n")
return m.CopyFuck(sub, "append").CopyFuck(sub, "result")
}, "send", rest, arg)
}
return

View File

@ -113,11 +113,8 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
"flow": &ctx.Command{Name: "flow", Help: "信息流", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch arg[0] {
case "ocean":
m.Confm("ssh.cert", func(key string, value map[string]interface{}) {
m.Add("append", "key", key)
m.Add("append", "user", value["user"])
})
m.Table()
m.Cmdy("ssh.cert", "work", "search")
case "river":
if len(arg) == 1 {
m.Confm("flow", func(key string, value map[string]interface{}) {

View File

@ -25,8 +25,6 @@ fieldset.Target {
padding:0;
min-width:160px;
min-height:80px;
}
fieldset.Target div.output {
overflow:auto;
}
fieldset.Source {

View File

@ -1,168 +1,111 @@
var pane = {}
var page = Page({
pane: pane,
initOcean: function(page, field, option, output) {
initOcean: function(page, pane, form, output) {
var table = kit.AppendChild(output, "table")
pane.Show = function() {
pane.ShowDialog() && (table.innerHTML = "", form.Run(["ocean"], function(msg) {
kit.AppendTable(table, ctx.Table(msg), ["key", "user.route"])
}))
}
return {"button": ["关闭"], "action": function(event) {
pane.ocean.showDialog()
pane.Show()
}}
},
initRiver: function(page, field, option, output) {
pane.channel = output
page.showRiver(page, option)
initRiver: function(page, pane, form, output) {
pane.Show = function() {
output.innerHTML = "", form.Runs(["river"], function(line, index, msg) {
index == 0 && page.target.Show(line.key)
kit.AppendChild(output, [{view: ["item", "div", line.name+"("+line.count+")"], click: function(event) {
page.target.Show(line.key)
}}])
})
}
pane.Show()
return {"button": ["添加", "查找"], "action": function(value) {
switch (value) {
case "添加":
var name = prompt("name")
if (name) {
ctx.Run(page, option.dataset, ["river", "create", name], function(msg) {
page.showRiver(page, option)
})
}
name && form.Run(["river", "create", name], pane.Show)
break
case "查找":
kit.showDialog(pane.ocean)
page.ocean.Show()
break
}
}}
},
showRiver: function(page, option) {
pane.channel.innerHTML = ""
page.getRiver(page, option, function(line, index) {
page.conf.river = page.conf.river || page.showTarget(page, option, line.key) || line.key
kit.AppendChild(pane.channel, [{view: ["item", "div", line.name+"("+line.count+")"], click: function(event) {
if (page.conf.river == line.key) {
return
}
page.conf.river = line.key
page.showTarget(page, option, line.key)
}}])
})
},
getRiver: function(page, option, cb) {
ctx.Run(page, option.dataset, ["river"], function(msg) {
ctx.Table(msg, function(line, index) {
cb(line, index)
initTarget: function(page, pane, form, output) {
var river = ""
pane.Show = function(which) {
which && river != which && (river = which, output.innerHTML = "", form.Runs(["river", "wave", river], function(line, index, msg) {
kit.AppendChild(output, [{view: ["item", "div", line.text], click: function(event) {}}])
pane.scrollBy(0,100)
}))
}
pane.Send = function(type, text, cb) {
form.Run(["river", "wave", river, type, text], function(msg) {
kit.AppendChild(output, [{"text" :[text, "div"]}])
pane.scrollBy(0,100)
typeof cb == "function" && cb(msg)
})
})
},
initTarget: function(page, field, option) {
pane.output = field.querySelector("div.target.output")
ctx.Run(page, option.dataset, ["river"], function(msg) {
kit.Log(msg.result)
})
}
return [{"text": ["target"]}]
},
showTarget: function(page, option, id) {
pane.output.innerHTML = ""
page.getTarget(page, option, id, function(line, index) {
kit.AppendChild(pane.output, [{"view": ["item", "div", line.text]}])
})
},
getTarget: function(page, option, id, cb) {
ctx.Run(page, option.dataset, ["river", "wave", id], function(msg) {
ctx.Table(msg, function(line, index) {
cb(line, index)
})
})
},
initSource: function(page, field, option) {
var ui = kit.AppendChild(option, [{"view": ["input", "textarea"], "name": "input", "data": {"onkeyup": function(event){
if (event.key == "Enter" && !event.shiftKey) {
var value = event.target.value
kit.AppendChild(pane.output, [{"text" :[value, "div"]}])
pane.output.scrollBy(0,100)
// event.target.value = ""
ctx.Run(page, option.dataset, ["river", "wave", page.conf.river, "text", value], function(msg) {
kit.Log(msg.result)
})
}
initSource: function(page, pane, form, output) {
var ui = kit.AppendChild(pane, [{"view": ["input", "textarea"], "name": "input", "data": {"onkeyup": function(event){
event.key == "Enter" && !event.shiftKey && page.target.Send("text", event.target.value, pane.Clear)
}, "onkeydown": function(event) {
if (event.key == "Enter" && !event.shiftKey) {
event.preventDefault()
}
event.key == "Enter" && !event.shiftKey && event.preventDefault()
}}}])
pane.input = ui.input
ctx.Run(page, option.dataset, ["river"], function(msg) {
msg.Table(function(index, line) {
console.log(index)
console.log(line)
})
kit.Log(msg.result)
})
pane.Size = function(width, height) {
pane.style.display = width==0? "none": "block"
pane.style.width = width+"px"
pane.style.height = height+"px"
ui.input.style.width = (width-7)+"px"
ui.input.style.height = (height-7)+"px"
}
pane.Clear = function() {
ui.input = ""
}
return
},
initStorm: function(page, field, option) {
ctx.Run(page, option.dataset, ["river"], function(msg) {
kit.Log(msg.result)
})
initStorm: function(page, pane, form, output) {
return [{"text": ["storm"]}]
},
initSteam: function(page, field, option) {
ctx.Run(page, option.dataset, ["river"], function(msg) {
kit.Log(msg.result)
})
initSteam: function(page, pane, form, output) {
return [{"text": ["steam"]}]
},
panes: {},
range: function(sizes) {
sizes = sizes || {}
var width = document.body.offsetWidth
var river_width = pane.river.offsetWidth
var storm_width = pane.storm.offsetWidth
var source_width = pane.source.offsetWidth
var source_height = pane.source.offsetHeight
var height = document.body.offsetHeight-80
sizes.left == undefined && (sizes.left = page.river.offsetWidth-page.conf.border)
sizes.right == undefined && (sizes.right = page.storm.offsetWidth-page.conf.border)
sizes.middle = width - sizes.left - sizes.right-5*page.conf.border
page.river.Size(sizes.left, height)
page.storm.Size(sizes.right, height)
pane.river.style.height = height+"px"
pane.storm.style.height = height+"px"
pane.target.style.height = (height-source_height)+"px"
if (sizes.left != undefined) {
if (sizes.left == 0) {
pane.river.style.display = "none"
} else {
pane.river.style.display = "block"
pane.river.style.width = sizes.left+"px"
}
}
if (sizes.right != undefined) {
if (sizes.right == 0) {
pane.storm.style.display = "none"
} else {
pane.storm.style.display = "block"
pane.storm.style.width = sizes.right+"px"
}
}
if (sizes.middle != undefined) {
pane.source.style.height = sizes.middle+"px"
pane.target.style.height = (height-sizes.middle-4)+"px"
pane.output.style.height = (height-sizes.middle-8)+"px"
pane.input.style.height = (sizes.middle-7)+"px"
if (sizes.top != undefined) {
sizes.bottom = height-sizes.top-page.conf.border
} else if (sizes.bottom != undefined) {
sizes.top = height-sizes.bottom-page.conf.border
} else {
var source_height = pane.source.offsetHeight-10
pane.input.style.height = source_height+"px"
pane.output.style.height = source_height+"px"
sizes.bottom = page.source.offsetHeight-page.conf.border
sizes.top = height-sizes.bottom-page.conf.border
}
var source_width = pane.source.offsetWidth-10
pane.input.style.width = source_width+"px"
pane.output.style.width = source_width+"px"
kit.Log(sizes)
page.target.Size(sizes.middle, sizes.top)
page.source.Size(sizes.middle, sizes.bottom)
},
init: function(exp) {
var page = this
document.querySelectorAll("body>fieldset").forEach(function(field) {
var option = field.querySelector("form.option")
var output = field.querySelector("div.output")
pane[option.dataset.componet_name] = field
var init = page[field.dataset.init]
page.eachField(page, function(init, pane, form) {
var output = pane.querySelector("div.output")
if (typeof init == "function") {
var conf = page[field.dataset.init](page, field, option, output)
var conf = init(page, pane, form, output)
if (conf && conf["button"]) {
var buttons = []
conf.button.forEach(function(value, index) {
@ -170,14 +113,14 @@ var page = Page({
typeof conf["action"] == "function" && conf["action"](value, event)
}]})
})
kit.InsertChild(field, output, "div", buttons)
kit.InsertChild(pane, output, "div", buttons)
} else if (conf) {
kit.AppendChild(output, conf)
}
}
})
window.onresize = this.range
this.range({left:120, middle:60, right:120})
this.range({left:160, bottom:60, right:160})
},
conf: {},
conf: {border: 4},
})

View File

@ -23,6 +23,13 @@ ctx = context = {
}
this.Run(page, data, [], cb || form.ondaemon)
},
Sync: function(page, option, cmds, cb) {
this.Run(page, option.dataset, cmds, function(msg) {
ctx.Table(msg, function(line, index) {
cb(line, index)
})
})
},
Table: function(msg, cb) {
var ret = []
if (!msg || !msg.append || !msg.append.length || !msg[msg.append[0]]) {

View File

@ -44,6 +44,37 @@ exp = example = {
reload: function() {
location.reload()
},
eachField: function(page, cb) {
document.querySelectorAll("body>fieldset").forEach(function(pane) {
// pane init
pane.ShowDialog = function(width, height) {
return kit.ShowDialog(this, width, height)
}
pane.Size = function(width, height) {
pane.style.display = width==0? "none": "block"
pane.style.width = width+"px"
pane.style.height = height+"px"
}
// form init
var form = pane.querySelector("form.option")
form.Run = function(cmds, cb) {
ctx.Run(page, form.dataset, cmds, cb)
}
form.Runs = function(cmds, cb) {
ctx.Run(page, form.dataset, cmds, function(msg) {
ctx.Table(msg, function(line, index) {
cb(line, index, msg)
})
})
}
page[form.dataset.componet_name] = pane
typeof cb == "function" && cb(page[pane.dataset.init], pane, form)
})
},
}
function Page(page) {
@ -52,8 +83,3 @@ function Page(page) {
}
return page
}
function Pane(pane) {
pane.showDialog = function(width, height) {
kit.showDialog(this, width, height)
}
}

View File

@ -1,4 +1,5 @@
kit = toolkit = {
isMobile: navigator.userAgent.indexOf("Mobile") > -1,
History: {dir: [], pod: [], ctx: [], cmd: [], txt: [], key: [],
add: function(type, data) {
var list = this[type] || []
@ -20,9 +21,6 @@ kit = toolkit = {
console.log(arguments.length == 1? args[0]: args)
return args
},
isMobile: navigator.userAgent.indexOf("Mobile") > -1,
CreateStyle: function(style) {
},
ModifyNode: function(which, html) {
var node = typeof which == "string"? document.querySelector(which): which
@ -54,9 +52,15 @@ kit = toolkit = {
return elm
}
// include require styles style
// tree, code, text, view, click
// type, name, data, list, style
// include require styles // 加载文件
// name
// click
// style
// button
// tree, fork, leaf // 树状结构
// code, text, view // 普通视图
// type, data, list // 基本结构
var kit = this
subs = subs || {}
@ -64,7 +68,7 @@ kit = toolkit = {
child.data = child.data || {}
child.type = child.type || "div"
if (child.style) {
if (typeof(child.style) == "object") {
var str = []
for (var k in child.style) {
str.push(k)
@ -163,9 +167,6 @@ kit = toolkit = {
return parent.insertBefore(elm, position || parent.firstElementChild)
},
AppendStyle: function(parent, style) {
return node
},
AppendTable: function(table, data, fields, cb) {
if (!data || !fields) {
return
@ -187,6 +188,7 @@ kit = toolkit = {
})
})
},
RangeTable: function(table, index, sort_asc) {
var list = table.querySelectorAll("tr")
var new_list = []
@ -435,6 +437,9 @@ kit = toolkit = {
if (w > width) {
w = width
}
if (h > height) {
h = height
}
args["top"] = (height-h)/2
args["left"] = (width-w)/2
@ -467,15 +472,16 @@ kit = toolkit = {
}
}
},
showDialog: function(pane, width, height) {
ShowDialog: function(pane, width, height) {
if (pane.style.display == "none") {
pane.style.display = "block"
this.setView(pane, {dialog: [width||800, height||400]})
} else {
pane.style.display = "none"
return true
}
pane.style.display = "none"
return false
},
showWindow: function(pane, width, height) {
ShowWindow: function(pane, width, height) {
this.setView(pane, {window: [width||80, height||40]})
},
}

View File

@ -338,15 +338,13 @@ web模块会将所有的HTTP请求转换成context的命令调用所以HTTP
根据code的componet下的login组件依次调用每个接口的命令然后将执行结果与参数一起调用golang的template渲染生成HTML。
所有命令都解析完成后就可以生成一个完整的网页。当然如果Accept是application/json则会跳过模块渲染直接返回多条命令的执行结果。
所以componet就是接口的集合统一提供参数配置、权限检查、命令执行、模板渲染降低内部命令与外部应用的耦合性但又将前后端完全融合在一起。
所以componet就是接口的集合统一提供参数配置、权限检查、命令执行、模板渲染前端展示样式前端初始化函数降低内部命令与外部应用的耦合性但又将前后端完全融合在一起。
如下是web.code模块的应用接口定义。配置componet下定义了多个组件每个组件下定义了多个接口。
login就是登录页面下面定义了三个接口code、login、tail
其中code使用模板head生成网页头会包括一些配置如favicon可以指定图标文件styles指定引用模式表。
其中tail使用模板tail生成网页尾会包括一些配置如scripts指定引用脚本文件。
login就是网页组件了生成一个网页登录的输入表单并接收表单请求调用aaa模块的auth命令进行用户身份的验证。
其中arguments指定了Form表单字段的列表。
```
@ -381,16 +379,32 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
#### 模板
usr/template 存放了网页的模板文件context会调用golang的template接口进行后端渲染生成html文件。
componet下每一个接口都会指定一个模板web模块下的/render命令会依次渲染从而生成一个完整的网页。
不同的应用模块都会有自己的模板目录,也有公共模板库。
- usr/template/common.tmpl 公共模板
- usr/template/code/ code模块的模板
- usr/template/wiki/ wiki
- usr/template/chat/
- usr/template/wiki/ wiki模块的模板
- usr/template/chat/ chat模块的模板
usr/librarys 存放了css与js
#### 样式
所有的css都存放usr/librarys
- example.css
- code.css
- wiki.css
- chat.css
#### 脚本
所有的js都存放usr/librarys
- toolkit.js 工具库主要是网页相关的操作如AppendChild
- context.js 通信库主要是用来与后端context进行通信
- example.js 框架库,统一定义了网页的框架,每个应用网页都会继承
- code.js 工具链应用的网页
- wiki.js 知识库应用的网页
- chat.js 信息流应用的网页
### 小程序
### 开发板