package chat import ( "net/http" "path" "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) func _website_url(m *ice.Message, file string) string { return strings.Split(web.MergePodWebSite(m, "", file), "?")[0] } func _website_parse(m *ice.Message, text string, args ...string) (ice.Map, bool) { if text == "" { return nil, false } const ( HEADER = "Header" RIVER = "River" FOOTER = "Footer" ORDER = "order" TITLE = "title" MENUS = "menus" ) river, storm, last := kit.Dict( HEADER, kit.Dict(MENUS, kit.List(), ctx.STYLE, kit.Dict(ctx.DISPLAY, "none")), RIVER, kit.Dict(MENUS, kit.List(), ctx.ACTION, kit.List("")), FOOTER, kit.Dict(MENUS, kit.List(), ctx.STYLE, kit.Dict(ctx.DISPLAY, "none")), args, ), kit.Dict(), kit.Dict() nriver, nstorm, prefix := 0, 0, "" m.Cmd(lex.SPLIT, "", mdb.KEY, mdb.NAME, kit.Dict(nfs.CAT_CONTENT, text), func(deep int, ls []string) { if deep == 1 { switch ls[0] { case HEADER, RIVER, FOOTER: for i := 1; i < len(ls); i += 2 { kit.Value(river, kit.Keys(ls[0], ls[i]), ls[i+1]) } return } } data := kit.Dict() switch kit.Ext(ls[0]) { case nfs.JS: ls[0], data[ctx.DISPLAY] = kit.Select(ctx.CAN_PLUGIN, ctx.GetFileCmd(ls[0])), ctx.FileURI(ls[0]) case nfs.GO: ls[0] = ctx.GetFileCmd(ls[0]) case nfs.SHY: ls[0], data[ctx.ARGS] = "web.wiki.word", ls[0] case nfs.SH: ls[0], data[ctx.ARGS] = "web.code.sh.sh", ls[0] case nfs.PY: ls[0], data[ctx.ARGS] = "web.code.sh.py", ls[0] case "~": prefix, ls = ls[1], ls[1:] fallthrough case "-": for _, v := range ls[1:] { last[mdb.LIST] = append(last[mdb.LIST].([]ice.Any), kit.Dict(mdb.INDEX, kit.Keys(prefix, v))) } return } if ls[0] == "" { return } else if len(ls) == 1 && deep > 2 { ls = append(ls, m.Cmd(ctx.COMMAND, ls[0]).Append(mdb.HELP)) } else if len(ls) == 1 { ls = append(ls, ls[0]) } else if ls[1] == "" { ls[1] = ls[0] } for i := 2; i < len(ls); i += 2 { switch ls[i] { case ctx.ARGS: data[ls[i]] = kit.Split(ls[i+1]) case ctx.DISPLAY: data[ls[i]] = ice.Display(ls[i+1])[ctx.DISPLAY] case ctx.STYLE, ctx.ACTION, TITLE, MENUS: data[ls[i]] = kit.UnMarshal(ls[i+1]) default: data[ls[i]] = ls[i+1] } } switch deep { case 1: if nriver++; ls[0] == ice.AUTO { ls[0] = kit.Format(nriver) } nstorm, storm = 0, kit.Dict() river[ls[0]] = kit.Dict(mdb.NAME, ls[1], STORM, storm, data, ORDER, len(river)) case 2: if nstorm++; ls[0] == ice.AUTO { ls[0] = kit.Format(nstorm) } last = kit.Dict(mdb.NAME, ls[1], mdb.LIST, kit.List(), data, ORDER, len(storm)) storm[ls[0]] = last prefix = "" default: last[mdb.LIST] = append(last[mdb.LIST].([]ice.Any), kit.Dict(mdb.NAME, kit.Select(ls[0], data[mdb.NAME]), mdb.HELP, ls[1], mdb.INDEX, ls[0], data)) } }) return river, true } func _website_render(m *ice.Message, w http.ResponseWriter, r *http.Request, kind, text, name string) bool { msg := m.Spawn(w, r) switch kind { case nfs.ZML: web.RenderCmd(msg, CAN_PARSE, text, name) case nfs.IML: res, _ := _website_parse(msg, text) msg.RenderResult(_website_template2, kit.Format(res)) case nfs.SHY: if r.Method == http.MethodGet { web.RenderCmd(msg, msg.Prefix(DIV), text) } else { r.URL.Path = "/chat/cmd/web.chat.div" return false } case nfs.JS: msg.RenderResult(_website_template, text) case nfs.JSON: msg.RenderResult(_website_template2, kit.Format(kit.UnMarshal(text))) case nfs.HTML: msg.RenderResult(text) case nfs.SVG: msg.RenderResult(`
%s`, msg.Cmdx(nfs.CAT, text)) default: msg.RenderDownload(text) } web.Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...) return true } const ( CAN_PARSE = "can.parse" SRC_WEBSITE = "src/website/" CHAT_WEBSITE = "/chat/website/" ) const WEBSITE = "website" func init() { Index.MergeCommands(ice.Commands{ WEBSITE: {Name: "website path auto create import", Help: "网站", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(mdb.RENDER, mdb.CREATE, nfs.IML, m.PrefixKey()) m.Cmd(mdb.ENGINE, mdb.CREATE, nfs.IML, m.PrefixKey()) web.AddRewrite(func(w http.ResponseWriter, r *http.Request) bool { if r.Method != http.MethodGet { return false } if strings.HasSuffix(r.URL.Path, ice.PS) { return false } if !strings.HasPrefix(r.Header.Get(web.UserAgent), "Mozilla") { return false } if strings.HasPrefix(r.URL.Path, CHAT_WEBSITE) { _website_render(m, w, r, kit.Ext(r.URL.Path), m.Cmdx(nfs.CAT, strings.Replace(r.URL.Path, CHAT_WEBSITE, SRC_WEBSITE, 1)), path.Base(r.URL.Path)) return true } if m.Cmd(WEBSITE, r.URL.Path, func(value ice.Maps) { _website_render(m, w, r, value[mdb.TYPE], value[mdb.TEXT], path.Base(r.URL.Path)) }).Length() > 0 { return true } return false }) }}, lex.PARSE: {Hand: func(m *ice.Message, arg ...string) { switch kit.Ext(arg[0]) { case nfs.ZML: web.RenderCmd(m, CAN_PARSE, m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, arg[0]))) case nfs.IML: if res, ok := _website_parse(m, m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, arg[0])), arg[1:]...); ok { m.Echo(_website_template2, kit.Format(res)) } default: if text := m.CmdAppend("", path.Join(ice.PS, arg[0]), mdb.TEXT); text != "" { if res, ok := _website_parse(m, text, arg[1:]...); ok { m.Echo(_website_template2, kit.Format(res)) } } } }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch m.Option(ctx.ACTION) { case mdb.CREATE: mdb.HashInputs(m, arg) return } switch arg[0] { case nfs.PATH: m.Cmdy(nfs.DIR, arg[1:]).ProcessAgain() } }}, mdb.CREATE: {Name: "create path type=zml,iml,json,js,html name text"}, mdb.IMPORT: {Name: "import path=src/website/", Hand: func(m *ice.Message, arg ...string) { m.Cmd(nfs.DIR, kit.Dict(nfs.DIR_ROOT, m.Option(nfs.PATH)), func(p string) { switch name := strings.TrimPrefix(p, m.Option(nfs.PATH)); kit.Ext(p) { case nfs.HTML, nfs.JS, nfs.JSON, nfs.ZML, nfs.IML, nfs.TXT: m.Cmd("", mdb.CREATE, nfs.PATH, path.Join(ice.PS, name), mdb.TYPE, kit.Ext(p), mdb.NAME, name, mdb.TEXT, m.Cmdx(nfs.CAT, p)) default: m.Cmd("", mdb.CREATE, nfs.PATH, path.Join(ice.PS, name), mdb.TYPE, kit.Ext(p), mdb.NAME, name, mdb.TEXT, p) } }) }}, mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) { m.EchoIFrame(_website_url(m, strings.TrimPrefix(path.Join(arg[2], arg[1]), SRC_WEBSITE))) }}, mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) { if res, ok := _website_parse(m, m.Cmdx(nfs.CAT, path.Join(arg[2], arg[1]))); ok { ctx.DisplayStoryJSON(m.Echo(kit.Formats(res))) } else { m.Echo(_website_url(m, strings.TrimPrefix(path.Join(arg[2], arg[1]), SRC_WEBSITE))) } }}, }, mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path,type,name,text"), ctx.CmdAction(), web.ApiAction(), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) { mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { m.PushAnchor(web.MergePodWebSite(m, "", value[nfs.PATH])) }) }}, }) } var _website_template = `