Experiment with rehoming the plugins.
Shorten more things and eliminate unnecessary bytes.
This commit is contained in:
parent
84cd10a8c9
commit
30de658e15
|
@ -1,10 +1,10 @@
|
||||||
// WIP - Experimental adventure plugin, this might find a new home soon, but it's here to stress test Gosora's extensibility for now
|
// WIP - Experimental adventure plugin, this might find a new home soon, but it's here to stress test Gosora's extensibility for now
|
||||||
package main
|
package extend
|
||||||
|
|
||||||
import "github.com/Azareal/Gosora/common"
|
import c "github.com/Azareal/Gosora/common"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
common.Plugins.Add(&common.Plugin{
|
c.Plugins.Add(&c.Plugin{
|
||||||
UName: "adventure",
|
UName: "adventure",
|
||||||
Name: "Adventure",
|
Name: "Adventure",
|
||||||
Tag: "WIP",
|
Tag: "WIP",
|
||||||
|
@ -16,14 +16,14 @@ func init() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func initAdventure(plugin *common.Plugin) error {
|
func initAdventure(plugin *c.Plugin) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Change the signature to return an error?
|
// TODO: Change the signature to return an error?
|
||||||
func deactivateAdventure(plugin *common.Plugin) {
|
func deactivateAdventure(plugin *c.Plugin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func installAdventure(plugin *common.Plugin) error {
|
func installAdventure(plugin *c.Plugin) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package extend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -26,11 +26,11 @@ var bbcodeQuotes *regexp.Regexp
|
||||||
var bbcodeCode *regexp.Regexp
|
var bbcodeCode *regexp.Regexp
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
c.Plugins.Add(&c.Plugin{UName: "bbcode", Name: "BBCode", Author: "Azareal", URL: "https://github.com/Azareal", Init: initBbcode, Deactivate: deactivateBbcode})
|
c.Plugins.Add(&c.Plugin{UName: "bbcode", Name: "BBCode", Author: "Azareal", URL: "https://github.com/Azareal", Init: InitBbcode, Deactivate: deactivateBbcode})
|
||||||
}
|
}
|
||||||
|
|
||||||
func initBbcode(plugin *c.Plugin) error {
|
func InitBbcode(plugin *c.Plugin) error {
|
||||||
plugin.AddHook("parse_assign", bbcodeFullParse)
|
plugin.AddHook("parse_assign", BbcodeFullParse)
|
||||||
|
|
||||||
bbcodeInvalidNumber = []byte("<red>[Invalid Number]</red>")
|
bbcodeInvalidNumber = []byte("<red>[Invalid Number]</red>")
|
||||||
bbcodeNoNegative = []byte("<red>[No Negative Numbers]</red>")
|
bbcodeNoNegative = []byte("<red>[No Negative Numbers]</red>")
|
||||||
|
@ -52,10 +52,10 @@ func initBbcode(plugin *c.Plugin) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateBbcode(plugin *c.Plugin) {
|
func deactivateBbcode(plugin *c.Plugin) {
|
||||||
plugin.RemoveHook("parse_assign", bbcodeFullParse)
|
plugin.RemoveHook("parse_assign", BbcodeFullParse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func bbcodeRegexParse(msg string) string {
|
func BbcodeRegexParse(msg string) string {
|
||||||
msg = bbcodeBold.ReplaceAllString(msg, "<b>$1</b>")
|
msg = bbcodeBold.ReplaceAllString(msg, "<b>$1</b>")
|
||||||
msg = bbcodeItalic.ReplaceAllString(msg, "<i>$1</i>")
|
msg = bbcodeItalic.ReplaceAllString(msg, "<i>$1</i>")
|
||||||
msg = bbcodeUnderline.ReplaceAllString(msg, "<u>$1</u>")
|
msg = bbcodeUnderline.ReplaceAllString(msg, "<u>$1</u>")
|
||||||
|
@ -118,11 +118,10 @@ func bbcodeSimpleParse(msg string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here for benchmarking purposes. Might add a plugin setting for disabling [code] as it has it's paws everywhere
|
// Here for benchmarking purposes. Might add a plugin setting for disabling [code] as it has it's paws everywhere
|
||||||
func bbcodeParseWithoutCode(msg string) string {
|
func BbcodeParseWithoutCode(msg string) string {
|
||||||
var hasU, hasB, hasI, hasS bool
|
var hasU, hasB, hasI, hasS bool
|
||||||
var complexBbc bool
|
var complexBbc bool
|
||||||
msgbytes := []byte(msg)
|
msgbytes := []byte(msg)
|
||||||
|
|
||||||
for i := 0; (i + 3) < len(msgbytes); i++ {
|
for i := 0; (i + 3) < len(msgbytes); i++ {
|
||||||
if msgbytes[i] == '[' {
|
if msgbytes[i] == '[' {
|
||||||
if msgbytes[i+2] != ']' {
|
if msgbytes[i+2] != ']' {
|
||||||
|
@ -207,7 +206,7 @@ func bbcodeParseWithoutCode(msg string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does every type of BBCode
|
// Does every type of BBCode
|
||||||
func bbcodeFullParse(msg string) string {
|
func BbcodeFullParse(msg string) string {
|
||||||
var hasU, hasB, hasI, hasS, hasC bool
|
var hasU, hasB, hasI, hasS, hasC bool
|
||||||
var complexBbc bool
|
var complexBbc bool
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
package extend
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
c "github.com/Azareal/Gosora/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
c.Plugins.Add(&c.Plugin{UName: "discord", Name: "Discord", Author: "Azareal", Init: discordInit, Activate: discordActivate, Deactivate: discordDeactivate})
|
||||||
|
}
|
||||||
|
|
||||||
|
func discordValidate() error {
|
||||||
|
webhook, ok := c.PluginConfig["DiscordWebhook"]
|
||||||
|
if !ok || webhook == "" {
|
||||||
|
return errors.New("You need to set a webhook to push to in config.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
ev := c.PluginConfig["DiscordEvents"]
|
||||||
|
if ev != "" && ev != "threads" && ev != "replies" {
|
||||||
|
return errors.New("Invalid value for DiscordEvents. Can only be blank, 'threads' or 'replies'")
|
||||||
|
}
|
||||||
|
|
||||||
|
fidsRaw := c.PluginConfig["DiscordForums"]
|
||||||
|
if fidsRaw != "" {
|
||||||
|
for _, fidRaw := range strings.Split(fidsRaw, ",") {
|
||||||
|
_, err := strconv.Atoi(fidRaw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("Invalid integer found in DiscordForums")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func discordInit(plugin *c.Plugin) error {
|
||||||
|
err := discordValidate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
plugin.AddHook("action_end_create_topic", discordEventTopic)
|
||||||
|
plugin.AddHook("action_end_create_reply", discordEventReply)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A bit of validation to make sure the admin isn't forgetting something or telling Plugin Discord to do something absurd
|
||||||
|
func discordActivate(plugin *c.Plugin) error {
|
||||||
|
return discordValidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func discordDeactivate(plugin *c.Plugin) {
|
||||||
|
plugin.RemoveHook("action_end_create_topic", discordEventTopic)
|
||||||
|
plugin.RemoveHook("action_end_create_reply", discordEventReply)
|
||||||
|
}
|
||||||
|
|
||||||
|
func discordEventTopic(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
discordEvent(0, args[0].(int))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
func discordEventReply(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
discordEvent(1, args[0].(int))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscordData struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Embeds []DiscordEmbed `json:"embeds"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscordEmbed struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Desc string `json:"description"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Author DiscordEmbedAuthor `json:"author"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscordEmbedAuthor struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Avatar string `json:"icon_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func discordEvent(typ int, id int) {
|
||||||
|
//fmt.Println("in discordEvent")
|
||||||
|
ev := c.PluginConfig["DiscordEvents"]
|
||||||
|
if (ev == "threads" && typ != 0) || (ev == "replies" && typ != 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var content, url string
|
||||||
|
var topic *c.Topic
|
||||||
|
var err error
|
||||||
|
var createdBy int
|
||||||
|
if typ == 0 {
|
||||||
|
topic, err = c.Topics.Get(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content = topic.Content
|
||||||
|
createdBy = topic.CreatedBy
|
||||||
|
} else {
|
||||||
|
reply, err := c.Rstore.Get(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content = reply.Content
|
||||||
|
createdBy = reply.CreatedBy
|
||||||
|
|
||||||
|
topic, err = reply.Topic()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url = topic.Link
|
||||||
|
|
||||||
|
user, err := c.Users.Get(createdBy)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fidsRaw := c.PluginConfig["DiscordForums"]
|
||||||
|
if fidsRaw != "" {
|
||||||
|
var hasForum = false
|
||||||
|
for _, fidRaw := range strings.Split(fidsRaw, ",") {
|
||||||
|
fid, err := strconv.Atoi(fidRaw)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if fid == topic.ParentID {
|
||||||
|
hasForum = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasForum {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(content) > 100 {
|
||||||
|
content = content[:97] + "..."
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = &http.Client{
|
||||||
|
Timeout: time.Second * 10,
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Dial: (&net.Dialer{Timeout: 5 * time.Second}).Dial,
|
||||||
|
TLSHandshakeTimeout: 5 * time.Second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var s string
|
||||||
|
if c.Site.EnableSsl {
|
||||||
|
s = "s"
|
||||||
|
}
|
||||||
|
var preURL = "http" + s + "://" + c.Site.URL
|
||||||
|
|
||||||
|
var avatar = user.MicroAvatar
|
||||||
|
if len(user.MicroAvatar) > 1 {
|
||||||
|
if user.MicroAvatar[0] == '/' && user.MicroAvatar[1] != '/' {
|
||||||
|
avatar = preURL + avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
author := DiscordEmbedAuthor{Name: user.Name, URL: preURL + user.Link, Avatar: avatar}
|
||||||
|
embed := DiscordEmbed{Title: topic.Title, Desc: content, URL: preURL + url, Author: author}
|
||||||
|
dat := DiscordData{Username: c.Site.Name, Embeds: []DiscordEmbed{embed}}
|
||||||
|
data, err := json.Marshal(dat)
|
||||||
|
if err != nil {
|
||||||
|
c.LogWarning(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Println("before discord push")
|
||||||
|
resp, err := client.Post(c.PluginConfig["DiscordWebhook"], "application/json", bytes.NewBuffer(data))
|
||||||
|
var body string
|
||||||
|
var respErr = func(err error) {
|
||||||
|
log.Printf("Sent: %+v\n", string(data))
|
||||||
|
log.Printf("Response: %+v\n", resp)
|
||||||
|
if body != "" {
|
||||||
|
log.Printf("Response Body: %+v\n", body)
|
||||||
|
}
|
||||||
|
c.LogWarning(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
respErr(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// TODO: Cap the amount we read
|
||||||
|
bBody, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
respErr(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
body = string(bBody)
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
respErr(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.DebugLog("Pushed event to Discord")
|
||||||
|
c.DebugLogf("Sent: %+v\n", string(data))
|
||||||
|
c.DebugLogf("Response: %+v\n", resp)
|
||||||
|
c.DebugLogf("Response Body: %+v\n", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add a settings page or something?
|
|
@ -0,0 +1,26 @@
|
||||||
|
package extend
|
||||||
|
|
||||||
|
import c "github.com/Azareal/Gosora/common"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
c.Plugins.Add(&c.Plugin{UName: "gallery", Name: "Gallery", Author: "Azareal", URL: "https://github.com/Azareal", Init: initGallery, Deactivate: deactivateGallery})
|
||||||
|
}
|
||||||
|
|
||||||
|
// init_heythere is separate from init() as we don't want the plugin to run if the plugin is disabled
|
||||||
|
func initGallery(plugin *c.Plugin) error {
|
||||||
|
plugin.AddHook("topic_reply_row_assign", galleryReply)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deactivateGallery(plugin *c.Plugin) {
|
||||||
|
plugin.RemoveHook("topic_reply_row_assign", galleryReply)
|
||||||
|
}
|
||||||
|
|
||||||
|
func galleryReply(data ...interface{}) interface{} {
|
||||||
|
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"
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package extend
|
||||||
|
|
||||||
import c "github.com/Azareal/Gosora/common"
|
import c "github.com/Azareal/Gosora/common"
|
||||||
|
|
|
@ -0,0 +1,241 @@
|
||||||
|
// Highly experimental plugin for caching rendered pages for guests
|
||||||
|
package extend
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"log"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
"sync/atomic"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
|
||||||
|
c "github.com/Azareal/Gosora/common"
|
||||||
|
"github.com/Azareal/Gosora/routes"
|
||||||
|
)
|
||||||
|
|
||||||
|
var hyperspace *Hyperspace
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
c.Plugins.Add(&c.Plugin{UName: "hyperdrive", Name: "Hyperdrive", Author: "Azareal", Init: initHdrive, Deactivate: deactivateHdrive})
|
||||||
|
}
|
||||||
|
|
||||||
|
func initHdrive(plugin *c.Plugin) error {
|
||||||
|
hyperspace = newHyperspace()
|
||||||
|
plugin.AddHook("tasks_tick_topic_list",tickHdrive)
|
||||||
|
plugin.AddHook("tasks_tick_widget_wol",tickHdriveWol)
|
||||||
|
plugin.AddHook("route_topic_list_start",jumpHdriveTopicList)
|
||||||
|
plugin.AddHook("route_forum_list_start",jumpHdriveForumList)
|
||||||
|
tickHdrive()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deactivateHdrive(plugin *c.Plugin) {
|
||||||
|
plugin.RemoveHook("tasks_tick_topic_list",tickHdrive)
|
||||||
|
plugin.RemoveHook("tasks_tick_widget_wol",tickHdriveWol)
|
||||||
|
plugin.RemoveHook("route_topic_list_start",jumpHdriveTopicList)
|
||||||
|
plugin.RemoveHook("route_forum_list_start",jumpHdriveForumList)
|
||||||
|
hyperspace = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hyperspace struct {
|
||||||
|
topicList atomic.Value
|
||||||
|
gzipTopicList atomic.Value
|
||||||
|
forumList atomic.Value
|
||||||
|
gzipForumList atomic.Value
|
||||||
|
lastTopicListUpdate atomic.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func newHyperspace() *Hyperspace {
|
||||||
|
pageCache := new(Hyperspace)
|
||||||
|
blank := make(map[string][]byte,len(c.Themes))
|
||||||
|
pageCache.topicList.Store(blank)
|
||||||
|
pageCache.gzipTopicList.Store(blank)
|
||||||
|
pageCache.forumList.Store(blank)
|
||||||
|
pageCache.gzipForumList.Store(blank)
|
||||||
|
pageCache.lastTopicListUpdate.Store(int64(0))
|
||||||
|
return pageCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func tickHdriveWol(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
c.DebugLog("docking at wol")
|
||||||
|
return tickHdrive(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Find a better way of doing this
|
||||||
|
func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
c.DebugLog("Refueling...")
|
||||||
|
|
||||||
|
// Avoid accidentally caching already cached content
|
||||||
|
blank := make(map[string][]byte,len(c.Themes))
|
||||||
|
hyperspace.topicList.Store(blank)
|
||||||
|
hyperspace.gzipTopicList.Store(blank)
|
||||||
|
hyperspace.forumList.Store(blank)
|
||||||
|
hyperspace.gzipForumList.Store(blank)
|
||||||
|
|
||||||
|
tListMap := make(map[string][]byte)
|
||||||
|
gtListMap := make(map[string][]byte)
|
||||||
|
fListMap := make(map[string][]byte)
|
||||||
|
gfListMap := make(map[string][]byte)
|
||||||
|
|
||||||
|
var cacheTheme = func(tname string) (skip bool, fail bool, rerr c.RouteError) {
|
||||||
|
|
||||||
|
themeCookie := http.Cookie{Name: "current_theme", Value: tname, Path: "/", MaxAge: c.Year}
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
req := httptest.NewRequest("get", "/topics/", bytes.NewReader(nil))
|
||||||
|
req.AddCookie(&themeCookie)
|
||||||
|
user := c.GuestUser
|
||||||
|
|
||||||
|
head, rerr := c.UserCheck(w, req, &user)
|
||||||
|
if rerr != nil {
|
||||||
|
return true, true, rerr
|
||||||
|
}
|
||||||
|
|
||||||
|
rerr = routes.TopicList(w, req, user, head)
|
||||||
|
if rerr != nil {
|
||||||
|
return true, true, rerr
|
||||||
|
}
|
||||||
|
if w.Code != 200 {
|
||||||
|
c.LogWarning(errors.New("not 200 for topic list in hyperdrive"))
|
||||||
|
return false, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
buf.ReadFrom(w.Result().Body)
|
||||||
|
tListMap[tname] = buf.Bytes()
|
||||||
|
|
||||||
|
gbuf, err := c.CompressBytesGzip(buf.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
c.LogWarning(err)
|
||||||
|
return false, true, nil
|
||||||
|
}
|
||||||
|
gtListMap[tname] = gbuf
|
||||||
|
|
||||||
|
w = httptest.NewRecorder()
|
||||||
|
req = httptest.NewRequest("get", "/forums/", bytes.NewReader(nil))
|
||||||
|
user = c.GuestUser
|
||||||
|
|
||||||
|
head, rerr = c.UserCheck(w, req, &user)
|
||||||
|
if rerr != nil {
|
||||||
|
return true, true, rerr
|
||||||
|
}
|
||||||
|
|
||||||
|
rerr = routes.ForumList(w, req, user, head)
|
||||||
|
if rerr != nil {
|
||||||
|
return true, true, rerr
|
||||||
|
}
|
||||||
|
if w.Code != 200 {
|
||||||
|
c.LogWarning(errors.New("not 200 for forum list in hyperdrive"))
|
||||||
|
return false, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = new(bytes.Buffer)
|
||||||
|
buf.ReadFrom(w.Result().Body)
|
||||||
|
fListMap[tname] = buf.Bytes()
|
||||||
|
|
||||||
|
gbuf, err = c.CompressBytesGzip(buf.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
c.LogWarning(err)
|
||||||
|
return false, true, nil
|
||||||
|
}
|
||||||
|
gfListMap[tname] = gbuf
|
||||||
|
return false, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for tname, _ := range c.Themes {
|
||||||
|
skip, fail, rerr := cacheTheme(tname)
|
||||||
|
if fail || rerr != nil {
|
||||||
|
return skip, rerr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hyperspace.topicList.Store(tListMap)
|
||||||
|
hyperspace.gzipTopicList.Store(gtListMap)
|
||||||
|
hyperspace.forumList.Store(fListMap)
|
||||||
|
hyperspace.gzipForumList.Store(gfListMap)
|
||||||
|
hyperspace.lastTopicListUpdate.Store(time.Now().Unix())
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func jumpHdriveTopicList(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
theme := c.GetThemeByReq(args[1].(*http.Request))
|
||||||
|
p := hyperspace.topicList.Load().(map[string][]byte)
|
||||||
|
pg := hyperspace.gzipTopicList.Load().(map[string][]byte)
|
||||||
|
return jumpHdrive(pg[theme.Name], p[theme.Name], args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func jumpHdriveForumList(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
theme := c.GetThemeByReq(args[1].(*http.Request))
|
||||||
|
p := hyperspace.forumList.Load().(map[string][]byte)
|
||||||
|
pg := hyperspace.gzipForumList.Load().(map[string][]byte)
|
||||||
|
return jumpHdrive(pg[theme.Name], p[theme.Name], args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func jumpHdrive(pg []byte, p []byte, args []interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
var tList []byte
|
||||||
|
w := args[0].(http.ResponseWriter)
|
||||||
|
var iw http.ResponseWriter
|
||||||
|
gzw, ok := w.(c.GzipResponseWriter)
|
||||||
|
if ok {
|
||||||
|
tList = pg
|
||||||
|
iw = gzw.ResponseWriter
|
||||||
|
} else {
|
||||||
|
tList = p
|
||||||
|
iw = w
|
||||||
|
}
|
||||||
|
if len(tList) == 0 {
|
||||||
|
c.DebugLog("no itemlist in hyperspace")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
//c.DebugLog("tList: ", tList)
|
||||||
|
|
||||||
|
// Avoid intercepting user requests as we only have guests in cache right now
|
||||||
|
user := args[2].(*c.User)
|
||||||
|
if user.ID != 0 {
|
||||||
|
c.DebugLog("not guest")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid intercepting search requests and filters as we don't have those in cache
|
||||||
|
r := args[1].(*http.Request)
|
||||||
|
//c.DebugLog("r.URL.Path:",r.URL.Path)
|
||||||
|
//c.DebugLog("r.URL.RawQuery:",r.URL.RawQuery)
|
||||||
|
if r.URL.RawQuery != "" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if r.FormValue("js") == "1" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
//c.DebugLog
|
||||||
|
c.DebugLog("Successful jump")
|
||||||
|
|
||||||
|
var etag string
|
||||||
|
lastUpdate := hyperspace.lastTopicListUpdate.Load().(int64)
|
||||||
|
c.DebugLog("lastUpdate:",lastUpdate)
|
||||||
|
if ok {
|
||||||
|
iw.Header().Set("X-I","1")
|
||||||
|
etag = "\""+strconv.FormatInt(lastUpdate, 10)+"-g\""
|
||||||
|
} else {
|
||||||
|
etag = "\""+strconv.FormatInt(lastUpdate, 10)+"\""
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastUpdate != 0 {
|
||||||
|
iw.Header().Set("ETag", etag)
|
||||||
|
if match := r.Header.Get("If-None-Match"); match != "" {
|
||||||
|
if strings.Contains(match, etag) {
|
||||||
|
iw.WriteHeader(http.StatusNotModified)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header := args[3].(*c.Header)
|
||||||
|
routes.FootHeaders(w, header)
|
||||||
|
iw.Write(tList)
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package extend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -23,11 +23,11 @@ var markdownH1TagOpen []byte
|
||||||
var markdownH1TagClose []byte
|
var markdownH1TagClose []byte
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
c.Plugins.Add(&c.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 *c.Plugin) error {
|
func InitMarkdown(plugin *c.Plugin) error {
|
||||||
plugin.AddHook("parse_assign", markdownParse)
|
plugin.AddHook("parse_assign", MarkdownParse)
|
||||||
|
|
||||||
markdownUnclosedElement = []byte("<red>[Unclosed Element]</red>")
|
markdownUnclosedElement = []byte("<red>[Unclosed Element]</red>")
|
||||||
|
|
||||||
|
@ -47,12 +47,12 @@ func initMarkdown(plugin *c.Plugin) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateMarkdown(plugin *c.Plugin) {
|
func deactivateMarkdown(plugin *c.Plugin) {
|
||||||
plugin.RemoveHook("parse_assign", markdownParse)
|
plugin.RemoveHook("parse_assign", MarkdownParse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// An adapter for the parser, so that the parser can call itself recursively.
|
// An adapter for the parser, so that the parser can call itself recursively.
|
||||||
// This is less for the simple Markdown elements like bold and italics and more for the really complicated ones I plan on adding at some point.
|
// This is less for the simple Markdown elements like bold and italics and more for the really complicated ones I plan on adding at some point.
|
||||||
func markdownParse(msg string) string {
|
func MarkdownParse(msg string) string {
|
||||||
msg = _markdownParse(msg+" ", 0)
|
msg = _markdownParse(msg+" ", 0)
|
||||||
if msg[len(msg)-1] == ' ' {
|
if msg[len(msg)-1] == ' ' {
|
||||||
msg = msg[:len(msg)-1]
|
msg = msg[:len(msg)-1]
|
||||||
|
@ -68,12 +68,12 @@ func _markdownParse(msg string, n int) string {
|
||||||
|
|
||||||
var outbytes []byte
|
var outbytes []byte
|
||||||
var lastElement int
|
var lastElement int
|
||||||
var breaking = false
|
breaking := false
|
||||||
c.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++ {
|
for index := 0; index < len(msg); index++ {
|
||||||
var simpleMatch = func(char byte, o []byte, c []byte) {
|
simpleMatch := func(char byte, o []byte, c []byte) {
|
||||||
var startIndex = index
|
startIndex := index
|
||||||
if (index + 1) >= len(msg) {
|
if (index + 1) >= len(msg) {
|
||||||
breaking = true
|
breaking = true
|
||||||
return
|
return
|
||||||
|
@ -100,8 +100,8 @@ func _markdownParse(msg string, n int) string {
|
||||||
index--
|
index--
|
||||||
}
|
}
|
||||||
|
|
||||||
var startLine = func() {
|
startLine := func() {
|
||||||
var startIndex = index
|
startIndex := index
|
||||||
if (index + 1) >= len(msg) /*|| (index + 2) >= len(msg)*/ {
|
if (index + 1) >= len(msg) /*|| (index + 2) >= len(msg)*/ {
|
||||||
breaking = true
|
breaking = true
|
||||||
return
|
return
|
||||||
|
@ -152,9 +152,9 @@ func _markdownParse(msg string, n int) string {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case '*':
|
case '*':
|
||||||
var startIndex = index
|
startIndex := index
|
||||||
var italic = true
|
italic := true
|
||||||
var bold = false
|
bold := false
|
||||||
if (index + 2) < len(msg) {
|
if (index + 2) < len(msg) {
|
||||||
if msg[index+1] == '*' {
|
if msg[index+1] == '*' {
|
||||||
bold = true
|
bold = true
|
||||||
|
@ -178,7 +178,7 @@ func _markdownParse(msg string, n int) string {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
var preBreak = func() {
|
preBreak := func() {
|
||||||
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
||||||
lastElement = startIndex
|
lastElement = startIndex
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ func markdownSkipUntilNotChar(data string, index int, char byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdownSkipUntilStrongSpace(data string, index int) int {
|
func markdownSkipUntilStrongSpace(data string, index int) int {
|
||||||
var inSpace = false
|
inSpace := false
|
||||||
for ; index < len(data); index++ {
|
for ; index < len(data); index++ {
|
||||||
if inSpace && data[index] == 32 {
|
if inSpace && data[index] == 32 {
|
||||||
index--
|
index--
|
||||||
|
@ -351,8 +351,7 @@ SwitchLoop:
|
||||||
// plugin_markdown doesn't support lists yet, but I want it to be easy to have nested lists when we do have them
|
// plugin_markdown doesn't support lists yet, but I want it to be easy to have nested lists when we do have them
|
||||||
func markdownSkipList(data string, index int) int {
|
func markdownSkipList(data string, index int) int {
|
||||||
var lastNewline int
|
var lastNewline int
|
||||||
var datalen = len(data)
|
datalen := len(data)
|
||||||
|
|
||||||
for ; index < datalen; index++ {
|
for ; index < datalen; index++ {
|
||||||
SkipListInnerLoop:
|
SkipListInnerLoop:
|
||||||
if data[index] == 10 {
|
if data[index] == 10 {
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package extend
|
||||||
|
|
||||||
import c "github.com/Azareal/Gosora/common"
|
import c "github.com/Azareal/Gosora/common"
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
|
e "github.com/Azareal/Gosora/extend"
|
||||||
"github.com/Azareal/Gosora/install"
|
"github.com/Azareal/Gosora/install"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
"github.com/Azareal/Gosora/routes"
|
"github.com/Azareal/Gosora/routes"
|
||||||
|
@ -969,7 +970,7 @@ func BenchmarkBBCodePluginWithRegexpSerial(b *testing.B) {
|
||||||
f := func(name string, msg string) {
|
f := func(name string, msg string) {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = bbcodeRegexParse(msg)
|
_ = e.BbcodeRegexParse(msg)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -989,7 +990,7 @@ func BenchmarkBBCodePluginWithoutCodeTagSerial(b *testing.B) {
|
||||||
f := func(name string, msg string) {
|
f := func(name string, msg string) {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = bbcodeParseWithoutCode(msg)
|
_ = e.BbcodeParseWithoutCode(msg)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +1010,7 @@ func BenchmarkBBCodePluginWithFullParserSerial(b *testing.B) {
|
||||||
f := func(name string, msg string) {
|
f := func(name string, msg string) {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = bbcodeFullParse(msg)
|
_ = e.BbcodeFullParse(msg)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
1
main.go
1
main.go
|
@ -25,6 +25,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
|
_ "github.com/Azareal/Gosora/extend"
|
||||||
co "github.com/Azareal/Gosora/common/counters"
|
co "github.com/Azareal/Gosora/common/counters"
|
||||||
p "github.com/Azareal/Gosora/common/phrases"
|
p "github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
|
e "github.com/Azareal/Gosora/extend"
|
||||||
)
|
)
|
||||||
|
|
||||||
// go test -v
|
// go test -v
|
||||||
|
@ -26,8 +27,7 @@ func (l *MEPairList) Add(msg string, expects string) {
|
||||||
|
|
||||||
func TestBBCodeRender(t *testing.T) {
|
func TestBBCodeRender(t *testing.T) {
|
||||||
//t.Skip()
|
//t.Skip()
|
||||||
err := initBbcode(c.Plugins["bbcode"])
|
if err := e.InitBbcode(c.Plugins["bbcode"]); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
|
|
||||||
t.Log("Testing bbcodeFullParse")
|
t.Log("Testing bbcodeFullParse")
|
||||||
for _, item := range l.Items {
|
for _, item := range l.Items {
|
||||||
res = bbcodeFullParse(item.Msg)
|
res = e.BbcodeFullParse(item.Msg)
|
||||||
if res != item.Expects {
|
if res != item.Expects {
|
||||||
t.Error("Testing string '" + item.Msg + "'")
|
t.Error("Testing string '" + item.Msg + "'")
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
|
@ -85,7 +85,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
|
|
||||||
f := func(msg, expects string) {
|
f := func(msg, expects string) {
|
||||||
t.Log("Testing string '" + msg + "'")
|
t.Log("Testing string '" + msg + "'")
|
||||||
res := bbcodeFullParse(msg)
|
res := e.BbcodeFullParse(msg)
|
||||||
if res != expects {
|
if res != expects {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
t.Error("Expected:", "'"+expects+"'")
|
t.Error("Expected:", "'"+expects+"'")
|
||||||
|
@ -101,7 +101,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
|
|
||||||
msg := "[rand]1[/rand]"
|
msg := "[rand]1[/rand]"
|
||||||
t.Log("Testing string '" + msg + "'")
|
t.Log("Testing string '" + msg + "'")
|
||||||
res = bbcodeFullParse(msg)
|
res = e.BbcodeFullParse(msg)
|
||||||
conv, err := strconv.Atoi(res)
|
conv, err := strconv.Atoi(res)
|
||||||
if err != nil || (conv > 1 || conv < 0) {
|
if err != nil || (conv > 1 || conv < 0) {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
|
@ -110,7 +110,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
|
|
||||||
msg = "[rand]0[/rand]"
|
msg = "[rand]0[/rand]"
|
||||||
t.Log("Testing string '" + msg + "'")
|
t.Log("Testing string '" + msg + "'")
|
||||||
res = bbcodeFullParse(msg)
|
res = e.BbcodeFullParse(msg)
|
||||||
conv, err = strconv.Atoi(res)
|
conv, err = strconv.Atoi(res)
|
||||||
if err != nil || conv != 0 {
|
if err != nil || conv != 0 {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
|
@ -119,7 +119,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
|
|
||||||
msg = "[rand]2147483647[/rand]" // Signed 32-bit MAX
|
msg = "[rand]2147483647[/rand]" // Signed 32-bit MAX
|
||||||
t.Log("Testing string '" + msg + "'")
|
t.Log("Testing string '" + msg + "'")
|
||||||
res = bbcodeFullParse(msg)
|
res = e.BbcodeFullParse(msg)
|
||||||
conv, err = strconv.Atoi(res)
|
conv, err = strconv.Atoi(res)
|
||||||
if err != nil || (conv > 2147483647 || conv < 0) {
|
if err != nil || (conv > 2147483647 || conv < 0) {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
|
@ -128,7 +128,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
|
|
||||||
msg = "[rand]9223372036854775807[/rand]" // Signed 64-bit MAX
|
msg = "[rand]9223372036854775807[/rand]" // Signed 64-bit MAX
|
||||||
t.Log("Testing string '" + msg + "'")
|
t.Log("Testing string '" + msg + "'")
|
||||||
res = bbcodeFullParse(msg)
|
res = e.BbcodeFullParse(msg)
|
||||||
conv, err = strconv.Atoi(res)
|
conv, err = strconv.Atoi(res)
|
||||||
if err != nil || (conv > 9223372036854775807 || conv < 0) {
|
if err != nil || (conv > 9223372036854775807 || conv < 0) {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
|
@ -138,7 +138,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
// Note: conv is commented out in these two, as these numbers overflow int
|
// Note: conv is commented out in these two, as these numbers overflow int
|
||||||
msg = "[rand]18446744073709551615[/rand]" // Unsigned 64-bit MAX
|
msg = "[rand]18446744073709551615[/rand]" // Unsigned 64-bit MAX
|
||||||
t.Log("Testing string '" + msg + "'")
|
t.Log("Testing string '" + msg + "'")
|
||||||
res = bbcodeFullParse(msg)
|
res = e.BbcodeFullParse(msg)
|
||||||
_, err = strconv.Atoi(res)
|
_, err = strconv.Atoi(res)
|
||||||
if err != nil && res != "<red>[Invalid Number]</red>[rand]18446744073709551615[/rand]" {
|
if err != nil && res != "<red>[Invalid Number]</red>[rand]18446744073709551615[/rand]" {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
|
@ -146,7 +146,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
}
|
}
|
||||||
msg = "[rand]170141183460469231731687303715884105727[/rand]" // Signed 128-bit MAX
|
msg = "[rand]170141183460469231731687303715884105727[/rand]" // Signed 128-bit MAX
|
||||||
t.Log("Testing string '" + msg + "'")
|
t.Log("Testing string '" + msg + "'")
|
||||||
res = bbcodeFullParse(msg)
|
res = e.BbcodeFullParse(msg)
|
||||||
_, err = strconv.Atoi(res)
|
_, err = strconv.Atoi(res)
|
||||||
if err != nil && res != "<red>[Invalid Number]</red>[rand]170141183460469231731687303715884105727[/rand]" {
|
if err != nil && res != "<red>[Invalid Number]</red>[rand]170141183460469231731687303715884105727[/rand]" {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
|
@ -166,8 +166,7 @@ func TestBBCodeRender(t *testing.T) {
|
||||||
|
|
||||||
func TestMarkdownRender(t *testing.T) {
|
func TestMarkdownRender(t *testing.T) {
|
||||||
//t.Skip()
|
//t.Skip()
|
||||||
err := initMarkdown(c.Plugins["markdown"])
|
if err := e.InitMarkdown(c.Plugins["markdown"]); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +250,7 @@ func TestMarkdownRender(t *testing.T) {
|
||||||
l.Add("*-你好-*", "<i>-你好-</i>") // TODO: More of these Unicode tests? Emoji, Chinese, etc.?
|
l.Add("*-你好-*", "<i>-你好-</i>") // TODO: More of these Unicode tests? Emoji, Chinese, etc.?
|
||||||
|
|
||||||
for _, item := range l.Items {
|
for _, item := range l.Items {
|
||||||
if res := markdownParse(item.Msg); res != item.Expects {
|
if res := e.MarkdownParse(item.Msg); res != item.Expects {
|
||||||
t.Error("Testing string '" + item.Msg + "'")
|
t.Error("Testing string '" + item.Msg + "'")
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
//t.Error("Ouput in bytes:", []byte(res))
|
//t.Error("Ouput in bytes:", []byte(res))
|
||||||
|
@ -260,7 +259,7 @@ func TestMarkdownRender(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range l2.Items {
|
for _, item := range l2.Items {
|
||||||
if res := markdownParse(item.Msg); res != item.Expects {
|
if res := e.MarkdownParse(item.Msg); res != item.Expects {
|
||||||
t.Error("Testing string '" + item.Msg + "'")
|
t.Error("Testing string '" + item.Msg + "'")
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
//t.Error("Ouput in bytes:", []byte(res))
|
//t.Error("Ouput in bytes:", []byte(res))
|
||||||
|
@ -268,26 +267,8 @@ func TestMarkdownRender(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*for _, item := range l.Items {
|
|
||||||
if res := markdownParse("\n" + item.Msg); res != "\n"+item.Expects {
|
|
||||||
t.Error("Testing string '\n" + item.Msg + "'")
|
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
|
||||||
//t.Error("Ouput in bytes:", []byte(res))
|
|
||||||
t.Error("Expected:", "'\n"+item.Expects+"'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range l.Items {
|
for _, item := range l.Items {
|
||||||
if res := markdownParse("\t" + item.Msg); res != "\t"+item.Expects {
|
if res := e.MarkdownParse("d" + item.Msg); res != "d"+item.Expects {
|
||||||
t.Error("Testing string '\t" + item.Msg + "'")
|
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
|
||||||
//t.Error("Ouput in bytes:", []byte(res))
|
|
||||||
t.Error("Expected:", "'\t"+item.Expects+"'")
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for _, item := range l.Items {
|
|
||||||
if res := markdownParse("d" + item.Msg); res != "d"+item.Expects {
|
|
||||||
t.Error("Testing string 'd" + item.Msg + "'")
|
t.Error("Testing string 'd" + item.Msg + "'")
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
//t.Error("Ouput in bytes:", []byte(res))
|
//t.Error("Ouput in bytes:", []byte(res))
|
||||||
|
|
|
@ -31,7 +31,7 @@ func Groups(w http.ResponseWriter, r *http.Request, u c.User) c.RouteError {
|
||||||
}
|
}
|
||||||
var rank string
|
var rank string
|
||||||
var rankClass string
|
var rankClass string
|
||||||
var canDelete = false
|
canDelete := false
|
||||||
|
|
||||||
// TODO: Localise this
|
// TODO: Localise this
|
||||||
switch {
|
switch {
|
||||||
|
@ -202,7 +202,7 @@ func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c
|
||||||
return c.LocalError("to must be integer", w, r, user)
|
return c.LocalError("to must be integer", w, r, user)
|
||||||
}
|
}
|
||||||
if from == to {
|
if from == to {
|
||||||
return c.LocalError("the from group and to group cannot be the same",w,r,user)
|
return c.LocalError("the from group and to group cannot be the same", w, r, user)
|
||||||
}
|
}
|
||||||
twoWay := r.FormValue("two-way") == "1"
|
twoWay := r.FormValue("two-way") == "1"
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
{{if .LastTopicTime}}<br /><span class="rowsmall" title="{{abstime .LastTopic.LastReplyAt}}">{{.LastTopicTime}}</span>{{end}}
|
{{if .LastTopicTime}}<br /><span class="rowsmall" title="{{abstime .LastTopic.LastReplyAt}}">{{.LastTopicTime}}</span>{{end}}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<div style="clear: both;"></div>
|
<div style="clear:both;"></div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive rowmsg">{{lang "forums_no_forums"}}</div>{{end}}
|
{{else}}<div class="rowitem passive rowmsg">{{lang "forums_no_forums"}}</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,15 +5,15 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock">
|
<div class="rowblock">
|
||||||
{{range .GuildList}}<div class="rowitem datarow">
|
{{range .GuildList}}<div class="rowitem datarow">
|
||||||
<span style="float: left;">
|
<span style="float:left;">
|
||||||
<a href="{{.Link}}" style="">{{.Name}}</a>
|
<a href="{{.Link}}" style="">{{.Name}}</a>
|
||||||
<br /><span class="rowsmall">{{.Desc}}</span>
|
<br /><span class="rowsmall">{{.Desc}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span style="float: right;">
|
<span style="float:right;">
|
||||||
<span style="float: right;font-size: 14px;">{{.MemberCount}} members</span>
|
<span style="float:right;font-size:14px;">{{.MemberCount}} members</span>
|
||||||
<br /><span class="rowsmall">{{.LastUpdateTime}}</span>
|
<br /><span class="rowsmall">{{.LastUpdateTime}}</span>
|
||||||
</span>
|
</span>
|
||||||
<div style="clear: both;"></div>
|
<div style="clear:both;"></div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive">There aren't any visible guilds.</div>{{end}}
|
{{else}}<div class="rowitem passive">There aren't any visible guilds.</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<textarea style='width: 99%;' name='edit_item'>{{.Source}}</textarea><br>
|
<textarea style='width:99%;' name='edit_item'>{{.Source}}</textarea><br>
|
||||||
<div class="update_buttons">
|
<div class="update_buttons">
|
||||||
<a href='{{.Ref}}'><button class='submit_edit' type='submit'>{{lang "topic.update_button"}}</button></a>
|
<a href='{{.Ref}}'><button class='submit_edit' type='submit'>{{lang "topic.update_button"}}</button></a>
|
||||||
<label for="upload_files_post_{{.ID}}" class="formbutton add_file_button">{{lang "topic.reply_add_file_button"}}</label>
|
<label for="upload_files_post_{{.ID}}" class="formbutton add_file_button">{{lang "topic.reply_add_file_button"}}</label>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<article class="rowblock post_container poll" aria-level="{{lang "topic.poll_aria"}}">
|
<article class="rowblock post_container poll" aria-level="{{lang "topic.poll_aria"}}">
|
||||||
<div class="rowitem passive editable_parent post_item poll_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;">
|
<div class="rowitem passive editable_parent post_item poll_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
|
||||||
<div class="topic_content user_content">
|
<div class="topic_content user_content">
|
||||||
{{range .Poll.QuickOptions}}
|
{{range .Poll.QuickOptions}}
|
||||||
<div class="poll_option">
|
<div class="poll_option">
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
<div class="rowitem"><h1>{{.Name}}</h1></div>
|
<div class="rowitem"><h1>{{.Name}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<nav class="rowblock">{{range .MenuList}}
|
<nav class="rowblock">{{range .MenuList}}
|
||||||
<div class="rowitem {{if .Compact}}datarow{{end}}"><a href="{{.Location}}">{{.Text}}</a></div>
|
<div class="rowitem{{if .Compact}} datarow{{end}}"><a href="{{.Location}}">{{.Text}}</a></div>
|
||||||
{{end}}</nav>
|
{{end}}</nav>
|
|
@ -3,7 +3,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock rowlist bgavatars not_grid widget_online">
|
<div class="rowblock rowlist bgavatars not_grid widget_online">
|
||||||
{{if lt .UserCount 30}}
|
{{if lt .UserCount 30}}
|
||||||
{{range .Users}}<div class="rowitem" style="background-image: url('{{.Avatar}}');">
|
{{range .Users}}<div class="rowitem" style="background-image:url('{{.Avatar}}');">
|
||||||
<img src="{{.Avatar}}" class="bgsub" alt="Avatar" aria-hidden="true" />
|
<img src="{{.Avatar}}" class="bgsub" alt="Avatar" aria-hidden="true" />
|
||||||
<a class="rowTitle" href="{{.Link}}">{{.Name}}</a>
|
<a class="rowTitle" href="{{.Link}}">{{.Name}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue