1
0
Fork 0
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:
Eggbertx 2022-06-01 14:17:27 -07:00
parent dd77ca9eff
commit 495399eae7
6 changed files with 149 additions and 1 deletions

View file

@ -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
View file

@ -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
View file

@ -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=

View file

@ -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
View 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
View 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())
}
}