Fixed the forum editor on Cosora. More excavating coming up.

Tweaked the preparser to hopefully fix a few problems with the WYSIWYG Editor.
Added BulkGetCopy to the ForumStores.
Added InternalErrorXML and SilentInternalErrorXML.
Tweaked the element queries so that the topic titles aren't truncated too short.

Began refactoring the topic list logic, more to come here.
This commit is contained in:
Azareal 2017-12-26 07:17:26 +00:00
parent e919812ee2
commit 21999cd7c6
8 changed files with 141 additions and 109 deletions

View File

@ -1,13 +1,13 @@
package main
import (
"errors"
"log"
"net/http"
"strconv"
"strings"
"./common"
"./query_gen/lib"
)
// TODO: Make this a static file somehow? Is it possible for us to put this file somewhere else?
@ -23,8 +23,6 @@ Disallow: /report/
return nil
}
var xmlInternalError = []byte(`<?xml version="1.0" encoding="UTF-8"?>
<error>A problem has occured</error>`)
var sitemapPageCap = 40000 // 40k, bump it up to 50k once we gzip this? Does brotli work on sitemaps?
func writeXMLHeader(w http.ResponseWriter, r *http.Request) {
@ -110,11 +108,7 @@ func routeSitemapForums(w http.ResponseWriter, r *http.Request) common.RouteErro
group, err := common.Groups.Get(common.GuestUser.Group)
if err != nil {
log.Print("The guest group doesn't exist for some reason")
// TODO: Add XML error handling to errors.go
w.WriteHeader(500)
w.Write(xmlInternalError)
return common.HandledRouteError()
return common.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
}
writeXMLHeader(w, r)
@ -145,54 +139,29 @@ func routeSitemapTopics(w http.ResponseWriter, r *http.Request) common.RouteErro
</sitemap>
`))
}
writeXMLHeader(w, r)
group, err := common.Groups.Get(common.GuestUser.Group)
if err != nil {
log.Print("The guest group doesn't exist for some reason")
// TODO: Add XML error handling to errors.go
w.WriteHeader(500)
w.Write(xmlInternalError)
return common.HandledRouteError()
return common.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
}
var argList []interface{}
var qlist string
var visibleForums []common.Forum
for _, fid := range group.CanSee {
forum := common.Forums.DirtyGet(fid)
if forum.Name != "" && forum.Active {
argList = append(argList, strconv.Itoa(fid))
qlist += "?,"
visibleForums = append(visibleForums, forum.Copy())
}
}
if qlist != "" {
qlist = qlist[0 : len(qlist)-1]
}
// TODO: Abstract this
topicCountStmt, err := qgen.Builder.SimpleCount("topics", "parentID IN("+qlist+")", "")
topicCount, err := common.TopicCountInForums(visibleForums)
if err != nil {
// TODO: Add XML error handling to errors.go
w.WriteHeader(500)
w.Write(xmlInternalError)
common.LogError(err)
return common.HandledRouteError()
}
defer topicCountStmt.Close()
var topicCount int
err = topicCountStmt.QueryRow(argList...).Scan(&topicCount)
if err != nil && err != ErrNoRows {
// TODO: Add XML error handling to errors.go
w.WriteHeader(500)
w.Write(xmlInternalError)
common.LogError(err)
return common.HandledRouteError()
return common.InternalErrorXML(err, w, r)
}
var pageCount = topicCount / sitemapPageCap
//log.Print("topicCount", topicCount)
//log.Print("pageCount", pageCount)
writeXMLHeader(w, r)
w.Write([]byte("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n"))
for i := 0; i <= pageCount; i++ {
sitemapItem("sitemaps/topics_page_" + strconv.Itoa(i) + ".xml")
@ -215,45 +184,21 @@ func routeSitemapTopic(w http.ResponseWriter, r *http.Request, page int) common.
group, err := common.Groups.Get(common.GuestUser.Group)
if err != nil {
log.Print("The guest group doesn't exist for some reason")
// TODO: Add XML error handling to errors.go
w.WriteHeader(500)
w.Write(xmlInternalError)
return common.HandledRouteError()
return common.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
}
var argList []interface{}
var qlist string
var visibleForums []common.Forum
for _, fid := range group.CanSee {
forum := common.Forums.DirtyGet(fid)
if forum.Name != "" && forum.Active {
argList = append(argList, strconv.Itoa(fid))
qlist += "?,"
visibleForums = append(visibleForums, forum.Copy())
}
}
if qlist != "" {
qlist = qlist[0 : len(qlist)-1]
}
// TODO: Abstract this
topicCountStmt, err := qgen.Builder.SimpleCount("topics", "parentID IN("+qlist+")", "")
argList, qlist := common.ForumListToArgQ(visibleForums)
topicCount, err := common.ArgQToTopicCount(argList, qlist)
if err != nil {
// TODO: Add XML error handling to errors.go
w.WriteHeader(500)
w.Write(xmlInternalError)
common.LogError(err)
return common.HandledRouteError()
}
defer topicCountStmt.Close()
var topicCount int
err = topicCountStmt.QueryRow(argList...).Scan(&topicCount)
if err != nil && err != ErrNoRows {
// TODO: Add XML error handling to errors.go
w.WriteHeader(500)
w.Write(xmlInternalError)
common.LogError(err)
return common.HandledRouteError()
return common.InternalErrorXML(err, w, r)
}
var pageCount = topicCount / sitemapPageCap

View File

@ -99,6 +99,26 @@ func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteErr
return HandledRouteError()
}
var xmlInternalError = []byte(`<?xml version="1.0" encoding="UTF-8"?>
<error>A problem has occured</error>`)
func InternalErrorXML(err error, w http.ResponseWriter, r *http.Request) RouteError {
w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(500)
w.Write(xmlInternalError)
LogError(err)
return HandledRouteError()
}
// TODO: Stop killing the instance upon hitting an error with InternalError* and deprecate this
func SilentInternalErrorXML(err error, w http.ResponseWriter, r *http.Request) RouteError {
w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(500)
w.Write(xmlInternalError)
log.Print("InternalError: ", err)
return HandledRouteError()
}
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500)
pi := Page{"Error", GuestUser, DefaultHeaderVar(), tList, errmsg}

View File

@ -27,6 +27,7 @@ type ForumStore interface {
DirtyGet(id int) *Forum
Get(id int) (*Forum, error)
BypassGet(id int) (*Forum, error)
BulkGetCopy(ids []int) (forums []Forum, err error)
Reload(id int) error // ? - Should we move this to ForumCache? It might require us to do some unnecessary casting though
//Update(Forum) error
Delete(id int) error
@ -188,6 +189,19 @@ func (mfs *MemoryForumStore) BypassGet(id int) (*Forum, error) {
return forum, err
}
// TODO: Optimise this
func (mfs *MemoryForumStore) BulkGetCopy(ids []int) (forums []Forum, err error) {
forums = make([]Forum, len(ids))
for i, id := range ids {
forum, err := mfs.Get(id)
if err != nil {
return nil, err
}
forums[i] = forum.Copy()
}
return forums, nil
}
func (mfs *MemoryForumStore) Reload(id int) error {
var forum = &Forum{ID: id}
err := mfs.get.QueryRow(id).Scan(&forum.Name, &forum.Desc, &forum.Active, &forum.Preset, &forum.ParentID, &forum.ParentType, &forum.TopicCount, &forum.LastTopicID, &forum.LastReplyerID)

View File

@ -165,10 +165,10 @@ func shortcodeToUnicode(msg string) string {
}
func PreparseMessage(msg string) string {
msg = strings.Replace(msg, "<p><br>", "\n", -1)
msg = strings.Replace(msg, "<p>", "\n", -1)
msg = strings.Replace(msg, "<p><br>", "\n\n", -1)
msg = strings.Replace(msg, "<p>", "\n\n", -1)
msg = strings.Replace(msg, "</p>", "", -1)
msg = strings.Replace(msg, "<br>", "\n", -1)
msg = strings.Replace(msg, "<br>", "\n\n", -1)
if Sshooks["preparse_preassign"] != nil {
msg = RunSshook("preparse_preassign", msg)
}

35
common/topic_list.go Normal file
View File

@ -0,0 +1,35 @@
package common
import "strconv"
import "../query_gen/lib"
// Internal. Don't rely on it.
func ForumListToArgQ(forums []Forum) (argList []interface{}, qlist string) {
for _, forum := range forums {
argList = append(argList, strconv.Itoa(forum.ID))
qlist += "?,"
}
if qlist != "" {
qlist = qlist[0 : len(qlist)-1]
}
return argList, qlist
}
// Internal. Don't rely on it.
func ArgQToTopicCount(argList []interface{}, qlist string) (topicCount int, err error) {
topicCountStmt, err := qgen.Builder.SimpleCount("topics", "parentID IN("+qlist+")", "")
if err != nil {
return 0, err
}
defer topicCountStmt.Close()
err = topicCountStmt.QueryRow(argList...).Scan(&topicCount)
if err != nil && err != ErrNoRows {
return 0, err
}
return topicCount, err
}
func TopicCountInForums(forums []Forum) (topicCount int, err error) {
return ArgQToTopicCount(ForumListToArgQ(forums))
}

View File

@ -135,8 +135,6 @@ func routeTopics(w http.ResponseWriter, r *http.Request, user common.User) commo
headerVars.Zone = "topics"
headerVars.MetaDesc = headerVars.Settings["meta_desc"].(string)
// TODO: Add a function for the qlist stuff
var qlist string
group, err := common.Groups.Get(user.Group)
if err != nil {
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
@ -156,39 +154,28 @@ func routeTopics(w http.ResponseWriter, r *http.Request, user common.User) commo
// We need a list of the visible forums for Quick Topic
var forumList []common.Forum
var argList []interface{}
for _, fid := range canSee {
forum := common.Forums.DirtyGet(fid)
if forum.Name != "" && forum.Active {
// This bit's for quick topic, as we don't want unbound forums (e.g. ones in plugin_socialgroups) showing up
// ? - Would it be useful, if we could post in social groups from /topics/?
if (forum.ParentType == "" || forum.ParentType == "forum") && user.Loggedin {
fcopy := forum.Copy()
// TODO: Add a hook here for plugin_guilds
forumList = append(forumList, fcopy)
}
}
}
// ? - Should we be showing plugin_guilds posts on /topics/?
// ? - Would it be useful, if we could post in social groups from /topics/?
argList = append(argList, strconv.Itoa(fid))
qlist += "?,"
}
}
argList, qlist := common.ForumListToArgQ(forumList)
// ! Need an inline error not a page level error
if qlist == "" {
return common.NotFound(w, r)
}
qlist = qlist[0 : len(qlist)-1]
// TODO: Abstract this
topicCountStmt, err := qgen.Builder.SimpleCount("topics", "parentID IN("+qlist+")", "")
if err != nil {
return common.InternalError(err, w, r)
}
defer topicCountStmt.Close()
var topicCount int
err = topicCountStmt.QueryRow(argList...).Scan(&topicCount)
topicCount, err := common.ArgQToTopicCount(argList, qlist)
if err != nil {
return common.InternalError(err, w, r)
}
@ -304,7 +291,6 @@ func routeForum(w http.ResponseWriter, r *http.Request, user common.User, sfid s
if ferr != nil {
return ferr
}
if !user.Perms.ViewTopic {
return common.NoPermissions(w, r, user)
}

View File

@ -580,11 +580,10 @@ select, input, textarea, button {
display: inline-block;
}
.topic_list .rowtopic span {
max-width: 112px;
max-width: 162px;
overflow: hidden;
color: var(--primary-text-color);
}
.topic_list .rowsmall {
font-size: 15px;
}
@ -596,17 +595,9 @@ select, input, textarea, button {
font-size: 15px;
}
.topic_list .rowsmall.starter:before {
content: "\f007";
font: normal normal normal 14px/1 FontAwesome;
margin-right: 5px;
font-size: 15px;
}
.topic_list .lastReplyAt {
font-size: 14px;
}
.topic_list .topic_status_e {
display: none;
}
@ -615,7 +606,6 @@ select, input, textarea, button {
flex: 1 1 calc(100% - 380px);
border-right: none;
}
.topic_inner_right {
margin-left: 15%;
margin-right: auto;
@ -633,12 +623,9 @@ select, input, textarea, button {
.topic_inner_right {
margin-top: 12px;
}
.topic_inner_right span {
/*font-size: 15px;*/
font-size: 16px;
}
.topic_inner_right span:after {
font-size: 13.5px;
}
@ -656,7 +643,6 @@ select, input, textarea, button {
content: var(--likes-lang-string);
color: var(--lightened-primary-text-color);
}
.parent_forum {
color: var(--lightened-primary-text-color);
}
@ -684,7 +670,7 @@ select, input, textarea, button {
margin-top: 12px;
margin-left: 8px;
margin-bottom: 14px;
width: 240px;
width: 220px;
}
.topic_right > span {
margin-top: 12px;
@ -698,7 +684,7 @@ select, input, textarea, button {
background-color: hsl(81, 60%, 95%);
}
@element .topic_left .rowtopic and (min-width: 110px) {
@element .topic_left .rowtopic and (min-width: 160px) {
$this, $this span, $this + .parent_forum {
float: left;
}
@ -712,6 +698,18 @@ select, input, textarea, button {
}
}
@element .topic_list and (min-width: 738px) {
.topic_left .topic_inner_left {
width: calc(240px + 1%);
}
}
@element .topic_list and (min-width: 875px) {
.topic_left .topic_inner_left {
width: calc(240px + 10%);
}
}
.forum_list, .post_container {
border: none;
}
@ -778,6 +776,9 @@ select, input, textarea, button {
.userinfo .tag_block {
color: var(--extra-lightened-primary-text-color);
}
.post_item .user_content {
margin-bottom: 10px;
}
.button_container {
margin-top: auto;
display: flex;

View File

@ -77,10 +77,41 @@
.formlist .formitem {
padding: 8px;
}
#forum_quick_perms .panel_floater,
.panel_theme_mobile, .panel_theme_tag {
display: none;
}
#panel_plugins .rowitem {
display: block;
}
#forum_quick_perms .formitem {
display: flex;
}
#forum_quick_perms .formitem .edit_fields {
margin-left: 3px;
margin-top: 1px;
}
.perm_preset_no_access:before {
content: "No Access";
color: hsl(0,100%,20%);
}
.perm_preset_read_only:before, .perm_preset_can_post:before {
color: hsl(120,100%,20%);
}
.perm_preset_read_only:before {
content: "Read Only";
}
.perm_preset_can_post:before {
content: "Can Post";
}
.perm_preset_can_moderate:before {
content: "Can Moderate";
color: hsl(240,100%,20%);
}
.perm_preset_custom:before {
content: "Custom";
color: hsl(0,0%,20%);
}
.perm_preset_default:before {
content: "Default";
}