Initial work on Plugin Hyperdrive.
Reduced the amount of boilerplate in Plugin Markdown. Reduced the amount of boilerplate in Plugin Sendmail. Reduced the amount of boilerplate in sample plugins Heythere and Skeleton. Fixed up Plugin GeoIP. It's not ready for use though. Added the routes.FootHeaders function. Added the route_topic_list_start plugin hook.
This commit is contained in:
parent
114afe0b13
commit
b4ffaa2cd6
|
@ -83,6 +83,8 @@ var hookTable = &HookTable{
|
|||
"simple_forum_check_pre_perms": nil,
|
||||
"forum_check_pre_perms": nil,
|
||||
|
||||
"route_topic_list_start": nil,
|
||||
|
||||
"action_end_create_topic": nil,
|
||||
"action_end_edit_topic":nil,
|
||||
"action_end_delete_topic":nil,
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
package main
|
||||
|
||||
import c "github.com/Azareal/Gosora/common"
|
||||
import "github.com/oschwald/geoip2-golang"
|
||||
|
||||
var geoip_db *geoip.DB
|
||||
var geoip_db_location string = "geoip_db.mmdb"
|
||||
var geoipDB *geoip.DB
|
||||
var geoipDBLocation = "geoip_db.mmdb"
|
||||
|
||||
func init() {
|
||||
plugins["geoip"] = NewPlugin("geoip","Geoip","Azareal","http://github.com/Azareal","","","",init_geoip,nil,deactivate_geoip,nil,nil)
|
||||
c.Plugins.Add(&c.Plugin{UName: "geoip", Name: "Geoip", Author: "Azareal", Init: initGeoip, Deactivate: deactivateGeoip})
|
||||
}
|
||||
|
||||
func init_geoip() (err error) {
|
||||
geoip_db, err = geoip2.Open(geoip_db_location)
|
||||
func initGeoip(plugin *c.Plugin) (err error) {
|
||||
geoipDB, err = geoip2.Open(geoipDBLocation)
|
||||
return err
|
||||
}
|
||||
|
||||
func deactivate_geoip() {
|
||||
geoip_db.Close()
|
||||
func deactivateGeoip(plugin *c.Plugin) {
|
||||
geoipDB.Close()
|
||||
}
|
||||
|
|
|
@ -2,33 +2,101 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"bytes"
|
||||
"sync/atomic"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"github.com/Azareal/Gosora/common"
|
||||
c "github.com/Azareal/Gosora/common"
|
||||
"github.com/Azareal/Gosora/routes"
|
||||
)
|
||||
|
||||
var hyperPageCache *HyperPageCache
|
||||
var hyperspace *Hyperspace
|
||||
|
||||
func init() {
|
||||
common.Plugins.Add(&common.Plugin{UName: "hyperdrive", Name: "Hyperdrive", Author: "Azareal", Init: initHyperdrive, Deactivate: deactivateHyperdrive})
|
||||
c.Plugins.Add(&c.Plugin{UName: "hyperdrive", Name: "Hyperdrive", Author: "Azareal", Init: initHdrive, Deactivate: deactivateHdrive})
|
||||
}
|
||||
|
||||
func initHyperdrive(plugin *common.Plugin) error {
|
||||
hyperPageCache = newHyperPageCache()
|
||||
plugin.AddHook("somewhere", deactivateHyperdrive)
|
||||
func initHdrive(plugin *c.Plugin) error {
|
||||
hyperspace = newHyperspace()
|
||||
plugin.AddHook("tasks_tick_topic_list",tickHdrive)
|
||||
plugin.AddHook("route_topic_list_start",jumpHdrive)
|
||||
return nil
|
||||
}
|
||||
|
||||
func deactivateHyperdrive(plugin *common.Plugin) {
|
||||
hyperPageCache = nil
|
||||
func deactivateHdrive(plugin *c.Plugin) {
|
||||
plugin.RemoveHook("tasks_tick_topic_list",tickHdrive)
|
||||
plugin.RemoveHook("route_topic_list_start",jumpHdrive)
|
||||
hyperspace = nil
|
||||
}
|
||||
|
||||
type HyperPageCache struct {
|
||||
type Hyperspace struct {
|
||||
topicList atomic.Value
|
||||
}
|
||||
|
||||
func newHyperPageCache() *HyperPageCache {
|
||||
pageCache := new(HyperPageCache)
|
||||
func newHyperspace() *Hyperspace {
|
||||
pageCache := new(Hyperspace)
|
||||
pageCache.topicList.Store([]byte(""))
|
||||
return pageCache
|
||||
}
|
||||
|
||||
// TODO: Find a better way of doing this
|
||||
func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||
log.Print("Refueling...")
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("get", "/topics/", bytes.NewReader(nil))
|
||||
user := c.GuestUser
|
||||
|
||||
head, err := c.UserCheck(w, req, &user)
|
||||
if err != nil {
|
||||
c.LogWarning(err)
|
||||
return true, rerr
|
||||
}
|
||||
|
||||
rerr = routes.TopicList(w, req, user, head)
|
||||
if rerr != nil {
|
||||
c.LogWarning(err)
|
||||
return true, rerr
|
||||
}
|
||||
if w.Code != 200 {
|
||||
c.LogWarning(err)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(w.Result().Body)
|
||||
hyperspace.topicList.Store(buf.Bytes())
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func jumpHdrive(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||
tList := hyperspace.topicList.Load().([]byte)
|
||||
if len(tList) == 0 {
|
||||
log.Print("no topiclist in hyperspace")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Avoid intercepting user requests as we only have guests in cache right now
|
||||
user := args[2].(*c.User)
|
||||
if user.ID != 0 {
|
||||
log.Print("not guest")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Avoid intercepting search requests and filters as we don't have those in cache
|
||||
r := args[1].(*http.Request)
|
||||
//log.Print("r.URL.Path:",r.URL.Path)
|
||||
log.Print("r.URL.RawQuery:",r.URL.RawQuery)
|
||||
if r.URL.RawQuery != "" {
|
||||
return false, nil
|
||||
}
|
||||
log.Print("Successful jump")
|
||||
|
||||
w := args[0].(http.ResponseWriter)
|
||||
header := args[3].(*c.Header)
|
||||
routes.FootHeaders(w, header)
|
||||
w.Write(tList)
|
||||
|
||||
return true, nil
|
||||
}
|
|
@ -6,7 +6,7 @@ import (
|
|||
"os/exec"
|
||||
"runtime"
|
||||
|
||||
"github.com/Azareal/Gosora/common"
|
||||
c "github.com/Azareal/Gosora/common"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -18,17 +18,17 @@ func init() {
|
|||
if runtime.GOOS != "linux" {
|
||||
return
|
||||
}
|
||||
common.Plugins.Add(&common.Plugin{UName: "sendmail", Name: "Sendmail", Author: "Azareal", URL: "http://github.com/Azareal", Tag: "Linux Only", Init: initSendmail, Activate: activateSendmail, Deactivate: deactivateSendmail})
|
||||
c.Plugins.Add(&c.Plugin{UName: "sendmail", Name: "Sendmail", Author: "Azareal", URL: "http://github.com/Azareal", Tag: "Linux Only", Init: initSendmail, Activate: activateSendmail, Deactivate: deactivateSendmail})
|
||||
}
|
||||
|
||||
func initSendmail(plugin *common.Plugin) error {
|
||||
func initSendmail(plugin *c.Plugin) error {
|
||||
plugin.AddHook("email_send_intercept", sendSendmail)
|
||||
return nil
|
||||
}
|
||||
|
||||
// /usr/sbin/sendmail is only available on Linux
|
||||
func activateSendmail(plugin *common.Plugin) error {
|
||||
if !common.Site.EnableEmails {
|
||||
func activateSendmail(plugin *c.Plugin) error {
|
||||
if !c.Site.EnableEmails {
|
||||
return errors.New("You have emails disabled in your configuration file")
|
||||
}
|
||||
if runtime.GOOS != "linux" {
|
||||
|
@ -37,7 +37,7 @@ func activateSendmail(plugin *common.Plugin) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func deactivateSendmail(plugin *common.Plugin) {
|
||||
func deactivateSendmail(plugin *c.Plugin) {
|
||||
plugin.RemoveHook("email_send_intercept", sendSendmail)
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ func sendSendmail(data ...interface{}) interface{} {
|
|||
subject := data[1].(string)
|
||||
body := data[2].(string)
|
||||
|
||||
msg := "From: " + common.Site.Email + "\n"
|
||||
msg := "From: " + c.Site.Email + "\n"
|
||||
msg += "To: " + to + "\n"
|
||||
msg += "Subject: " + subject + "\n\n"
|
||||
msg += body + "\n"
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
package main
|
||||
|
||||
import "github.com/Azareal/Gosora/common"
|
||||
import c "github.com/Azareal/Gosora/common"
|
||||
|
||||
func init() {
|
||||
common.Plugins.Add(&common.Plugin{UName: "heythere", Name: "Hey There", Author: "Azareal", URL: "https://github.com/Azareal", Init: initHeythere, Deactivate: deactivateHeythere})
|
||||
c.Plugins.Add(&c.Plugin{UName: "heythere", Name: "Hey There", Author: "Azareal", URL: "https://github.com/Azareal", Init: initHeythere, Deactivate: deactivateHeythere})
|
||||
}
|
||||
|
||||
// init_heythere is separate from init() as we don't want the plugin to run if the plugin is disabled
|
||||
func initHeythere(plugin *common.Plugin) error {
|
||||
func initHeythere(plugin *c.Plugin) error {
|
||||
plugin.AddHook("topic_reply_row_assign", heythereReply)
|
||||
return nil
|
||||
}
|
||||
|
||||
func deactivateHeythere(plugin *common.Plugin) {
|
||||
func deactivateHeythere(plugin *c.Plugin) {
|
||||
plugin.RemoveHook("topic_reply_row_assign", heythereReply)
|
||||
}
|
||||
|
||||
func heythereReply(data ...interface{}) interface{} {
|
||||
currentUser := data[0].(*common.TopicPage).Header.CurrentUser
|
||||
reply := data[1].(*common.ReplyUser)
|
||||
currentUser := data[0].(*c.TopicPage).Header.CurrentUser
|
||||
reply := data[1].(*c.ReplyUser)
|
||||
reply.Content = "Hey there, " + currentUser.Name + "!"
|
||||
reply.ContentHtml = "Hey there, " + currentUser.Name + "!"
|
||||
reply.Tag = "Auto"
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/Azareal/Gosora/common"
|
||||
c "github.com/Azareal/Gosora/common"
|
||||
)
|
||||
|
||||
var markdownMaxDepth = 25 // How deep the parser will go when parsing Markdown strings
|
||||
|
@ -23,10 +23,10 @@ var markdownH1TagOpen []byte
|
|||
var markdownH1TagClose []byte
|
||||
|
||||
func init() {
|
||||
common.Plugins.Add(&common.Plugin{UName: "markdown", Name: "Markdown", Author: "Azareal", URL: "https://github.com/Azareal", Init: initMarkdown, Deactivate: deactivateMarkdown})
|
||||
c.Plugins.Add(&c.Plugin{UName: "markdown", Name: "Markdown", Author: "Azareal", URL: "https://github.com/Azareal", Init: initMarkdown, Deactivate: deactivateMarkdown})
|
||||
}
|
||||
|
||||
func initMarkdown(plugin *common.Plugin) error {
|
||||
func initMarkdown(plugin *c.Plugin) error {
|
||||
plugin.AddHook("parse_assign", markdownParse)
|
||||
|
||||
markdownUnclosedElement = []byte("<red>[Unclosed Element]</red>")
|
||||
|
@ -46,7 +46,7 @@ func initMarkdown(plugin *common.Plugin) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func deactivateMarkdown(plugin *common.Plugin) {
|
||||
func deactivateMarkdown(plugin *c.Plugin) {
|
||||
plugin.RemoveHook("parse_assign", markdownParse)
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ func _markdownParse(msg string, n int) string {
|
|||
var outbytes []byte
|
||||
var lastElement int
|
||||
var breaking = false
|
||||
common.DebugLogf("Initial Message: %+v\n", strings.Replace(msg, "\r", "\\r", -1))
|
||||
c.DebugLogf("Initial Message: %+v\n", strings.Replace(msg, "\r", "\\r", -1))
|
||||
|
||||
for index := 0; index < len(msg); index++ {
|
||||
var simpleMatch = func(char byte, o []byte, c []byte) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package main
|
||||
|
||||
import "github.com/Azareal/Gosora/common"
|
||||
import c "github.com/Azareal/Gosora/common"
|
||||
|
||||
func init() {
|
||||
/*
|
||||
|
@ -28,12 +28,12 @@ func init() {
|
|||
|
||||
That Uninstallation field which is currently unused is for not only deactivating this plugin, but for purging any data associated with it such a new tables or data produced by the end-user.
|
||||
*/
|
||||
common.Plugins.Add(&common.Plugin{UName: "skeleton", Name: "Skeleton", Author: "Azareal", Init: initSkeleton, Activate: activateSkeleton, Deactivate: deactivateSkeleton})
|
||||
c.Plugins.Add(&c.Plugin{UName: "skeleton", Name: "Skeleton", Author: "Azareal", Init: initSkeleton, Activate: activateSkeleton, Deactivate: deactivateSkeleton})
|
||||
}
|
||||
|
||||
func initSkeleton(plugin *common.Plugin) error { return nil }
|
||||
func initSkeleton(plugin *c.Plugin) error { return nil }
|
||||
|
||||
// Any errors encountered while trying to activate the plugin are reported back to the admin and the activation is aborted
|
||||
func activateSkeleton(plugin *common.Plugin) error { return nil }
|
||||
func activateSkeleton(plugin *c.Plugin) error { return nil }
|
||||
|
||||
func deactivateSkeleton(plugin *common.Plugin) {}
|
||||
func deactivateSkeleton(plugin *c.Plugin) {}
|
||||
|
|
|
@ -70,6 +70,7 @@ func doPush(w http.ResponseWriter, header *c.Header) {
|
|||
var push = func(in []string) {
|
||||
for _, path := range in {
|
||||
//fmt.Println("pushing /static/" + path)
|
||||
// TODO: Avoid concatenating here
|
||||
err := pusher.Push("/static/"+path, nil)
|
||||
if err != nil {
|
||||
break
|
||||
|
@ -96,20 +97,11 @@ func renderTemplate2(tmplName string, hookName string, w http.ResponseWriter, r
|
|||
return nil
|
||||
}
|
||||
|
||||
func renderTemplate3(tmplName string, hookName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) error {
|
||||
c.PrepResources(&header.CurrentUser, header, header.Theme)
|
||||
|
||||
if header.CurrentUser.Loggedin {
|
||||
header.MetaDesc = ""
|
||||
header.OGDesc = ""
|
||||
} else if header.MetaDesc != "" && header.OGDesc == "" {
|
||||
header.OGDesc = header.MetaDesc
|
||||
}
|
||||
func FootHeaders(w http.ResponseWriter, header *c.Header) {
|
||||
// TODO: Expand this to non-HTTPS requests too
|
||||
if !header.LooseCSP && c.Site.EnableSsl {
|
||||
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com;upgrade-insecure-requests")
|
||||
}
|
||||
header.AddScript("global.js")
|
||||
|
||||
// Server pushes can backfire on certain browsers, so we want to make sure it's only triggered for ones where it'll help
|
||||
lastAgent := header.CurrentUser.LastAgent
|
||||
|
@ -117,7 +109,19 @@ func renderTemplate3(tmplName string, hookName string, w http.ResponseWriter, r
|
|||
if lastAgent == "chrome" || lastAgent == "firefox" {
|
||||
doPush(w, header)
|
||||
}
|
||||
}
|
||||
|
||||
func renderTemplate3(tmplName string, hookName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) error {
|
||||
c.PrepResources(&header.CurrentUser, header, header.Theme)
|
||||
if header.CurrentUser.Loggedin {
|
||||
header.MetaDesc = ""
|
||||
header.OGDesc = ""
|
||||
} else if header.MetaDesc != "" && header.OGDesc == "" {
|
||||
header.OGDesc = header.MetaDesc
|
||||
}
|
||||
header.AddScript("global.js")
|
||||
|
||||
FootHeaders(w, header)
|
||||
if header.CurrentUser.IsAdmin {
|
||||
header.Elapsed1 = time.Since(header.StartedAt).String()
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@ func wsTopicList(topicList []*c.TopicsRow, lastPage int) *c.WsTopicList {
|
|||
}
|
||||
|
||||
func TopicList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||
skip, rerr := header.Hooks.VhookSkippable("route_topic_list_start", w, r, &user, header)
|
||||
if skip || rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
return TopicListCommon(w, r, user, header, "lastupdated", "")
|
||||
}
|
||||
|
||||
|
@ -106,7 +110,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, header
|
|||
if err != nil && err != sql.ErrNoRows {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
//fmt.Printf("tids %+v\n", tids)
|
||||
//log.Printf("tids %+v\n", tids)
|
||||
// TODO: Handle the case where there aren't any items...
|
||||
// TODO: Add a BulkGet method which returns a slice?
|
||||
tMap, err := c.Topics.BulkGetMap(tids)
|
||||
|
|
Loading…
Reference in New Issue