mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-25 09:36:24 -07:00
Add simple plugin loader
(though it doesn't do anything useful yet)
This commit is contained in:
parent
dd77ca9eff
commit
495399eae7
6 changed files with 149 additions and 1 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gclog"
|
||||
"github.com/gochan-org/gochan/pkg/gcplugin"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
"github.com/gochan-org/gochan/pkg/gctemplates"
|
||||
"github.com/gochan-org/gochan/pkg/posting"
|
||||
|
@ -36,6 +37,11 @@ func main() {
|
|||
|
||||
systemCritical := config.GetSystemCriticalConfig()
|
||||
|
||||
err := gcplugin.LoadPlugins(systemCritical.Plugins)
|
||||
if err != nil {
|
||||
gclog.Println(stdFatal|gclog.LErrorLog, "Failed loading plugins:", err.Error())
|
||||
}
|
||||
|
||||
gcsql.ConnectToDB(
|
||||
systemCritical.DBhost, systemCritical.DBtype, systemCritical.DBname,
|
||||
systemCritical.DBusername, systemCritical.DBpassword, systemCritical.DBprefix)
|
||||
|
@ -45,7 +51,7 @@ func main() {
|
|||
|
||||
posting.InitCaptcha()
|
||||
if err := gctemplates.InitTemplates(); err != nil {
|
||||
gclog.Printf(gclog.LErrorLog|gclog.LStdLog|gclog.LFatal, err.Error())
|
||||
gclog.Printf(stdFatal|gclog.LErrorLog, err.Error())
|
||||
}
|
||||
|
||||
sc := make(chan os.Signal, 1)
|
||||
|
|
2
go.mod
2
go.mod
|
@ -13,6 +13,8 @@ require (
|
|||
github.com/tdewolff/minify v2.3.6+incompatible
|
||||
github.com/tdewolff/parse v2.3.4+incompatible // indirect
|
||||
github.com/tdewolff/test v1.0.6 // indirect
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
|
||||
layeh.com/gopher-luar v1.0.10 // indirect
|
||||
)
|
||||
|
|
9
go.sum
9
go.sum
|
@ -1,5 +1,8 @@
|
|||
github.com/aquilax/tripcode v1.0.0 h1:uPW1T2brVth0t6YiDPlouncHXFGneflsAvkh4zEBN58=
|
||||
github.com/aquilax/tripcode v1.0.0/go.mod h1:Tucn/H6BM/DEmxzj/tnmR7Vs/NV/bgCKo8Wi0yXrtzQ=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/frustra/bbcode v0.0.0-20201127003707-6ef347fbe1c8 h1:sdIsYe6Vv7KIWZWp8KqSeTl+XlF17d+wHCC4lbxFcYs=
|
||||
|
@ -20,6 +23,9 @@ github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxp
|
|||
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
||||
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ=
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b h1:7gd+rd8P3bqcn/96gOZa3F5dpJr/vEiDQYlNb/y2uNs=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
|
||||
|
@ -30,6 +36,7 @@ golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+o
|
|||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -39,3 +46,5 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
layeh.com/gopher-luar v1.0.10 h1:55b0mpBhN9XSshEd2Nz6WsbYXctyBT35azk4POQNSXo=
|
||||
layeh.com/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=
|
||||
|
|
|
@ -272,6 +272,7 @@ type SystemCriticalConfig struct {
|
|||
DocumentRoot string `critical:"true"`
|
||||
TemplateDir string `critical:"true"`
|
||||
LogDir string `critical:"true"`
|
||||
Plugins []string
|
||||
|
||||
SiteHeaderURL string
|
||||
WebRoot string `description:"The HTTP root appearing in the browser (e.g. '/', 'https://yoursite.net/', etc) that all internal links start with"`
|
||||
|
@ -403,3 +404,11 @@ func GetBoardConfig(board string) *BoardConfig {
|
|||
func GetVersion() *GochanVersion {
|
||||
return cfg.Version
|
||||
}
|
||||
|
||||
// SetVersion should (in most cases) only be used for tests, where a config file wouldn't be loaded
|
||||
func SetVersion(version string) {
|
||||
if cfg == nil {
|
||||
cfg = &GochanConfig{}
|
||||
cfg.Version = ParseVersion(version)
|
||||
}
|
||||
}
|
||||
|
|
75
pkg/gcplugin/gcplugin.go
Normal file
75
pkg/gcplugin/gcplugin.go
Normal file
|
@ -0,0 +1,75 @@
|
|||
package gcplugin
|
||||
|
||||
import (
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gclog"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
var (
|
||||
lState *lua.LState
|
||||
eventPlugins map[string][]*lua.LFunction
|
||||
)
|
||||
|
||||
func initLua() {
|
||||
if lState == nil {
|
||||
lState = lua.NewState()
|
||||
registerLuaFunctions()
|
||||
}
|
||||
}
|
||||
|
||||
func createLuaLogFunc(which string) lua.LGFunction {
|
||||
return func(l *lua.LState) int {
|
||||
args := []interface{}{}
|
||||
for v := 1; v <= l.GetTop(); v++ {
|
||||
args = append(args, l.Get(v))
|
||||
}
|
||||
switch which {
|
||||
case "access":
|
||||
gclog.Println(gclog.LAccessLog, args...)
|
||||
case "error":
|
||||
gclog.Println(gclog.LErrorLog, args...)
|
||||
case "staff":
|
||||
gclog.Println(gclog.LStaffLog, args...)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func registerLuaFunctions() {
|
||||
lState.Register("access_log", createLuaLogFunc("access"))
|
||||
lState.Register("error_log", createLuaLogFunc("error"))
|
||||
lState.Register("staff_log", createLuaLogFunc("staff"))
|
||||
lState.SetGlobal("_GOCHAN_VERSION", lua.LString(config.GetVersion().String()))
|
||||
}
|
||||
|
||||
func registerEventFunction(name string, fn *lua.LFunction) {
|
||||
switch name {
|
||||
case "onStartup":
|
||||
fallthrough
|
||||
case "onPost":
|
||||
fallthrough
|
||||
case "onDelete":
|
||||
eventPlugins[name] = append(eventPlugins[name], fn)
|
||||
}
|
||||
}
|
||||
|
||||
func LoadPlugins(paths []string) error {
|
||||
var err error
|
||||
for _, pluginPath := range paths {
|
||||
initLua()
|
||||
if err = lState.DoFile(pluginPath); err != nil {
|
||||
return err
|
||||
}
|
||||
pluginTable := lState.CheckTable(-1)
|
||||
pluginTable.ForEach(func(key, val lua.LValue) {
|
||||
keyStr := key.String()
|
||||
fn, ok := val.(*lua.LFunction)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
registerEventFunction(keyStr, fn)
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
47
pkg/gcplugin/lua_test.go
Normal file
47
pkg/gcplugin/lua_test.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package gcplugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
const (
|
||||
versionStr = `return _GOCHAN_VERSION
|
||||
`
|
||||
)
|
||||
|
||||
func TestVersionFunction(t *testing.T) {
|
||||
config.SetVersion("3.1")
|
||||
initLua()
|
||||
err := lState.DoString(versionStr)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
testingVersionStr := lState.Get(-1).(lua.LString)
|
||||
if testingVersionStr != "3.1" {
|
||||
t.Fatalf("%q != \"3.1\"", testingVersionStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStructPassing(t *testing.T) {
|
||||
initLua()
|
||||
p := &gcsql.Post{
|
||||
Name: "Joe Poster",
|
||||
Email: "joeposter@gmail.com",
|
||||
MessageHTML: "Message test<br />",
|
||||
MessageText: "Message text\n",
|
||||
}
|
||||
uData := lState.NewUserData()
|
||||
uData.Value = p
|
||||
lState.SetGlobal("post", luar.New(lState, p))
|
||||
err := lState.DoString(`print("Receiving post from " .. post["Name"])`)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue