diff options
author | 2020-01-20 22:04:50 +0100 | |
---|---|---|
committer | 2020-01-20 22:04:50 +0100 | |
commit | b58c15d121095ef58f8fb1ac5d3a456e89baee2a (patch) | |
tree | 2cc12e88691d811b3379f437cc821ab214e1992d /plugin_lua.go | |
parent | efa08163333654f3245c272333e77565b6287b14 (diff) | |
download | alps-b58c15d121095ef58f8fb1ac5d3a456e89baee2a.tar.gz alps-b58c15d121095ef58f8fb1ac5d3a456e89baee2a.tar.bz2 alps-b58c15d121095ef58f8fb1ac5d3a456e89baee2a.zip |
Extract Lua infrastructure into a plugin
Diffstat (limited to 'plugin_lua.go')
-rw-r--r-- | plugin_lua.go | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/plugin_lua.go b/plugin_lua.go deleted file mode 100644 index 8291a20..0000000 --- a/plugin_lua.go +++ /dev/null @@ -1,180 +0,0 @@ -package koushin - -import ( - "fmt" - "html/template" - "path/filepath" - - "github.com/labstack/echo/v4" - "github.com/yuin/gopher-lua" - "layeh.com/gopher-luar" -) - -type luaRoute struct { - method string - path string - f *lua.LFunction -} - -type luaPlugin struct { - filename string - state *lua.LState - renderCallbacks map[string]*lua.LFunction - filters template.FuncMap - routes []luaRoute -} - -func (p *luaPlugin) Name() string { - return p.filename -} - -func (p *luaPlugin) onRender(l *lua.LState) int { - name := l.CheckString(1) - f := l.CheckFunction(2) - p.renderCallbacks[name] = f - return 0 -} - -func (p *luaPlugin) setFilter(l *lua.LState) int { - name := l.CheckString(1) - f := l.CheckFunction(2) - p.filters[name] = func(args ...interface{}) string { - luaArgs := make([]lua.LValue, len(args)) - for i, v := range args { - luaArgs[i] = luar.New(l, v) - } - - err := l.CallByParam(lua.P{ - Fn: f, - NRet: 1, - Protect: true, - }, luaArgs...) - if err != nil { - panic(err) // TODO: better error handling? - } - - ret := l.CheckString(-1) - l.Pop(1) - return ret - } - return 0 -} - -func (p *luaPlugin) setRoute(l *lua.LState) int { - method := l.CheckString(1) - path := l.CheckString(2) - f := l.CheckFunction(3) - p.routes = append(p.routes, luaRoute{method, path, f}) - return 0 -} - -func (p *luaPlugin) inject(name string, data RenderData) error { - f, ok := p.renderCallbacks[name] - if !ok { - return nil - } - - err := p.state.CallByParam(lua.P{ - Fn: f, - NRet: 0, - Protect: true, - }, luar.New(p.state, data)) - if err != nil { - return err - } - - return nil -} - -func (p *luaPlugin) Inject(ctx *Context, name string, data RenderData) error { - if err := p.inject("*", data); err != nil { - return err - } - return p.inject(name, data) -} - -func (p *luaPlugin) LoadTemplate(t *template.Template) error { - t.Funcs(p.filters) - - paths, err := filepath.Glob(filepath.Dir(p.filename) + "/public/*.html") - if err != nil { - return err - } - if len(paths) > 0 { - if _, err := t.ParseFiles(paths...); err != nil { - return err - } - } - - return nil -} - -func (p *luaPlugin) SetRoutes(group *echo.Group) { - for _, r := range p.routes { - group.Match([]string{r.method}, r.path, func(ctx echo.Context) error { - err := p.state.CallByParam(lua.P{ - Fn: r.f, - NRet: 0, - Protect: true, - }, luar.New(p.state, ctx)) - if err != nil { - return fmt.Errorf("Lua plugin error: %v", err) - } - - return nil - }) - } - - _, name := filepath.Split(filepath.Dir(p.filename)) - group.Static("/plugins/"+name+"/assets", filepath.Dir(p.filename)+"/public/assets") -} - -func (p *luaPlugin) Close() error { - p.state.Close() - return nil -} - -func loadLuaPlugin(filename string) (*luaPlugin, error) { - l := lua.NewState() - p := &luaPlugin{ - filename: filename, - state: l, - renderCallbacks: make(map[string]*lua.LFunction), - filters: make(template.FuncMap), - } - - mt := l.NewTypeMetatable("koushin") - l.SetGlobal("koushin", mt) - l.SetField(mt, "on_render", l.NewFunction(p.onRender)) - l.SetField(mt, "set_filter", l.NewFunction(p.setFilter)) - l.SetField(mt, "set_route", l.NewFunction(p.setRoute)) - - if err := l.DoFile(filename); err != nil { - l.Close() - return nil, err - } - - return p, nil -} - -func loadAllLuaPlugins(log echo.Logger) ([]Plugin, error) { - filenames, err := filepath.Glob(pluginDir + "/*/main.lua") - if err != nil { - return nil, fmt.Errorf("filepath.Glob failed: %v", err) - } - - plugins := make([]Plugin, 0, len(filenames)) - for _, filename := range filenames { - log.Printf("Loading Lua plugin '%v'", filename) - p, err := loadLuaPlugin(filename) - if err != nil { - for _, p := range plugins { - p.Close() - } - return nil, fmt.Errorf("failed to load Lua plugin '%v': %v", filename, err) - } - plugins = append(plugins, p) - } - - return plugins, nil -} |