1
0
forked from x/icebergs

opt story

This commit is contained in:
shaoying 2020-01-01 15:27:37 +08:00
parent a0586fce14
commit deb76d84cb
3 changed files with 177 additions and 85 deletions

View File

@ -41,8 +41,9 @@ func Cookie(msg *ice.Message, sessid string) string {
return sessid return sessid
} }
func IsLocalIP(ip string) bool { func IsLocalIP(ip string) bool {
return ip == "::1" || ip == "127.0.0.1" return ip == "::1" || strings.HasPrefix(ip, "127.")
} }
func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request) bool { func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request) bool {
if msg.Options(ice.WEB_SESS) { if msg.Options(ice.WEB_SESS) {
// 会话认证 // 会话认证
@ -212,6 +213,10 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
msg.Optionv(k, v) msg.Optionv(k, v)
} }
if msg.Optionv("cmds") == nil {
msg.Optionv("cmds", strings.Split(msg.Option(ice.MSG_USERURL), "/")[2:])
}
// 执行命令 // 执行命令
if web.Login(msg, w, r) && msg.Target().Run(msg, cmd, msg.Option(ice.MSG_USERURL), kit.Simple(msg.Optionv("cmds"))...) != nil { if web.Login(msg, w, r) && msg.Target().Run(msg, cmd, msg.Option(ice.MSG_USERURL), kit.Simple(msg.Optionv("cmds"))...) != nil {
// 输出响应 // 输出响应
@ -1008,30 +1013,29 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
// head list data time text file // head list data time text file
switch arg[0] { switch arg[0] {
case "pull": case ice.STORY_PULL:
// 起止节点 // 起止节点
begin, end := arg[2], "" prev, begin, end := "", arg[2], ""
m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, val map[string]interface{}) { m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, val map[string]interface{}) {
end = kit.Format(kit.Value(val, kit.Keys("remote", arg[1], "list"))) prev, end = kit.Format(val["list"]), kit.Format(kit.Value(val, kit.Keys("remote", arg[1], "pull", "list")))
}) })
prev, pull := "", end pull := end
var first map[string]interface{} var first map[string]interface{}
for begin != end { for begin != end {
msg := m.Cmd(ice.WEB_SPIDE, arg[1], "/space/pull/"+begin+"/"+end).Table(func(index int, value map[string]string, head []string) { if m.Cmd(ice.WEB_SPIDE, arg[1], "/story/pull", "begin", begin, "end", end).Table(func(index int, value map[string]string, head []string) {
if m.Confm(ice.WEB_CACHE, kit.Keys("hash", value["data"])) == nil { if m.Richs(ice.WEB_CACHE, nil, value["data"], nil) == nil {
// 导入缓存 // 导入缓存
m.Log(ice.LOG_IMPORT, "%v: %v", value["data"], value["save"]) m.Log(ice.LOG_IMPORT, "%v: %v", value["data"], value["save"])
if node := kit.UnMarshal(value["save"]); kit.Format(kit.Value(node, "file")) != "" { if node := kit.UnMarshal(value["save"]); kit.Format(kit.Value(node, "file")) != "" {
m.Cmd(ice.WEB_SPIDE, arg[1], "cache", "/space/download/"+kit.Format(kit.Value(value, "data"))) m.Cmd(ice.WEB_SPIDE, arg[1], "cache", "GET", "/story/download/"+kit.Format(value["data"]))
} else { } else {
m.Conf(ice.WEB_CACHE, kit.Keys("hash", value["data"]), node) m.Conf(ice.WEB_CACHE, kit.Keys("hash", value["data"]), node)
} }
} }
node := kit.UnMarshal(value["node"]).(map[string]interface{}) node := kit.UnMarshal(value["node"]).(map[string]interface{})
if m.Confm(ice.WEB_STORY, kit.Keys("hash", value["list"])) == nil { if m.Richs(ice.WEB_STORY, nil, value["list"], nil) == nil {
// 导入节点 // 导入节点
m.Log(ice.LOG_IMPORT, "%v: %v", value["list"], value["node"]) m.Log(ice.LOG_IMPORT, "%v: %v", value["list"], value["node"])
m.Conf(ice.WEB_STORY, kit.Keys("hash", value["list"]), node) m.Conf(ice.WEB_STORY, kit.Keys("hash", value["list"]), node)
@ -1041,19 +1045,22 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
if m.Richs(ice.WEB_STORY, "head", node["story"], nil) == nil { if m.Richs(ice.WEB_STORY, "head", node["story"], nil) == nil {
// 自动创建 // 自动创建
h := m.Rich(ice.WEB_STORY, "head", kit.Dict( h := m.Rich(ice.WEB_STORY, "head", kit.Dict(
"count", node["count"], "scene", node["scene"], "story", node["story"], "list", value["list"], "scene", node["scene"], "story", node["story"],
"count", node["count"], "list", value["list"],
)) ))
m.Log(ice.LOG_CREATE, "%v: %v", h, node["story"]) m.Log(ice.LOG_CREATE, "%v: %v", h, node["story"])
} }
pull, first = kit.Format(value["list"]), node pull, first = kit.Format(value["list"]), node
m.Richs(ice.WEB_STORY, "head", node["story"], func(key string, val map[string]interface{}) { m.Richs(ice.WEB_STORY, "head", node["story"], func(key string, val map[string]interface{}) {
// 更新分支
prev = kit.Format(val["list"]) prev = kit.Format(val["list"])
m.Log(ice.LOG_IMPORT, "%v: %v", pull, arg[1]) if kit.Int(node["count"]) > kit.Int(kit.Value(val, kit.Keys("remote", arg[1], "pull", "count"))) {
kit.Value(val, kit.Keys("remote", arg[1]), kit.Dict( // 更新分支
"list", pull, "time", node["time"], "count", node["count"], m.Log(ice.LOG_IMPORT, "%v: %v", pull, arg[1])
)) kit.Value(val, kit.Keys("remote", arg[1], "pull"), kit.Dict(
"time", node["time"], "list", pull, "count", node["count"],
))
}
}) })
} }
@ -1069,61 +1076,71 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
} }
begin = kit.Format(node["prev"]) begin = kit.Format(node["prev"])
}) }).Append("list") == "" {
if msg.Append("list") == "" {
break break
} }
} }
if prev != pull { if !m.Warn(prev != pull, "unmerge: %s", pull) {
m.Log(ice.LOG_WARN, "unmerge %s", pull) m.Echo(pull)
m.Echo("unmerge %s", pull)
} }
case "push": case ice.STORY_PUSH:
// 更新分支
m.Cmdx(ice.WEB_STORY, "pull", arg[1:]) m.Cmdx(ice.WEB_STORY, "pull", arg[1:])
// 查询索引 // 查询索引
push, list := "", m.Cmd(ice.WEB_STORY, "index", arg[2]).Append("list") push, list := "", m.Cmd(ice.WEB_STORY, "index", arg[2]).Append("list")
m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, val map[string]interface{}) { m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, val map[string]interface{}) {
push = kit.Format(kit.Value(val, kit.Keys("remote", arg[1], "list"))) push = kit.Format(kit.Value(val, kit.Keys("remote", arg[1], "push", "list")))
}) })
// 查询节点 // 查询节点
nodes := []string{} nodes := []string{}
for list != "" && list != push { for list != "" && list != push {
m.Confm(ice.WEB_STORY, kit.Keys("hash", list), func(value map[string]interface{}) { m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) {
nodes, list = append(nodes, list), kit.Format(value["prev"]) nodes, list = append(nodes, list), kit.Format(value["prev"])
}) })
} }
for _, v := range kit.Revert(nodes) { for _, v := range kit.Revert(nodes) {
node := m.Confm(ice.WEB_STORY, kit.Keys("hash", v)) m.Richs(ice.WEB_STORY, nil, v, func(list string, node map[string]interface{}) {
save := m.Confm(ice.WEB_CACHE, kit.Keys("hash", node["data"])) m.Richs(ice.WEB_CACHE, nil, node["data"], func(data string, save map[string]interface{}) {
// 推送节点
m.Log(ice.LOG_EXPORT, "%s: %s", v, kit.Format(node))
m.Cmd(ice.WEB_SPIDE, arg[1], "/story/push",
"list", v, "node", kit.Format(node),
"data", node["data"], "save", kit.Format(save),
)
// 推送节点 if kit.Format(save["file"]) != "" {
m.Log(ice.LOG_EXPORT, "%s: %s", v, node) // 推送缓存
m.Cmd(ice.WEB_SPIDE, arg[1], "/space/push", m.Cmd(ice.WEB_SPIDE, arg[1], "/story/upload",
"list", v, "node", kit.Format(node), "part", "upload", "@"+kit.Format(save["file"]),
"data", node["data"], "save", kit.Format(save), )
) }
if kit.Format(save["file"]) != "" { })
// 推送缓存 })
m.Cmd(ice.WEB_SPIDE, arg[1], "/space/upload",
"part", "upload", "@"+kit.Format(save["file"]),
)
}
} }
// 更新分支
m.Cmd(ice.WEB_STORY, "pull", arg[1:]) m.Cmd(ice.WEB_STORY, "pull", arg[1:])
case "watch": case ice.STORY_WATCH:
msg := m.Cmd(ice.WEB_STORY, "index", arg[1]) msg := m.Cmd(ice.WEB_STORY, "index", arg[1])
name := kit.Select(arg[1], arg, 2) name := kit.Select(arg[1], arg, 2)
os.Rename(name, kit.Keys(name, "bak")) os.Rename(name, kit.Keys(name, "bak"))
os.Link(msg.Append("file"), name) if msg.Append("file") != "" {
m.Log(ice.LOG_EXPORT, "%s: %s", msg.Append("link"), name) os.Link(msg.Append("file"), name)
m.Log(ice.LOG_EXPORT, "%s: %s", msg.Append("file"), name)
} else {
if f, p, e := kit.Create(name); m.Assert(e) {
defer f.Close()
f.WriteString(msg.Append("text"))
m.Log(ice.LOG_EXPORT, "%s: %s", msg.Append("text"), p)
}
}
case "catch": case ice.STORY_CATCH:
if last := m.Richs(ice.WEB_STORY, "head", arg[2], nil); last != nil { if last := m.Richs(ice.WEB_STORY, "head", arg[2], nil); last != nil {
if t, e := time.ParseInLocation(ice.ICE_TIME, kit.Format(last["time"]), time.Local); e == nil { if t, e := time.ParseInLocation(ice.ICE_TIME, kit.Format(last["time"]), time.Local); e == nil {
if s, e := os.Stat(arg[2]); e == nil && s.ModTime().Before(t) { if s, e := os.Stat(arg[2]); e == nil && s.ModTime().Before(t) {
@ -1134,9 +1151,18 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
} }
} }
fallthrough fallthrough
case "add", "upload", "merge": case "add", ice.STORY_UPLOAD:
pull := ""
if arg[0] == ice.STORY_CATCH {
pull, arg = kit.Select("", arg, 3), arg[:3]
m.Richs(ice.WEB_STORY, "head", pull, func(key string, value map[string]interface{}) {
// 合并分支
pull = kit.Format(kit.Value(value, kit.Keys("remote", pull, "pull", "list")))
})
}
// 保存数据 // 保存数据
if arg[0] != "merge" && m.Richs(ice.WEB_CACHE, nil, kit.Select("", arg, 3), nil) == nil { if m.Richs(ice.WEB_CACHE, nil, kit.Select("", arg, 3), nil) == nil {
m.Cmdy(ice.WEB_CACHE, arg) m.Cmdy(ice.WEB_CACHE, arg)
arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")} arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")}
} }
@ -1148,51 +1174,34 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
m.Log("info", "head: %v prev: %v count: %v", head, prev, count) m.Log("info", "head: %v prev: %v count: %v", head, prev, count)
}) })
pull := "" if last := m.Richs(ice.WEB_STORY, nil, prev, nil); prev != "" && last != nil && last["data"] == arg[3] {
if arg[0] == "merge" {
m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, value map[string]interface{}) {
pull = kit.Format(kit.Value(value, kit.Keys("remote", arg[3], "list")))
})
if pull != "" {
m.Conf(ice.WEB_STORY, kit.Keys("head", prev, "data"))
arg[3] = m.Conf(ice.WEB_STORY, kit.Keys("hash", prev, "data"))
m.Log("merge %s <- %s", arg[3], pull)
} else {
break
}
} else if last := m.Richs(ice.WEB_STORY, nil, prev, nil); prev != "" && last != nil && last["data"] == arg[3] {
// 重复提交 // 重复提交
break break
} }
// 添加节点 // 添加节点
list := m.Rich(ice.WEB_STORY, nil, kit.Dict( list := m.Rich(ice.WEB_STORY, nil, kit.Dict(
"count", count+1, "scene", arg[1], "story", arg[2], "data", arg[3], "prev", prev, "pull", pull, "scene", arg[1], "story", arg[2], "count", count+1, "data", arg[3], "prev", prev, "pull", pull,
)) ))
m.Log(ice.LOG_CREATE, "story: %s %s: %s", list, arg[1], arg[2]) m.Log(ice.LOG_CREATE, "story: %s %s: %s", list, arg[1], arg[2])
m.Push("list", list) m.Push("list", list)
m.Push("pull", pull)
if head == "" { if head == "" {
// 添加索引 // 添加索引
m.Rich(ice.WEB_STORY, "head", kit.Dict( m.Rich(ice.WEB_STORY, "head", kit.Dict("scene", arg[1], "story", arg[2], "count", count+1, "list", list))
"count", count+1, "scene", arg[1], "story", arg[2], "list", list,
))
} else { } else {
// 更新索引 // 更新索引
value["count"] = count + 1 value["count"] = count + 1
value["time"] = m.Time() value["time"] = m.Time()
value["list"] = list value["list"] = list
} }
m.Echo(list) m.Echo(list)
case "download": case ice.STORY_DOWNLOAD:
// 下载文件 // 下载文件
if m.Cmdy(ice.WEB_STORY, "index", arg[1]); m.Append("file") != "" { m.Cmdy(ice.WEB_STORY, "index", arg[1])
m.Push("_output", "file") m.Push("_output", kit.Select("file", "result", m.Append("file") == ""))
} else {
m.Push("_output", "result")
}
case "commit": case "commit":
// 查询索引 // 查询索引
@ -1349,6 +1358,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
m.Echo(h) m.Echo(h)
} }
}}, }},
ice.WEB_ROUTE: {Name: "route", Help: "路由", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_ROUTE: {Name: "route", Help: "路由", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}}, }},
ice.WEB_PROXY: {Name: "proxy", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_PROXY: {Name: "proxy", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
@ -1358,28 +1368,93 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
ice.WEB_LABEL: {Name: "label", Help: "标签", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_LABEL: {Name: "label", Help: "标签", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}}, }},
"/proxy/": {Name: "/proxy/", Help: "代理商", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
key := kit.Select("", strings.Split(cmd, "/"), 2) switch arg[0] {
m.Confm(ice.WEB_SHARE, kit.Keys("hash", key), func(value map[string]interface{}) { case "login":
m.Info("share %s %v", key, kit.Format(value)) Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option("username"), m.Option("password")))
switch value["type"] {
case ice.TYPE_STORY:
if m.Cmdy(ice.WEB_STORY, "index", kit.Value(value, "extra.data")).Append("text") == "" {
m.Cmdy(ice.WEB_SPACE, kit.Value(value, "extra.pod"), ice.WEB_STORY, "index", kit.Value(value, "extra.data"))
}
m.Push("_output", kit.Select("file", "result", m.Append("file") == ""))
default: default:
if m.Cmdy(ice.WEB_STORY, "index", value["data"]); m.Append("file") != "" { key := kit.Select("", strings.Split(cmd, "/"), 2)
m.Push("_output", "file") m.Confm(ice.WEB_SHARE, kit.Keys("hash", key), func(value map[string]interface{}) {
} else { m.Info("share %s %v", key, kit.Format(value))
m.Push("_output", "result") switch value["type"] {
case ice.TYPE_STORY:
if m.Cmdy(ice.WEB_STORY, "index", kit.Value(value, "extra.data")).Append("text") == "" {
m.Cmdy(ice.WEB_SPACE, kit.Value(value, "extra.pod"), ice.WEB_STORY, "index", kit.Value(value, "extra.data"))
}
m.Push("_output", kit.Select("file", "result", m.Append("file") == ""))
default:
if m.Cmdy(ice.WEB_STORY, "index", value["data"]); m.Append("file") != "" {
m.Push("_output", "file")
} else {
m.Push("_output", "result")
}
}
})
}
}},
"/story/": {Name: "/story/", Help: "故事会", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] {
case ice.STORY_PULL:
// 下载节点
list := m.Cmd(ice.WEB_STORY, "index", m.Option("begin")).Append("list")
for i := 0; i < 10 && list != "" && list != m.Option("end"); i++ {
if m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) {
// 节点信息
m.Push("list", key)
m.Push("node", kit.Format(value))
m.Push("data", value["data"])
m.Push("save", kit.Format(m.Richs(ice.WEB_CACHE, nil, value["data"], nil)))
list = kit.Format(value["prev"])
}) == nil {
break
} }
} }
}) case ice.STORY_PUSH:
// 上传节点
if m.Richs(ice.WEB_CACHE, nil, m.Option("data"), nil) == nil {
// 导入缓存
m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("data"), m.Option("save"))
node := kit.UnMarshal(m.Option("save"))
m.Conf(ice.WEB_CACHE, kit.Keys("hash", m.Option("data")), node)
}
node := kit.UnMarshal(m.Option("node")).(map[string]interface{})
if m.Richs(ice.WEB_STORY, nil, m.Option("list"), nil) == nil {
// 导入节点
m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("list"), m.Option("node"))
m.Conf(ice.WEB_STORY, kit.Keys("hash", m.Option("list")), node)
}
if head := m.Richs(ice.WEB_STORY, "head", node["story"], nil); head == nil {
// 自动创建
h := m.Rich(ice.WEB_STORY, "head", kit.Dict(
"scene", node["scene"], "story", node["story"],
"count", node["count"], "list", m.Option("list"),
))
m.Log(ice.LOG_CREATE, "%v: %v", h, node["story"])
} else if head["list"] == kit.Format(node["prev"]) || head["list"] == kit.Format(node["pull"]) {
// 快速合并
head["list"] = m.Option("list")
head["count"] = node["count"]
head["time"] = node["time"]
} else {
// 推送失败
}
case ice.STORY_UPLOAD:
// 上传数据
m.Cmdy(ice.WEB_CACHE, "upload")
case ice.STORY_DOWNLOAD:
// 下载数据
m.Cmdy(ice.WEB_STORY, "index", arg[1])
m.Push("_output", kit.Select("file", "result", m.Append("file") == ""))
}
}}, }},
"/space/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/space/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
list := strings.Split(cmd, "/") list := strings.Split(cmd, "/")

13
conf.go
View File

@ -151,6 +151,19 @@ const ( // FAVOR
FAVOR_TMUX = "tmux.init" FAVOR_TMUX = "tmux.init"
FAVOR_RIVER = "river.init" FAVOR_RIVER = "river.init"
) )
const ( // FAVOR
STORY_CATCH = "catch"
STORY_WATCH = "watch"
STORY_STATUS = "status"
STORY_COMMIT = "commit"
STORY_BRANCH = "branch"
STORY_HISTORY = "history"
STORY_PULL = "pull"
STORY_PUSH = "push"
STORY_UPLOAD = "upload"
STORY_DOWNLOAD = "download"
)
var Alias = map[string]string{ var Alias = map[string]string{
CTX_CONFIG: "ctx.config", CTX_CONFIG: "ctx.config",

View File

@ -6,6 +6,10 @@ icebergs是一个后端框架通过模块化、集群化实现资源的无限
``` ```
mkdir miss; cd miss && curl -s https://shylinux.com/publish/build.sh | sh mkdir miss; cd miss && curl -s https://shylinux.com/publish/build.sh | sh
``` ```
一键启动项目
```
mkdir miss; cd miss && curl -s https://shylinux.com/publish/ice.sh | sh
```
## 命令模块 base/cli ## 命令模块 base/cli