Finished moving the files into the subpackage, this should open more doors to us.
Moved more queries out of the global stmt holder. Refactored several things.
This commit is contained in:
parent
10e681f15f
commit
f30ea7a9bb
28
alerts.go
28
alerts.go
|
@ -6,10 +6,14 @@
|
||||||
*/
|
*/
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "log"
|
import (
|
||||||
import "strings"
|
"errors"
|
||||||
import "strconv"
|
"log"
|
||||||
import "errors"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"./common"
|
||||||
|
)
|
||||||
|
|
||||||
// These notes are for me, don't worry about it too much ^_^
|
// These notes are for me, don't worry about it too much ^_^
|
||||||
/*
|
/*
|
||||||
|
@ -26,10 +30,10 @@ import "errors"
|
||||||
"{x}{created a new topic}{topic}"
|
"{x}{created a new topic}{topic}"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func buildAlert(asid int, event string, elementType string, actorID int, targetUserID int, elementID int, user User /* The current user */) (string, error) {
|
func buildAlert(asid int, event string, elementType string, actorID int, targetUserID int, elementID int, user common.User /* The current user */) (string, error) {
|
||||||
var targetUser *User
|
var targetUser *common.User
|
||||||
|
|
||||||
actor, err := users.Get(actorID)
|
actor, err := common.Users.Get(actorID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Unable to find the actor")
|
return "", errors.New("Unable to find the actor")
|
||||||
}
|
}
|
||||||
|
@ -52,7 +56,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
|
||||||
case "forum":
|
case "forum":
|
||||||
if event == "reply" {
|
if event == "reply" {
|
||||||
act = "created a new topic"
|
act = "created a new topic"
|
||||||
topic, err := topics.Get(elementID)
|
topic, err := common.Topics.Get(elementID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Unable to find the linked topic")
|
return "", errors.New("Unable to find the linked topic")
|
||||||
}
|
}
|
||||||
|
@ -64,7 +68,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
|
||||||
act = "did something in a forum"
|
act = "did something in a forum"
|
||||||
}
|
}
|
||||||
case "topic":
|
case "topic":
|
||||||
topic, err := topics.Get(elementID)
|
topic, err := common.Topics.Get(elementID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Unable to find the linked topic")
|
return "", errors.New("Unable to find the linked topic")
|
||||||
}
|
}
|
||||||
|
@ -75,7 +79,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
|
||||||
postAct = " your topic"
|
postAct = " your topic"
|
||||||
}
|
}
|
||||||
case "user":
|
case "user":
|
||||||
targetUser, err = users.Get(elementID)
|
targetUser, err = common.Users.Get(elementID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Unable to find the target user")
|
return "", errors.New("Unable to find the target user")
|
||||||
}
|
}
|
||||||
|
@ -83,7 +87,9 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
|
||||||
endFrag = "'s profile"
|
endFrag = "'s profile"
|
||||||
url = targetUser.Link
|
url = targetUser.Link
|
||||||
case "post":
|
case "post":
|
||||||
topic, err := getTopicByReply(elementID)
|
reply := common.BlankReply()
|
||||||
|
reply.ID = elementID
|
||||||
|
topic, err := reply.Topic()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Unable to find the linked reply or parent topic")
|
return "", errors.New("Unable to find the linked reply or parent topic")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,17 @@
|
||||||
* Copyright Azareal 2017 - 2018
|
* Copyright Azareal 2017 - 2018
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import "log"
|
|
||||||
import "errors"
|
import "errors"
|
||||||
import "strconv"
|
import "strconv"
|
||||||
import "net/http"
|
import "net/http"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
|
||||||
import "./query_gen/lib"
|
|
||||||
import "golang.org/x/crypto/bcrypt"
|
import "golang.org/x/crypto/bcrypt"
|
||||||
|
import "../query_gen/lib"
|
||||||
|
|
||||||
var auth Auth
|
var Auth AuthInt
|
||||||
|
|
||||||
// ErrMismatchedHashAndPassword is thrown whenever a hash doesn't match it's unhashed password
|
// ErrMismatchedHashAndPassword is thrown whenever a hash doesn't match it's unhashed password
|
||||||
var ErrMismatchedHashAndPassword = bcrypt.ErrMismatchedHashAndPassword
|
var ErrMismatchedHashAndPassword = bcrypt.ErrMismatchedHashAndPassword
|
||||||
|
@ -27,8 +26,8 @@ var ErrWrongPassword = errors.New("That's not the correct password.")
|
||||||
var ErrSecretError = errors.New("There was a glitch in the system. Please contact your local administrator.")
|
var ErrSecretError = errors.New("There was a glitch in the system. Please contact your local administrator.")
|
||||||
var ErrNoUserByName = errors.New("We couldn't find an account with that username.")
|
var ErrNoUserByName = errors.New("We couldn't find an account with that username.")
|
||||||
|
|
||||||
// Auth is the main authentication interface.
|
// AuthInt is the main authentication interface.
|
||||||
type Auth interface {
|
type AuthInt interface {
|
||||||
Authenticate(username string, password string) (uid int, err error)
|
Authenticate(username string, password string) (uid int, err error)
|
||||||
Logout(w http.ResponseWriter, uid int)
|
Logout(w http.ResponseWriter, uid int)
|
||||||
ForceLogout(uid int) error
|
ForceLogout(uid int) error
|
||||||
|
@ -40,24 +39,19 @@ type Auth interface {
|
||||||
|
|
||||||
// DefaultAuth is the default authenticator used by Gosora, may be swapped with an alternate authenticator in some situations. E.g. To support LDAP.
|
// DefaultAuth is the default authenticator used by Gosora, may be swapped with an alternate authenticator in some situations. E.g. To support LDAP.
|
||||||
type DefaultAuth struct {
|
type DefaultAuth struct {
|
||||||
login *sql.Stmt
|
login *sql.Stmt
|
||||||
logout *sql.Stmt
|
logout *sql.Stmt
|
||||||
|
updateSession *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDefaultAuth is a factory for spitting out DefaultAuths
|
// NewDefaultAuth is a factory for spitting out DefaultAuths
|
||||||
func NewDefaultAuth() *DefaultAuth {
|
func NewDefaultAuth() (*DefaultAuth, error) {
|
||||||
loginStmt, err := qgen.Builder.SimpleSelect("users", "uid, password, salt", "name = ?", "", "")
|
acc := qgen.Builder.Accumulator()
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
logoutStmt, err := qgen.Builder.SimpleUpdate("users", "session = ''", "uid = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return &DefaultAuth{
|
return &DefaultAuth{
|
||||||
login: loginStmt,
|
login: acc.SimpleSelect("users", "uid, password, salt", "name = ?", "", ""),
|
||||||
logout: logoutStmt,
|
logout: acc.SimpleUpdate("users", "session = ''", "uid = ?"),
|
||||||
}
|
updateSession: acc.SimpleUpdate("users", "session = ?", "uid = ?"),
|
||||||
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate checks if a specific username and password is valid and returns the UID for the corresponding user, if so. Otherwise, a user safe error.
|
// Authenticate checks if a specific username and password is valid and returns the UID for the corresponding user, if so. Otherwise, a user safe error.
|
||||||
|
@ -97,7 +91,7 @@ func (auth *DefaultAuth) ForceLogout(uid int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the user out of the cache
|
// Flush the user out of the cache
|
||||||
ucache, ok := users.(UserCache)
|
ucache, ok := Users.(UserCache)
|
||||||
if ok {
|
if ok {
|
||||||
ucache.CacheRemove(uid)
|
ucache.CacheRemove(uid)
|
||||||
}
|
}
|
||||||
|
@ -107,18 +101,18 @@ func (auth *DefaultAuth) ForceLogout(uid int) error {
|
||||||
|
|
||||||
// Logout logs you out of the computer you requested the logout for, but not the other computers you're logged in with
|
// Logout logs you out of the computer you requested the logout for, but not the other computers you're logged in with
|
||||||
func (auth *DefaultAuth) Logout(w http.ResponseWriter, _ int) {
|
func (auth *DefaultAuth) Logout(w http.ResponseWriter, _ int) {
|
||||||
cookie := http.Cookie{Name: "uid", Value: "", Path: "/", MaxAge: year}
|
cookie := http.Cookie{Name: "uid", Value: "", Path: "/", MaxAge: Year}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
cookie = http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: year}
|
cookie = http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: Year}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Set the cookie domain
|
// TODO: Set the cookie domain
|
||||||
// SetCookies sets the two cookies required for the current user to be recognised as a specific user in future requests
|
// SetCookies sets the two cookies required for the current user to be recognised as a specific user in future requests
|
||||||
func (auth *DefaultAuth) SetCookies(w http.ResponseWriter, uid int, session string) {
|
func (auth *DefaultAuth) SetCookies(w http.ResponseWriter, uid int, session string) {
|
||||||
cookie := http.Cookie{Name: "uid", Value: strconv.Itoa(uid), Path: "/", MaxAge: year}
|
cookie := http.Cookie{Name: "uid", Value: strconv.Itoa(uid), Path: "/", MaxAge: Year}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
cookie = http.Cookie{Name: "session", Value: session, Path: "/", MaxAge: year}
|
cookie = http.Cookie{Name: "session", Value: session, Path: "/", MaxAge: Year}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,20 +138,20 @@ func (auth *DefaultAuth) GetCookies(r *http.Request) (uid int, session string, e
|
||||||
func (auth *DefaultAuth) SessionCheck(w http.ResponseWriter, r *http.Request) (user *User, halt bool) {
|
func (auth *DefaultAuth) SessionCheck(w http.ResponseWriter, r *http.Request) (user *User, halt bool) {
|
||||||
uid, session, err := auth.GetCookies(r)
|
uid, session, err := auth.GetCookies(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &guestUser, false
|
return &GuestUser, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this session valid..?
|
// Is this session valid..?
|
||||||
user, err = users.Get(uid)
|
user, err = Users.Get(uid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return &guestUser, false
|
return &GuestUser, false
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
InternalError(err, w, r)
|
InternalError(err, w, r)
|
||||||
return &guestUser, true
|
return &GuestUser, true
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Session == "" || session != user.Session {
|
if user.Session == "" || session != user.Session {
|
||||||
return &guestUser, false
|
return &GuestUser, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return user, false
|
return user, false
|
||||||
|
@ -165,18 +159,18 @@ func (auth *DefaultAuth) SessionCheck(w http.ResponseWriter, r *http.Request) (u
|
||||||
|
|
||||||
// CreateSession generates a new session to allow a remote client to stay logged in as a specific user
|
// CreateSession generates a new session to allow a remote client to stay logged in as a specific user
|
||||||
func (auth *DefaultAuth) CreateSession(uid int) (session string, err error) {
|
func (auth *DefaultAuth) CreateSession(uid int) (session string, err error) {
|
||||||
session, err = GenerateSafeString(sessionLength)
|
session, err = GenerateSafeString(SessionLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmts.updateSession.Exec(session, uid)
|
_, err = auth.updateSession.Exec(session, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the user data from the cache
|
// Flush the user data from the cache
|
||||||
ucache, ok := users.(UserCache)
|
ucache, ok := Users.(UserCache)
|
||||||
if ok {
|
if ok {
|
||||||
ucache.CacheRemove(uid)
|
ucache.CacheRemove(uid)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@ var ErrStoreCapacityOverflow = errors.New("This datastore has reached it's maxim
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
type DataStore interface {
|
type DataStore interface {
|
||||||
Load(id int) error
|
DirtyGet(id int) interface{}
|
||||||
Get(id int) (interface{}, error)
|
Get(id int) (interface{}, error)
|
||||||
BypassGet(id int) (interface{}, error)
|
BypassGet(id int) (interface{}, error)
|
||||||
//GetGlobalCount()
|
//GlobalCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
|
@ -32,6 +32,9 @@ type DataCache interface {
|
||||||
CacheAddUnsafe(item interface{}) error
|
CacheAddUnsafe(item interface{}) error
|
||||||
CacheRemove(id int) error
|
CacheRemove(id int) error
|
||||||
CacheRemoveUnsafe(id int) error
|
CacheRemoveUnsafe(id int) error
|
||||||
GetLength() int
|
Reload(id int) error
|
||||||
|
Flush()
|
||||||
|
Length() int
|
||||||
|
SetCapacity(capacity int)
|
||||||
GetCapacity() int
|
GetCapacity() int
|
||||||
}
|
}
|
|
@ -2,5 +2,78 @@ package common
|
||||||
|
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
|
||||||
|
// nolint I don't want to write comments for each of these o.o
|
||||||
|
const Hour int = 60 * 60
|
||||||
|
const Day int = Hour * 24
|
||||||
|
const Week int = Day * 7
|
||||||
|
const Month int = Day * 30
|
||||||
|
const Year int = Day * 365
|
||||||
|
const Kilobyte int = 1024
|
||||||
|
const Megabyte int = Kilobyte * 1024
|
||||||
|
const Gigabyte int = Megabyte * 1024
|
||||||
|
const Terabyte int = Gigabyte * 1024
|
||||||
|
const Petabyte int = Terabyte * 1024
|
||||||
|
|
||||||
|
const SaltLength int = 32
|
||||||
|
const SessionLength int = 80
|
||||||
|
|
||||||
|
var TmplPtrMap = make(map[string]interface{})
|
||||||
|
|
||||||
// ErrNoRows is an alias of sql.ErrNoRows, just in case we end up with non-database/sql datastores
|
// ErrNoRows is an alias of sql.ErrNoRows, just in case we end up with non-database/sql datastores
|
||||||
var ErrNoRows = sql.ErrNoRows
|
var ErrNoRows = sql.ErrNoRows
|
||||||
|
|
||||||
|
// ? - Make this more customisable?
|
||||||
|
var ExternalSites = map[string]string{
|
||||||
|
"YT": "https://www.youtube.com/",
|
||||||
|
}
|
||||||
|
|
||||||
|
type StringList []string
|
||||||
|
|
||||||
|
// ? - Should we allow users to upload .php or .go files? It could cause security issues. We could store them with a mangled extension to render them inert
|
||||||
|
// TODO: Let admins manage this from the Control Panel
|
||||||
|
var AllowedFileExts = StringList{
|
||||||
|
"png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", "apng", // images
|
||||||
|
|
||||||
|
"txt", "xml", "json", "yaml", "toml", "ini", "md", "html", "rtf", "js", "py", "rb", "css", "scss", "less", "eqcss", "pcss", "java", "ts", "cs", "c", "cc", "cpp", "cxx", "C", "c++", "h", "hh", "hpp", "hxx", "h++", "rs", "rlib", "htaccess", "gitignore", // text
|
||||||
|
|
||||||
|
"mp3", "mp4", "avi", "wmv", "webm", // video
|
||||||
|
|
||||||
|
"otf", "woff2", "woff", "ttf", "eot", // fonts
|
||||||
|
}
|
||||||
|
var ImageFileExts = StringList{
|
||||||
|
"png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", "apng",
|
||||||
|
}
|
||||||
|
var ArchiveFileExts = StringList{
|
||||||
|
"bz2", "zip", "gz", "7z", "tar", "cab",
|
||||||
|
}
|
||||||
|
var ExecutableFileExts = StringList{
|
||||||
|
"exe", "jar", "phar", "shar", "iso",
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Write a test for this
|
||||||
|
func (slice StringList) Contains(needle string) bool {
|
||||||
|
for _, item := range slice {
|
||||||
|
if item == needle {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type DBInits []func() error
|
||||||
|
|
||||||
|
var DbInits DBInits
|
||||||
|
|
||||||
|
func (inits DBInits) Run() error {
|
||||||
|
for _, init := range inits {
|
||||||
|
err := init()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (inits DBInits) Add(init ...func() error) {
|
||||||
|
inits = append(inits, init...)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/smtp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Email struct {
|
||||||
|
UserID int
|
||||||
|
Email string
|
||||||
|
Validated bool
|
||||||
|
Primary bool
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendValidationEmail(username string, email string, token string) bool {
|
||||||
|
var schema = "http"
|
||||||
|
if Site.EnableSsl {
|
||||||
|
schema += "s"
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Move these to the phrase system
|
||||||
|
subject := "Validate Your Email @ " + Site.Name
|
||||||
|
msg := "Dear " + username + ", following your registration on our forums, we ask you to validate your email, so that we can confirm that this email actually belongs to you.\n\nClick on the following link to do so. " + schema + "://" + Site.URL + "/user/edit/token/" + token + "\n\nIf you haven't created an account here, then please feel free to ignore this email.\nWe're sorry for the inconvenience this may have caused."
|
||||||
|
return SendEmail(email, subject, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Refactor this
|
||||||
|
func SendEmail(email string, subject string, msg string) bool {
|
||||||
|
// This hook is useful for plugin_sendmail or for testing tools. Possibly to hook it into some sort of mail server?
|
||||||
|
if Vhooks["email_send_intercept"] != nil {
|
||||||
|
return Vhooks["email_send_intercept"](email, subject, msg).(bool)
|
||||||
|
}
|
||||||
|
body := "Subject: " + subject + "\n\n" + msg + "\n"
|
||||||
|
|
||||||
|
con, err := smtp.Dial(Config.SMTPServer + ":" + Config.SMTPPort)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if Config.SMTPUsername != "" {
|
||||||
|
auth := smtp.PlainAuth("", Config.SMTPUsername, Config.SMTPPassword, Config.SMTPServer)
|
||||||
|
err = con.Auth(auth)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = con.Mail(Site.Email)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
err = con.Rcpt(email)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
emailData, err := con.Data()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(emailData, body)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
err = emailData.Close()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
err = con.Quit()
|
||||||
|
return err == nil
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ var tList []interface{}
|
||||||
type RouteError interface {
|
type RouteError interface {
|
||||||
Type() string
|
Type() string
|
||||||
Error() string
|
Error() string
|
||||||
Json() bool
|
JSON() bool
|
||||||
Handled() bool
|
Handled() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ func (err *RouteErrorImpl) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respond with JSON?
|
// Respond with JSON?
|
||||||
func (err *RouteErrorImpl) Json() bool {
|
func (err *RouteErrorImpl) JSON() bool {
|
||||||
return err.json
|
return err.json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError
|
||||||
// TODO: Centralise the user struct somewhere else
|
// TODO: Centralise the user struct somewhere else
|
||||||
user := User{0, "guest", "Guest", "", 0, false, false, false, false, false, false, GuestPerms, nil, "", false, "", "", "", "", "", 0, 0, "0.0.0.0.0", 0}
|
user := User{0, "guest", "Guest", "", 0, false, false, false, false, false, false, GuestPerms, nil, "", false, "", "", "", "", "", 0, 0, "0.0.0.0.0", 0}
|
||||||
pi := Page{"Internal Server Error", user, DefaultHeaderVar(), tList, "A problem has occurred in the system."}
|
pi := Page{"Internal Server Error", user, DefaultHeaderVar(), tList, "A problem has occurred in the system."}
|
||||||
err = templates.ExecuteTemplate(w, "error.html", pi)
|
err = Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
|
@ -119,33 +119,16 @@ func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteErr
|
||||||
return HandledRouteError()
|
return HandledRouteError()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? - Where is this used? Should we use it more?
|
|
||||||
// LoginRequired is an error shown to the end-user when they try to access an area which requires them to login
|
|
||||||
func LoginRequired(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
|
||||||
w.WriteHeader(401)
|
|
||||||
pi := Page{"Local Error", user, DefaultHeaderVar(), tList, "You need to login to do that."}
|
|
||||||
if preRenderHooks["pre_render_error"] != nil {
|
|
||||||
if runPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
LogError(err)
|
|
||||||
}
|
|
||||||
return HandledRouteError()
|
|
||||||
}
|
|
||||||
|
|
||||||
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
|
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
user := User{ID: 0, Group: 6, Perms: GuestPerms}
|
user := User{ID: 0, Group: 6, Perms: GuestPerms}
|
||||||
pi := Page{"Error", user, DefaultHeaderVar(), tList, errmsg}
|
pi := Page{"Error", user, DefaultHeaderVar(), tList, errmsg}
|
||||||
if preRenderHooks["pre_render_error"] != nil {
|
if PreRenderHooks["pre_render_error"] != nil {
|
||||||
if runPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
if RunPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
@ -169,12 +152,12 @@ func PreErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, isJs boo
|
||||||
func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
pi := Page{"Local Error", user, DefaultHeaderVar(), tList, errmsg}
|
pi := Page{"Local Error", user, DefaultHeaderVar(), tList, errmsg}
|
||||||
if preRenderHooks["pre_render_error"] != nil {
|
if PreRenderHooks["pre_render_error"] != nil {
|
||||||
if runPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
if RunPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
@ -200,12 +183,12 @@ func NoPermissions(w http.ResponseWriter, r *http.Request, user User) RouteError
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
pi := Page{"Local Error", user, DefaultHeaderVar(), tList, "You don't have permission to do that."}
|
pi := Page{"Local Error", user, DefaultHeaderVar(), tList, "You don't have permission to do that."}
|
||||||
// TODO: What to do about this hook?
|
// TODO: What to do about this hook?
|
||||||
if preRenderHooks["pre_render_error"] != nil {
|
if PreRenderHooks["pre_render_error"] != nil {
|
||||||
if runPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
if RunPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
@ -229,12 +212,12 @@ func NoPermissionsJS(w http.ResponseWriter, r *http.Request, user User) RouteErr
|
||||||
func Banned(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func Banned(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
pi := Page{"Banned", user, DefaultHeaderVar(), tList, "You have been banned from this site."}
|
pi := Page{"Banned", user, DefaultHeaderVar(), tList, "You have been banned from this site."}
|
||||||
if preRenderHooks["pre_render_error"] != nil {
|
if PreRenderHooks["pre_render_error"] != nil {
|
||||||
if runPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
if RunPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
@ -258,21 +241,33 @@ func BannedJS(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, isJs bool) RouteError {
|
func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, isJs bool) RouteError {
|
||||||
w.WriteHeader(401)
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
pi := Page{"Local Error", user, DefaultHeaderVar(), tList, "You need to login to do that."}
|
return LoginRequired(w, r, user)
|
||||||
if preRenderHooks["pre_render_error"] != nil {
|
|
||||||
if runPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
LogError(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_, _ = w.Write([]byte(`{"errmsg":"You need to login to do that."}`))
|
|
||||||
}
|
}
|
||||||
|
return LoginRequiredJS(w, r, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ? - Where is this used? Should we use it more?
|
||||||
|
// LoginRequired is an error shown to the end-user when they try to access an area which requires them to login
|
||||||
|
func LoginRequired(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
|
w.WriteHeader(401)
|
||||||
|
pi := Page{"Local Error", user, DefaultHeaderVar(), tList, "You need to login to do that."}
|
||||||
|
if PreRenderHooks["pre_render_error"] != nil {
|
||||||
|
if RunPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
|
if err != nil {
|
||||||
|
LogError(err)
|
||||||
|
}
|
||||||
|
return HandledRouteError()
|
||||||
|
}
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
|
w.WriteHeader(401)
|
||||||
|
_, _ = w.Write([]byte(`{"errmsg":"You need to login to do that."}`))
|
||||||
return HandledRouteError()
|
return HandledRouteError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,12 +276,12 @@ func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, isJs bo
|
||||||
func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
pi := Page{"Security Error", user, DefaultHeaderVar(), tList, "There was a security issue with your request."}
|
pi := Page{"Security Error", user, DefaultHeaderVar(), tList, "There was a security issue with your request."}
|
||||||
if preRenderHooks["pre_render_security_error"] != nil {
|
if PreRenderHooks["pre_render_security_error"] != nil {
|
||||||
if runPreRenderHook("pre_render_security_error", w, r, &user, &pi) {
|
if RunPreRenderHook("pre_render_security_error", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
@ -301,7 +296,7 @@ func NotFound(w http.ResponseWriter, r *http.Request) RouteError {
|
||||||
// TODO: Centralise the user struct somewhere else
|
// TODO: Centralise the user struct somewhere else
|
||||||
user := User{0, "guest", "Guest", "", 0, false, false, false, false, false, false, GuestPerms, nil, "", false, "", "", "", "", "", 0, 0, "0.0.0.0.0", 0}
|
user := User{0, "guest", "Guest", "", 0, false, false, false, false, false, false, GuestPerms, nil, "", false, "", "", "", "", "", 0, 0, "0.0.0.0.0", 0}
|
||||||
pi := Page{"Not Found", user, DefaultHeaderVar(), tList, "The requested page doesn't exist."}
|
pi := Page{"Not Found", user, DefaultHeaderVar(), tList, "The requested page doesn't exist."}
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
@ -312,12 +307,12 @@ func NotFound(w http.ResponseWriter, r *http.Request) RouteError {
|
||||||
func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
w.WriteHeader(errcode)
|
w.WriteHeader(errcode)
|
||||||
pi := Page{errtitle, user, DefaultHeaderVar(), tList, errmsg}
|
pi := Page{errtitle, user, DefaultHeaderVar(), tList, errmsg}
|
||||||
if preRenderHooks["pre_render_error"] != nil {
|
if PreRenderHooks["pre_render_error"] != nil {
|
||||||
if runPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
if RunPreRenderHook("pre_render_error", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,13 @@ type PluginList map[string]*Plugin
|
||||||
var Plugins PluginList = make(map[string]*Plugin)
|
var Plugins PluginList = make(map[string]*Plugin)
|
||||||
|
|
||||||
// Hooks with a single argument. Is this redundant? Might be useful for inlining, as variadics aren't inlined? Are closures even inlined to begin with?
|
// Hooks with a single argument. Is this redundant? Might be useful for inlining, as variadics aren't inlined? Are closures even inlined to begin with?
|
||||||
var hooks = map[string][]func(interface{}) interface{}{
|
var Hooks = map[string][]func(interface{}) interface{}{
|
||||||
"forums_frow_assign": nil,
|
"forums_frow_assign": nil,
|
||||||
"topic_create_frow_assign": nil,
|
"topic_create_frow_assign": nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooks with a variable number of arguments
|
// Hooks with a variable number of arguments
|
||||||
var vhooks = map[string]func(...interface{}) interface{}{
|
var Vhooks = map[string]func(...interface{}) interface{}{
|
||||||
"intercept_build_widgets": nil,
|
"intercept_build_widgets": nil,
|
||||||
"forum_trow_assign": nil,
|
"forum_trow_assign": nil,
|
||||||
"topics_topic_row_assign": nil,
|
"topics_topic_row_assign": nil,
|
||||||
|
@ -35,7 +35,7 @@ var vhooks = map[string]func(...interface{}) interface{}{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooks with a variable number of arguments and return values for skipping the parent function and propagating an error upwards
|
// Hooks with a variable number of arguments and return values for skipping the parent function and propagating an error upwards
|
||||||
var vhookSkippable = map[string]func(...interface{}) (bool, RouteError){
|
var VhookSkippable = map[string]func(...interface{}) (bool, RouteError){
|
||||||
"simple_forum_check_pre_perms": nil,
|
"simple_forum_check_pre_perms": nil,
|
||||||
"forum_check_pre_perms": nil,
|
"forum_check_pre_perms": nil,
|
||||||
}
|
}
|
||||||
|
@ -65,13 +65,13 @@ var messageHooks = map[string][]func(Message, PageInt, ...interface{}) interface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooks which take in and spit out a string. This is usually used for parser components
|
// Hooks which take in and spit out a string. This is usually used for parser components
|
||||||
var sshooks = map[string][]func(string) string{
|
var Sshooks = map[string][]func(string) string{
|
||||||
"preparse_preassign": nil,
|
"preparse_preassign": nil,
|
||||||
"parse_assign": nil,
|
"parse_assign": nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The hooks which run before the template is rendered for a route
|
// The hooks which run before the template is rendered for a route
|
||||||
var preRenderHooks = map[string][]func(http.ResponseWriter, *http.Request, *User, interface{}) bool{
|
var PreRenderHooks = map[string][]func(http.ResponseWriter, *http.Request, *User, interface{}) bool{
|
||||||
"pre_render": nil,
|
"pre_render": nil,
|
||||||
|
|
||||||
"pre_render_forum_list": nil,
|
"pre_render_forum_list": nil,
|
||||||
|
@ -137,7 +137,7 @@ type Plugin struct {
|
||||||
Data interface{} // Usually used for hosting the VMs / reusable elements of non-native plugins
|
Data interface{} // Usually used for hosting the VMs / reusable elements of non-native plugins
|
||||||
}
|
}
|
||||||
|
|
||||||
func initExtend() (err error) {
|
func InitExtend() (err error) {
|
||||||
err = InitPluginLangs()
|
err = InitPluginLangs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -145,7 +145,7 @@ func initExtend() (err error) {
|
||||||
return Plugins.Load()
|
return Plugins.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadPlugins polls the database to see which plugins have been activated and which have been installed
|
// Load polls the database to see which plugins have been activated and which have been installed
|
||||||
func (plugins PluginList) Load() error {
|
func (plugins PluginList) Load() error {
|
||||||
getPlugins, err := qgen.Builder.SimpleSelect("plugins", "uname, active, installed", "", "", "")
|
getPlugins, err := qgen.Builder.SimpleSelect("plugins", "uname, active, installed", "", "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -206,37 +206,37 @@ func NewPlugin(uname string, name string, author string, url string, settings st
|
||||||
func (plugin *Plugin) AddHook(name string, handler interface{}) {
|
func (plugin *Plugin) AddHook(name string, handler interface{}) {
|
||||||
switch h := handler.(type) {
|
switch h := handler.(type) {
|
||||||
case func(interface{}) interface{}:
|
case func(interface{}) interface{}:
|
||||||
if len(hooks[name]) == 0 {
|
if len(Hooks[name]) == 0 {
|
||||||
var hookSlice []func(interface{}) interface{}
|
var hookSlice []func(interface{}) interface{}
|
||||||
hookSlice = append(hookSlice, h)
|
hookSlice = append(hookSlice, h)
|
||||||
hooks[name] = hookSlice
|
Hooks[name] = hookSlice
|
||||||
} else {
|
} else {
|
||||||
hooks[name] = append(hooks[name], h)
|
Hooks[name] = append(Hooks[name], h)
|
||||||
}
|
}
|
||||||
plugin.Hooks[name] = len(hooks[name])
|
plugin.Hooks[name] = len(Hooks[name])
|
||||||
case func(string) string:
|
case func(string) string:
|
||||||
if len(sshooks[name]) == 0 {
|
if len(Sshooks[name]) == 0 {
|
||||||
var hookSlice []func(string) string
|
var hookSlice []func(string) string
|
||||||
hookSlice = append(hookSlice, h)
|
hookSlice = append(hookSlice, h)
|
||||||
sshooks[name] = hookSlice
|
Sshooks[name] = hookSlice
|
||||||
} else {
|
} else {
|
||||||
sshooks[name] = append(sshooks[name], h)
|
Sshooks[name] = append(Sshooks[name], h)
|
||||||
}
|
}
|
||||||
plugin.Hooks[name] = len(sshooks[name])
|
plugin.Hooks[name] = len(Sshooks[name])
|
||||||
case func(http.ResponseWriter, *http.Request, *User, interface{}) bool:
|
case func(http.ResponseWriter, *http.Request, *User, interface{}) bool:
|
||||||
if len(preRenderHooks[name]) == 0 {
|
if len(PreRenderHooks[name]) == 0 {
|
||||||
var hookSlice []func(http.ResponseWriter, *http.Request, *User, interface{}) bool
|
var hookSlice []func(http.ResponseWriter, *http.Request, *User, interface{}) bool
|
||||||
hookSlice = append(hookSlice, h)
|
hookSlice = append(hookSlice, h)
|
||||||
preRenderHooks[name] = hookSlice
|
PreRenderHooks[name] = hookSlice
|
||||||
} else {
|
} else {
|
||||||
preRenderHooks[name] = append(preRenderHooks[name], h)
|
PreRenderHooks[name] = append(PreRenderHooks[name], h)
|
||||||
}
|
}
|
||||||
plugin.Hooks[name] = len(preRenderHooks[name])
|
plugin.Hooks[name] = len(PreRenderHooks[name])
|
||||||
case func(...interface{}) interface{}:
|
case func(...interface{}) interface{}:
|
||||||
vhooks[name] = h
|
Vhooks[name] = h
|
||||||
plugin.Hooks[name] = 0
|
plugin.Hooks[name] = 0
|
||||||
case func(...interface{}) (bool, RouteError):
|
case func(...interface{}) (bool, RouteError):
|
||||||
vhookSkippable[name] = h
|
VhookSkippable[name] = h
|
||||||
plugin.Hooks[name] = 0
|
plugin.Hooks[name] = 0
|
||||||
default:
|
default:
|
||||||
panic("I don't recognise this kind of handler!") // Should this be an error for the plugin instead of a panic()?
|
panic("I don't recognise this kind of handler!") // Should this be an error for the plugin instead of a panic()?
|
||||||
|
@ -248,35 +248,35 @@ func (plugin *Plugin) RemoveHook(name string, handler interface{}) {
|
||||||
switch handler.(type) {
|
switch handler.(type) {
|
||||||
case func(interface{}) interface{}:
|
case func(interface{}) interface{}:
|
||||||
key := plugin.Hooks[name]
|
key := plugin.Hooks[name]
|
||||||
hook := hooks[name]
|
hook := Hooks[name]
|
||||||
if len(hook) == 1 {
|
if len(hook) == 1 {
|
||||||
hook = []func(interface{}) interface{}{}
|
hook = []func(interface{}) interface{}{}
|
||||||
} else {
|
} else {
|
||||||
hook = append(hook[:key], hook[key+1:]...)
|
hook = append(hook[:key], hook[key+1:]...)
|
||||||
}
|
}
|
||||||
hooks[name] = hook
|
Hooks[name] = hook
|
||||||
case func(string) string:
|
case func(string) string:
|
||||||
key := plugin.Hooks[name]
|
key := plugin.Hooks[name]
|
||||||
hook := sshooks[name]
|
hook := Sshooks[name]
|
||||||
if len(hook) == 1 {
|
if len(hook) == 1 {
|
||||||
hook = []func(string) string{}
|
hook = []func(string) string{}
|
||||||
} else {
|
} else {
|
||||||
hook = append(hook[:key], hook[key+1:]...)
|
hook = append(hook[:key], hook[key+1:]...)
|
||||||
}
|
}
|
||||||
sshooks[name] = hook
|
Sshooks[name] = hook
|
||||||
case func(http.ResponseWriter, *http.Request, *User, interface{}) bool:
|
case func(http.ResponseWriter, *http.Request, *User, interface{}) bool:
|
||||||
key := plugin.Hooks[name]
|
key := plugin.Hooks[name]
|
||||||
hook := preRenderHooks[name]
|
hook := PreRenderHooks[name]
|
||||||
if len(hook) == 1 {
|
if len(hook) == 1 {
|
||||||
hook = []func(http.ResponseWriter, *http.Request, *User, interface{}) bool{}
|
hook = []func(http.ResponseWriter, *http.Request, *User, interface{}) bool{}
|
||||||
} else {
|
} else {
|
||||||
hook = append(hook[:key], hook[key+1:]...)
|
hook = append(hook[:key], hook[key+1:]...)
|
||||||
}
|
}
|
||||||
preRenderHooks[name] = hook
|
PreRenderHooks[name] = hook
|
||||||
case func(...interface{}) interface{}:
|
case func(...interface{}) interface{}:
|
||||||
delete(vhooks, name)
|
delete(Vhooks, name)
|
||||||
case func(...interface{}) (bool, RouteError):
|
case func(...interface{}) (bool, RouteError):
|
||||||
delete(vhookSkippable, name)
|
delete(VhookSkippable, name)
|
||||||
default:
|
default:
|
||||||
panic("I don't recognise this kind of handler!") // Should this be an error for the plugin instead of a panic()?
|
panic("I don't recognise this kind of handler!") // Should this be an error for the plugin instead of a panic()?
|
||||||
}
|
}
|
||||||
|
@ -285,18 +285,18 @@ func (plugin *Plugin) RemoveHook(name string, handler interface{}) {
|
||||||
|
|
||||||
var pluginsInited = false
|
var pluginsInited = false
|
||||||
|
|
||||||
func initPlugins() {
|
func InitPlugins() {
|
||||||
for name, body := range Plugins {
|
for name, body := range Plugins {
|
||||||
log.Print("Added plugin " + name)
|
log.Printf("Added plugin %s", name)
|
||||||
if body.Active {
|
if body.Active {
|
||||||
log.Print("Initialised plugin " + name)
|
log.Printf("Initialised plugin %s", name)
|
||||||
if Plugins[name].Init != nil {
|
if Plugins[name].Init != nil {
|
||||||
err := Plugins[name].Init()
|
err := Plugins[name].Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Print("Plugin " + name + " doesn't have an initialiser.")
|
log.Printf("Plugin %s doesn't have an initialiser.", name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,49 +304,49 @@ func initPlugins() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? - Are the following functions racey?
|
// ? - Are the following functions racey?
|
||||||
func runHook(name string, data interface{}) interface{} {
|
func RunHook(name string, data interface{}) interface{} {
|
||||||
for _, hook := range hooks[name] {
|
for _, hook := range Hooks[name] {
|
||||||
data = hook(data)
|
data = hook(data)
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHookNoreturn(name string, data interface{}) {
|
func RunHookNoreturn(name string, data interface{}) {
|
||||||
for _, hook := range hooks[name] {
|
for _, hook := range Hooks[name] {
|
||||||
_ = hook(data)
|
_ = hook(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runVhook(name string, data ...interface{}) interface{} {
|
func RunVhook(name string, data ...interface{}) interface{} {
|
||||||
return vhooks[name](data...)
|
return Vhooks[name](data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runVhookSkippable(name string, data ...interface{}) (bool, RouteError) {
|
func RunVhookSkippable(name string, data ...interface{}) (bool, RouteError) {
|
||||||
return vhookSkippable[name](data...)
|
return VhookSkippable[name](data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runVhookNoreturn(name string, data ...interface{}) {
|
func RunVhookNoreturn(name string, data ...interface{}) {
|
||||||
_ = vhooks[name](data...)
|
_ = Vhooks[name](data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trying to get a teeny bit of type-safety where-ever possible, especially for such a critical set of hooks
|
// Trying to get a teeny bit of type-safety where-ever possible, especially for such a critical set of hooks
|
||||||
func runSshook(name string, data string) string {
|
func RunSshook(name string, data string) string {
|
||||||
for _, hook := range sshooks[name] {
|
for _, hook := range Sshooks[name] {
|
||||||
data = hook(data)
|
data = hook(data)
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPreRenderHook(name string, w http.ResponseWriter, r *http.Request, user *User, data interface{}) (halt bool) {
|
func RunPreRenderHook(name string, w http.ResponseWriter, r *http.Request, user *User, data interface{}) (halt bool) {
|
||||||
// This hook runs on ALL pre_render hooks
|
// This hook runs on ALL pre_render hooks
|
||||||
for _, hook := range preRenderHooks["pre_render"] {
|
for _, hook := range PreRenderHooks["pre_render"] {
|
||||||
if hook(w, r, user, data) {
|
if hook(w, r, user, data) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The actual pre_render hook
|
// The actual pre_render hook
|
||||||
for _, hook := range preRenderHooks[name] {
|
for _, hook := range PreRenderHooks[name] {
|
||||||
if hook(w, r, user, data) {
|
if hook(w, r, user, data) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -13,6 +13,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SFileList map[string]SFile
|
||||||
|
|
||||||
|
var StaticFiles SFileList = make(map[string]SFile)
|
||||||
|
|
||||||
type SFile struct {
|
type SFile struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
GzipData []byte
|
GzipData []byte
|
||||||
|
@ -28,7 +32,7 @@ type CSSData struct {
|
||||||
ComingSoon string
|
ComingSoon string
|
||||||
}
|
}
|
||||||
|
|
||||||
func initStaticFiles() error {
|
func (list SFileList) Init() error {
|
||||||
return filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
return filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
|
@ -44,16 +48,16 @@ func initStaticFiles() error {
|
||||||
var ext = filepath.Ext("/public/" + path)
|
var ext = filepath.Ext("/public/" + path)
|
||||||
gzipData := compressBytesGzip(data)
|
gzipData := compressBytesGzip(data)
|
||||||
|
|
||||||
staticFiles["/static/"+path] = SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}
|
list["/static/"+path] = SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}
|
||||||
|
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Added the '" + path + "' static file.")
|
log.Print("Added the '" + path + "' static file.")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func addStaticFile(path string, prefix string) error {
|
func (list SFileList) Add(path string, prefix string) error {
|
||||||
data, err := ioutil.ReadFile(path)
|
data, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -71,10 +75,10 @@ func addStaticFile(path string, prefix string) error {
|
||||||
path = strings.TrimPrefix(path, prefix)
|
path = strings.TrimPrefix(path, prefix)
|
||||||
gzipData := compressBytesGzip(data)
|
gzipData := compressBytesGzip(data)
|
||||||
|
|
||||||
staticFiles["/static"+path] = SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}
|
list["/static"+path] = SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}
|
||||||
|
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Added the '" + path + "' static file")
|
log.Printf("Added the '%s' static file", path)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
|
@ -2,12 +2,15 @@ package common
|
||||||
|
|
||||||
//import "fmt"
|
//import "fmt"
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: Do we really need this?
|
||||||
type ForumAdmin struct {
|
type ForumAdmin struct {
|
||||||
ID int
|
ID int
|
||||||
Name string
|
Name string
|
||||||
|
@ -44,11 +47,25 @@ type ForumSimple struct {
|
||||||
Preset string
|
Preset string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ForumStmts struct {
|
||||||
|
update *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
var forumStmts ForumStmts
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
DbInits.Add(func() error {
|
||||||
|
acc := qgen.Builder.Accumulator()
|
||||||
|
forumStmts = ForumStmts{
|
||||||
|
update: acc.SimpleUpdate("forums", "name = ?, desc = ?, active = ?, preset = ?", "fid = ?"),
|
||||||
|
}
|
||||||
|
return acc.FirstError()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Copy gives you a non-pointer concurrency safe copy of the forum
|
// Copy gives you a non-pointer concurrency safe copy of the forum
|
||||||
func (forum *Forum) Copy() (fcopy Forum) {
|
func (forum *Forum) Copy() (fcopy Forum) {
|
||||||
//forum.LastLock.RLock()
|
|
||||||
fcopy = *forum
|
fcopy = *forum
|
||||||
//forum.LastLock.RUnlock()
|
|
||||||
return fcopy
|
return fcopy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,17 +75,17 @@ func (forum *Forum) Update(name string, desc string, active bool, preset string)
|
||||||
name = forum.Name
|
name = forum.Name
|
||||||
}
|
}
|
||||||
preset = strings.TrimSpace(preset)
|
preset = strings.TrimSpace(preset)
|
||||||
_, err := stmts.updateForum.Exec(name, desc, active, preset, forum.ID)
|
_, err := forumStmts.update.Exec(name, desc, active, preset, forum.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if forum.Preset != preset || preset == "custom" || preset == "" {
|
if forum.Preset != preset || preset == "custom" || preset == "" {
|
||||||
err = permmapToQuery(presetToPermmap(preset), forum.ID)
|
err = PermmapToQuery(PresetToPermmap(preset), forum.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = fstore.Reload(forum.ID)
|
_ = Fstore.Reload(forum.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,13 +108,13 @@ func makeDummyForum(fid int, link string, name string, desc string, active bool,
|
||||||
return &Forum{ID: fid, Link: link, Name: name, Desc: desc, Active: active, Preset: preset, ParentID: parentID, ParentType: parentType, TopicCount: topicCount}
|
return &Forum{ID: fid, Link: link, Name: name, Desc: desc, Active: active, Preset: preset, ParentID: parentID, ParentType: parentType, TopicCount: topicCount}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildForumURL(slug string, fid int) string {
|
func BuildForumURL(slug string, fid int) string {
|
||||||
if slug == "" {
|
if slug == "" {
|
||||||
return "/forum/" + strconv.Itoa(fid)
|
return "/forum/" + strconv.Itoa(fid)
|
||||||
}
|
}
|
||||||
return "/forum/" + slug + "." + strconv.Itoa(fid)
|
return "/forum/" + slug + "." + strconv.Itoa(fid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getForumURLPrefix() string {
|
func GetForumURLPrefix() string {
|
||||||
return "/forum/"
|
return "/forum/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fpstore ForumPermsStore
|
var Fpstore ForumPermsStore
|
||||||
|
|
||||||
type ForumPermsStore interface {
|
type ForumPermsStore interface {
|
||||||
Init() error
|
Init() error
|
||||||
|
@ -40,11 +40,11 @@ func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) Init() error {
|
func (fps *MemoryForumPermsStore) Init() error {
|
||||||
fids, err := fstore.GetAllIDs()
|
fids, err := Fstore.GetAllIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Print("fids: ", fids)
|
log.Print("fids: ", fids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +54,9 @@ func (fps *MemoryForumPermsStore) Init() error {
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Adding the forum permissions")
|
log.Print("Adding the forum permissions")
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Print("forumPerms[gid][fid]")
|
log.Print("forumPerms[gid][fid]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ func (fps *MemoryForumPermsStore) Init() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Print("perms: ", string(perms))
|
log.Print("perms: ", string(perms))
|
||||||
}
|
}
|
||||||
err = json.Unmarshal(perms, &pperms)
|
err = json.Unmarshal(perms, &pperms)
|
||||||
|
@ -86,7 +86,7 @@ func (fps *MemoryForumPermsStore) Init() error {
|
||||||
forumPerms[gid] = make(map[int]ForumPerms)
|
forumPerms[gid] = make(map[int]ForumPerms)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Print("gid: ", gid)
|
log.Print("gid: ", gid)
|
||||||
log.Print("fid: ", fid)
|
log.Print("fid: ", fid)
|
||||||
log.Printf("perms: %+v\n", pperms)
|
log.Printf("perms: %+v\n", pperms)
|
||||||
|
@ -99,10 +99,10 @@ func (fps *MemoryForumPermsStore) Init() error {
|
||||||
|
|
||||||
// TODO: Need a more thread-safe way of doing this. Possibly with sync.Map?
|
// TODO: Need a more thread-safe way of doing this. Possibly with sync.Map?
|
||||||
func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Printf("Reloading the forum permissions for forum #%d", fid)
|
log.Printf("Reloading the forum permissions for forum #%d", fid)
|
||||||
}
|
}
|
||||||
fids, err := fstore.GetAllIDs()
|
fids, err := Fstore.GetAllIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -138,20 +138,20 @@ func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[int]ForumPerms, fids []int) error {
|
func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[int]ForumPerms, fids []int) error {
|
||||||
groups, err := gstore.GetAll()
|
groups, err := Gstore.GetAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Printf("Updating the forum permissions for Group #%d", group.ID)
|
log.Printf("Updating the forum permissions for Group #%d", group.ID)
|
||||||
}
|
}
|
||||||
group.Forums = []ForumPerms{BlankForumPerms}
|
group.Forums = []ForumPerms{BlankForumPerms}
|
||||||
group.CanSee = []int{}
|
group.CanSee = []int{}
|
||||||
fps.cascadePermSetToGroup(forumPerms, group, fids)
|
fps.cascadePermSetToGroup(forumPerms, group, fids)
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Printf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
|
log.Printf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
|
||||||
log.Printf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums)
|
log.Printf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums)
|
||||||
}
|
}
|
||||||
|
@ -161,12 +161,12 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]ForumPerms, group *Group, fids []int) {
|
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]ForumPerms, group *Group, fids []int) {
|
||||||
for _, fid := range fids {
|
for _, fid := range fids {
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Printf("Forum #%+v\n", fid)
|
log.Printf("Forum #%+v\n", fid)
|
||||||
}
|
}
|
||||||
forumPerm, ok := forumPerms[group.ID][fid]
|
forumPerm, ok := forumPerms[group.ID][fid]
|
||||||
if ok {
|
if ok {
|
||||||
//log.Print("Overriding permissions for forum #%d",fid)
|
//log.Printf("Overriding permissions for forum #%d",fid)
|
||||||
group.Forums = append(group.Forums, forumPerm)
|
group.Forums = append(group.Forums, forumPerm)
|
||||||
} else {
|
} else {
|
||||||
//log.Printf("Inheriting from group defaults for forum #%d",fid)
|
//log.Printf("Inheriting from group defaults for forum #%d",fid)
|
||||||
|
@ -181,7 +181,7 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[i
|
||||||
group.CanSee = append(group.CanSee, fid)
|
group.CanSee = append(group.CanSee, fid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Print("group.ID: ", group.ID)
|
log.Print("group.ID: ", group.ID)
|
||||||
log.Printf("forumPerm: %+v\n", forumPerm)
|
log.Printf("forumPerm: %+v\n", forumPerm)
|
||||||
log.Print("group.CanSee: ", group.CanSee)
|
log.Print("group.CanSee: ", group.CanSee)
|
||||||
|
@ -191,7 +191,7 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[i
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms ForumPerms, err error) {
|
func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms ForumPerms, err error) {
|
||||||
// TODO: Add a hook here and have plugin_guilds use it
|
// TODO: Add a hook here and have plugin_guilds use it
|
||||||
group, err := gstore.Get(gid)
|
group, err := Gstore.Get(gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fperms, ErrNoRows
|
return fperms, ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,10 @@ import (
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var forumUpdateMutex sync.Mutex
|
var ForumUpdateMutex sync.Mutex
|
||||||
var forumCreateMutex sync.Mutex
|
var forumCreateMutex sync.Mutex
|
||||||
var forumPerms map[int]map[int]ForumPerms // [gid][fid]Perms // TODO: Add an abstraction around this and make it more thread-safe
|
var forumPerms map[int]map[int]ForumPerms // [gid][fid]Perms // TODO: Add an abstraction around this and make it more thread-safe
|
||||||
var fstore ForumStore
|
var Fstore ForumStore
|
||||||
|
|
||||||
// ForumStore is an interface for accessing the forums and the metadata stored on them
|
// ForumStore is an interface for accessing the forums and the metadata stored on them
|
||||||
type ForumStore interface {
|
type ForumStore interface {
|
||||||
|
@ -110,26 +110,16 @@ func (mfs *MemoryForumStore) LoadForums() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if forum.Name == "" {
|
if forum.Name == "" {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Adding a placeholder forum")
|
log.Print("Adding a placeholder forum")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Adding the %s forum", forum.Name)
|
log.Printf("Adding the '%s' forum", forum.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
forum.Link = buildForumURL(nameToSlug(forum.Name), forum.ID)
|
forum.Link = BuildForumURL(NameToSlug(forum.Name), forum.ID)
|
||||||
|
forum.LastTopic = Topics.DirtyGet(forum.LastTopicID)
|
||||||
topic, err := topics.Get(forum.LastTopicID)
|
forum.LastReplyer = Users.DirtyGet(forum.LastReplyerID)
|
||||||
if err != nil {
|
|
||||||
topic = getDummyTopic()
|
|
||||||
}
|
|
||||||
user, err := users.Get(forum.LastReplyerID)
|
|
||||||
if err != nil {
|
|
||||||
user = getDummyUser()
|
|
||||||
}
|
|
||||||
forum.LastTopic = topic
|
|
||||||
forum.LastReplyer = user
|
|
||||||
//forum.SetLast(topic, user)
|
|
||||||
|
|
||||||
addForum(forum)
|
addForum(forum)
|
||||||
}
|
}
|
||||||
|
@ -178,19 +168,9 @@ func (mfs *MemoryForumStore) Get(id int) (*Forum, error) {
|
||||||
return forum, err
|
return forum, err
|
||||||
}
|
}
|
||||||
|
|
||||||
forum.Link = buildForumURL(nameToSlug(forum.Name), forum.ID)
|
forum.Link = BuildForumURL(NameToSlug(forum.Name), forum.ID)
|
||||||
|
forum.LastTopic = Topics.DirtyGet(forum.LastTopicID)
|
||||||
topic, err := topics.Get(forum.LastTopicID)
|
forum.LastReplyer = Users.DirtyGet(forum.LastReplyerID)
|
||||||
if err != nil {
|
|
||||||
topic = getDummyTopic()
|
|
||||||
}
|
|
||||||
user, err := users.Get(forum.LastReplyerID)
|
|
||||||
if err != nil {
|
|
||||||
user = getDummyUser()
|
|
||||||
}
|
|
||||||
forum.LastTopic = topic
|
|
||||||
forum.LastReplyer = user
|
|
||||||
//forum.SetLast(topic, user)
|
|
||||||
|
|
||||||
mfs.CacheSet(forum)
|
mfs.CacheSet(forum)
|
||||||
return forum, err
|
return forum, err
|
||||||
|
@ -205,19 +185,9 @@ func (mfs *MemoryForumStore) BypassGet(id int) (*Forum, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
forum.Link = buildForumURL(nameToSlug(forum.Name), forum.ID)
|
forum.Link = BuildForumURL(NameToSlug(forum.Name), forum.ID)
|
||||||
|
forum.LastTopic = Topics.DirtyGet(forum.LastTopicID)
|
||||||
topic, err := topics.Get(forum.LastTopicID)
|
forum.LastReplyer = Users.DirtyGet(forum.LastReplyerID)
|
||||||
if err != nil {
|
|
||||||
topic = getDummyTopic()
|
|
||||||
}
|
|
||||||
user, err := users.Get(forum.LastReplyerID)
|
|
||||||
if err != nil {
|
|
||||||
user = getDummyUser()
|
|
||||||
}
|
|
||||||
forum.LastTopic = topic
|
|
||||||
forum.LastReplyer = user
|
|
||||||
//forum.SetLast(topic, user)
|
|
||||||
|
|
||||||
return forum, err
|
return forum, err
|
||||||
}
|
}
|
||||||
|
@ -228,19 +198,9 @@ func (mfs *MemoryForumStore) Reload(id int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
forum.Link = buildForumURL(nameToSlug(forum.Name), forum.ID)
|
forum.Link = BuildForumURL(NameToSlug(forum.Name), forum.ID)
|
||||||
|
forum.LastTopic = Topics.DirtyGet(forum.LastTopicID)
|
||||||
topic, err := topics.Get(forum.LastTopicID)
|
forum.LastReplyer = Users.DirtyGet(forum.LastReplyerID)
|
||||||
if err != nil {
|
|
||||||
topic = getDummyTopic()
|
|
||||||
}
|
|
||||||
user, err := users.Get(forum.LastReplyerID)
|
|
||||||
if err != nil {
|
|
||||||
user = getDummyUser()
|
|
||||||
}
|
|
||||||
forum.LastTopic = topic
|
|
||||||
forum.LastReplyer = user
|
|
||||||
//forum.SetLast(topic, user)
|
|
||||||
|
|
||||||
mfs.CacheSet(forum)
|
mfs.CacheSet(forum)
|
||||||
return nil
|
return nil
|
||||||
|
@ -372,7 +332,7 @@ func (mfs *MemoryForumStore) Create(forumName string, forumDesc string, active b
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
permmapToQuery(presetToPermmap(preset), fid)
|
PermmapToQuery(PresetToPermmap(preset), fid)
|
||||||
forumCreateMutex.Unlock()
|
forumCreateMutex.Unlock()
|
||||||
return fid, nil
|
return fid, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
|
import "database/sql"
|
||||||
|
import "../query_gen/lib"
|
||||||
|
|
||||||
var blankGroup = Group{ID: 0, Name: ""}
|
var blankGroup = Group{ID: 0, Name: ""}
|
||||||
|
|
||||||
type GroupAdmin struct {
|
type GroupAdmin struct {
|
||||||
|
@ -27,13 +30,29 @@ type Group struct {
|
||||||
CanSee []int // The IDs of the forums this group can see
|
CanSee []int // The IDs of the forums this group can see
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GroupStmts struct {
|
||||||
|
updateGroupRank *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupStmts GroupStmts
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
DbInits.Add(func() error {
|
||||||
|
acc := qgen.Builder.Accumulator()
|
||||||
|
groupStmts = GroupStmts{
|
||||||
|
updateGroupRank: acc.SimpleUpdate("users_groups", "is_admin = ?, is_mod = ?, is_banned = ?", "gid = ?"),
|
||||||
|
}
|
||||||
|
return acc.FirstError()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (group *Group) ChangeRank(isAdmin bool, isMod bool, isBanned bool) (err error) {
|
func (group *Group) ChangeRank(isAdmin bool, isMod bool, isBanned bool) (err error) {
|
||||||
_, err = stmts.updateGroupRank.Exec(isAdmin, isMod, isBanned, group.ID)
|
_, err = groupStmts.updateGroupRank.Exec(isAdmin, isMod, isBanned, group.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gstore.Reload(group.ID)
|
Gstore.Reload(group.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var gstore GroupStore
|
var Gstore GroupStore
|
||||||
|
|
||||||
// ? - We could fallback onto the database when an item can't be found in the cache?
|
// ? - We could fallback onto the database when an item can't be found in the cache?
|
||||||
type GroupStore interface {
|
type GroupStore interface {
|
||||||
|
@ -38,6 +38,7 @@ type MemoryGroupStore struct {
|
||||||
groupCount int
|
groupCount int
|
||||||
getAll *sql.Stmt
|
getAll *sql.Stmt
|
||||||
get *sql.Stmt
|
get *sql.Stmt
|
||||||
|
count *sql.Stmt
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
@ -49,6 +50,7 @@ func NewMemoryGroupStore() (*MemoryGroupStore, error) {
|
||||||
groupCount: 0,
|
groupCount: 0,
|
||||||
getAll: acc.SimpleSelect("users_groups", "gid, name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag", "", "", ""),
|
getAll: acc.SimpleSelect("users_groups", "gid, name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag", "", "", ""),
|
||||||
get: acc.SimpleSelect("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag", "gid = ?", "", ""),
|
get: acc.SimpleSelect("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag", "gid = ?", "", ""),
|
||||||
|
count: acc.SimpleCount("users_groups", "", ""),
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +86,7 @@ func (mgs *MemoryGroupStore) LoadGroups() error {
|
||||||
}
|
}
|
||||||
mgs.groupCount = i
|
mgs.groupCount = i
|
||||||
|
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Binding the Not Loggedin Group")
|
log.Print("Binding the Not Loggedin Group")
|
||||||
}
|
}
|
||||||
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
|
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
|
||||||
|
@ -146,7 +148,7 @@ func (mgs *MemoryGroupStore) Reload(id int) error {
|
||||||
}
|
}
|
||||||
mgs.CacheSet(group)
|
mgs.CacheSet(group)
|
||||||
|
|
||||||
err = rebuildGroupPermissions(id)
|
err = RebuildGroupPermissions(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +162,7 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
|
||||||
log.Print("bad group perms: ", group.PermissionsText)
|
log.Print("bad group perms: ", group.PermissionsText)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Printf(group.Name+": %+v\n", group.Perms)
|
log.Printf(group.Name+": %+v\n", group.Perms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +172,7 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
|
||||||
log.Print("bad group plugin perms: ", group.PluginPermsText)
|
log.Print("bad group plugin perms: ", group.PluginPermsText)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Printf(group.Name+": %+v\n", group.PluginPerms)
|
log.Printf(group.Name+": %+v\n", group.PluginPerms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +202,7 @@ func (mgs *MemoryGroupStore) Exists(gid int) bool {
|
||||||
// ? Allow two groups with the same name?
|
// ? Allow two groups with the same name?
|
||||||
func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod bool, isBanned bool) (gid int, err error) {
|
func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod bool, isBanned bool) (gid int, err error) {
|
||||||
var permstr = "{}"
|
var permstr = "{}"
|
||||||
tx, err := db.Begin()
|
tx, err := qgen.Builder.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -226,20 +228,20 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
|
||||||
var blankIntList []int
|
var blankIntList []int
|
||||||
var pluginPerms = make(map[string]bool)
|
var pluginPerms = make(map[string]bool)
|
||||||
var pluginPermsBytes = []byte("{}")
|
var pluginPermsBytes = []byte("{}")
|
||||||
if vhooks["create_group_preappend"] != nil {
|
if Vhooks["create_group_preappend"] != nil {
|
||||||
runVhook("create_group_preappend", &pluginPerms, &pluginPermsBytes)
|
RunVhook("create_group_preappend", &pluginPerms, &pluginPermsBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the forum permissions based on the presets...
|
// Generate the forum permissions based on the presets...
|
||||||
fdata, err := fstore.GetAll()
|
fdata, err := Fstore.GetAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var presetSet = make(map[int]string)
|
var presetSet = make(map[int]string)
|
||||||
var permSet = make(map[int]ForumPerms)
|
var permSet = make(map[int]ForumPerms)
|
||||||
permUpdateMutex.Lock()
|
PermUpdateMutex.Lock()
|
||||||
defer permUpdateMutex.Unlock()
|
defer PermUpdateMutex.Unlock()
|
||||||
for _, forum := range fdata {
|
for _, forum := range fdata {
|
||||||
var thePreset string
|
var thePreset string
|
||||||
if isAdmin {
|
if isAdmin {
|
||||||
|
@ -252,7 +254,7 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
|
||||||
thePreset = "members"
|
thePreset = "members"
|
||||||
}
|
}
|
||||||
|
|
||||||
permmap := presetToPermmap(forum.Preset)
|
permmap := PresetToPermmap(forum.Preset)
|
||||||
permItem := permmap[thePreset]
|
permItem := permmap[thePreset]
|
||||||
permItem.Overrides = true
|
permItem.Overrides = true
|
||||||
|
|
||||||
|
@ -260,7 +262,7 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
|
||||||
presetSet[forum.ID] = forum.Preset
|
presetSet[forum.ID] = forum.Preset
|
||||||
}
|
}
|
||||||
|
|
||||||
err = replaceForumPermsForGroupTx(tx, gid, presetSet, permSet)
|
err = ReplaceForumPermsForGroupTx(tx, gid, presetSet, permSet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -281,7 +283,7 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
|
||||||
mgs.Unlock()
|
mgs.Unlock()
|
||||||
|
|
||||||
for _, forum := range fdata {
|
for _, forum := range fdata {
|
||||||
err = fpstore.Reload(forum.ID)
|
err = Fpstore.Reload(forum.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gid, err
|
return gid, err
|
||||||
}
|
}
|
||||||
|
@ -344,8 +346,10 @@ func (mgs *MemoryGroupStore) Length() int {
|
||||||
return mgs.groupCount
|
return mgs.groupCount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mgs *MemoryGroupStore) GlobalCount() int {
|
func (mgs *MemoryGroupStore) GlobalCount() (count int) {
|
||||||
mgs.RLock()
|
err := mgs.count.QueryRow().Scan(&count)
|
||||||
defer mgs.RUnlock()
|
if err != nil {
|
||||||
return mgs.groupCount
|
LogError(err)
|
||||||
|
}
|
||||||
|
return count
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Copyright Azareal 2016 - 2018
|
* Copyright Azareal 2016 - 2018
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
|
@ -11,7 +11,7 @@ type HeaderVars struct {
|
||||||
Scripts []string
|
Scripts []string
|
||||||
Stylesheets []string
|
Stylesheets []string
|
||||||
Widgets PageWidgets
|
Widgets PageWidgets
|
||||||
Site *Site
|
Site *site
|
||||||
Settings map[string]interface{}
|
Settings map[string]interface{}
|
||||||
Themes map[string]Theme // TODO: Use a slice containing every theme instead of the main map for speed
|
Themes map[string]Theme // TODO: Use a slice containing every theme instead of the main map for speed
|
||||||
ThemeName string
|
ThemeName string
|
||||||
|
@ -21,7 +21,7 @@ type HeaderVars struct {
|
||||||
|
|
||||||
// TODO: Add this to routes which don't use templates. E.g. Json APIs.
|
// TODO: Add this to routes which don't use templates. E.g. Json APIs.
|
||||||
type HeaderLite struct {
|
type HeaderLite struct {
|
||||||
Site *Site
|
Site *site
|
||||||
Settings SettingMap
|
Settings SettingMap
|
||||||
ExtData ExtData
|
ExtData ExtData
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ type PageWidgets struct {
|
||||||
// TODO: Add a ExtDataHolder interface with methods for manipulating the contents?
|
// TODO: Add a ExtDataHolder interface with methods for manipulating the contents?
|
||||||
// ? - Could we use a sync.Map instead?
|
// ? - Could we use a sync.Map instead?
|
||||||
type ExtData struct {
|
type ExtData struct {
|
||||||
items map[string]interface{} // Key: pluginname
|
Items map[string]interface{} // Key: pluginname
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ type PanelEditGroupPermsPage struct {
|
||||||
GlobalPerms []NameLangToggle
|
GlobalPerms []NameLangToggle
|
||||||
}
|
}
|
||||||
|
|
||||||
type backupItem struct {
|
type BackupItem struct {
|
||||||
SQLURL string
|
SQLURL string
|
||||||
|
|
||||||
// TODO: Add an easier to parse format here for Gosora to be able to more easily reimport portions of the dump and to strip unnecessary data (e.g. table defs and parsed post data)
|
// TODO: Add an easier to parse format here for Gosora to be able to more easily reimport portions of the dump and to strip unnecessary data (e.g. table defs and parsed post data)
|
||||||
|
@ -239,10 +239,10 @@ type PanelBackupPage struct {
|
||||||
CurrentUser User
|
CurrentUser User
|
||||||
Header *HeaderVars
|
Header *HeaderVars
|
||||||
Stats PanelStats
|
Stats PanelStats
|
||||||
Backups []backupItem
|
Backups []BackupItem
|
||||||
}
|
}
|
||||||
|
|
||||||
type logItem struct {
|
type LogItem struct {
|
||||||
Action template.HTML
|
Action template.HTML
|
||||||
IPAddress string
|
IPAddress string
|
||||||
DoneAt string
|
DoneAt string
|
||||||
|
@ -253,7 +253,7 @@ type PanelLogsPage struct {
|
||||||
CurrentUser User
|
CurrentUser User
|
||||||
Header *HeaderVars
|
Header *HeaderVars
|
||||||
Stats PanelStats
|
Stats PanelStats
|
||||||
Logs []logItem
|
Logs []LogItem
|
||||||
PageList []int
|
PageList []int
|
||||||
Page int
|
Page int
|
||||||
LastPage int
|
LastPage int
|
||||||
|
@ -282,5 +282,5 @@ type AreYouSure struct {
|
||||||
// This is mostly for errors.go, please create *HeaderVars on the spot instead of relying on this or the atomic store underlying it, if possible
|
// This is mostly for errors.go, please create *HeaderVars on the spot instead of relying on this or the atomic store underlying it, if possible
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func DefaultHeaderVar() *HeaderVars {
|
func DefaultHeaderVar() *HeaderVars {
|
||||||
return &HeaderVars{Site: site, ThemeName: fallbackTheme}
|
return &HeaderVars{Site: Site, ThemeName: fallbackTheme}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
//"fmt"
|
//"fmt"
|
||||||
|
@ -9,19 +9,19 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var spaceGap = []byte(" ")
|
var SpaceGap = []byte(" ")
|
||||||
var httpProtBytes = []byte("http://")
|
var httpProtBytes = []byte("http://")
|
||||||
var invalidURL = []byte("<span style='color: red;'>[Invalid URL]</span>")
|
var InvalidURL = []byte("<span style='color: red;'>[Invalid URL]</span>")
|
||||||
var invalidTopic = []byte("<span style='color: red;'>[Invalid Topic]</span>")
|
var InvalidTopic = []byte("<span style='color: red;'>[Invalid Topic]</span>")
|
||||||
var invalidProfile = []byte("<span style='color: red;'>[Invalid Profile]</span>")
|
var InvalidProfile = []byte("<span style='color: red;'>[Invalid Profile]</span>")
|
||||||
var invalidForum = []byte("<span style='color: red;'>[Invalid Forum]</span>")
|
var InvalidForum = []byte("<span style='color: red;'>[Invalid Forum]</span>")
|
||||||
var unknownMedia = []byte("<span style='color: red;'>[Unknown Media]</span>")
|
var unknownMedia = []byte("<span style='color: red;'>[Unknown Media]</span>")
|
||||||
var urlOpen = []byte("<a href='")
|
var UrlOpen = []byte("<a href='")
|
||||||
var urlOpen2 = []byte("'>")
|
var UrlOpen2 = []byte("'>")
|
||||||
var bytesSinglequote = []byte("'")
|
var bytesSinglequote = []byte("'")
|
||||||
var bytesGreaterthan = []byte(">")
|
var bytesGreaterthan = []byte(">")
|
||||||
var urlMention = []byte(" class='mention'")
|
var urlMention = []byte(" class='mention'")
|
||||||
var urlClose = []byte("</a>")
|
var UrlClose = []byte("</a>")
|
||||||
var imageOpen = []byte("<a href=\"")
|
var imageOpen = []byte("<a href=\"")
|
||||||
var imageOpen2 = []byte("\"><img src='")
|
var imageOpen2 = []byte("\"><img src='")
|
||||||
var imageClose = []byte("' class='postImage' /></a>")
|
var imageClose = []byte("' class='postImage' /></a>")
|
||||||
|
@ -164,16 +164,16 @@ func shortcodeToUnicode(msg string) string {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func preparseMessage(msg string) string {
|
func PreparseMessage(msg string) string {
|
||||||
if sshooks["preparse_preassign"] != nil {
|
if Sshooks["preparse_preassign"] != nil {
|
||||||
msg = runSshook("preparse_preassign", msg)
|
msg = RunSshook("preparse_preassign", msg)
|
||||||
}
|
}
|
||||||
return shortcodeToUnicode(msg)
|
return shortcodeToUnicode(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
// TODO: We need a lot more hooks here. E.g. To add custom media types and handlers.
|
// TODO: We need a lot more hooks here. E.g. To add custom media types and handlers.
|
||||||
func parseMessage(msg string, sectionID int, sectionType string /*, user User*/) string {
|
func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/) string {
|
||||||
msg = strings.Replace(msg, ":)", "😀", -1)
|
msg = strings.Replace(msg, ":)", "😀", -1)
|
||||||
msg = strings.Replace(msg, ":(", "😞", -1)
|
msg = strings.Replace(msg, ":(", "😞", -1)
|
||||||
msg = strings.Replace(msg, ":D", "😃", -1)
|
msg = strings.Replace(msg, ":D", "😃", -1)
|
||||||
|
@ -185,7 +185,7 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
//msg = url_reg.ReplaceAllString(msg,"<a href=\"$2$3//$4\" rel=\"nofollow\">$2$3//$4</a>")
|
//msg = url_reg.ReplaceAllString(msg,"<a href=\"$2$3//$4\" rel=\"nofollow\">$2$3//$4</a>")
|
||||||
|
|
||||||
// Word filter list. E.g. Swear words and other things the admins don't like
|
// Word filter list. E.g. Swear words and other things the admins don't like
|
||||||
wordFilters := wordFilterBox.Load().(WordFilterBox)
|
wordFilters := WordFilterBox.Load().(WordFilterMap)
|
||||||
for _, filter := range wordFilters {
|
for _, filter := range wordFilters {
|
||||||
msg = strings.Replace(msg, filter.Find, filter.Replacement, -1)
|
msg = strings.Replace(msg, filter.Find, filter.Replacement, -1)
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
//log.Print("Parser Loop!")
|
//log.Print("Parser Loop!")
|
||||||
var msgbytes = []byte(msg)
|
var msgbytes = []byte(msg)
|
||||||
var outbytes []byte
|
var outbytes []byte
|
||||||
msgbytes = append(msgbytes, spaceGap...)
|
msgbytes = append(msgbytes, SpaceGap...)
|
||||||
//log.Printf("string(msgbytes) %+v\n", `"`+string(msgbytes)+`"`)
|
//log.Printf("string(msgbytes) %+v\n", `"`+string(msgbytes)+`"`)
|
||||||
var lastItem = 0
|
var lastItem = 0
|
||||||
var i = 0
|
var i = 0
|
||||||
|
@ -215,23 +215,23 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||||
i += 5
|
i += 5
|
||||||
start := i
|
start := i
|
||||||
tid, intLen := coerceIntBytes(msgbytes[start:])
|
tid, intLen := CoerceIntBytes(msgbytes[start:])
|
||||||
i += intLen
|
i += intLen
|
||||||
|
|
||||||
topic, err := topics.Get(tid)
|
topic, err := Topics.Get(tid)
|
||||||
if err != nil || !fstore.Exists(topic.ParentID) {
|
if err != nil || !Fstore.Exists(topic.ParentID) {
|
||||||
outbytes = append(outbytes, invalidTopic...)
|
outbytes = append(outbytes, InvalidTopic...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, urlOpen...)
|
outbytes = append(outbytes, UrlOpen...)
|
||||||
var urlBit = []byte(buildTopicURL("", tid))
|
var urlBit = []byte(BuildTopicURL("", tid))
|
||||||
outbytes = append(outbytes, urlBit...)
|
outbytes = append(outbytes, urlBit...)
|
||||||
outbytes = append(outbytes, urlOpen2...)
|
outbytes = append(outbytes, UrlOpen2...)
|
||||||
var tidBit = []byte("#tid-" + strconv.Itoa(tid))
|
var tidBit = []byte("#tid-" + strconv.Itoa(tid))
|
||||||
outbytes = append(outbytes, tidBit...)
|
outbytes = append(outbytes, tidBit...)
|
||||||
outbytes = append(outbytes, urlClose...)
|
outbytes = append(outbytes, UrlClose...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
|
|
||||||
//log.Print("string(msgbytes): ",string(msgbytes))
|
//log.Print("string(msgbytes): ",string(msgbytes))
|
||||||
|
@ -244,44 +244,46 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||||
i += 5
|
i += 5
|
||||||
start := i
|
start := i
|
||||||
rid, intLen := coerceIntBytes(msgbytes[start:])
|
rid, intLen := CoerceIntBytes(msgbytes[start:])
|
||||||
i += intLen
|
i += intLen
|
||||||
|
|
||||||
topic, err := getTopicByReply(rid)
|
reply := BlankReply()
|
||||||
if err != nil || !fstore.Exists(topic.ParentID) {
|
reply.ID = rid
|
||||||
outbytes = append(outbytes, invalidTopic...)
|
topic, err := reply.Topic()
|
||||||
|
if err != nil || !Fstore.Exists(topic.ParentID) {
|
||||||
|
outbytes = append(outbytes, InvalidTopic...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, urlOpen...)
|
outbytes = append(outbytes, UrlOpen...)
|
||||||
var urlBit = []byte(buildTopicURL("", topic.ID))
|
var urlBit = []byte(BuildTopicURL("", topic.ID))
|
||||||
outbytes = append(outbytes, urlBit...)
|
outbytes = append(outbytes, urlBit...)
|
||||||
outbytes = append(outbytes, urlOpen2...)
|
outbytes = append(outbytes, UrlOpen2...)
|
||||||
var ridBit = []byte("#rid-" + strconv.Itoa(rid))
|
var ridBit = []byte("#rid-" + strconv.Itoa(rid))
|
||||||
outbytes = append(outbytes, ridBit...)
|
outbytes = append(outbytes, ridBit...)
|
||||||
outbytes = append(outbytes, urlClose...)
|
outbytes = append(outbytes, UrlClose...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
} else if bytes.Equal(msgbytes[i+1:i+5], []byte("fid-")) {
|
} else if bytes.Equal(msgbytes[i+1:i+5], []byte("fid-")) {
|
||||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||||
i += 5
|
i += 5
|
||||||
start := i
|
start := i
|
||||||
fid, intLen := coerceIntBytes(msgbytes[start:])
|
fid, intLen := CoerceIntBytes(msgbytes[start:])
|
||||||
i += intLen
|
i += intLen
|
||||||
|
|
||||||
if !fstore.Exists(fid) {
|
if !Fstore.Exists(fid) {
|
||||||
outbytes = append(outbytes, invalidForum...)
|
outbytes = append(outbytes, InvalidForum...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, urlOpen...)
|
outbytes = append(outbytes, UrlOpen...)
|
||||||
var urlBit = []byte(buildForumURL("", fid))
|
var urlBit = []byte(BuildForumURL("", fid))
|
||||||
outbytes = append(outbytes, urlBit...)
|
outbytes = append(outbytes, urlBit...)
|
||||||
outbytes = append(outbytes, urlOpen2...)
|
outbytes = append(outbytes, UrlOpen2...)
|
||||||
var fidBit = []byte("#fid-" + strconv.Itoa(fid))
|
var fidBit = []byte("#fid-" + strconv.Itoa(fid))
|
||||||
outbytes = append(outbytes, fidBit...)
|
outbytes = append(outbytes, fidBit...)
|
||||||
outbytes = append(outbytes, urlClose...)
|
outbytes = append(outbytes, UrlClose...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
} else {
|
} else {
|
||||||
// TODO: Forum Shortcode Link
|
// TODO: Forum Shortcode Link
|
||||||
|
@ -291,17 +293,17 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||||
i++
|
i++
|
||||||
start := i
|
start := i
|
||||||
uid, intLen := coerceIntBytes(msgbytes[start:])
|
uid, intLen := CoerceIntBytes(msgbytes[start:])
|
||||||
i += intLen
|
i += intLen
|
||||||
|
|
||||||
menUser, err := users.Get(uid)
|
menUser, err := Users.Get(uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
outbytes = append(outbytes, invalidProfile...)
|
outbytes = append(outbytes, InvalidProfile...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, urlOpen...)
|
outbytes = append(outbytes, UrlOpen...)
|
||||||
var urlBit = []byte(menUser.Link)
|
var urlBit = []byte(menUser.Link)
|
||||||
outbytes = append(outbytes, urlBit...)
|
outbytes = append(outbytes, urlBit...)
|
||||||
outbytes = append(outbytes, bytesSinglequote...)
|
outbytes = append(outbytes, bytesSinglequote...)
|
||||||
|
@ -309,7 +311,7 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
outbytes = append(outbytes, bytesGreaterthan...)
|
outbytes = append(outbytes, bytesGreaterthan...)
|
||||||
var uidBit = []byte("@" + menUser.Name)
|
var uidBit = []byte("@" + menUser.Name)
|
||||||
outbytes = append(outbytes, uidBit...)
|
outbytes = append(outbytes, uidBit...)
|
||||||
outbytes = append(outbytes, urlClose...)
|
outbytes = append(outbytes, UrlClose...)
|
||||||
lastItem = i
|
lastItem = i
|
||||||
|
|
||||||
//log.Print(string(msgbytes))
|
//log.Print(string(msgbytes))
|
||||||
|
@ -338,21 +340,21 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
|
|
||||||
//log.Print("Normal URL")
|
//log.Print("Normal URL")
|
||||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||||
urlLen := partialURLBytesLen(msgbytes[i:])
|
urlLen := PartialURLBytesLen(msgbytes[i:])
|
||||||
if msgbytes[i+urlLen] > 32 { // space and invisibles
|
if msgbytes[i+urlLen] > 32 { // space and invisibles
|
||||||
//log.Print("INVALID URL")
|
//log.Print("INVALID URL")
|
||||||
//log.Print("msgbytes[i+urlLen]: ", msgbytes[i+urlLen])
|
//log.Print("msgbytes[i+urlLen]: ", msgbytes[i+urlLen])
|
||||||
//log.Print("string(msgbytes[i+urlLen]): ", string(msgbytes[i+urlLen]))
|
//log.Print("string(msgbytes[i+urlLen]): ", string(msgbytes[i+urlLen]))
|
||||||
//log.Print("msgbytes[i:i+urlLen]: ", msgbytes[i:i+urlLen])
|
//log.Print("msgbytes[i:i+urlLen]: ", msgbytes[i:i+urlLen])
|
||||||
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
||||||
outbytes = append(outbytes, invalidURL...)
|
outbytes = append(outbytes, InvalidURL...)
|
||||||
i += urlLen
|
i += urlLen
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
media, ok := parseMediaBytes(msgbytes[i : i+urlLen])
|
media, ok := parseMediaBytes(msgbytes[i : i+urlLen])
|
||||||
if !ok {
|
if !ok {
|
||||||
outbytes = append(outbytes, invalidURL...)
|
outbytes = append(outbytes, InvalidURL...)
|
||||||
i += urlLen
|
i += urlLen
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -386,23 +388,23 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, urlOpen...)
|
outbytes = append(outbytes, UrlOpen...)
|
||||||
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
||||||
outbytes = append(outbytes, urlOpen2...)
|
outbytes = append(outbytes, UrlOpen2...)
|
||||||
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
||||||
outbytes = append(outbytes, urlClose...)
|
outbytes = append(outbytes, UrlClose...)
|
||||||
i += urlLen
|
i += urlLen
|
||||||
lastItem = i
|
lastItem = i
|
||||||
} else if msgbytes[i] == '/' && msgbytes[i+1] == '/' {
|
} else if msgbytes[i] == '/' && msgbytes[i+1] == '/' {
|
||||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||||
urlLen := partialURLBytesLen(msgbytes[i:])
|
urlLen := PartialURLBytesLen(msgbytes[i:])
|
||||||
if msgbytes[i+urlLen] > 32 { // space and invisibles
|
if msgbytes[i+urlLen] > 32 { // space and invisibles
|
||||||
//log.Print("INVALID URL")
|
//log.Print("INVALID URL")
|
||||||
//log.Print("msgbytes[i+urlLen]: ", msgbytes[i+urlLen])
|
//log.Print("msgbytes[i+urlLen]: ", msgbytes[i+urlLen])
|
||||||
//log.Print("string(msgbytes[i+urlLen]): ", string(msgbytes[i+urlLen]))
|
//log.Print("string(msgbytes[i+urlLen]): ", string(msgbytes[i+urlLen]))
|
||||||
//log.Print("msgbytes[i:i+urlLen]: ", msgbytes[i:i+urlLen])
|
//log.Print("msgbytes[i:i+urlLen]: ", msgbytes[i:i+urlLen])
|
||||||
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
||||||
outbytes = append(outbytes, invalidURL...)
|
outbytes = append(outbytes, InvalidURL...)
|
||||||
i += urlLen
|
i += urlLen
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -412,7 +414,7 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
||||||
media, ok := parseMediaBytes(msgbytes[i : i+urlLen])
|
media, ok := parseMediaBytes(msgbytes[i : i+urlLen])
|
||||||
if !ok {
|
if !ok {
|
||||||
outbytes = append(outbytes, invalidURL...)
|
outbytes = append(outbytes, InvalidURL...)
|
||||||
i += urlLen
|
i += urlLen
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -446,11 +448,11 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, urlOpen...)
|
outbytes = append(outbytes, UrlOpen...)
|
||||||
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
||||||
outbytes = append(outbytes, urlOpen2...)
|
outbytes = append(outbytes, UrlOpen2...)
|
||||||
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
||||||
outbytes = append(outbytes, urlClose...)
|
outbytes = append(outbytes, UrlClose...)
|
||||||
i += urlLen
|
i += urlLen
|
||||||
lastItem = i
|
lastItem = i
|
||||||
}
|
}
|
||||||
|
@ -474,25 +476,12 @@ func parseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
//log.Print("msg",`"`+msg+`"`)
|
//log.Print("msg",`"`+msg+`"`)
|
||||||
|
|
||||||
msg = strings.Replace(msg, "\n", "<br>", -1)
|
msg = strings.Replace(msg, "\n", "<br>", -1)
|
||||||
if sshooks["parse_assign"] != nil {
|
if Sshooks["parse_assign"] != nil {
|
||||||
msg = runSshook("parse_assign", msg)
|
msg = RunSshook("parse_assign", msg)
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
|
||||||
/*func regexParseMessage(msg string) string {
|
|
||||||
msg = strings.Replace(msg, ":)", "😀", -1)
|
|
||||||
msg = strings.Replace(msg, ":D", "😃", -1)
|
|
||||||
msg = strings.Replace(msg, ":P", "😛", -1)
|
|
||||||
msg = urlReg.ReplaceAllString(msg, "<a href=\"$2$3//$4\" rel=\"nofollow\">$2$3//$4</a>")
|
|
||||||
msg = strings.Replace(msg, "\n", "<br>", -1)
|
|
||||||
if sshooks["parse_assign"] != nil {
|
|
||||||
msg = runSshook("parse_assign", msg)
|
|
||||||
}
|
|
||||||
return msg
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// 6, 7, 8, 6, 2, 7
|
// 6, 7, 8, 6, 2, 7
|
||||||
// ftp://, http://, https:// git://, //, mailto: (not a URL, just here for length comparison purposes)
|
// ftp://, http://, https:// git://, //, mailto: (not a URL, just here for length comparison purposes)
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
|
@ -541,7 +530,7 @@ func validatedURLBytes(data []byte) (url []byte) {
|
||||||
// ? - There should only be one : and that's only if the URL is on a non-standard port. Same for ?s.
|
// ? - There should only be one : and that's only if the URL is on a non-standard port. Same for ?s.
|
||||||
for ; datalen > i; i++ {
|
for ; datalen > i; i++ {
|
||||||
if data[i] != '\\' && data[i] != '_' && data[i] != ':' && data[i] != '?' && data[i] != '&' && data[i] != '=' && data[i] != ';' && data[i] != '@' && !(data[i] > 44 && data[i] < 58) && !(data[i] > 64 && data[i] < 91) && !(data[i] > 96 && data[i] < 123) {
|
if data[i] != '\\' && data[i] != '_' && data[i] != ':' && data[i] != '?' && data[i] != '&' && data[i] != '=' && data[i] != ';' && data[i] != '@' && !(data[i] > 44 && data[i] < 58) && !(data[i] > 64 && data[i] < 91) && !(data[i] > 96 && data[i] < 123) {
|
||||||
return invalidURL
|
return InvalidURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,7 +539,7 @@ func validatedURLBytes(data []byte) (url []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func partialURLBytes(data []byte) (url []byte) {
|
func PartialURLBytes(data []byte) (url []byte) {
|
||||||
datalen := len(data)
|
datalen := len(data)
|
||||||
i := 0
|
i := 0
|
||||||
end := datalen - 1
|
end := datalen - 1
|
||||||
|
@ -579,7 +568,7 @@ func partialURLBytes(data []byte) (url []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func partialURLBytesLen(data []byte) int {
|
func PartialURLBytesLen(data []byte) int {
|
||||||
datalen := len(data)
|
datalen := len(data)
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
|
@ -632,13 +621,12 @@ func parseMediaBytes(data []byte) (media MediaEmbed, ok bool) {
|
||||||
query := url.Query()
|
query := url.Query()
|
||||||
//log.Printf("query %+v\n", query)
|
//log.Printf("query %+v\n", query)
|
||||||
|
|
||||||
var samesite = hostname == "localhost" || hostname == site.URL
|
var samesite = hostname == "localhost" || hostname == Site.URL
|
||||||
if samesite {
|
if samesite {
|
||||||
//log.Print("samesite")
|
hostname = strings.Split(Site.URL, ":")[0]
|
||||||
hostname = strings.Split(site.URL, ":")[0]
|
|
||||||
// ?- Test this as I'm not sure it'll do what it should. If someone's running SSL on port 80 or non-SSL on port 443 then... Well... They're in far worse trouble than this...
|
// ?- Test this as I'm not sure it'll do what it should. If someone's running SSL on port 80 or non-SSL on port 443 then... Well... They're in far worse trouble than this...
|
||||||
port = site.Port
|
port = Site.Port
|
||||||
if scheme == "" && site.EnableSsl {
|
if scheme == "" && Site.EnableSsl {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -684,7 +672,7 @@ func parseMediaBytes(data []byte) (media MediaEmbed, ok bool) {
|
||||||
extarr := strings.Split(lastFrag, ".")
|
extarr := strings.Split(lastFrag, ".")
|
||||||
if len(extarr) >= 2 {
|
if len(extarr) >= 2 {
|
||||||
ext := extarr[len(extarr)-1]
|
ext := extarr[len(extarr)-1]
|
||||||
if imageFileExts.Contains(ext) {
|
if ImageFileExts.Contains(ext) {
|
||||||
media.Type = "image"
|
media.Type = "image"
|
||||||
var sport string
|
var sport string
|
||||||
if port != "443" && port != "80" {
|
if port != "443" && port != "80" {
|
||||||
|
@ -704,7 +692,7 @@ func parseURL(data []byte) (*url.URL, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func coerceIntBytes(data []byte) (res int, length int) {
|
func CoerceIntBytes(data []byte) (res int, length int) {
|
||||||
if !(data[0] > 47 && data[0] < 58) {
|
if !(data[0] > 47 && data[0] < 58) {
|
||||||
return 0, 1
|
return 0, 1
|
||||||
}
|
}
|
||||||
|
@ -728,7 +716,7 @@ func coerceIntBytes(data []byte) (res int, length int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write tests for this
|
// TODO: Write tests for this
|
||||||
func paginate(count int, perPage int, maxPages int) []int {
|
func Paginate(count int, perPage int, maxPages int) []int {
|
||||||
if count < perPage {
|
if count < perPage {
|
||||||
return []int{1}
|
return []int{1}
|
||||||
}
|
}
|
||||||
|
@ -745,7 +733,7 @@ func paginate(count int, perPage int, maxPages int) []int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write tests for this
|
// TODO: Write tests for this
|
||||||
func pageOffset(count int, page int, perPage int) (int, int, int) {
|
func PageOffset(count int, page int, perPage int) (int, int, int) {
|
||||||
var offset int
|
var offset int
|
||||||
lastPage := (count / perPage) + 1
|
lastPage := (count / perPage) + 1
|
||||||
if page > 1 {
|
if page > 1 {
|
|
@ -5,18 +5,24 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Refactor the perms system
|
// TODO: Refactor the perms system
|
||||||
|
|
||||||
var permUpdateMutex sync.Mutex
|
var PermUpdateMutex sync.Mutex
|
||||||
var BlankPerms Perms
|
var BlankPerms Perms
|
||||||
var BlankForumPerms ForumPerms
|
var BlankForumPerms ForumPerms
|
||||||
var GuestPerms Perms
|
var GuestPerms Perms
|
||||||
var ReadForumPerms ForumPerms
|
var ReadForumPerms ForumPerms
|
||||||
var ReadReplyForumPerms ForumPerms
|
var ReadReplyForumPerms ForumPerms
|
||||||
var ReadWriteForumPerms ForumPerms
|
var ReadWriteForumPerms ForumPerms
|
||||||
|
|
||||||
|
// AllPerms is a set of global permissions with everything set to true
|
||||||
var AllPerms Perms
|
var AllPerms Perms
|
||||||
|
|
||||||
|
// AllForumPerms is a set of forum local permissions with everything set to true
|
||||||
var AllForumPerms ForumPerms
|
var AllForumPerms ForumPerms
|
||||||
var AllPluginPerms = make(map[string]bool)
|
var AllPluginPerms = make(map[string]bool)
|
||||||
|
|
||||||
|
@ -216,15 +222,15 @@ func init() {
|
||||||
ExtData: make(map[string]bool),
|
ExtData: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
guestUser.Perms = GuestPerms
|
GuestUser.Perms = GuestPerms
|
||||||
|
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Printf("Guest Perms: %+v\n", GuestPerms)
|
log.Printf("Guest Perms: %+v\n", GuestPerms)
|
||||||
log.Printf("All Perms: %+v\n", AllPerms)
|
log.Printf("All Perms: %+v\n", AllPerms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func presetToPermmap(preset string) (out map[string]ForumPerms) {
|
func PresetToPermmap(preset string) (out map[string]ForumPerms) {
|
||||||
out = make(map[string]ForumPerms)
|
out = make(map[string]ForumPerms)
|
||||||
switch preset {
|
switch preset {
|
||||||
case "all":
|
case "all":
|
||||||
|
@ -266,8 +272,8 @@ func presetToPermmap(preset string) (out map[string]ForumPerms) {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func permmapToQuery(permmap map[string]ForumPerms, fid int) error {
|
func PermmapToQuery(permmap map[string]ForumPerms, fid int) error {
|
||||||
tx, err := db.Begin()
|
tx, err := qgen.Builder.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -337,7 +343,7 @@ func permmapToQuery(permmap map[string]ForumPerms, fid int) error {
|
||||||
|
|
||||||
// 6 is the ID of the Not Loggedin Group
|
// 6 is the ID of the Not Loggedin Group
|
||||||
// TODO: Use a shared variable rather than a literal for the group ID
|
// TODO: Use a shared variable rather than a literal for the group ID
|
||||||
err = replaceForumPermsForGroupTx(tx, 6, map[int]string{fid: ""}, map[int]ForumPerms{fid: permmap["guests"]})
|
err = ReplaceForumPermsForGroupTx(tx, 6, map[int]string{fid: ""}, map[int]ForumPerms{fid: permmap["guests"]})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -347,25 +353,25 @@ func permmapToQuery(permmap map[string]ForumPerms, fid int) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
permUpdateMutex.Lock()
|
PermUpdateMutex.Lock()
|
||||||
defer permUpdateMutex.Unlock()
|
defer PermUpdateMutex.Unlock()
|
||||||
return fpstore.Reload(fid)
|
return Fpstore.Reload(fid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceForumPermsForGroup(gid int, presetSet map[int]string, permSets map[int]ForumPerms) error {
|
func ReplaceForumPermsForGroup(gid int, presetSet map[int]string, permSets map[int]ForumPerms) error {
|
||||||
tx, err := db.Begin()
|
tx, err := qgen.Builder.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
err = replaceForumPermsForGroupTx(tx, gid, presetSet, permSets)
|
err = ReplaceForumPermsForGroupTx(tx, gid, presetSet, permSets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return tx.Commit()
|
return tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string, permSets map[int]ForumPerms) error {
|
func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string, permSets map[int]ForumPerms) error {
|
||||||
deleteForumPermsForGroupTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "gid = ? AND fid = ?")
|
deleteForumPermsForGroupTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "gid = ? AND fid = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -394,7 +400,7 @@ func replaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this and write tests for it
|
// TODO: Refactor this and write tests for it
|
||||||
func forumPermsToGroupForumPreset(fperms ForumPerms) string {
|
func ForumPermsToGroupForumPreset(fperms ForumPerms) string {
|
||||||
if !fperms.Overrides {
|
if !fperms.Overrides {
|
||||||
return "default"
|
return "default"
|
||||||
}
|
}
|
||||||
|
@ -422,7 +428,7 @@ func forumPermsToGroupForumPreset(fperms ForumPerms) string {
|
||||||
return "custom"
|
return "custom"
|
||||||
}
|
}
|
||||||
|
|
||||||
func groupForumPresetToForumPerms(preset string) (fperms ForumPerms, changed bool) {
|
func GroupForumPresetToForumPerms(preset string) (fperms ForumPerms, changed bool) {
|
||||||
switch preset {
|
switch preset {
|
||||||
case "read_only":
|
case "read_only":
|
||||||
return ReadForumPerms, true
|
return ReadForumPerms, true
|
||||||
|
@ -439,7 +445,7 @@ func groupForumPresetToForumPerms(preset string) (fperms ForumPerms, changed boo
|
||||||
return fperms, false
|
return fperms, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func stripInvalidGroupForumPreset(preset string) string {
|
func StripInvalidGroupForumPreset(preset string) string {
|
||||||
switch preset {
|
switch preset {
|
||||||
case "read_only", "can_post", "can_moderate", "no_access", "default", "custom":
|
case "read_only", "can_post", "can_moderate", "no_access", "default", "custom":
|
||||||
return preset
|
return preset
|
||||||
|
@ -447,7 +453,7 @@ func stripInvalidGroupForumPreset(preset string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func stripInvalidPreset(preset string) string {
|
func StripInvalidPreset(preset string) string {
|
||||||
switch preset {
|
switch preset {
|
||||||
case "all", "announce", "members", "staff", "admins", "archive", "custom":
|
case "all", "announce", "members", "staff", "admins", "archive", "custom":
|
||||||
return preset
|
return preset
|
||||||
|
@ -457,7 +463,7 @@ func stripInvalidPreset(preset string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this into the phrase system?
|
// TODO: Move this into the phrase system?
|
||||||
func presetToLang(preset string) string {
|
func PresetToLang(preset string) string {
|
||||||
phrases := GetAllPermPresets()
|
phrases := GetAllPermPresets()
|
||||||
phrase, ok := phrases[preset]
|
phrase, ok := phrases[preset]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -467,10 +473,18 @@ func presetToLang(preset string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Is this racey?
|
// TODO: Is this racey?
|
||||||
func rebuildGroupPermissions(gid int) error {
|
// TODO: Test this along with the rest of the perms system
|
||||||
|
func RebuildGroupPermissions(gid int) error {
|
||||||
var permstr []byte
|
var permstr []byte
|
||||||
log.Print("Reloading a group")
|
log.Print("Reloading a group")
|
||||||
err := db.QueryRow("select permissions from users_groups where gid = ?", gid).Scan(&permstr)
|
|
||||||
|
// TODO: Avoid re-initting this all the time
|
||||||
|
getGroupPerms, err := qgen.Builder.SimpleSelect("users_groups", "permissions", "gid = ?", "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = getGroupPerms.QueryRow(gid).Scan(&permstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -483,7 +497,7 @@ func rebuildGroupPermissions(gid int) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := gstore.Get(gid)
|
group, err := Gstore.Get(gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -491,7 +505,7 @@ func rebuildGroupPermissions(gid int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func overridePerms(perms *Perms, status bool) {
|
func OverridePerms(perms *Perms, status bool) {
|
||||||
if status {
|
if status {
|
||||||
*perms = AllPerms
|
*perms = AllPerms
|
||||||
} else {
|
} else {
|
||||||
|
@ -500,7 +514,7 @@ func overridePerms(perms *Perms, status bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We need a better way of overriding forum perms rather than setting them one by one
|
// TODO: We need a better way of overriding forum perms rather than setting them one by one
|
||||||
func overrideForumPerms(perms *Perms, status bool) {
|
func OverrideForumPerms(perms *Perms, status bool) {
|
||||||
perms.ViewTopic = status
|
perms.ViewTopic = status
|
||||||
perms.LikeItem = status
|
perms.LikeItem = status
|
||||||
perms.CreateTopic = status
|
perms.CreateTopic = status
|
||||||
|
@ -513,10 +527,10 @@ func overrideForumPerms(perms *Perms, status bool) {
|
||||||
perms.CloseTopic = status
|
perms.CloseTopic = status
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerPluginPerm(name string) {
|
func RegisterPluginPerm(name string) {
|
||||||
AllPluginPerms[name] = true
|
AllPluginPerms[name] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func deregisterPluginPerm(name string) {
|
func DeregisterPluginPerm(name string) {
|
||||||
delete(AllPluginPerms, name)
|
delete(AllPluginPerms, name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Copyright Azareal 2017 - 2018
|
* Copyright Azareal 2017 - 2018
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -20,7 +20,7 @@ import (
|
||||||
// TODO: Let the admin edit phrases from inside the Control Panel? How should we persist these? Should we create a copy of the langpack or edit the primaries? Use the changeLangpack mutex for this?
|
// TODO: Let the admin edit phrases from inside the Control Panel? How should we persist these? Should we create a copy of the langpack or edit the primaries? Use the changeLangpack mutex for this?
|
||||||
// nolint Be quiet megacheck, this *is* used
|
// nolint Be quiet megacheck, this *is* used
|
||||||
var currentLangPack atomic.Value
|
var currentLangPack atomic.Value
|
||||||
var langpackCount int // TODO: Use atomics for this
|
var langPackCount int // TODO: Use atomics for this
|
||||||
|
|
||||||
// TODO: We'll be implementing the level phrases in the software proper very very soon!
|
// TODO: We'll be implementing the level phrases in the software proper very very soon!
|
||||||
type LevelPhrases struct {
|
type LevelPhrases struct {
|
||||||
|
@ -44,10 +44,9 @@ type LanguagePack struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add the ability to edit language JSON files from the Control Panel and automatically scan the files for changes
|
// TODO: Add the ability to edit language JSON files from the Control Panel and automatically scan the files for changes
|
||||||
////var langpacks = map[string]*LanguagePack
|
var langPacks sync.Map // nolint it is used
|
||||||
var langpacks sync.Map // nolint it is used
|
|
||||||
|
|
||||||
func initPhrases() error {
|
func InitPhrases() error {
|
||||||
log.Print("Loading the language packs")
|
log.Print("Loading the language packs")
|
||||||
err := filepath.Walk("./langs", func(path string, f os.FileInfo, err error) error {
|
err := filepath.Walk("./langs", func(path string, f os.FileInfo, err error) error {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
|
@ -61,8 +60,8 @@ func initPhrases() error {
|
||||||
|
|
||||||
var ext = filepath.Ext("/langs/" + path)
|
var ext = filepath.Ext("/langs/" + path)
|
||||||
if ext != ".json" {
|
if ext != ".json" {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Found a " + ext + "in /langs/")
|
log.Printf("Found a '%s' in /langs/", ext)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -74,8 +73,8 @@ func initPhrases() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Adding the '" + langPack.Name + "' language pack")
|
log.Print("Adding the '" + langPack.Name + "' language pack")
|
||||||
langpacks.Store(langPack.Name, &langPack)
|
langPacks.Store(langPack.Name, &langPack)
|
||||||
langpackCount++
|
langPackCount++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -83,13 +82,13 @@ func initPhrases() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if langpackCount == 0 {
|
if langPackCount == 0 {
|
||||||
return errors.New("You don't have any language packs")
|
return errors.New("You don't have any language packs")
|
||||||
}
|
}
|
||||||
|
|
||||||
langPack, ok := langpacks.Load(site.Language)
|
langPack, ok := langPacks.Load(Site.Language)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("Couldn't find the " + site.Language + " language pack")
|
return errors.New("Couldn't find the " + Site.Language + " language pack")
|
||||||
}
|
}
|
||||||
currentLangPack.Store(langPack)
|
currentLangPack.Store(langPack)
|
||||||
return nil
|
return nil
|
||||||
|
@ -167,7 +166,7 @@ func DeletePhrase() {
|
||||||
// TODO: Use atomics to store the pointer of the current active langpack?
|
// TODO: Use atomics to store the pointer of the current active langpack?
|
||||||
// nolint
|
// nolint
|
||||||
func ChangeLanguagePack(name string) (exists bool) {
|
func ChangeLanguagePack(name string) (exists bool) {
|
||||||
pack, ok := langpacks.Load(name)
|
pack, ok := langPacks.Load(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
|
@ -89,7 +89,7 @@ func InitPluginLangs() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
plugins[plugin.UName] = pplugin
|
Plugins[plugin.UName] = pplugin
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var prstore ProfileReplyStore
|
var Prstore ProfileReplyStore
|
||||||
|
|
||||||
type ProfileReplyStore interface {
|
type ProfileReplyStore interface {
|
||||||
Get(id int) (*Reply, error)
|
Get(id int) (*Reply, error)
|
||||||
|
@ -33,7 +35,7 @@ func (store *SQLProfileReplyStore) Get(id int) (*Reply, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *SQLProfileReplyStore) Create(profileID int, content string, createdBy int, ipaddress string) (id int, err error) {
|
func (store *SQLProfileReplyStore) Create(profileID int, content string, createdBy int, ipaddress string) (id int, err error) {
|
||||||
res, err := store.create.Exec(profileID, content, parseMessage(content, 0, ""), createdBy, ipaddress)
|
res, err := store.create.Exec(profileID, content, ParseMessage(content, 0, ""), createdBy, ipaddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,11 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ReplyUser struct {
|
type ReplyUser struct {
|
||||||
|
@ -56,12 +59,37 @@ type Reply struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrAlreadyLiked = errors.New("You already liked this!")
|
var ErrAlreadyLiked = errors.New("You already liked this!")
|
||||||
|
var replyStmts ReplyStmts
|
||||||
|
|
||||||
|
type ReplyStmts struct {
|
||||||
|
isLiked *sql.Stmt
|
||||||
|
createLike *sql.Stmt
|
||||||
|
delete *sql.Stmt
|
||||||
|
addLikesToReply *sql.Stmt
|
||||||
|
removeRepliesFromTopic *sql.Stmt
|
||||||
|
getParent *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
DbInits.Add(func() error {
|
||||||
|
acc := qgen.Builder.Accumulator()
|
||||||
|
replyStmts = ReplyStmts{
|
||||||
|
isLiked: acc.SimpleSelect("likes", "targetItem", "sentBy = ? and targetItem = ? and targetType = 'replies'", "", ""),
|
||||||
|
createLike: acc.SimpleInsert("likes", "weight, targetItem, targetType, sentBy", "?,?,?,?"),
|
||||||
|
delete: acc.SimpleDelete("replies", "rid = ?"),
|
||||||
|
addLikesToReply: acc.SimpleUpdate("replies", "likeCount = likeCount + ?", "rid = ?"),
|
||||||
|
removeRepliesFromTopic: acc.SimpleUpdate("topics", "postCount = postCount - ?", "tid = ?"),
|
||||||
|
getParent: acc.SimpleLeftJoin("replies", "topics", "topics.tid, topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, topics.data", "replies.tid = topics.tid", "rid = ?", "", ""),
|
||||||
|
}
|
||||||
|
return acc.FirstError()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Write tests for this
|
// TODO: Write tests for this
|
||||||
// TODO: Wrap these queries in a transaction to make sure the state is consistent
|
// TODO: Wrap these queries in a transaction to make sure the state is consistent
|
||||||
func (reply *Reply) Like(uid int) (err error) {
|
func (reply *Reply) Like(uid int) (err error) {
|
||||||
var rid int // unused, just here to avoid mutating reply.ID
|
var rid int // unused, just here to avoid mutating reply.ID
|
||||||
err = stmts.hasLikedReply.QueryRow(uid, reply.ID).Scan(&rid)
|
err = replyStmts.isLiked.QueryRow(uid, reply.ID).Scan(&rid)
|
||||||
if err != nil && err != ErrNoRows {
|
if err != nil && err != ErrNoRows {
|
||||||
return err
|
return err
|
||||||
} else if err != ErrNoRows {
|
} else if err != ErrNoRows {
|
||||||
|
@ -69,29 +97,41 @@ func (reply *Reply) Like(uid int) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
score := 1
|
score := 1
|
||||||
_, err = stmts.createLike.Exec(score, reply.ID, "replies", uid)
|
_, err = replyStmts.createLike.Exec(score, reply.ID, "replies", uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = stmts.addLikesToReply.Exec(1, reply.ID)
|
_, err = replyStmts.addLikesToReply.Exec(1, reply.ID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write tests for this
|
// TODO: Write tests for this
|
||||||
func (reply *Reply) Delete() error {
|
func (reply *Reply) Delete() error {
|
||||||
_, err := stmts.deleteReply.Exec(reply.ID)
|
_, err := replyStmts.delete.Exec(reply.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = stmts.removeRepliesFromTopic.Exec(1, reply.ParentID)
|
// TODO: Move this bit to *Topic
|
||||||
tcache, ok := topics.(TopicCache)
|
_, err = replyStmts.removeRepliesFromTopic.Exec(1, reply.ParentID)
|
||||||
|
tcache, ok := Topics.(TopicCache)
|
||||||
if ok {
|
if ok {
|
||||||
tcache.CacheRemove(reply.ParentID)
|
tcache.CacheRemove(reply.ParentID)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (reply *Reply) Topic() (*Topic, error) {
|
||||||
|
topic := Topic{ID: 0}
|
||||||
|
err := replyStmts.getParent.QueryRow(reply.ID).Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), topic.ID)
|
||||||
|
return &topic, err
|
||||||
|
}
|
||||||
|
|
||||||
// Copy gives you a non-pointer concurrency safe copy of the reply
|
// Copy gives you a non-pointer concurrency safe copy of the reply
|
||||||
func (reply *Reply) Copy() Reply {
|
func (reply *Reply) Copy() Reply {
|
||||||
return *reply
|
return *reply
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BlankReply() *Reply {
|
||||||
|
return &Reply{ID: 0}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package common
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
import "../query_gen/lib"
|
import "../query_gen/lib"
|
||||||
|
|
||||||
var rstore ReplyStore
|
var Rstore ReplyStore
|
||||||
|
|
||||||
type ReplyStore interface {
|
type ReplyStore interface {
|
||||||
Get(id int) (*Reply, error)
|
Get(id int) (*Reply, error)
|
||||||
|
@ -31,8 +31,8 @@ func (store *SQLReplyStore) Get(id int) (*Reply, error) {
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func (store *SQLReplyStore) Create(topic *Topic, content string, ipaddress string, uid int) (id int, err error) {
|
func (store *SQLReplyStore) Create(topic *Topic, content string, ipaddress string, uid int) (id int, err error) {
|
||||||
wcount := wordCount(content)
|
wcount := WordCount(content)
|
||||||
res, err := store.create.Exec(topic.ID, content, parseMessage(content, topic.ParentID, "forums"), ipaddress, wcount, uid)
|
res, err := store.create.Exec(topic.ID, content, ParseMessage(content, topic.ParentID, "forums"), ipaddress, wcount, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html"
|
"html"
|
||||||
|
@ -7,8 +7,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"./common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
|
@ -16,28 +14,28 @@ var PreRoute func(http.ResponseWriter, *http.Request) (User, bool) = preRoute
|
||||||
|
|
||||||
// TODO: Come up with a better middleware solution
|
// TODO: Come up with a better middleware solution
|
||||||
// nolint We need these types so people can tell what they are without scrolling to the bottom of the file
|
// nolint We need these types so people can tell what they are without scrolling to the bottom of the file
|
||||||
var PanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*common.HeaderVars, common.PanelStats, RouteError) = panelUserCheck
|
var PanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*HeaderVars, PanelStats, RouteError) = panelUserCheck
|
||||||
var SimplePanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*common.HeaderLite, RouteError) = simplePanelUserCheck
|
var SimplePanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*HeaderLite, RouteError) = simplePanelUserCheck
|
||||||
var SimpleForumUserCheck func(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerLite *common.HeaderLite, err RouteError) = simpleForumUserCheck
|
var SimpleForumUserCheck func(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerLite *HeaderLite, err RouteError) = simpleForumUserCheck
|
||||||
var ForumUserCheck func(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerVars *common.HeaderVars, err RouteError) = forumUserCheck
|
var ForumUserCheck func(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerVars *HeaderVars, err RouteError) = forumUserCheck
|
||||||
var MemberCheck func(w http.ResponseWriter, r *http.Request, user *User) (headerVars *common.HeaderVars, err RouteError) = memberCheck
|
var MemberCheck func(w http.ResponseWriter, r *http.Request, user *User) (headerVars *HeaderVars, err RouteError) = memberCheck
|
||||||
var UserCheck func(w http.ResponseWriter, r *http.Request, user *User) (headerVars *common.HeaderVars, err RouteError) = userCheck
|
var SimpleUserCheck func(w http.ResponseWriter, r *http.Request, user *User) (headerLite *HeaderLite, err RouteError) = simpleUserCheck
|
||||||
var UserCheck func(w http.ResponseWriter, r *http.Request, user *User) (headerVars *common.HeaderVars, err RouteError) = userCheck
|
var UserCheck func(w http.ResponseWriter, r *http.Request, user *User) (headerVars *HeaderVars, err RouteError) = userCheck
|
||||||
|
|
||||||
// TODO: Support for left sidebars and sidebars on both sides
|
// TODO: Support for left sidebars and sidebars on both sides
|
||||||
// http.Request is for context.Context middleware. Mostly for plugin_guilds right now
|
// http.Request is for context.Context middleware. Mostly for plugin_guilds right now
|
||||||
func BuildWidgets(zone string, data interface{}, headerVars *common.HeaderVars, r *http.Request) {
|
func BuildWidgets(zone string, data interface{}, headerVars *HeaderVars, r *http.Request) {
|
||||||
if vhooks["intercept_build_widgets"] != nil {
|
if Vhooks["intercept_build_widgets"] != nil {
|
||||||
if runVhook("intercept_build_widgets", zone, data, headerVars, r).(bool) {
|
if RunVhook("intercept_build_widgets", zone, data, headerVars, r).(bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.Print("themes[headerVars.ThemeName].Sidebars",themes[headerVars.ThemeName].Sidebars)
|
//log.Print("Themes[headerVars.ThemeName].Sidebars", Themes[headerVars.ThemeName].Sidebars)
|
||||||
if themes[headerVars.ThemeName].Sidebars == "right" {
|
if Themes[headerVars.ThemeName].Sidebars == "right" {
|
||||||
if len(docks.RightSidebar) != 0 {
|
if len(Docks.RightSidebar) != 0 {
|
||||||
var sbody string
|
var sbody string
|
||||||
for _, widget := range docks.RightSidebar {
|
for _, widget := range Docks.RightSidebar {
|
||||||
if widget.Enabled {
|
if widget.Enabled {
|
||||||
if widget.Location == "global" || widget.Location == zone {
|
if widget.Location == "global" || widget.Location == zone {
|
||||||
sbody += widget.Body
|
sbody += widget.Body
|
||||||
|
@ -49,21 +47,21 @@ func BuildWidgets(zone string, data interface{}, headerVars *common.HeaderVars,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func simpleForumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerLite *common.HeaderLite, rerr RouteError) {
|
func simpleForumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerLite *HeaderLite, rerr RouteError) {
|
||||||
if !fstore.Exists(fid) {
|
if !Fstore.Exists(fid) {
|
||||||
return nil, PreError("The target forum doesn't exist.", w, r)
|
return nil, PreError("The target forum doesn't exist.", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is there a better way of doing the skip AND the success flag on this hook like multiple returns?
|
// Is there a better way of doing the skip AND the success flag on this hook like multiple returns?
|
||||||
if vhookSkippable["simple_forum_check_pre_perms"] != nil {
|
if VhookSkippable["simple_forum_check_pre_perms"] != nil {
|
||||||
var skip bool
|
var skip bool
|
||||||
skip, rerr = runVhookSkippable("simple_forum_check_pre_perms", w, r, user, &fid, &headerLite)
|
skip, rerr = RunVhookSkippable("simple_forum_check_pre_perms", w, r, user, &fid, &headerLite)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return headerLite, rerr
|
return headerLite, rerr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fperms, err := fpstore.Get(fid, user.Group)
|
fperms, err := Fpstore.Get(fid, user.Group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: Refactor this
|
// TODO: Refactor this
|
||||||
log.Printf("Unable to get the forum perms for Group #%d for User #%d", user.Group, user.ID)
|
log.Printf("Unable to get the forum perms for Group #%d for User #%d", user.Group, user.ID)
|
||||||
|
@ -73,24 +71,24 @@ func simpleForumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fi
|
||||||
return headerLite, nil
|
return headerLite, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func forumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerVars *common.HeaderVars, rerr RouteError) {
|
func forumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerVars *HeaderVars, rerr RouteError) {
|
||||||
headerVars, rerr = UserCheck(w, r, user)
|
headerVars, rerr = UserCheck(w, r, user)
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return headerVars, rerr
|
return headerVars, rerr
|
||||||
}
|
}
|
||||||
if !fstore.Exists(fid) {
|
if !Fstore.Exists(fid) {
|
||||||
return headerVars, NotFound(w, r)
|
return headerVars, NotFound(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vhookSkippable["forum_check_pre_perms"] != nil {
|
if VhookSkippable["forum_check_pre_perms"] != nil {
|
||||||
var skip bool
|
var skip bool
|
||||||
skip, rerr = runVhookSkippable("forum_check_pre_perms", w, r, user, &fid, &headerVars)
|
skip, rerr = RunVhookSkippable("forum_check_pre_perms", w, r, user, &fid, &headerVars)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return headerVars, rerr
|
return headerVars, rerr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fperms, err := fpstore.Get(fid, user.Group)
|
fperms, err := Fpstore.Get(fid, user.Group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: Refactor this
|
// TODO: Refactor this
|
||||||
log.Printf("Unable to get the forum perms for Group #%d for User #%d", user.Group, user.ID)
|
log.Printf("Unable to get the forum perms for Group #%d for User #%d", user.Group, user.ID)
|
||||||
|
@ -126,29 +124,29 @@ func cascadeForumPerms(fperms ForumPerms, user *User) {
|
||||||
|
|
||||||
// Even if they have the right permissions, the control panel is only open to supermods+. There are many areas without subpermissions which assume that the current user is a supermod+ and admins are extremely unlikely to give these permissions to someone who isn't at-least a supermod to begin with
|
// Even if they have the right permissions, the control panel is only open to supermods+. There are many areas without subpermissions which assume that the current user is a supermod+ and admins are extremely unlikely to give these permissions to someone who isn't at-least a supermod to begin with
|
||||||
// TODO: Do a panel specific theme?
|
// TODO: Do a panel specific theme?
|
||||||
func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *common.HeaderVars, stats common.PanelStats, rerr RouteError) {
|
func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *HeaderVars, stats PanelStats, rerr RouteError) {
|
||||||
var themeName = defaultThemeBox.Load().(string)
|
var themeName = DefaultThemeBox.Load().(string)
|
||||||
|
|
||||||
cookie, err := r.Cookie("current_theme")
|
cookie, err := r.Cookie("current_theme")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cookie := html.EscapeString(cookie.Value)
|
cookie := html.EscapeString(cookie.Value)
|
||||||
theme, ok := themes[cookie]
|
theme, ok := Themes[cookie]
|
||||||
if ok && !theme.HideFromThemes {
|
if ok && !theme.HideFromThemes {
|
||||||
themeName = cookie
|
themeName = cookie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
headerVars = &HeaderVars{
|
headerVars = &HeaderVars{
|
||||||
Site: site,
|
Site: Site,
|
||||||
Settings: settingBox.Load().(SettingBox),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
Themes: themes,
|
Themes: Themes,
|
||||||
ThemeName: themeName,
|
ThemeName: themeName,
|
||||||
}
|
}
|
||||||
// TODO: We should probably initialise headerVars.ExtData
|
// TODO: We should probably initialise headerVars.ExtData
|
||||||
|
|
||||||
headerVars.Stylesheets = append(headerVars.Stylesheets, headerVars.ThemeName+"/panel.css")
|
headerVars.Stylesheets = append(headerVars.Stylesheets, headerVars.ThemeName+"/panel.css")
|
||||||
if len(themes[headerVars.ThemeName].Resources) > 0 {
|
if len(Themes[headerVars.ThemeName].Resources) > 0 {
|
||||||
rlist := themes[headerVars.ThemeName].Resources
|
rlist := Themes[headerVars.ThemeName].Resources
|
||||||
for _, resource := range rlist {
|
for _, resource := range rlist {
|
||||||
if resource.Location == "global" || resource.Location == "panel" {
|
if resource.Location == "global" || resource.Location == "panel" {
|
||||||
extarr := strings.Split(resource.Name, ".")
|
extarr := strings.Split(resource.Name, ".")
|
||||||
|
@ -162,16 +160,12 @@ func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = stmts.groupCount.QueryRow().Scan(&stats.Groups)
|
stats.Users = Users.GlobalCount()
|
||||||
if err != nil {
|
stats.Groups = Gstore.GlobalCount()
|
||||||
return headerVars, stats, InternalError(err, w, r)
|
stats.Forums = Fstore.GlobalCount() // TODO: Stop it from showing the blanked forums
|
||||||
}
|
|
||||||
|
|
||||||
stats.Users = users.GlobalCount()
|
|
||||||
stats.Forums = fstore.GlobalCount() // TODO: Stop it from showing the blanked forums
|
|
||||||
stats.Settings = len(headerVars.Settings)
|
stats.Settings = len(headerVars.Settings)
|
||||||
stats.WordFilters = len(wordFilterBox.Load().(WordFilterBox))
|
stats.WordFilters = len(WordFilterBox.Load().(WordFilterMap))
|
||||||
stats.Themes = len(themes)
|
stats.Themes = len(Themes)
|
||||||
stats.Reports = 0 // TODO: Do the report count. Only show open threads?
|
stats.Reports = 0 // TODO: Do the report count. Only show open threads?
|
||||||
|
|
||||||
pusher, ok := w.(http.Pusher)
|
pusher, ok := w.(http.Pusher)
|
||||||
|
@ -188,15 +182,15 @@ func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerV
|
||||||
return headerVars, stats, nil
|
return headerVars, stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func simplePanelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerLite *common.HeaderLite, rerr RouteError) {
|
func simplePanelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerLite *HeaderLite, rerr RouteError) {
|
||||||
return &HeaderLite{
|
return &HeaderLite{
|
||||||
Site: site,
|
Site: Site,
|
||||||
Settings: settingBox.Load().(SettingBox),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add this to the member routes
|
// TODO: Add this to the member routes
|
||||||
func memberCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *common.HeaderVars, rerr RouteError) {
|
func memberCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *HeaderVars, rerr RouteError) {
|
||||||
headerVars, rerr = UserCheck(w, r, user)
|
headerVars, rerr = UserCheck(w, r, user)
|
||||||
if !user.Loggedin {
|
if !user.Loggedin {
|
||||||
return headerVars, NoPermissions(w, r, *user)
|
return headerVars, NoPermissions(w, r, *user)
|
||||||
|
@ -205,31 +199,31 @@ func memberCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimpleUserCheck is back from the grave, yay :D
|
// SimpleUserCheck is back from the grave, yay :D
|
||||||
func simpleUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerLite *common.HeaderLite, rerr RouteError) {
|
func simpleUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerLite *HeaderLite, rerr RouteError) {
|
||||||
headerLite = &HeaderLite{
|
headerLite = &HeaderLite{
|
||||||
Site: site,
|
Site: Site,
|
||||||
Settings: settingBox.Load().(SettingBox),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
}
|
}
|
||||||
return headerLite, nil
|
return headerLite, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add the ability for admins to restrict certain themes to certain groups?
|
// TODO: Add the ability for admins to restrict certain themes to certain groups?
|
||||||
func userCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *common.HeaderVars, rerr RouteError) {
|
func userCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *HeaderVars, rerr RouteError) {
|
||||||
var themeName = defaultThemeBox.Load().(string)
|
var themeName = DefaultThemeBox.Load().(string)
|
||||||
|
|
||||||
cookie, err := r.Cookie("current_theme")
|
cookie, err := r.Cookie("current_theme")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cookie := html.EscapeString(cookie.Value)
|
cookie := html.EscapeString(cookie.Value)
|
||||||
theme, ok := themes[cookie]
|
theme, ok := Themes[cookie]
|
||||||
if ok && !theme.HideFromThemes {
|
if ok && !theme.HideFromThemes {
|
||||||
themeName = cookie
|
themeName = cookie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
headerVars = &HeaderVars{
|
headerVars = &HeaderVars{
|
||||||
Site: site,
|
Site: Site,
|
||||||
Settings: settingBox.Load().(SettingBox),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
Themes: themes,
|
Themes: Themes,
|
||||||
ThemeName: themeName,
|
ThemeName: themeName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,8 +231,8 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *
|
||||||
headerVars.NoticeList = append(headerVars.NoticeList, "Your account has been suspended. Some of your permissions may have been revoked.")
|
headerVars.NoticeList = append(headerVars.NoticeList, "Your account has been suspended. Some of your permissions may have been revoked.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(themes[headerVars.ThemeName].Resources) > 0 {
|
if len(Themes[headerVars.ThemeName].Resources) > 0 {
|
||||||
rlist := themes[headerVars.ThemeName].Resources
|
rlist := Themes[headerVars.ThemeName].Resources
|
||||||
for _, resource := range rlist {
|
for _, resource := range rlist {
|
||||||
if resource.Location == "global" || resource.Location == "frontend" {
|
if resource.Location == "global" || resource.Location == "frontend" {
|
||||||
extarr := strings.Split(resource.Name, ".")
|
extarr := strings.Split(resource.Name, ".")
|
||||||
|
@ -266,27 +260,28 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *
|
||||||
}
|
}
|
||||||
|
|
||||||
func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
|
func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
|
||||||
user, halt := auth.SessionCheck(w, r)
|
user, halt := Auth.SessionCheck(w, r)
|
||||||
if halt {
|
if halt {
|
||||||
return *user, false
|
return *user, false
|
||||||
}
|
}
|
||||||
if user == &guestUser {
|
if user == &GuestUser {
|
||||||
return *user, true
|
return *user, true
|
||||||
}
|
}
|
||||||
|
|
||||||
var usercpy = *user
|
var usercpy *User
|
||||||
|
*usercpy = *user
|
||||||
|
|
||||||
// TODO: WIP. Refactor this to eliminate the unnecessary query
|
// TODO: WIP. Refactor this to eliminate the unnecessary query
|
||||||
host, _, err := net.SplitHostPort(r.RemoteAddr)
|
host, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
PreError("Bad IP", w, r)
|
PreError("Bad IP", w, r)
|
||||||
return usercpy, false
|
return *usercpy, false
|
||||||
}
|
}
|
||||||
if host != usercpy.LastIP {
|
if host != usercpy.LastIP {
|
||||||
_, err = stmts.updateLastIP.Exec(host, usercpy.ID)
|
err = usercpy.UpdateIP(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
InternalError(err, w, r)
|
InternalError(err, w, r)
|
||||||
return usercpy, false
|
return *usercpy, false
|
||||||
}
|
}
|
||||||
usercpy.LastIP = host
|
usercpy.LastIP = host
|
||||||
}
|
}
|
||||||
|
@ -296,7 +291,7 @@ func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
|
||||||
//h.Set("X-XSS-Protection", "1")
|
//h.Set("X-XSS-Protection", "1")
|
||||||
// TODO: Set the content policy header
|
// TODO: Set the content policy header
|
||||||
|
|
||||||
return usercpy, true
|
return *usercpy, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuperModeOnly makes sure that only super mods or higher can access the panel routes
|
// SuperModeOnly makes sure that only super mods or higher can access the panel routes
|
|
@ -3,6 +3,7 @@ package common
|
||||||
import "strconv"
|
import "strconv"
|
||||||
import "strings"
|
import "strings"
|
||||||
import "sync/atomic"
|
import "sync/atomic"
|
||||||
|
import "../query_gen/lib"
|
||||||
|
|
||||||
// SettingMap is a map type specifically for holding the various settings admins set to toggle features on and off or to otherwise alter Gosora's behaviour from the Control Panel
|
// SettingMap is a map type specifically for holding the various settings admins set to toggle features on and off or to otherwise alter Gosora's behaviour from the Control Panel
|
||||||
type SettingMap map[string]interface{}
|
type SettingMap map[string]interface{}
|
||||||
|
@ -27,7 +28,12 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadSettings() error {
|
func LoadSettings() error {
|
||||||
rows, err := stmts.getFullSettings.Query()
|
// TODO: Stop doing this inline
|
||||||
|
getFullSettings, err := qgen.Builder.SimpleSelect("settings", "name, content, type, constraints", "", "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, err := getFullSettings.Query()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,31 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var site = &Site{Name: "Magical Fairy Land", Language: "english"}
|
// Site holds the basic settings which should be tweaked when setting up a site, we might move them to the settings table at some point
|
||||||
var dbConfig = DBConfig{Host: "localhost"}
|
var Site = &site{Name: "Magical Fairy Land", Language: "english"}
|
||||||
var config Config
|
|
||||||
var dev DevConfig
|
|
||||||
|
|
||||||
type Site struct {
|
// DbConfig holds the database configuration
|
||||||
|
var DbConfig = dbConfig{Host: "localhost"}
|
||||||
|
|
||||||
|
// Config holds the more technical settings
|
||||||
|
var Config config
|
||||||
|
|
||||||
|
// Dev holds build flags and other things which should only be modified during developers or to gather additional test data
|
||||||
|
var Dev devConfig
|
||||||
|
|
||||||
|
type site struct {
|
||||||
ShortName string
|
ShortName string
|
||||||
Name string // ? - Move this into the settings table? Should we make a second version of this for the abbreviation shown in the navbar?
|
Name string
|
||||||
Email string // ? - Move this into the settings table?
|
Email string
|
||||||
URL string
|
URL string
|
||||||
Port string
|
Port string
|
||||||
EnableSsl bool
|
EnableSsl bool
|
||||||
EnableEmails bool
|
EnableEmails bool
|
||||||
HasProxy bool
|
HasProxy bool
|
||||||
Language string // ? - Move this into the settings table?
|
Language string
|
||||||
}
|
}
|
||||||
|
|
||||||
type DBConfig struct {
|
type dbConfig struct {
|
||||||
// Production database
|
// Production database
|
||||||
Host string
|
Host string
|
||||||
Username string
|
Username string
|
||||||
|
@ -39,7 +46,7 @@ type DBConfig struct {
|
||||||
TestPort string
|
TestPort string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type config struct {
|
||||||
SslPrivkey string
|
SslPrivkey string
|
||||||
SslFullchain string
|
SslFullchain string
|
||||||
|
|
||||||
|
@ -65,7 +72,7 @@ type Config struct {
|
||||||
ItemsPerPage int // ? - Move this into the settings table?
|
ItemsPerPage int // ? - Move this into the settings table?
|
||||||
}
|
}
|
||||||
|
|
||||||
type DevConfig struct {
|
type devConfig struct {
|
||||||
DebugMode bool
|
DebugMode bool
|
||||||
SuperDebug bool
|
SuperDebug bool
|
||||||
TemplateDebug bool
|
TemplateDebug bool
|
||||||
|
@ -73,35 +80,35 @@ type DevConfig struct {
|
||||||
TestDB bool
|
TestDB bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func processConfig() error {
|
func ProcessConfig() error {
|
||||||
config.Noavatar = strings.Replace(config.Noavatar, "{site_url}", site.URL, -1)
|
Config.Noavatar = strings.Replace(Config.Noavatar, "{site_url}", Site.URL, -1)
|
||||||
if site.Port != "80" && site.Port != "443" {
|
if Site.Port != "80" && Site.Port != "443" {
|
||||||
site.URL = strings.TrimSuffix(site.URL, "/")
|
Site.URL = strings.TrimSuffix(Site.URL, "/")
|
||||||
site.URL = strings.TrimSuffix(site.URL, "\\")
|
Site.URL = strings.TrimSuffix(Site.URL, "\\")
|
||||||
site.URL = strings.TrimSuffix(site.URL, ":")
|
Site.URL = strings.TrimSuffix(Site.URL, ":")
|
||||||
site.URL = site.URL + ":" + site.Port
|
Site.URL = Site.URL + ":" + Site.Port
|
||||||
}
|
}
|
||||||
// We need this in here rather than verifyConfig as switchToTestDB() currently overwrites the values it verifies
|
// We need this in here rather than verifyConfig as switchToTestDB() currently overwrites the values it verifies
|
||||||
if dbConfig.TestDbname == dbConfig.Dbname {
|
if DbConfig.TestDbname == DbConfig.Dbname {
|
||||||
return errors.New("Your test database can't have the same name as your production database")
|
return errors.New("Your test database can't have the same name as your production database")
|
||||||
}
|
}
|
||||||
if dev.TestDB {
|
if Dev.TestDB {
|
||||||
switchToTestDB()
|
SwitchToTestDB()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyConfig() error {
|
func VerifyConfig() error {
|
||||||
if !fstore.Exists(config.DefaultForum) {
|
if !Fstore.Exists(Config.DefaultForum) {
|
||||||
return errors.New("Invalid default forum")
|
return errors.New("Invalid default forum")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func switchToTestDB() {
|
func SwitchToTestDB() {
|
||||||
dbConfig.Host = dbConfig.TestHost
|
DbConfig.Host = DbConfig.TestHost
|
||||||
dbConfig.Username = dbConfig.TestUsername
|
DbConfig.Username = DbConfig.TestUsername
|
||||||
dbConfig.Password = dbConfig.TestPassword
|
DbConfig.Password = DbConfig.TestPassword
|
||||||
dbConfig.Dbname = dbConfig.TestDbname
|
DbConfig.Dbname = DbConfig.TestDbname
|
||||||
dbConfig.Port = dbConfig.TestPort
|
DbConfig.Port = DbConfig.TestPort
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
* Copyright Azareal 2017 - 2018
|
* Copyright Azareal 2017 - 2018
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var lastSync time.Time
|
var lastSync time.Time
|
||||||
|
@ -17,8 +19,12 @@ func init() {
|
||||||
lastSync = time.Now()
|
lastSync = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleExpiredScheduledGroups() error {
|
func HandleExpiredScheduledGroups() error {
|
||||||
rows, err := stmts.getExpiredScheduledGroups.Query()
|
getExpiredScheduledGroups, err := qgen.Builder.SimpleSelect("users_groups_scheduler", "uid", "UTC_TIMESTAMP() > revert_at AND temporary = 1", "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, err := getExpiredScheduledGroups.Query()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -32,7 +38,7 @@ func handleExpiredScheduledGroups() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sneaky way of initialising a *User, please use the methods on the UserStore instead
|
// Sneaky way of initialising a *User, please use the methods on the UserStore instead
|
||||||
user := getDummyUser()
|
user := BlankUser()
|
||||||
user.ID = uid
|
user.ID = uid
|
||||||
err = user.RevertGroupUpdate()
|
err = user.RevertGroupUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -42,16 +48,20 @@ func handleExpiredScheduledGroups() error {
|
||||||
return rows.Err()
|
return rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleServerSync() error {
|
func HandleServerSync() error {
|
||||||
var lastUpdate time.Time
|
var lastUpdate time.Time
|
||||||
err := stmts.getSync.QueryRow().Scan(&lastUpdate)
|
getSync, err := qgen.Builder.SimpleSelect("sync", "last_update", "", "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = getSync.QueryRow().Scan(&lastUpdate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if lastUpdate.After(lastSync) {
|
if lastUpdate.After(lastSync) {
|
||||||
// TODO: A more granular sync
|
// TODO: A more granular sync
|
||||||
err = fstore.LoadForums()
|
err = Fstore.LoadForums()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print("Unable to reload the forums")
|
log.Print("Unable to reload the forums")
|
||||||
return err
|
return err
|
|
@ -5,10 +5,12 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"./templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
var templates = template.New("")
|
var Templates = template.New("")
|
||||||
var prebuildTmplList []func(*User, *HeaderVars) CTmpl
|
var PrebuildTmplList []func(User, *HeaderVars) CTmpl
|
||||||
|
|
||||||
type CTmpl struct {
|
type CTmpl struct {
|
||||||
Name string
|
Name string
|
||||||
|
@ -20,11 +22,11 @@ type CTmpl struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func interpreted_topic_template(pi TopicPage, w http.ResponseWriter) error {
|
func interpreted_topic_template(pi TopicPage, w http.ResponseWriter) error {
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap["topic"]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["topic"]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = "topic"
|
mapping = "topic"
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
|
@ -33,64 +35,66 @@ var template_topic_alt_handle func(TopicPage, http.ResponseWriter) error = inter
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
var template_topics_handle func(TopicsPage, http.ResponseWriter) error = func(pi TopicsPage, w http.ResponseWriter) error {
|
var template_topics_handle func(TopicsPage, http.ResponseWriter) error = func(pi TopicsPage, w http.ResponseWriter) error {
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap["topics"]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["topics"]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = "topics"
|
mapping = "topics"
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
var template_forum_handle func(ForumPage, http.ResponseWriter) error = func(pi ForumPage, w http.ResponseWriter) error {
|
var template_forum_handle func(ForumPage, http.ResponseWriter) error = func(pi ForumPage, w http.ResponseWriter) error {
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap["forum"]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["forum"]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = "forum"
|
mapping = "forum"
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
var template_forums_handle func(ForumsPage, http.ResponseWriter) error = func(pi ForumsPage, w http.ResponseWriter) error {
|
var template_forums_handle func(ForumsPage, http.ResponseWriter) error = func(pi ForumsPage, w http.ResponseWriter) error {
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap["forums"]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["forums"]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = "forums"
|
mapping = "forums"
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
var template_profile_handle func(ProfilePage, http.ResponseWriter) error = func(pi ProfilePage, w http.ResponseWriter) error {
|
var template_profile_handle func(ProfilePage, http.ResponseWriter) error = func(pi ProfilePage, w http.ResponseWriter) error {
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap["profile"]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["profile"]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = "profile"
|
mapping = "profile"
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
var template_create_topic_handle func(CreateTopicPage, http.ResponseWriter) error = func(pi CreateTopicPage, w http.ResponseWriter) error {
|
var template_create_topic_handle func(CreateTopicPage, http.ResponseWriter) error = func(pi CreateTopicPage, w http.ResponseWriter) error {
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap["create-topic"]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["create-topic"]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = "create-topic"
|
mapping = "create-topic"
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? - Add template hooks?
|
// ? - Add template hooks?
|
||||||
func compileTemplates() error {
|
func compileTemplates() error {
|
||||||
var c CTemplateSet
|
var c tmpl.CTemplateSet
|
||||||
|
c.Minify(Config.MinifyTemplates)
|
||||||
|
c.SuperDebug(Dev.TemplateDebug)
|
||||||
|
|
||||||
// Schemas to train the template compiler on what to expect
|
// Schemas to train the template compiler on what to expect
|
||||||
// TODO: Add support for interface{}s
|
// TODO: Add support for interface{}s
|
||||||
user := User{62, buildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", "", "", "", "", 0, 0, "0.0.0.0.0", 0}
|
user := User{62, BuildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", "", "", "", "", 0, 0, "0.0.0.0.0", 0}
|
||||||
// TODO: Do a more accurate level calculation for this?
|
// TODO: Do a more accurate level calculation for this?
|
||||||
user2 := User{1, buildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", "", "", "", "", 58, 1000, "127.0.0.1", 0}
|
user2 := User{1, BuildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", "", "", "", "", 58, 1000, "127.0.0.1", 0}
|
||||||
user3 := User{2, buildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", "", "", "", "", 42, 900, "::1", 0}
|
user3 := User{2, BuildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", "", "", "", "", 42, 900, "::1", 0}
|
||||||
headerVars := &HeaderVars{
|
headerVars := &HeaderVars{
|
||||||
Site: site,
|
Site: Site,
|
||||||
Settings: settingBox.Load().(SettingBox),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
Themes: themes,
|
Themes: Themes,
|
||||||
ThemeName: defaultThemeBox.Load().(string),
|
ThemeName: DefaultThemeBox.Load().(string),
|
||||||
NoticeList: []string{"test"},
|
NoticeList: []string{"test"},
|
||||||
Stylesheets: []string{"panel"},
|
Stylesheets: []string{"panel"},
|
||||||
Scripts: []string{"whatever"},
|
Scripts: []string{"whatever"},
|
||||||
|
@ -102,31 +106,31 @@ func compileTemplates() error {
|
||||||
log.Print("Compiling the templates")
|
log.Print("Compiling the templates")
|
||||||
|
|
||||||
var now = time.Now()
|
var now = time.Now()
|
||||||
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, relativeTime(now), now, relativeTime(now), 0, "", "127.0.0.1", 0, 1, "classname", "weird-data", buildProfileURL("fake-user", 62), "Fake User", config.DefaultGroup, "", 0, "", "", "", "", "", 58, false}
|
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, RelativeTime(now), now, RelativeTime(now), 0, "", "127.0.0.1", 0, 1, "classname", "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, "", 0, "", "", "", "", "", 58, false}
|
||||||
var replyList []ReplyUser
|
var replyList []ReplyUser
|
||||||
replyList = append(replyList, ReplyUser{0, 0, "Yo!", "Yo!", 0, "alice", "Alice", config.DefaultGroup, now, relativeTime(now), 0, 0, "", "", 0, "", "", "", "", 0, "127.0.0.1", false, 1, "", ""})
|
replyList = append(replyList, ReplyUser{0, 0, "Yo!", "Yo!", 0, "alice", "Alice", Config.DefaultGroup, now, RelativeTime(now), 0, 0, "", "", 0, "", "", "", "", 0, "127.0.0.1", false, 1, "", ""})
|
||||||
|
|
||||||
var varList = make(map[string]VarItem)
|
var varList = make(map[string]tmpl.VarItem)
|
||||||
tpage := TopicPage{"Title", user, headerVars, replyList, topic, 1, 1}
|
tpage := TopicPage{"Title", user, headerVars, replyList, topic, 1, 1}
|
||||||
topicIDTmpl, err := c.compileTemplate("topic.html", "templates/", "TopicPage", tpage, varList)
|
topicIDTmpl, err := c.Compile("topic.html", "templates/", "TopicPage", tpage, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
topicIDAltTmpl, err := c.compileTemplate("topic_alt.html", "templates/", "TopicPage", tpage, varList)
|
topicIDAltTmpl, err := c.Compile("topic_alt.html", "templates/", "TopicPage", tpage, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
varList = make(map[string]VarItem)
|
varList = make(map[string]tmpl.VarItem)
|
||||||
ppage := ProfilePage{"User 526", user, headerVars, replyList, user}
|
ppage := ProfilePage{"User 526", user, headerVars, replyList, user}
|
||||||
profileTmpl, err := c.compileTemplate("profile.html", "templates/", "ProfilePage", ppage, varList)
|
profileTmpl, err := c.Compile("profile.html", "templates/", "ProfilePage", ppage, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use a dummy forum list to avoid o(n) problems
|
// TODO: Use a dummy forum list to avoid o(n) problems
|
||||||
var forumList []Forum
|
var forumList []Forum
|
||||||
forums, err := fstore.GetAll()
|
forums, err := Fstore.GetAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -135,17 +139,17 @@ func compileTemplates() error {
|
||||||
//log.Printf("*forum %+v\n", *forum)
|
//log.Printf("*forum %+v\n", *forum)
|
||||||
forumList = append(forumList, *forum)
|
forumList = append(forumList, *forum)
|
||||||
}
|
}
|
||||||
varList = make(map[string]VarItem)
|
varList = make(map[string]tmpl.VarItem)
|
||||||
forumsPage := ForumsPage{"Forum List", user, headerVars, forumList}
|
forumsPage := ForumsPage{"Forum List", user, headerVars, forumList}
|
||||||
forumsTmpl, err := c.compileTemplate("forums.html", "templates/", "ForumsPage", forumsPage, varList)
|
forumsTmpl, err := c.Compile("forums.html", "templates/", "ForumsPage", forumsPage, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var topicsList []*TopicsRow
|
var topicsList []*TopicsRow
|
||||||
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, "Date", time.Now(), "Date", user3.ID, 1, "", "127.0.0.1", 0, 1, "classname", "", &user2, "", 0, &user3, "General", "/forum/general.2"})
|
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, "Date", time.Now(), "Date", user3.ID, 1, "", "127.0.0.1", 0, 1, "classname", "", &user2, "", 0, &user3, "General", "/forum/general.2"})
|
||||||
topicsPage := TopicsPage{"Topic List", user, headerVars, topicsList, forumList, config.DefaultForum}
|
topicsPage := TopicsPage{"Topic List", user, headerVars, topicsList, forumList, Config.DefaultForum}
|
||||||
topicsTmpl, err := c.compileTemplate("topics.html", "templates/", "TopicsPage", topicsPage, varList)
|
topicsTmpl, err := c.Compile("topics.html", "templates/", "TopicsPage", topicsPage, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -154,20 +158,20 @@ func compileTemplates() error {
|
||||||
//topicList = append(topicList,TopicUser{1,"topic-title","Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,1,"classname","","admin-fred","Admin Fred",config.DefaultGroup,"",0,"","","","",58,false})
|
//topicList = append(topicList,TopicUser{1,"topic-title","Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,1,"classname","","admin-fred","Admin Fred",config.DefaultGroup,"",0,"","","","",58,false})
|
||||||
forumItem := makeDummyForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0)
|
forumItem := makeDummyForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0)
|
||||||
forumPage := ForumPage{"General Forum", user, headerVars, topicsList, forumItem, 1, 1}
|
forumPage := ForumPage{"General Forum", user, headerVars, topicsList, forumItem, 1, 1}
|
||||||
forumTmpl, err := c.compileTemplate("forum.html", "templates/", "ForumPage", forumPage, varList)
|
forumTmpl, err := c.Compile("forum.html", "templates/", "ForumPage", forumPage, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let plugins register their own templates
|
// Let plugins register their own templates
|
||||||
for _, tmplfunc := range prebuildTmplList {
|
for _, tmplfunc := range PrebuildTmplList {
|
||||||
tmpl := tmplfunc(user, headerVars)
|
tmplItem := tmplfunc(user, headerVars)
|
||||||
varList = make(map[string]VarItem)
|
varList = make(map[string]tmpl.VarItem)
|
||||||
compiledTmpl, err := c.compileTemplate(tmpl.Filename, tmpl.Path, tmpl.StructName, tmpl.Data, varList)
|
compiledTmpl, err := c.Compile(tmplItem.Filename, tmplItem.Path, tmplItem.StructName, tmplItem.Data, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go writeTemplate(tmpl.Name, compiledTmpl)
|
go writeTemplate(tmplItem.Name, compiledTmpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Writing the templates")
|
log.Print("Writing the templates")
|
||||||
|
@ -194,8 +198,8 @@ func writeTemplate(name string, content string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initTemplates() {
|
func InitTemplates() {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Initialising the template system")
|
log.Print("Initialising the template system")
|
||||||
}
|
}
|
||||||
compileTemplates()
|
compileTemplates()
|
||||||
|
@ -259,10 +263,10 @@ func initTemplates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The interpreted templates...
|
// The interpreted templates...
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Loading the template files...")
|
log.Print("Loading the template files...")
|
||||||
}
|
}
|
||||||
templates.Funcs(fmap)
|
Templates.Funcs(fmap)
|
||||||
template.Must(templates.ParseGlob("templates/*"))
|
template.Must(Templates.ParseGlob("templates/*"))
|
||||||
template.Must(templates.ParseGlob("pages/*"))
|
template.Must(Templates.ParseGlob("pages/*"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package tmpl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -14,8 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Turn this file into a library
|
// TODO: Turn this file into a library
|
||||||
var ctemplates []string
|
var cTemplates []string
|
||||||
var tmplPtrMap = make(map[string]interface{})
|
|
||||||
var textOverlapList = make(map[string]int)
|
var textOverlapList = make(map[string]int)
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
|
@ -47,11 +46,26 @@ type CTemplateSet struct {
|
||||||
nextNode parse.NodeType
|
nextNode parse.NodeType
|
||||||
//tempVars map[string]string
|
//tempVars map[string]string
|
||||||
doImports bool
|
doImports bool
|
||||||
|
minify bool
|
||||||
|
debug bool
|
||||||
|
superDebug bool
|
||||||
expectsInt interface{}
|
expectsInt interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CTemplateSet) compileTemplate(name string, dir string, expects string, expectsInt interface{}, varList map[string]VarItem) (out string, err error) {
|
func (c *CTemplateSet) Minify(on bool) {
|
||||||
if dev.DebugMode {
|
c.minify = on
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CTemplateSet) Debug(on bool) {
|
||||||
|
c.debug = on
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CTemplateSet) SuperDebug(on bool) {
|
||||||
|
c.superDebug = on
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CTemplateSet) Compile(name string, dir string, expects string, expectsInt interface{}, varList map[string]VarItem) (out string, err error) {
|
||||||
|
if c.debug {
|
||||||
fmt.Println("Compiling template '" + name + "'")
|
fmt.Println("Compiling template '" + name + "'")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +89,7 @@ func (c *CTemplateSet) compileTemplate(name string, dir string, expects string,
|
||||||
|
|
||||||
c.importMap = map[string]string{
|
c.importMap = map[string]string{
|
||||||
"net/http": "net/http",
|
"net/http": "net/http",
|
||||||
|
"./common": "./common",
|
||||||
}
|
}
|
||||||
c.varList = varList
|
c.varList = varList
|
||||||
//c.pVarList = ""
|
//c.pVarList = ""
|
||||||
|
@ -89,7 +104,7 @@ func (c *CTemplateSet) compileTemplate(name string, dir string, expects string,
|
||||||
}
|
}
|
||||||
|
|
||||||
content := string(res)
|
content := string(res)
|
||||||
if config.MinifyTemplates {
|
if c.minify {
|
||||||
content = minify(content)
|
content = minify(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +148,7 @@ func (c *CTemplateSet) compileTemplate(name string, dir string, expects string,
|
||||||
|
|
||||||
fout := "// +build !no_templategen\n\n// Code generated by Gosora. More below:\n/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */\n"
|
fout := "// +build !no_templategen\n\n// Code generated by Gosora. More below:\n/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */\n"
|
||||||
fout += "package main\n" + importList + c.pVarList + "\n"
|
fout += "package main\n" + importList + c.pVarList + "\n"
|
||||||
fout += "// nolint\nfunc init() {\n\ttemplate_" + fname + "_handle = template_" + fname + "\n\t//o_template_" + fname + "_handle = template_" + fname + "\n\tctemplates = append(ctemplates,\"" + fname + "\")\n\ttmplPtrMap[\"" + fname + "\"] = &template_" + fname + "_handle\n\ttmplPtrMap[\"o_" + fname + "\"] = template_" + fname + "\n}\n\n"
|
fout += "// nolint\nfunc init() {\n\ttemplate_" + fname + "_handle = template_" + fname + "\n\t//o_template_" + fname + "_handle = template_" + fname + "\n\tctemplates = append(ctemplates,\"" + fname + "\")\n\tTmplPtrMap[\"" + fname + "\"] = &template_" + fname + "_handle\n\tcommon.TmplPtrMap[\"o_" + fname + "\"] = template_" + fname + "\n}\n\n"
|
||||||
fout += "// nolint\nfunc template_" + fname + "(tmpl_" + fname + "_vars " + expects + ", w http.ResponseWriter) error {\n" + varString + out + "\treturn nil\n}\n"
|
fout += "// nolint\nfunc template_" + fname + "(tmpl_" + fname + "_vars " + expects + ", w http.ResponseWriter) error {\n" + varString + out + "\treturn nil\n}\n"
|
||||||
|
|
||||||
fout = strings.Replace(fout, `))
|
fout = strings.Replace(fout, `))
|
||||||
|
@ -143,7 +158,7 @@ w.Write([]byte(`, " + ", -1)
|
||||||
//whitespaceWrites := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`)
|
//whitespaceWrites := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`)
|
||||||
//fout = whitespaceWrites.ReplaceAllString(fout,"")
|
//fout = whitespaceWrites.ReplaceAllString(fout,"")
|
||||||
|
|
||||||
if dev.DebugMode {
|
if c.debug {
|
||||||
for index, count := range c.stats {
|
for index, count := range c.stats {
|
||||||
fmt.Println(index+": ", strconv.Itoa(count))
|
fmt.Println(index+": ", strconv.Itoa(count))
|
||||||
}
|
}
|
||||||
|
@ -160,9 +175,7 @@ func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdrefle
|
||||||
c.log(tree.Root)
|
c.log(tree.Root)
|
||||||
treeLength := len(tree.Root.Nodes)
|
treeLength := len(tree.Root.Nodes)
|
||||||
for index, node := range tree.Root.Nodes {
|
for index, node := range tree.Root.Nodes {
|
||||||
if dev.TemplateDebug {
|
c.log("Node:", node.String())
|
||||||
fmt.Println("Node:", node.String())
|
|
||||||
}
|
|
||||||
c.previousNode = c.currentNode
|
c.previousNode = c.currentNode
|
||||||
c.currentNode = node.Type()
|
c.currentNode = node.Type()
|
||||||
if treeLength != (index + 1) {
|
if treeLength != (index + 1) {
|
||||||
|
@ -245,9 +258,7 @@ func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Va
|
||||||
|
|
||||||
var outVal reflect.Value
|
var outVal reflect.Value
|
||||||
for _, cmd := range node.Pipe.Cmds {
|
for _, cmd := range node.Pipe.Cmds {
|
||||||
if dev.TemplateDebug {
|
c.log("Range Bit:", cmd)
|
||||||
fmt.Println("Range Bit:", cmd)
|
|
||||||
}
|
|
||||||
out, outVal = c.compileReflectSwitch(varholder, holdreflect, templateName, cmd)
|
out, outVal = c.compileReflectSwitch(varholder, holdreflect, templateName, cmd)
|
||||||
}
|
}
|
||||||
c.log("Returned:", out)
|
c.log("Returned:", out)
|
||||||
|
@ -259,7 +270,7 @@ func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Va
|
||||||
for _, key := range outVal.MapKeys() {
|
for _, key := range outVal.MapKeys() {
|
||||||
item = outVal.MapIndex(key)
|
item = outVal.MapIndex(key)
|
||||||
}
|
}
|
||||||
if dev.DebugMode {
|
if c.debug {
|
||||||
fmt.Println("Range item:", item)
|
fmt.Println("Range item:", item)
|
||||||
}
|
}
|
||||||
if !item.IsValid() {
|
if !item.IsValid() {
|
||||||
|
@ -317,11 +328,11 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cur.IsValid() {
|
if !cur.IsValid() {
|
||||||
if dev.DebugMode {
|
if c.debug {
|
||||||
fmt.Println("Debug Data:")
|
fmt.Println("Debug Data:")
|
||||||
fmt.Println("Holdreflect:", holdreflect)
|
fmt.Println("Holdreflect:", holdreflect)
|
||||||
fmt.Println("Holdreflect.Kind():", holdreflect.Kind())
|
fmt.Println("Holdreflect.Kind():", holdreflect.Kind())
|
||||||
if !dev.TemplateDebug {
|
if !c.superDebug {
|
||||||
fmt.Println("cur.Kind():", cur.Kind().String())
|
fmt.Println("cur.Kind():", cur.Kind().String())
|
||||||
}
|
}
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
@ -382,7 +393,7 @@ func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Va
|
||||||
firstWord := node.Args[0]
|
firstWord := node.Args[0]
|
||||||
switch n := firstWord.(type) {
|
switch n := firstWord.(type) {
|
||||||
case *parse.FieldNode:
|
case *parse.FieldNode:
|
||||||
if dev.TemplateDebug {
|
if c.superDebug {
|
||||||
fmt.Println("Field Node:", n.Ident)
|
fmt.Println("Field Node:", n.Ident)
|
||||||
for _, id := range n.Ident {
|
for _, id := range n.Ident {
|
||||||
fmt.Println("Field Bit:", id)
|
fmt.Println("Field Bit:", id)
|
||||||
|
@ -564,7 +575,7 @@ func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflec
|
||||||
firstWord := node.Args[0]
|
firstWord := node.Args[0]
|
||||||
switch n := firstWord.(type) {
|
switch n := firstWord.(type) {
|
||||||
case *parse.FieldNode:
|
case *parse.FieldNode:
|
||||||
if dev.TemplateDebug {
|
if c.superDebug {
|
||||||
fmt.Println("Field Node:", n.Ident)
|
fmt.Println("Field Node:", n.Ident)
|
||||||
for _, id := range n.Ident {
|
for _, id := range n.Ident {
|
||||||
fmt.Println("Field Bit:", id)
|
fmt.Println("Field Bit:", id)
|
||||||
|
@ -771,7 +782,7 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec
|
||||||
}
|
}
|
||||||
|
|
||||||
content := string(res)
|
content := string(res)
|
||||||
if config.MinifyTemplates {
|
if c.minify {
|
||||||
content = minify(content)
|
content = minify(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,7 +806,7 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CTemplateSet) log(args ...interface{}) {
|
func (c *CTemplateSet) log(args ...interface{}) {
|
||||||
if dev.TemplateDebug {
|
if c.superDebug {
|
||||||
fmt.Println(args...)
|
fmt.Println(args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,13 +17,15 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ThemeList map[string]Theme
|
type ThemeList map[string]Theme
|
||||||
|
|
||||||
//var themes ThemeList = make(map[string]Theme)
|
var Themes ThemeList = make(map[string]Theme)
|
||||||
var DefaultThemeBox atomic.Value
|
var DefaultThemeBox atomic.Value
|
||||||
var changeDefaultThemeMutex sync.Mutex
|
var ChangeDefaultThemeMutex sync.Mutex
|
||||||
|
|
||||||
// TODO: Use this when the default theme doesn't exist
|
// TODO: Use this when the default theme doesn't exist
|
||||||
var fallbackTheme = "shadow"
|
var fallbackTheme = "shadow"
|
||||||
|
@ -73,14 +75,19 @@ type ThemeResource struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
defaultThemeBox.Store(fallbackTheme)
|
DefaultThemeBox.Store(fallbackTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make the initThemes and LoadThemes functions less confusing
|
// TODO: Make the initThemes and LoadThemes functions less confusing
|
||||||
// ? - Delete themes which no longer exist in the themes folder from the database?
|
// ? - Delete themes which no longer exist in the themes folder from the database?
|
||||||
func LoadThemeActiveStatus() error {
|
func (themes ThemeList) LoadActiveStatus() error {
|
||||||
changeDefaultThemeMutex.Lock()
|
getThemes, err := qgen.Builder.SimpleSelect("themes", "uname, default", "", "", "")
|
||||||
rows, err := stmts.getThemes.Query()
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeDefaultThemeMutex.Lock()
|
||||||
|
rows, err := getThemes.Query()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -103,8 +110,8 @@ func LoadThemeActiveStatus() error {
|
||||||
if defaultThemeSwitch {
|
if defaultThemeSwitch {
|
||||||
log.Print("Loading the default theme '" + theme.Name + "'")
|
log.Print("Loading the default theme '" + theme.Name + "'")
|
||||||
theme.Active = true
|
theme.Active = true
|
||||||
defaultThemeBox.Store(theme.Name)
|
DefaultThemeBox.Store(theme.Name)
|
||||||
mapThemeTemplates(theme)
|
MapThemeTemplates(theme)
|
||||||
} else {
|
} else {
|
||||||
log.Print("Loading the theme '" + theme.Name + "'")
|
log.Print("Loading the theme '" + theme.Name + "'")
|
||||||
theme.Active = false
|
theme.Active = false
|
||||||
|
@ -112,11 +119,11 @@ func LoadThemeActiveStatus() error {
|
||||||
|
|
||||||
themes[uname] = theme
|
themes[uname] = theme
|
||||||
}
|
}
|
||||||
changeDefaultThemeMutex.Unlock()
|
ChangeDefaultThemeMutex.Unlock()
|
||||||
return rows.Err()
|
return rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initThemes() error {
|
func InitThemes() error {
|
||||||
themeFiles, err := ioutil.ReadDir("./themes")
|
themeFiles, err := ioutil.ReadDir("./themes")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -156,10 +163,10 @@ func initThemes() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if theme.FullImage != "" {
|
if theme.FullImage != "" {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Adding theme image")
|
log.Print("Adding theme image")
|
||||||
}
|
}
|
||||||
err = addStaticFile("./themes/"+themeName+"/"+theme.FullImage, "./themes/"+themeName)
|
err = StaticFiles.Add("./themes/"+themeName+"/"+theme.FullImage, "./themes/"+themeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -170,7 +177,7 @@ func initThemes() error {
|
||||||
if theme.Templates != nil {
|
if theme.Templates != nil {
|
||||||
for _, themeTmpl := range theme.Templates {
|
for _, themeTmpl := range theme.Templates {
|
||||||
theme.TemplatesMap[themeTmpl.Name] = themeTmpl.Source
|
theme.TemplatesMap[themeTmpl.Name] = themeTmpl.Source
|
||||||
theme.TmplPtr[themeTmpl.Name] = tmplPtrMap["o_"+themeTmpl.Source]
|
theme.TmplPtr[themeTmpl.Name] = TmplPtrMap["o_"+themeTmpl.Source]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,20 +185,20 @@ func initThemes() error {
|
||||||
template.Must(theme.ResourceTemplates.ParseGlob("./themes/" + theme.Name + "/public/*.css"))
|
template.Must(theme.ResourceTemplates.ParseGlob("./themes/" + theme.Name + "/public/*.css"))
|
||||||
|
|
||||||
// It should be safe for us to load the files for all the themes in memory, as-long as the admin hasn't setup a ridiculous number of themes
|
// It should be safe for us to load the files for all the themes in memory, as-long as the admin hasn't setup a ridiculous number of themes
|
||||||
err = addThemeStaticFiles(theme)
|
err = AddThemeStaticFiles(theme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
themes[theme.Name] = theme
|
Themes[theme.Name] = theme
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addThemeStaticFiles(theme Theme) error {
|
func AddThemeStaticFiles(theme Theme) error {
|
||||||
// TODO: Use a function instead of a closure to make this more testable? What about a function call inside the closure to take the theme variable into account?
|
// TODO: Use a function instead of a closure to make this more testable? What about a function call inside the closure to take the theme variable into account?
|
||||||
return filepath.Walk("./themes/"+theme.Name+"/public", func(path string, f os.FileInfo, err error) error {
|
return filepath.Walk("./themes/"+theme.Name+"/public", func(path string, f os.FileInfo, err error) error {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Attempting to add static file '" + path + "' for default theme '" + theme.Name + "'")
|
log.Print("Attempting to add static file '" + path + "' for default theme '" + theme.Name + "'")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -224,16 +231,16 @@ func addThemeStaticFiles(theme Theme) error {
|
||||||
|
|
||||||
path = strings.TrimPrefix(path, "themes/"+theme.Name+"/public")
|
path = strings.TrimPrefix(path, "themes/"+theme.Name+"/public")
|
||||||
gzipData := compressBytesGzip(data)
|
gzipData := compressBytesGzip(data)
|
||||||
staticFiles["/static/"+theme.Name+path] = SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}
|
StaticFiles["/static/"+theme.Name+path] = SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}
|
||||||
|
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".")
|
log.Print("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapThemeTemplates(theme Theme) {
|
func MapThemeTemplates(theme Theme) {
|
||||||
if theme.Templates != nil {
|
if theme.Templates != nil {
|
||||||
for _, themeTmpl := range theme.Templates {
|
for _, themeTmpl := range theme.Templates {
|
||||||
if themeTmpl.Name == "" {
|
if themeTmpl.Name == "" {
|
||||||
|
@ -245,11 +252,11 @@ func mapThemeTemplates(theme Theme) {
|
||||||
|
|
||||||
// `go generate` is one possibility for letting plugins inject custom page structs, but it would simply add another step of compilation. It might be simpler than the current build process from the perspective of the administrator?
|
// `go generate` is one possibility for letting plugins inject custom page structs, but it would simply add another step of compilation. It might be simpler than the current build process from the perspective of the administrator?
|
||||||
|
|
||||||
destTmplPtr, ok := tmplPtrMap[themeTmpl.Name]
|
destTmplPtr, ok := TmplPtrMap[themeTmpl.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sourceTmplPtr, ok := tmplPtrMap[themeTmpl.Source]
|
sourceTmplPtr, ok := TmplPtrMap[themeTmpl.Source]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Fatal("The source template doesn't exist!")
|
log.Fatal("The source template doesn't exist!")
|
||||||
}
|
}
|
||||||
|
@ -325,20 +332,20 @@ func mapThemeTemplates(theme Theme) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetTemplateOverrides() {
|
func ResetTemplateOverrides() {
|
||||||
log.Print("Resetting the template overrides")
|
log.Print("Resetting the template overrides")
|
||||||
|
|
||||||
for name := range overridenTemplates {
|
for name := range overridenTemplates {
|
||||||
log.Print("Resetting '" + name + "' template override")
|
log.Print("Resetting '" + name + "' template override")
|
||||||
|
|
||||||
originPointer, ok := tmplPtrMap["o_"+name]
|
originPointer, ok := TmplPtrMap["o_"+name]
|
||||||
if !ok {
|
if !ok {
|
||||||
//log.Fatal("The origin template doesn't exist!")
|
//log.Fatal("The origin template doesn't exist!")
|
||||||
log.Print("The origin template doesn't exist!")
|
log.Print("The origin template doesn't exist!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
destTmplPtr, ok := tmplPtrMap[name]
|
destTmplPtr, ok := TmplPtrMap[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
//log.Fatal("The destination template doesn't exist!")
|
//log.Fatal("The destination template doesn't exist!")
|
||||||
log.Print("The destination template doesn't exist!")
|
log.Print("The destination template doesn't exist!")
|
||||||
|
@ -447,11 +454,11 @@ func RunThemeTemplate(theme string, template string, pi interface{}, w http.Resp
|
||||||
case func(Page, http.ResponseWriter) error:
|
case func(Page, http.ResponseWriter) error:
|
||||||
return tmplO(pi.(Page), w)
|
return tmplO(pi.(Page), w)
|
||||||
case string:
|
case string:
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap[template]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap[template]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = template
|
mapping = template
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
default:
|
default:
|
||||||
log.Print("theme ", theme)
|
log.Print("theme ", theme)
|
||||||
log.Print("template ", template)
|
log.Print("template ", template)
|
||||||
|
@ -474,11 +481,11 @@ func RunThemeTemplate(theme string, template string, pi interface{}, w http.Resp
|
||||||
|
|
||||||
// GetThemeTemplate attempts to get the template for a specific theme, otherwise it falls back on the default template pointer, which if absent will fallback onto the template interpreter
|
// GetThemeTemplate attempts to get the template for a specific theme, otherwise it falls back on the default template pointer, which if absent will fallback onto the template interpreter
|
||||||
func GetThemeTemplate(theme string, template string) interface{} {
|
func GetThemeTemplate(theme string, template string) interface{} {
|
||||||
tmpl, ok := themes[theme].TmplPtr[template]
|
tmpl, ok := Themes[theme].TmplPtr[template]
|
||||||
if ok {
|
if ok {
|
||||||
return tmpl
|
return tmpl
|
||||||
}
|
}
|
||||||
tmpl, ok = tmplPtrMap[template]
|
tmpl, ok = TmplPtrMap[template]
|
||||||
if ok {
|
if ok {
|
||||||
return tmpl
|
return tmpl
|
||||||
}
|
}
|
||||||
|
@ -487,19 +494,19 @@ func GetThemeTemplate(theme string, template string) interface{} {
|
||||||
|
|
||||||
// CreateThemeTemplate creates a theme template on the current default theme
|
// CreateThemeTemplate creates a theme template on the current default theme
|
||||||
func CreateThemeTemplate(theme string, name string) {
|
func CreateThemeTemplate(theme string, name string) {
|
||||||
themes[theme].TmplPtr[name] = func(pi Page, w http.ResponseWriter) error {
|
Themes[theme].TmplPtr[name] = func(pi Page, w http.ResponseWriter) error {
|
||||||
mapping, ok := themes[defaultThemeBox.Load().(string)].TemplatesMap[name]
|
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
mapping = name
|
mapping = name
|
||||||
}
|
}
|
||||||
return templates.ExecuteTemplate(w, mapping+".html", pi)
|
return Templates.ExecuteTemplate(w, mapping+".html", pi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDefaultThemeName() string {
|
func GetDefaultThemeName() string {
|
||||||
return defaultThemeBox.Load().(string)
|
return DefaultThemeBox.Load().(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetDefaultThemeName(name string) {
|
func SetDefaultThemeName(name string) {
|
||||||
defaultThemeBox.Store(name)
|
DefaultThemeBox.Store(name)
|
||||||
}
|
}
|
||||||
|
|
116
common/topic.go
116
common/topic.go
|
@ -6,12 +6,14 @@
|
||||||
*/
|
*/
|
||||||
package common
|
package common
|
||||||
|
|
||||||
//import "fmt"
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"html"
|
"html"
|
||||||
"html/template"
|
"html/template"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is also in reply.go
|
// This is also in reply.go
|
||||||
|
@ -105,10 +107,49 @@ type TopicsRow struct {
|
||||||
ForumLink string
|
ForumLink string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TopicStmts struct {
|
||||||
|
addRepliesToTopic *sql.Stmt
|
||||||
|
lock *sql.Stmt
|
||||||
|
unlock *sql.Stmt
|
||||||
|
stick *sql.Stmt
|
||||||
|
unstick *sql.Stmt
|
||||||
|
hasLikedTopic *sql.Stmt
|
||||||
|
createLike *sql.Stmt
|
||||||
|
addLikesToTopic *sql.Stmt
|
||||||
|
delete *sql.Stmt
|
||||||
|
edit *sql.Stmt
|
||||||
|
createActionReply *sql.Stmt
|
||||||
|
|
||||||
|
getTopicUser *sql.Stmt // TODO: Can we get rid of this?
|
||||||
|
}
|
||||||
|
|
||||||
|
var topicStmts TopicStmts
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
DbInits.Add(func() error {
|
||||||
|
acc := qgen.Builder.Accumulator()
|
||||||
|
topicStmts = TopicStmts{
|
||||||
|
addRepliesToTopic: acc.SimpleUpdate("topics", "postCount = postCount + ?, lastReplyBy = ?, lastReplyAt = UTC_TIMESTAMP()", "tid = ?"),
|
||||||
|
lock: acc.SimpleUpdate("topics", "is_closed = 1", "tid = ?"),
|
||||||
|
unlock: acc.SimpleUpdate("topics", "is_closed = 0", "tid = ?"),
|
||||||
|
stick: acc.SimpleUpdate("topics", "sticky = 1", "tid = ?"),
|
||||||
|
unstick: acc.SimpleUpdate("topics", "sticky = 0", "tid = ?"),
|
||||||
|
hasLikedTopic: acc.SimpleSelect("likes", "targetItem", "sentBy = ? and targetItem = ? and targetType = 'topics'", "", ""),
|
||||||
|
createLike: acc.SimpleInsert("likes", "weight, targetItem, targetType, sentBy", "?,?,?,?"),
|
||||||
|
addLikesToTopic: acc.SimpleUpdate("topics", "likeCount = likeCount + ?", "tid = ?"),
|
||||||
|
delete: acc.SimpleDelete("topics", "tid = ?"),
|
||||||
|
edit: acc.SimpleUpdate("topics", "title = ?, content = ?, parsed_content = ?", "tid = ?"),
|
||||||
|
createActionReply: acc.SimpleInsert("replies", "tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''"),
|
||||||
|
getTopicUser: acc.SimpleLeftJoin("topics", "users", "topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level", "topics.createdBy = users.uid", "tid = ?", "", ""),
|
||||||
|
}
|
||||||
|
return acc.FirstError()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Flush the topic out of the cache
|
// Flush the topic out of the cache
|
||||||
// ? - We do a CacheRemove() here instead of mutating the pointer to avoid creating a race condition
|
// ? - We do a CacheRemove() here instead of mutating the pointer to avoid creating a race condition
|
||||||
func (topic *Topic) cacheRemove() {
|
func (topic *Topic) cacheRemove() {
|
||||||
tcache, ok := topics.(TopicCache)
|
tcache, ok := Topics.(TopicCache)
|
||||||
if ok {
|
if ok {
|
||||||
tcache.CacheRemove(topic.ID)
|
tcache.CacheRemove(topic.ID)
|
||||||
}
|
}
|
||||||
|
@ -116,32 +157,32 @@ func (topic *Topic) cacheRemove() {
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func (topic *Topic) AddReply(uid int) (err error) {
|
func (topic *Topic) AddReply(uid int) (err error) {
|
||||||
_, err = stmts.addRepliesToTopic.Exec(1, uid, topic.ID)
|
_, err = topicStmts.addRepliesToTopic.Exec(1, uid, topic.ID)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topic *Topic) Lock() (err error) {
|
func (topic *Topic) Lock() (err error) {
|
||||||
_, err = stmts.lockTopic.Exec(topic.ID)
|
_, err = topicStmts.lock.Exec(topic.ID)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topic *Topic) Unlock() (err error) {
|
func (topic *Topic) Unlock() (err error) {
|
||||||
_, err = stmts.unlockTopic.Exec(topic.ID)
|
_, err = topicStmts.unlock.Exec(topic.ID)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We might want more consistent terminology rather than using stick in some places and pin in others. If you don't understand the difference, there is none, they are one and the same.
|
// TODO: We might want more consistent terminology rather than using stick in some places and pin in others. If you don't understand the difference, there is none, they are one and the same.
|
||||||
func (topic *Topic) Stick() (err error) {
|
func (topic *Topic) Stick() (err error) {
|
||||||
_, err = stmts.stickTopic.Exec(topic.ID)
|
_, err = topicStmts.stick.Exec(topic.ID)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topic *Topic) Unstick() (err error) {
|
func (topic *Topic) Unstick() (err error) {
|
||||||
_, err = stmts.unstickTopic.Exec(topic.ID)
|
_, err = topicStmts.unstick.Exec(topic.ID)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -150,19 +191,19 @@ func (topic *Topic) Unstick() (err error) {
|
||||||
// TODO: Use a transaction for this
|
// TODO: Use a transaction for this
|
||||||
func (topic *Topic) Like(score int, uid int) (err error) {
|
func (topic *Topic) Like(score int, uid int) (err error) {
|
||||||
var tid int // Unused
|
var tid int // Unused
|
||||||
err = stmts.hasLikedTopic.QueryRow(uid, topic.ID).Scan(&tid)
|
err = topicStmts.hasLikedTopic.QueryRow(uid, topic.ID).Scan(&tid)
|
||||||
if err != nil && err != ErrNoRows {
|
if err != nil && err != ErrNoRows {
|
||||||
return err
|
return err
|
||||||
} else if err != ErrNoRows {
|
} else if err != ErrNoRows {
|
||||||
return ErrAlreadyLiked
|
return ErrAlreadyLiked
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmts.createLike.Exec(score, tid, "topics", uid)
|
_, err = topicStmts.createLike.Exec(score, tid, "topics", uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmts.addLikesToTopic.Exec(1, tid)
|
_, err = topicStmts.addLikesToTopic.Exec(1, tid)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -174,10 +215,10 @@ func (topic *Topic) Unlike(uid int) error {
|
||||||
|
|
||||||
// TODO: Use a transaction here
|
// TODO: Use a transaction here
|
||||||
func (topic *Topic) Delete() error {
|
func (topic *Topic) Delete() error {
|
||||||
topicCreator, err := users.Get(topic.CreatedBy)
|
topicCreator, err := Users.Get(topic.CreatedBy)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
wcount := wordCount(topic.Content)
|
wcount := WordCount(topic.Content)
|
||||||
err = topicCreator.decreasePostStats(wcount, true)
|
err = topicCreator.DecreasePostStats(wcount, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -185,31 +226,31 @@ func (topic *Topic) Delete() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fstore.RemoveTopic(topic.ParentID)
|
err = Fstore.RemoveTopic(topic.ParentID)
|
||||||
if err != nil && err != ErrNoRows {
|
if err != nil && err != ErrNoRows {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmts.deleteTopic.Exec(topic.ID)
|
_, err = topicStmts.delete.Exec(topic.ID)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topic *Topic) Update(name string, content string) error {
|
func (topic *Topic) Update(name string, content string) error {
|
||||||
content = preparseMessage(content)
|
content = PreparseMessage(content)
|
||||||
parsed_content := parseMessage(html.EscapeString(content), topic.ParentID, "forums")
|
parsedContent := ParseMessage(html.EscapeString(content), topic.ParentID, "forums")
|
||||||
|
_, err := topicStmts.edit.Exec(name, content, parsedContent, topic.ID)
|
||||||
_, err := stmts.editTopic.Exec(name, content, parsed_content, topic.ID)
|
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Have this go through the ReplyStore?
|
||||||
func (topic *Topic) CreateActionReply(action string, ipaddress string, user User) (err error) {
|
func (topic *Topic) CreateActionReply(action string, ipaddress string, user User) (err error) {
|
||||||
_, err = stmts.createActionReply.Exec(topic.ID, action, ipaddress, user.ID)
|
_, err = topicStmts.createActionReply.Exec(topic.ID, action, ipaddress, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = stmts.addRepliesToTopic.Exec(1, user.ID, topic.ID)
|
_, err = topicStmts.addRepliesToTopic.Exec(1, user.ID, topic.ID)
|
||||||
topic.cacheRemove()
|
topic.cacheRemove()
|
||||||
// ? - Update the last topic cache for the parent forum?
|
// ? - Update the last topic cache for the parent forum?
|
||||||
return err
|
return err
|
||||||
|
@ -221,13 +262,13 @@ func (topic *Topic) Copy() Topic {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor the caller to take a Topic and a User rather than a combined TopicUser
|
// TODO: Refactor the caller to take a Topic and a User rather than a combined TopicUser
|
||||||
func getTopicUser(tid int) (TopicUser, error) {
|
func GetTopicUser(tid int) (TopicUser, error) {
|
||||||
tcache, tok := topics.(TopicCache)
|
tcache, tok := Topics.(TopicCache)
|
||||||
ucache, uok := users.(UserCache)
|
ucache, uok := Users.(UserCache)
|
||||||
if tok && uok {
|
if tok && uok {
|
||||||
topic, err := tcache.CacheGet(tid)
|
topic, err := tcache.CacheGet(tid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user, err := users.Get(topic.CreatedBy)
|
user, err := Users.Get(topic.CreatedBy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return TopicUser{ID: tid}, err
|
return TopicUser{ID: tid}, err
|
||||||
}
|
}
|
||||||
|
@ -235,11 +276,11 @@ func getTopicUser(tid int) (TopicUser, error) {
|
||||||
// We might be better off just passing separate topic and user structs to the caller?
|
// We might be better off just passing separate topic and user structs to the caller?
|
||||||
return copyTopicToTopicUser(topic, user), nil
|
return copyTopicToTopicUser(topic, user), nil
|
||||||
} else if ucache.Length() < ucache.GetCapacity() {
|
} else if ucache.Length() < ucache.GetCapacity() {
|
||||||
topic, err = topics.Get(tid)
|
topic, err = Topics.Get(tid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return TopicUser{ID: tid}, err
|
return TopicUser{ID: tid}, err
|
||||||
}
|
}
|
||||||
user, err := users.Get(topic.CreatedBy)
|
user, err := Users.Get(topic.CreatedBy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return TopicUser{ID: tid}, err
|
return TopicUser{ID: tid}, err
|
||||||
}
|
}
|
||||||
|
@ -248,14 +289,14 @@ func getTopicUser(tid int) (TopicUser, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tu := TopicUser{ID: tid}
|
tu := TopicUser{ID: tid}
|
||||||
err := stmts.getTopicUser.QueryRow(tid).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.IsClosed, &tu.Sticky, &tu.ParentID, &tu.IPAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
|
err := topicStmts.getTopicUser.QueryRow(tid).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.IsClosed, &tu.Sticky, &tu.ParentID, &tu.IPAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
|
||||||
tu.Link = buildTopicURL(nameToSlug(tu.Title), tu.ID)
|
tu.Link = BuildTopicURL(NameToSlug(tu.Title), tu.ID)
|
||||||
tu.UserLink = buildProfileURL(nameToSlug(tu.CreatedByName), tu.CreatedBy)
|
tu.UserLink = BuildProfileURL(NameToSlug(tu.CreatedByName), tu.CreatedBy)
|
||||||
tu.Tag = gstore.DirtyGet(tu.Group).Tag
|
tu.Tag = Gstore.DirtyGet(tu.Group).Tag
|
||||||
|
|
||||||
if tok {
|
if tok {
|
||||||
theTopic := Topic{ID: tu.ID, Link: tu.Link, Title: tu.Title, Content: tu.Content, CreatedBy: tu.CreatedBy, IsClosed: tu.IsClosed, Sticky: tu.Sticky, CreatedAt: tu.CreatedAt, LastReplyAt: tu.LastReplyAt, ParentID: tu.ParentID, IPAddress: tu.IPAddress, PostCount: tu.PostCount, LikeCount: tu.LikeCount}
|
theTopic := Topic{ID: tu.ID, Link: tu.Link, Title: tu.Title, Content: tu.Content, CreatedBy: tu.CreatedBy, IsClosed: tu.IsClosed, Sticky: tu.Sticky, CreatedAt: tu.CreatedAt, LastReplyAt: tu.LastReplyAt, ParentID: tu.ParentID, IPAddress: tu.IPAddress, PostCount: tu.PostCount, LikeCount: tu.LikeCount}
|
||||||
//log.Printf("the_topic: %+v\n", theTopic)
|
//log.Printf("theTopic: %+v\n", theTopic)
|
||||||
_ = tcache.CacheAdd(&theTopic)
|
_ = tcache.CacheAdd(&theTopic)
|
||||||
}
|
}
|
||||||
return tu, err
|
return tu, err
|
||||||
|
@ -289,18 +330,11 @@ func copyTopicToTopicUser(topic *Topic, user *User) (tu TopicUser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use in tests and for generating blank topics for forums which don't have a last poster
|
// For use in tests and for generating blank topics for forums which don't have a last poster
|
||||||
func getDummyTopic() *Topic {
|
func BlankTopic() *Topic {
|
||||||
return &Topic{ID: 0, Title: ""}
|
return &Topic{ID: 0, Title: ""}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTopicByReply(rid int) (*Topic, error) {
|
func BuildTopicURL(slug string, tid int) string {
|
||||||
topic := Topic{ID: 0}
|
|
||||||
err := stmts.getTopicByReply.QueryRow(rid).Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
||||||
topic.Link = buildTopicURL(nameToSlug(topic.Title), topic.ID)
|
|
||||||
return &topic, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildTopicURL(slug string, tid int) string {
|
|
||||||
if slug == "" {
|
if slug == "" {
|
||||||
return "/topic/" + strconv.Itoa(tid)
|
return "/topic/" + strconv.Itoa(tid)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,12 @@ import (
|
||||||
// TODO: Add BulkGetMap
|
// TODO: Add BulkGetMap
|
||||||
// TODO: Add some sort of update method
|
// TODO: Add some sort of update method
|
||||||
// ? - Should we add stick, lock, unstick, and unlock methods? These might be better on the Topics not the TopicStore
|
// ? - Should we add stick, lock, unstick, and unlock methods? These might be better on the Topics not the TopicStore
|
||||||
var topics TopicStore
|
var Topics TopicStore
|
||||||
var ErrNoTitle = errors.New("This message is missing a title")
|
var ErrNoTitle = errors.New("This message is missing a title")
|
||||||
var ErrNoBody = errors.New("This message is missing a body")
|
var ErrNoBody = errors.New("This message is missing a body")
|
||||||
|
|
||||||
type TopicStore interface {
|
type TopicStore interface {
|
||||||
|
DirtyGet(id int) *Topic
|
||||||
Get(id int) (*Topic, error)
|
Get(id int) (*Topic, error)
|
||||||
BypassGet(id int) (*Topic, error)
|
BypassGet(id int) (*Topic, error)
|
||||||
Exists(id int) bool
|
Exists(id int) bool
|
||||||
|
@ -93,6 +94,24 @@ func (mts *MemoryTopicStore) CacheGetUnsafe(id int) (*Topic, error) {
|
||||||
return item, ErrNoRows
|
return item, ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mts *MemoryTopicStore) DirtyGet(id int) *Topic {
|
||||||
|
mts.RLock()
|
||||||
|
topic, ok := mts.items[id]
|
||||||
|
mts.RUnlock()
|
||||||
|
if ok {
|
||||||
|
return topic
|
||||||
|
}
|
||||||
|
|
||||||
|
topic = &Topic{ID: id}
|
||||||
|
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
|
if err == nil {
|
||||||
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||||
|
_ = mts.CacheAdd(topic)
|
||||||
|
return topic
|
||||||
|
}
|
||||||
|
return BlankTopic()
|
||||||
|
}
|
||||||
|
|
||||||
func (mts *MemoryTopicStore) Get(id int) (*Topic, error) {
|
func (mts *MemoryTopicStore) Get(id int) (*Topic, error) {
|
||||||
mts.RLock()
|
mts.RLock()
|
||||||
topic, ok := mts.items[id]
|
topic, ok := mts.items[id]
|
||||||
|
@ -104,7 +123,7 @@ func (mts *MemoryTopicStore) Get(id int) (*Topic, error) {
|
||||||
topic = &Topic{ID: id}
|
topic = &Topic{ID: id}
|
||||||
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||||
_ = mts.CacheAdd(topic)
|
_ = mts.CacheAdd(topic)
|
||||||
}
|
}
|
||||||
return topic, err
|
return topic, err
|
||||||
|
@ -114,7 +133,7 @@ func (mts *MemoryTopicStore) Get(id int) (*Topic, error) {
|
||||||
func (mts *MemoryTopicStore) BypassGet(id int) (*Topic, error) {
|
func (mts *MemoryTopicStore) BypassGet(id int) (*Topic, error) {
|
||||||
topic := &Topic{ID: id}
|
topic := &Topic{ID: id}
|
||||||
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||||
return topic, err
|
return topic, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +141,7 @@ func (mts *MemoryTopicStore) Reload(id int) error {
|
||||||
topic := &Topic{ID: id}
|
topic := &Topic{ID: id}
|
||||||
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||||
_ = mts.CacheSet(topic)
|
_ = mts.CacheSet(topic)
|
||||||
} else {
|
} else {
|
||||||
_ = mts.CacheRemove(id)
|
_ = mts.CacheRemove(id)
|
||||||
|
@ -141,12 +160,12 @@ func (mts *MemoryTopicStore) Create(fid int, topicName string, content string, u
|
||||||
}
|
}
|
||||||
|
|
||||||
content = strings.TrimSpace(content)
|
content = strings.TrimSpace(content)
|
||||||
parsedContent := parseMessage(content, fid, "forums")
|
parsedContent := ParseMessage(content, fid, "forums")
|
||||||
if strings.TrimSpace(parsedContent) == "" {
|
if strings.TrimSpace(parsedContent) == "" {
|
||||||
return 0, ErrNoBody
|
return 0, ErrNoBody
|
||||||
}
|
}
|
||||||
|
|
||||||
wcount := wordCount(content)
|
wcount := WordCount(content)
|
||||||
// TODO: Move this statement into the topic store
|
// TODO: Move this statement into the topic store
|
||||||
res, err := mts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
|
res, err := mts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -158,8 +177,7 @@ func (mts *MemoryTopicStore) Create(fid int, topicName string, content string, u
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fstore.AddTopic(int(lastID), uid, fid)
|
return int(lastID), Fstore.AddTopic(int(lastID), uid, fid)
|
||||||
return int(lastID), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mts *MemoryTopicStore) CacheSet(item *Topic) error {
|
func (mts *MemoryTopicStore) CacheSet(item *Topic) error {
|
||||||
|
@ -268,10 +286,20 @@ func NewSQLTopicStore() (*SQLTopicStore, error) {
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sts *SQLTopicStore) DirtyGet(id int) *Topic {
|
||||||
|
topic := &Topic{ID: id}
|
||||||
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||||
|
if err != nil {
|
||||||
|
return BlankTopic()
|
||||||
|
}
|
||||||
|
return topic
|
||||||
|
}
|
||||||
|
|
||||||
func (sts *SQLTopicStore) Get(id int) (*Topic, error) {
|
func (sts *SQLTopicStore) Get(id int) (*Topic, error) {
|
||||||
topic := Topic{ID: id}
|
topic := Topic{ID: id}
|
||||||
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||||
return &topic, err
|
return &topic, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +307,7 @@ func (sts *SQLTopicStore) Get(id int) (*Topic, error) {
|
||||||
func (sts *SQLTopicStore) BypassGet(id int) (*Topic, error) {
|
func (sts *SQLTopicStore) BypassGet(id int) (*Topic, error) {
|
||||||
topic := &Topic{ID: id}
|
topic := &Topic{ID: id}
|
||||||
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||||
return topic, err
|
return topic, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,12 +322,12 @@ func (sts *SQLTopicStore) Create(fid int, topicName string, content string, uid
|
||||||
}
|
}
|
||||||
|
|
||||||
content = strings.TrimSpace(content)
|
content = strings.TrimSpace(content)
|
||||||
parsedContent := parseMessage(content, fid, "forums")
|
parsedContent := ParseMessage(content, fid, "forums")
|
||||||
if strings.TrimSpace(parsedContent) == "" {
|
if strings.TrimSpace(parsedContent) == "" {
|
||||||
return 0, ErrNoBody
|
return 0, ErrNoBody
|
||||||
}
|
}
|
||||||
|
|
||||||
wcount := wordCount(content)
|
wcount := WordCount(content)
|
||||||
// TODO: Move this statement into the topic store
|
// TODO: Move this statement into the topic store
|
||||||
res, err := sts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
|
res, err := sts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -311,8 +339,7 @@ func (sts *SQLTopicStore) Create(fid int, topicName string, content string, uid
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fstore.AddTopic(int(lastID), uid, fid)
|
return int(lastID), Fstore.AddTopic(int(lastID), uid, fid)
|
||||||
return int(lastID), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? - What're we going to do about this?
|
// ? - What're we going to do about this?
|
||||||
|
|
183
common/user.go
183
common/user.go
|
@ -15,12 +15,14 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Replace any literals with this
|
// TODO: Replace any literals with this
|
||||||
var BanGroup = 4
|
var BanGroup = 4
|
||||||
|
|
||||||
|
// GuestUser is an instance of user which holds guest data to avoid having to initialise a guest every time
|
||||||
var GuestUser = User{ID: 0, Link: "#", Group: 6, Perms: GuestPerms}
|
var GuestUser = User{ID: 0, Link: "#", Group: 6, Perms: GuestPerms}
|
||||||
|
|
||||||
//func(real_password string, password string, salt string) (err error)
|
//func(real_password string, password string, salt string) (err error)
|
||||||
|
@ -57,12 +59,48 @@ type User struct {
|
||||||
TempGroup int
|
TempGroup int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Email struct {
|
type UserStmts struct {
|
||||||
UserID int
|
activate *sql.Stmt
|
||||||
Email string
|
changeGroup *sql.Stmt
|
||||||
Validated bool
|
delete *sql.Stmt
|
||||||
Primary bool
|
setAvatar *sql.Stmt
|
||||||
Token string
|
setUsername *sql.Stmt
|
||||||
|
updateGroup *sql.Stmt
|
||||||
|
incrementTopics *sql.Stmt
|
||||||
|
updateLevel *sql.Stmt
|
||||||
|
incrementScore *sql.Stmt
|
||||||
|
incrementPosts *sql.Stmt
|
||||||
|
incrementBigposts *sql.Stmt
|
||||||
|
incrementMegaposts *sql.Stmt
|
||||||
|
updateLastIP *sql.Stmt
|
||||||
|
|
||||||
|
setPassword *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
var userStmts UserStmts
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
DbInits.Add(func() error {
|
||||||
|
acc := qgen.Builder.Accumulator()
|
||||||
|
userStmts = UserStmts{
|
||||||
|
activate: acc.SimpleUpdate("users", "active = 1", "uid = ?"),
|
||||||
|
changeGroup: acc.SimpleUpdate("users", "group = ?", "uid = ?"),
|
||||||
|
delete: acc.SimpleDelete("users", "uid = ?"),
|
||||||
|
setAvatar: acc.SimpleUpdate("users", "avatar = ?", "uid = ?"),
|
||||||
|
setUsername: acc.SimpleUpdate("users", "name = ?", "uid = ?"),
|
||||||
|
updateGroup: acc.SimpleUpdate("users", "group = ?", "uid = ?"),
|
||||||
|
incrementTopics: acc.SimpleUpdate("users", "topics = topics + ?", "uid = ?"),
|
||||||
|
updateLevel: acc.SimpleUpdate("users", "level = ?", "uid = ?"),
|
||||||
|
incrementScore: acc.SimpleUpdate("users", "score = score + ?", "uid = ?"),
|
||||||
|
incrementPosts: acc.SimpleUpdate("users", "posts = posts + ?", "uid = ?"),
|
||||||
|
incrementBigposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?", "uid = ?"),
|
||||||
|
incrementMegaposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?", "uid = ?"),
|
||||||
|
updateLastIP: acc.SimpleUpdate("users", "last_ip = ?", "uid = ?"),
|
||||||
|
|
||||||
|
setPassword: acc.SimpleUpdate("users", "password = ?, salt = ?", "uid = ?"),
|
||||||
|
}
|
||||||
|
return acc.FirstError()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Init() {
|
func (user *User) Init() {
|
||||||
|
@ -71,15 +109,22 @@ func (user *User) Init() {
|
||||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
user.Avatar = strings.Replace(config.Noavatar, "{id}", strconv.Itoa(user.ID), 1)
|
user.Avatar = strings.Replace(Config.Noavatar, "{id}", strconv.Itoa(user.ID), 1)
|
||||||
|
}
|
||||||
|
user.Link = BuildProfileURL(NameToSlug(user.Name), user.ID)
|
||||||
|
user.Tag = Gstore.DirtyGet(user.Group).Tag
|
||||||
|
user.InitPerms()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (user *User) CacheRemove() {
|
||||||
|
ucache, ok := Users.(UserCache)
|
||||||
|
if ok {
|
||||||
|
ucache.CacheRemove(user.ID)
|
||||||
}
|
}
|
||||||
user.Link = buildProfileURL(nameToSlug(user.Name), user.ID)
|
|
||||||
user.Tag = gstore.DirtyGet(user.Group).Tag
|
|
||||||
user.initPerms()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Ban(duration time.Duration, issuedBy int) error {
|
func (user *User) Ban(duration time.Duration, issuedBy int) error {
|
||||||
return user.ScheduleGroupUpdate(banGroup, issuedBy, duration)
|
return user.ScheduleGroupUpdate(BanGroup, issuedBy, duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Unban() error {
|
func (user *User) Unban() error {
|
||||||
|
@ -112,7 +157,7 @@ func (user *User) ScheduleGroupUpdate(gid int, issuedBy int, duration time.Durat
|
||||||
}
|
}
|
||||||
revertAt := time.Now().Add(duration)
|
revertAt := time.Now().Add(duration)
|
||||||
|
|
||||||
tx, err := db.Begin()
|
tx, err := qgen.Builder.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -138,15 +183,12 @@ func (user *User) ScheduleGroupUpdate(gid int, issuedBy int, duration time.Durat
|
||||||
}
|
}
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
|
|
||||||
ucache, ok := users.(UserCache)
|
user.CacheRemove()
|
||||||
if ok {
|
|
||||||
ucache.CacheRemove(user.ID)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) RevertGroupUpdate() error {
|
func (user *User) RevertGroupUpdate() error {
|
||||||
tx, err := db.Begin()
|
tx, err := qgen.Builder.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -163,25 +205,19 @@ func (user *User) RevertGroupUpdate() error {
|
||||||
}
|
}
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
|
|
||||||
ucache, ok := users.(UserCache)
|
user.CacheRemove()
|
||||||
if ok {
|
|
||||||
ucache.CacheRemove(user.ID)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use a transaction here
|
// TODO: Use a transaction here
|
||||||
// ? - Add a Deactivate method? Not really needed, if someone's been bad you could do a ban, I guess it might be useful, if someone says that email x isn't actually owned by the user in question?
|
// ? - Add a Deactivate method? Not really needed, if someone's been bad you could do a ban, I guess it might be useful, if someone says that email x isn't actually owned by the user in question?
|
||||||
func (user *User) Activate() (err error) {
|
func (user *User) Activate() (err error) {
|
||||||
_, err = stmts.activateUser.Exec(user.ID)
|
_, err = userStmts.activate.Exec(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = stmts.changeGroup.Exec(config.DefaultGroup, user.ID)
|
_, err = userStmts.changeGroup.Exec(Config.DefaultGroup, user.ID)
|
||||||
ucache, ok := users.(UserCache)
|
user.CacheRemove()
|
||||||
if ok {
|
|
||||||
ucache.CacheRemove(user.ID)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,111 +225,105 @@ func (user *User) Activate() (err error) {
|
||||||
// TODO: Delete this user's content too?
|
// TODO: Delete this user's content too?
|
||||||
// TODO: Expose this to the admin?
|
// TODO: Expose this to the admin?
|
||||||
func (user *User) Delete() error {
|
func (user *User) Delete() error {
|
||||||
_, err := stmts.deleteUser.Exec(user.ID)
|
_, err := userStmts.delete.Exec(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ucache, ok := users.(UserCache)
|
user.CacheRemove()
|
||||||
if ok {
|
|
||||||
ucache.CacheRemove(user.ID)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) ChangeName(username string) (err error) {
|
func (user *User) ChangeName(username string) (err error) {
|
||||||
_, err = stmts.setUsername.Exec(username, user.ID)
|
_, err = userStmts.setUsername.Exec(username, user.ID)
|
||||||
ucache, ok := users.(UserCache)
|
user.CacheRemove()
|
||||||
if ok {
|
|
||||||
ucache.CacheRemove(user.ID)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) ChangeAvatar(avatar string) (err error) {
|
func (user *User) ChangeAvatar(avatar string) (err error) {
|
||||||
_, err = stmts.setAvatar.Exec(avatar, user.ID)
|
_, err = userStmts.setAvatar.Exec(avatar, user.ID)
|
||||||
ucache, ok := users.(UserCache)
|
user.CacheRemove()
|
||||||
if ok {
|
|
||||||
ucache.CacheRemove(user.ID)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) ChangeGroup(group int) (err error) {
|
func (user *User) ChangeGroup(group int) (err error) {
|
||||||
_, err = stmts.updateUserGroup.Exec(group, user.ID)
|
_, err = userStmts.updateGroup.Exec(group, user.ID)
|
||||||
ucache, ok := users.(UserCache)
|
user.CacheRemove()
|
||||||
if ok {
|
|
||||||
ucache.CacheRemove(user.ID)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) increasePostStats(wcount int, topic bool) (err error) {
|
// ! Only updates the database not the *User for safety reasons
|
||||||
|
func (user *User) UpdateIP(host string) error {
|
||||||
|
_, err := userStmts.updateLastIP.Exec(host, user.ID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (user *User) IncreasePostStats(wcount int, topic bool) (err error) {
|
||||||
var mod int
|
var mod int
|
||||||
baseScore := 1
|
baseScore := 1
|
||||||
if topic {
|
if topic {
|
||||||
_, err = stmts.incrementUserTopics.Exec(1, user.ID)
|
_, err = userStmts.incrementTopics.Exec(1, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
baseScore = 2
|
baseScore = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
settings := settingBox.Load().(SettingBox)
|
settings := SettingBox.Load().(SettingMap)
|
||||||
if wcount >= settings["megapost_min_words"].(int) {
|
if wcount >= settings["megapost_min_words"].(int) {
|
||||||
_, err = stmts.incrementUserMegaposts.Exec(1, 1, 1, user.ID)
|
_, err = userStmts.incrementMegaposts.Exec(1, 1, 1, user.ID)
|
||||||
mod = 4
|
mod = 4
|
||||||
} else if wcount >= settings["bigpost_min_words"].(int) {
|
} else if wcount >= settings["bigpost_min_words"].(int) {
|
||||||
_, err = stmts.incrementUserBigposts.Exec(1, 1, user.ID)
|
_, err = userStmts.incrementBigposts.Exec(1, 1, user.ID)
|
||||||
mod = 1
|
mod = 1
|
||||||
} else {
|
} else {
|
||||||
_, err = stmts.incrementUserPosts.Exec(1, user.ID)
|
_, err = userStmts.incrementPosts.Exec(1, user.ID)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmts.incrementUserScore.Exec(baseScore+mod, user.ID)
|
_, err = userStmts.incrementScore.Exec(baseScore+mod, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//log.Print(user.Score + base_score + mod)
|
//log.Print(user.Score + base_score + mod)
|
||||||
//log.Print(getLevel(user.Score + base_score + mod))
|
//log.Print(getLevel(user.Score + base_score + mod))
|
||||||
// TODO: Use a transaction to prevent level desyncs?
|
// TODO: Use a transaction to prevent level desyncs?
|
||||||
_, err = stmts.updateUserLevel.Exec(getLevel(user.Score+baseScore+mod), user.ID)
|
_, err = userStmts.updateLevel.Exec(GetLevel(user.Score+baseScore+mod), user.ID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) decreasePostStats(wcount int, topic bool) (err error) {
|
func (user *User) DecreasePostStats(wcount int, topic bool) (err error) {
|
||||||
var mod int
|
var mod int
|
||||||
baseScore := -1
|
baseScore := -1
|
||||||
if topic {
|
if topic {
|
||||||
_, err = stmts.incrementUserTopics.Exec(-1, user.ID)
|
_, err = userStmts.incrementTopics.Exec(-1, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
baseScore = -2
|
baseScore = -2
|
||||||
}
|
}
|
||||||
|
|
||||||
settings := settingBox.Load().(SettingBox)
|
settings := SettingBox.Load().(SettingMap)
|
||||||
if wcount >= settings["megapost_min_words"].(int) {
|
if wcount >= settings["megapost_min_words"].(int) {
|
||||||
_, err = stmts.incrementUserMegaposts.Exec(-1, -1, -1, user.ID)
|
_, err = userStmts.incrementMegaposts.Exec(-1, -1, -1, user.ID)
|
||||||
mod = 4
|
mod = 4
|
||||||
} else if wcount >= settings["bigpost_min_words"].(int) {
|
} else if wcount >= settings["bigpost_min_words"].(int) {
|
||||||
_, err = stmts.incrementUserBigposts.Exec(-1, -1, user.ID)
|
_, err = userStmts.incrementBigposts.Exec(-1, -1, user.ID)
|
||||||
mod = 1
|
mod = 1
|
||||||
} else {
|
} else {
|
||||||
_, err = stmts.incrementUserPosts.Exec(-1, user.ID)
|
_, err = userStmts.incrementPosts.Exec(-1, user.ID)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmts.incrementUserScore.Exec(baseScore-mod, user.ID)
|
_, err = userStmts.incrementScore.Exec(baseScore-mod, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// TODO: Use a transaction to prevent level desyncs?
|
// TODO: Use a transaction to prevent level desyncs?
|
||||||
_, err = stmts.updateUserLevel.Exec(getLevel(user.Score-baseScore-mod), user.ID)
|
_, err = userStmts.updateLevel.Exec(GetLevel(user.Score-baseScore-mod), user.ID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,12 +333,12 @@ func (user *User) Copy() User {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write unit tests for this
|
// TODO: Write unit tests for this
|
||||||
func (user *User) initPerms() {
|
func (user *User) InitPerms() {
|
||||||
if user.TempGroup != 0 {
|
if user.TempGroup != 0 {
|
||||||
user.Group = user.TempGroup
|
user.Group = user.TempGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
group := gstore.DirtyGet(user.Group)
|
group := Gstore.DirtyGet(user.Group)
|
||||||
if user.IsSuperAdmin {
|
if user.IsSuperAdmin {
|
||||||
user.Perms = AllPerms
|
user.Perms = AllPerms
|
||||||
user.PluginPerms = AllPluginPerms
|
user.PluginPerms = AllPluginPerms
|
||||||
|
@ -332,7 +362,7 @@ func BcryptCheckPassword(realPassword string, password string, salt string) (err
|
||||||
|
|
||||||
// Investigate. Do we need the extra salt?
|
// Investigate. Do we need the extra salt?
|
||||||
func BcryptGeneratePassword(password string) (hashedPassword string, salt string, err error) {
|
func BcryptGeneratePassword(password string) (hashedPassword string, salt string, err error) {
|
||||||
salt, err = GenerateSafeString(saltLength)
|
salt, err = GenerateSafeString(SaltLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
@ -353,27 +383,16 @@ func BcryptGeneratePasswordNoSalt(password string) (hash string, err error) {
|
||||||
return string(hashedPassword), nil
|
return string(hashedPassword), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move this to *User
|
||||||
func SetPassword(uid int, password string) error {
|
func SetPassword(uid int, password string) error {
|
||||||
hashedPassword, salt, err := GeneratePassword(password)
|
hashedPassword, salt, err := GeneratePassword(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = stmts.setPassword.Exec(hashedPassword, salt, uid)
|
_, err = userStmts.setPassword.Exec(hashedPassword, salt, uid)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendValidationEmail(username string, email string, token string) bool {
|
|
||||||
var schema = "http"
|
|
||||||
if site.EnableSsl {
|
|
||||||
schema += "s"
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Move these to the phrase system
|
|
||||||
subject := "Validate Your Email @ " + site.Name
|
|
||||||
msg := "Dear " + username + ", following your registration on our forums, we ask you to validate your email, so that we can confirm that this email actually belongs to you.\n\nClick on the following link to do so. " + schema + "://" + site.URL + "/user/edit/token/" + token + "\n\nIf you haven't created an account here, then please feel free to ignore this email.\nWe're sorry for the inconvenience this may have caused."
|
|
||||||
return SendEmail(email, subject, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Write units tests for this
|
// TODO: Write units tests for this
|
||||||
func wordsToScore(wcount int, topic bool) (score int) {
|
func wordsToScore(wcount int, topic bool) (score int) {
|
||||||
if topic {
|
if topic {
|
||||||
|
@ -382,7 +401,7 @@ func wordsToScore(wcount int, topic bool) (score int) {
|
||||||
score = 1
|
score = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
settings := settingBox.Load().(SettingBox)
|
settings := SettingBox.Load().(SettingMap)
|
||||||
if wcount >= settings["megapost_min_words"].(int) {
|
if wcount >= settings["megapost_min_words"].(int) {
|
||||||
score += 4
|
score += 4
|
||||||
} else if wcount >= settings["bigpost_min_words"].(int) {
|
} else if wcount >= settings["bigpost_min_words"].(int) {
|
||||||
|
@ -392,12 +411,12 @@ func wordsToScore(wcount int, topic bool) (score int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use in tests and to help generate dummy users for forums which don't have last posters
|
// For use in tests and to help generate dummy users for forums which don't have last posters
|
||||||
func getDummyUser() *User {
|
func BlankUser() *User {
|
||||||
return &User{ID: 0, Name: ""}
|
return &User{ID: 0, Name: ""}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write unit tests for this
|
// TODO: Write unit tests for this
|
||||||
func buildProfileURL(slug string, uid int) string {
|
func BuildProfileURL(slug string, uid int) string {
|
||||||
if slug == "" {
|
if slug == "" {
|
||||||
return "/user/" + strconv.Itoa(uid)
|
return "/user/" + strconv.Itoa(uid)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,17 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add the watchdog goroutine
|
// TODO: Add the watchdog goroutine
|
||||||
// TODO: Add some sort of update method
|
// TODO: Add some sort of update method
|
||||||
var users UserStore
|
var Users UserStore
|
||||||
var errAccountExists = errors.New("this username is already in use")
|
var ErrAccountExists = errors.New("this username is already in use")
|
||||||
|
|
||||||
type UserStore interface {
|
type UserStore interface {
|
||||||
|
DirtyGet(id int) *User
|
||||||
Get(id int) (*User, error)
|
Get(id int) (*User, error)
|
||||||
Exists(id int) bool
|
Exists(id int) bool
|
||||||
//BulkGet(ids []int) ([]*User, error)
|
//BulkGet(ids []int) ([]*User, error)
|
||||||
|
@ -86,6 +88,25 @@ func (mus *MemoryUserStore) CacheGetUnsafe(id int) (*User, error) {
|
||||||
return item, ErrNoRows
|
return item, ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mus *MemoryUserStore) DirtyGet(id int) *User {
|
||||||
|
mus.RLock()
|
||||||
|
user, ok := mus.items[id]
|
||||||
|
mus.RUnlock()
|
||||||
|
if ok {
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
user = &User{ID: id, Loggedin: true}
|
||||||
|
err := mus.get.QueryRow(id).Scan(&user.Name, &user.Group, &user.IsSuperAdmin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.LastIP, &user.TempGroup)
|
||||||
|
|
||||||
|
user.Init()
|
||||||
|
if err == nil {
|
||||||
|
mus.CacheSet(user)
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
return BlankUser()
|
||||||
|
}
|
||||||
|
|
||||||
func (mus *MemoryUserStore) Get(id int) (*User, error) {
|
func (mus *MemoryUserStore) Get(id int) (*User, error) {
|
||||||
mus.RLock()
|
mus.RLock()
|
||||||
user, ok := mus.items[id]
|
user, ok := mus.items[id]
|
||||||
|
@ -188,7 +209,7 @@ func (mus *MemoryUserStore) BulkGetMap(ids []int) (list map[int]*User, err error
|
||||||
|
|
||||||
// We probably don't need this, but it might be useful in case of bugs in BulkCascadeGetMap
|
// We probably don't need this, but it might be useful in case of bugs in BulkCascadeGetMap
|
||||||
if sidList == "" {
|
if sidList == "" {
|
||||||
if dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
|
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
|
||||||
log.Print("idCount", idCount)
|
log.Print("idCount", idCount)
|
||||||
log.Print("ids", ids)
|
log.Print("ids", ids)
|
||||||
|
@ -298,10 +319,10 @@ func (mus *MemoryUserStore) Create(username string, password string, email strin
|
||||||
// Is this username already taken..?
|
// Is this username already taken..?
|
||||||
err := mus.usernameExists.QueryRow(username).Scan(&username)
|
err := mus.usernameExists.QueryRow(username).Scan(&username)
|
||||||
if err != ErrNoRows {
|
if err != ErrNoRows {
|
||||||
return 0, errAccountExists
|
return 0, ErrAccountExists
|
||||||
}
|
}
|
||||||
|
|
||||||
salt, err := GenerateSafeString(saltLength)
|
salt, err := GenerateSafeString(SaltLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -370,6 +391,17 @@ func NewSQLUserStore() (*SQLUserStore, error) {
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mus *SQLUserStore) DirtyGet(id int) *User {
|
||||||
|
user := &User{ID: id, Loggedin: true}
|
||||||
|
err := mus.get.QueryRow(id).Scan(&user.Name, &user.Group, &user.IsSuperAdmin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.LastIP, &user.TempGroup)
|
||||||
|
|
||||||
|
user.Init()
|
||||||
|
if err != nil {
|
||||||
|
return BlankUser()
|
||||||
|
}
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
func (mus *SQLUserStore) Get(id int) (*User, error) {
|
func (mus *SQLUserStore) Get(id int) (*User, error) {
|
||||||
user := &User{ID: id, Loggedin: true}
|
user := &User{ID: id, Loggedin: true}
|
||||||
err := mus.get.QueryRow(id).Scan(&user.Name, &user.Group, &user.IsSuperAdmin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.LastIP, &user.TempGroup)
|
err := mus.get.QueryRow(id).Scan(&user.Name, &user.Group, &user.IsSuperAdmin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.LastIP, &user.TempGroup)
|
||||||
|
@ -436,10 +468,10 @@ func (mus *SQLUserStore) Create(username string, password string, email string,
|
||||||
// Is this username already taken..?
|
// Is this username already taken..?
|
||||||
err := mus.usernameExists.QueryRow(username).Scan(&username)
|
err := mus.usernameExists.QueryRow(username).Scan(&username)
|
||||||
if err != ErrNoRows {
|
if err != ErrNoRows {
|
||||||
return 0, errAccountExists
|
return 0, ErrAccountExists
|
||||||
}
|
}
|
||||||
|
|
||||||
salt, err := GenerateSafeString(saltLength)
|
salt, err := GenerateSafeString(SaltLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
127
common/utils.go
127
common/utils.go
|
@ -12,12 +12,13 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"net/smtp"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version stores a Gosora version
|
// Version stores a Gosora version
|
||||||
|
@ -53,7 +54,7 @@ func GenerateSafeString(length int) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func relativeTimeFromString(in string) (string, error) {
|
func RelativeTimeFromString(in string) (string, error) {
|
||||||
if in == "" {
|
if in == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
@ -63,11 +64,11 @@ func relativeTimeFromString(in string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return relativeTime(t), nil
|
return RelativeTime(t), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func relativeTime(t time.Time) string {
|
func RelativeTime(t time.Time) string {
|
||||||
diff := time.Since(t)
|
diff := time.Since(t)
|
||||||
hours := diff.Hours()
|
hours := diff.Hours()
|
||||||
seconds := diff.Seconds()
|
seconds := diff.Seconds()
|
||||||
|
@ -105,36 +106,36 @@ func relativeTime(t time.Time) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func convertByteUnit(bytes float64) (float64, string) {
|
func ConvertByteUnit(bytes float64) (float64, string) {
|
||||||
switch {
|
switch {
|
||||||
case bytes >= float64(petabyte):
|
case bytes >= float64(Petabyte):
|
||||||
return bytes / float64(petabyte), "PB"
|
return bytes / float64(Petabyte), "PB"
|
||||||
case bytes >= float64(terabyte):
|
case bytes >= float64(Terabyte):
|
||||||
return bytes / float64(terabyte), "TB"
|
return bytes / float64(Terabyte), "TB"
|
||||||
case bytes >= float64(gigabyte):
|
case bytes >= float64(Gigabyte):
|
||||||
return bytes / float64(gigabyte), "GB"
|
return bytes / float64(Gigabyte), "GB"
|
||||||
case bytes >= float64(megabyte):
|
case bytes >= float64(Megabyte):
|
||||||
return bytes / float64(megabyte), "MB"
|
return bytes / float64(Megabyte), "MB"
|
||||||
case bytes >= float64(kilobyte):
|
case bytes >= float64(Kilobyte):
|
||||||
return bytes / float64(kilobyte), "KB"
|
return bytes / float64(Kilobyte), "KB"
|
||||||
default:
|
default:
|
||||||
return bytes, " bytes"
|
return bytes, " bytes"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func convertByteInUnit(bytes float64, unit string) (count float64) {
|
func ConvertByteInUnit(bytes float64, unit string) (count float64) {
|
||||||
switch unit {
|
switch unit {
|
||||||
case "PB":
|
case "PB":
|
||||||
count = bytes / float64(petabyte)
|
count = bytes / float64(Petabyte)
|
||||||
case "TB":
|
case "TB":
|
||||||
count = bytes / float64(terabyte)
|
count = bytes / float64(Terabyte)
|
||||||
case "GB":
|
case "GB":
|
||||||
count = bytes / float64(gigabyte)
|
count = bytes / float64(Gigabyte)
|
||||||
case "MB":
|
case "MB":
|
||||||
count = bytes / float64(megabyte)
|
count = bytes / float64(Megabyte)
|
||||||
case "KB":
|
case "KB":
|
||||||
count = bytes / float64(kilobyte)
|
count = bytes / float64(Kilobyte)
|
||||||
default:
|
default:
|
||||||
count = 0.1
|
count = 0.1
|
||||||
}
|
}
|
||||||
|
@ -146,7 +147,7 @@ func convertByteInUnit(bytes float64, unit string) (count float64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func convertUnit(num int) (int, string) {
|
func ConvertUnit(num int) (int, string) {
|
||||||
switch {
|
switch {
|
||||||
case num >= 1000000000000:
|
case num >= 1000000000000:
|
||||||
return num / 1000000000000, "T"
|
return num / 1000000000000, "T"
|
||||||
|
@ -162,7 +163,7 @@ func convertUnit(num int) (int, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func convertFriendlyUnit(num int) (int, string) {
|
func ConvertFriendlyUnit(num int) (int, string) {
|
||||||
switch {
|
switch {
|
||||||
case num >= 1000000000000000:
|
case num >= 1000000000000000:
|
||||||
return 0, " quadrillion"
|
return 0, " quadrillion"
|
||||||
|
@ -179,7 +180,7 @@ func convertFriendlyUnit(num int) (int, string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func nameToSlug(name string) (slug string) {
|
func NameToSlug(name string) (slug string) {
|
||||||
name = strings.TrimSpace(name)
|
name = strings.TrimSpace(name)
|
||||||
name = strings.Replace(name, " ", " ", -1)
|
name = strings.Replace(name, " ", " ", -1)
|
||||||
|
|
||||||
|
@ -199,58 +200,8 @@ func nameToSlug(name string) (slug string) {
|
||||||
return slug
|
return slug
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this
|
|
||||||
func SendEmail(email string, subject string, msg string) bool {
|
|
||||||
// This hook is useful for plugin_sendmail or for testing tools. Possibly to hook it into some sort of mail server?
|
|
||||||
if vhooks["email_send_intercept"] != nil {
|
|
||||||
return vhooks["email_send_intercept"](email, subject, msg).(bool)
|
|
||||||
}
|
|
||||||
body := "Subject: " + subject + "\n\n" + msg + "\n"
|
|
||||||
|
|
||||||
con, err := smtp.Dial(config.SMTPServer + ":" + config.SMTPPort)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.SMTPUsername != "" {
|
|
||||||
auth := smtp.PlainAuth("", config.SMTPUsername, config.SMTPPassword, config.SMTPServer)
|
|
||||||
err = con.Auth(auth)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = con.Mail(site.Email)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
err = con.Rcpt(email)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
emailData, err := con.Data()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprintf(emailData, body)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
err = emailData.Close()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
err = con.Quit()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func weakPassword(password string) error {
|
func WeakPassword(password string) error {
|
||||||
if len(password) < 8 {
|
if len(password) < 8 {
|
||||||
return errors.New("your password needs to be at-least eight characters long")
|
return errors.New("your password needs to be at-least eight characters long")
|
||||||
}
|
}
|
||||||
|
@ -335,7 +286,7 @@ func Stripslashes(text string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func wordCount(input string) (count int) {
|
func WordCount(input string) (count int) {
|
||||||
input = strings.TrimSpace(input)
|
input = strings.TrimSpace(input)
|
||||||
if input == "" {
|
if input == "" {
|
||||||
return 0
|
return 0
|
||||||
|
@ -355,7 +306,7 @@ func wordCount(input string) (count int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func getLevel(score int) (level int) {
|
func GetLevel(score int) (level int) {
|
||||||
var base float64 = 25
|
var base float64 = 25
|
||||||
var current, prev float64
|
var current, prev float64
|
||||||
var expFactor = 2.8
|
var expFactor = 2.8
|
||||||
|
@ -376,7 +327,7 @@ func getLevel(score int) (level int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func getLevelScore(getLevel int) (score int) {
|
func GetLevelScore(getLevel int) (score int) {
|
||||||
var base float64 = 25
|
var base float64 = 25
|
||||||
var current, prev float64
|
var current, prev float64
|
||||||
var level int
|
var level int
|
||||||
|
@ -398,7 +349,7 @@ func getLevelScore(getLevel int) (score int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
func getLevels(maxLevel int) []float64 {
|
func GetLevels(maxLevel int) []float64 {
|
||||||
var base float64 = 25
|
var base float64 = 25
|
||||||
var current, prev float64 // = 0
|
var current, prev float64 // = 0
|
||||||
var expFactor = 2.8
|
var expFactor = 2.8
|
||||||
|
@ -417,7 +368,7 @@ func getLevels(maxLevel int) []float64 {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildSlug(slug string, id int) string {
|
func BuildSlug(slug string, id int) string {
|
||||||
if slug == "" {
|
if slug == "" {
|
||||||
return strconv.Itoa(id)
|
return strconv.Itoa(id)
|
||||||
}
|
}
|
||||||
|
@ -425,13 +376,21 @@ func buildSlug(slug string, id int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make a store for this?
|
// TODO: Make a store for this?
|
||||||
func addModLog(action string, elementID int, elementType string, ipaddress string, actorID int) (err error) {
|
func AddModLog(action string, elementID int, elementType string, ipaddress string, actorID int) (err error) {
|
||||||
_, err = stmts.addModlogEntry.Exec(action, elementID, elementType, ipaddress, actorID)
|
addModLogEntry, err := qgen.Builder.SimpleInsert("moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "?,?,?,?,?,UTC_TIMESTAMP()")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = addModLogEntry.Exec(action, elementID, elementType, ipaddress, actorID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make a store for this?
|
// TODO: Make a store for this?
|
||||||
func addAdminLog(action string, elementID string, elementType int, ipaddress string, actorID int) (err error) {
|
func AddAdminLog(action string, elementID string, elementType int, ipaddress string, actorID int) (err error) {
|
||||||
_, err = stmts.addAdminlogEntry.Exec(action, elementID, elementType, ipaddress, actorID)
|
addAdminLogEntry, err := qgen.Builder.SimpleInsert("administration_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "?,?,?,?,?,UTC_TIMESTAMP()")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = addAdminLogEntry.Exec(action, elementID, elementType, ipaddress, actorID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
/* Copyright Azareal 2017 - 2018 */
|
/* Copyright Azareal 2017 - 2018 */
|
||||||
package main
|
package common
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "bytes"
|
import "bytes"
|
||||||
import "sync"
|
import "sync"
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
|
import "../query_gen/lib"
|
||||||
|
|
||||||
//import "html/template"
|
var Docks WidgetDocks
|
||||||
|
|
||||||
var docks WidgetDocks
|
|
||||||
var widgetUpdateMutex sync.RWMutex
|
var widgetUpdateMutex sync.RWMutex
|
||||||
|
|
||||||
type WidgetDocks struct {
|
type WidgetDocks struct {
|
||||||
|
@ -41,8 +40,12 @@ type NameTextPair struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make a store for this?
|
// TODO: Make a store for this?
|
||||||
func initWidgets() error {
|
func InitWidgets() error {
|
||||||
rows, err := stmts.getWidgets.Query()
|
getWidgets, err := qgen.Builder.SimpleSelect("widgets", "position, side, type, active, location, data", "", "position ASC", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, err := getWidgets.Query()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -71,7 +74,7 @@ func initWidgets() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
err = templates.ExecuteTemplate(&b, "widget_simple.html", tmp)
|
err = Templates.ExecuteTemplate(&b, "widget_simple.html", tmp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -92,13 +95,13 @@ func initWidgets() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
widgetUpdateMutex.Lock()
|
widgetUpdateMutex.Lock()
|
||||||
docks.LeftSidebar = leftWidgets
|
Docks.LeftSidebar = leftWidgets
|
||||||
docks.RightSidebar = rightWidgets
|
Docks.RightSidebar = rightWidgets
|
||||||
widgetUpdateMutex.Unlock()
|
widgetUpdateMutex.Unlock()
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Print("docks.LeftSidebar", docks.LeftSidebar)
|
log.Print("Docks.LeftSidebar", Docks.LeftSidebar)
|
||||||
log.Print("docks.RightSidebar", docks.RightSidebar)
|
log.Print("Docks.RightSidebar", Docks.RightSidebar)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
|
@ -0,0 +1,50 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import "sync/atomic"
|
||||||
|
import "../query_gen/lib"
|
||||||
|
|
||||||
|
type WordFilter struct {
|
||||||
|
ID int
|
||||||
|
Find string
|
||||||
|
Replacement string
|
||||||
|
}
|
||||||
|
type WordFilterMap map[int]WordFilter
|
||||||
|
|
||||||
|
var WordFilterBox atomic.Value // An atomic value holding a WordFilterBox
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
WordFilterBox.Store(WordFilterMap(make(map[int]WordFilter)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadWordFilters() error {
|
||||||
|
getWordFilters, err := qgen.Builder.SimpleSelect("word_filters", "wfid, find, replacement", "", "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, err := getWordFilters.Query()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var wordFilters = WordFilterMap(make(map[int]WordFilter))
|
||||||
|
var wfid int
|
||||||
|
var find string
|
||||||
|
var replacement string
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&wfid, &find, &replacement)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
wordFilters[wfid] = WordFilter{ID: wfid, Find: find, Replacement: replacement}
|
||||||
|
}
|
||||||
|
WordFilterBox.Store(wordFilters)
|
||||||
|
return rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddWordFilter(id int, find string, replacement string) {
|
||||||
|
wordFilters := WordFilterBox.Load().(WordFilterMap)
|
||||||
|
wordFilters[id] = WordFilter{ID: id, Find: find, Replacement: replacement}
|
||||||
|
WordFilterBox.Store(wordFilters)
|
||||||
|
}
|
66
database.go
66
database.go
|
@ -1,8 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "log"
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
|
||||||
import "database/sql"
|
"./common"
|
||||||
|
)
|
||||||
|
|
||||||
var stmts *Stmts
|
var stmts *Stmts
|
||||||
|
|
||||||
|
@ -15,7 +18,7 @@ var ErrNoRows = sql.ErrNoRows
|
||||||
|
|
||||||
var _initDatabase func() error
|
var _initDatabase func() error
|
||||||
|
|
||||||
func initDatabase() (err error) {
|
func InitDatabase() (err error) {
|
||||||
stmts = &Stmts{Mocks: false}
|
stmts = &Stmts{Mocks: false}
|
||||||
|
|
||||||
// Engine specific code
|
// Engine specific code
|
||||||
|
@ -25,70 +28,69 @@ func initDatabase() (err error) {
|
||||||
}
|
}
|
||||||
globs = &Globs{stmts}
|
globs = &Globs{stmts}
|
||||||
|
|
||||||
log.Print("Loading the usergroups.")
|
err = common.DbInits.Run()
|
||||||
gstore, err = NewMemoryGroupStore()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = gstore.LoadGroups()
|
|
||||||
|
log.Print("Loading the usergroups.")
|
||||||
|
common.Gstore, err = common.NewMemoryGroupStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
err2 := common.Gstore.LoadGroups()
|
||||||
|
if err2 != nil {
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
// We have to put this here, otherwise LoadForums() won't be able to get the last poster data when building it's forums
|
// We have to put this here, otherwise LoadForums() won't be able to get the last poster data when building it's forums
|
||||||
log.Print("Initialising the user and topic stores")
|
log.Print("Initialising the user and topic stores")
|
||||||
if config.CacheTopicUser == CACHE_STATIC {
|
if common.Config.CacheTopicUser == common.CACHE_STATIC {
|
||||||
users, err = NewMemoryUserStore(config.UserCacheCapacity)
|
common.Users, err = common.NewMemoryUserStore(common.Config.UserCacheCapacity)
|
||||||
if err != nil {
|
common.Topics, err2 = common.NewMemoryTopicStore(common.Config.TopicCacheCapacity)
|
||||||
return err
|
|
||||||
}
|
|
||||||
topics, err = NewMemoryTopicStore(config.TopicCacheCapacity)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
users, err = NewSQLUserStore()
|
common.Users, err = common.NewSQLUserStore()
|
||||||
if err != nil {
|
common.Topics, err2 = common.NewSQLTopicStore()
|
||||||
return err
|
|
||||||
}
|
|
||||||
topics, err = NewSQLTopicStore()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Loading the forums.")
|
|
||||||
fstore, err = NewMemoryForumStore()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = fstore.LoadForums()
|
if err2 != nil {
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Print("Loading the forums.")
|
||||||
|
common.Fstore, err = common.NewMemoryForumStore()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = common.Fstore.LoadForums()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Loading the forum permissions.")
|
log.Print("Loading the forum permissions.")
|
||||||
fpstore, err = NewMemoryForumPermsStore()
|
common.Fpstore, err = common.NewMemoryForumPermsStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = fpstore.Init()
|
err = common.Fpstore.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Loading the settings.")
|
log.Print("Loading the settings.")
|
||||||
err = LoadSettings()
|
err = common.LoadSettings()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Loading the plugins.")
|
log.Print("Loading the plugins.")
|
||||||
err = initExtend()
|
err = common.InitExtend()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Loading the themes.")
|
log.Print("Loading the themes.")
|
||||||
return LoadThemeActiveStatus()
|
return common.Themes.LoadActiveStatus()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ import (
|
||||||
"../../../common"
|
"../../../common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// A blank list to fill out that parameter in Page for routes which don't use it
|
||||||
|
var tList []interface{}
|
||||||
|
|
||||||
var ListStmt *sql.Stmt
|
var ListStmt *sql.Stmt
|
||||||
var MemberListStmt *sql.Stmt
|
var MemberListStmt *sql.Stmt
|
||||||
var MemberListJoinStmt *sql.Stmt
|
var MemberListJoinStmt *sql.Stmt
|
||||||
|
@ -45,15 +48,15 @@ type Guild struct {
|
||||||
MainForumID int
|
MainForumID int
|
||||||
MainForum *common.Forum
|
MainForum *common.Forum
|
||||||
Forums []*common.Forum
|
Forums []*common.Forum
|
||||||
ExtData ExtData
|
ExtData common.ExtData
|
||||||
}
|
}
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Title string
|
Title string
|
||||||
CurrentUser User
|
CurrentUser common.User
|
||||||
Header *common.HeaderVars
|
Header *common.HeaderVars
|
||||||
ItemList []*TopicsRow
|
ItemList []*common.TopicsRow
|
||||||
Forum *commmon.Forum
|
Forum *common.Forum
|
||||||
Guild *Guild
|
Guild *Guild
|
||||||
Page int
|
Page int
|
||||||
LastPage int
|
LastPage int
|
||||||
|
@ -62,16 +65,16 @@ type Page struct {
|
||||||
// ListPage is a page struct for constructing a list of every guild
|
// ListPage is a page struct for constructing a list of every guild
|
||||||
type ListPage struct {
|
type ListPage struct {
|
||||||
Title string
|
Title string
|
||||||
CurrentUser User
|
CurrentUser common.User
|
||||||
Header *HeaderVars
|
Header *common.HeaderVars
|
||||||
GuildList []*Guild
|
GuildList []*Guild
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemberListPage struct {
|
type MemberListPage struct {
|
||||||
Title string
|
Title string
|
||||||
CurrentUser User
|
CurrentUser common.User
|
||||||
Header *HeaderVars
|
Header *common.HeaderVars
|
||||||
ItemList []GuildMember
|
ItemList []Member
|
||||||
Guild *Guild
|
Guild *Guild
|
||||||
Page int
|
Page int
|
||||||
LastPage int
|
LastPage int
|
||||||
|
@ -86,15 +89,15 @@ type Member struct {
|
||||||
JoinedAt string
|
JoinedAt string
|
||||||
Offline bool // TODO: Need to track the online states of members when WebSockets are enabled
|
Offline bool // TODO: Need to track the online states of members when WebSockets are enabled
|
||||||
|
|
||||||
User User
|
User common.User
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrebuildTmplList(user *User, headerVars *HeaderVars) CTmpl {
|
func PrebuildTmplList(user common.User, headerVars *common.HeaderVars) common.CTmpl {
|
||||||
var guildList = []*Guild{
|
var guildList = []*Guild{
|
||||||
&Guild{
|
&Guild{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Name: "lol",
|
Name: "lol",
|
||||||
Link: guildsBuildGuildURL(nameToSlug("lol"), 1),
|
Link: BuildGuildURL(common.NameToSlug("lol"), 1),
|
||||||
Desc: "A group for people who like to laugh",
|
Desc: "A group for people who like to laugh",
|
||||||
Active: true,
|
Active: true,
|
||||||
MemberCount: 1,
|
MemberCount: 1,
|
||||||
|
@ -102,38 +105,38 @@ func PrebuildTmplList(user *User, headerVars *HeaderVars) CTmpl {
|
||||||
CreatedAt: "date",
|
CreatedAt: "date",
|
||||||
LastUpdateTime: "date",
|
LastUpdateTime: "date",
|
||||||
MainForumID: 1,
|
MainForumID: 1,
|
||||||
MainForum: fstore.DirtyGet(1),
|
MainForum: common.Fstore.DirtyGet(1),
|
||||||
Forums: []*Forum{fstore.DirtyGet(1)},
|
Forums: []*common.Forum{common.Fstore.DirtyGet(1)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
listPage := ListPage{"Guild List", user, headerVars, guildList}
|
listPage := ListPage{"Guild List", user, headerVars, guildList}
|
||||||
return CTmpl{"guilds-guild-list", "guilds_guild_list", "templates/", "guilds.ListPage", listPage}
|
return common.CTmpl{"guilds-guild-list", "guilds_guild_list", "templates/", "guilds.ListPage", listPage}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Do this properly via the widget system
|
// TODO: Do this properly via the widget system
|
||||||
func CommonAreaWidgets(headerVars *HeaderVars) {
|
func CommonAreaWidgets(headerVars *common.HeaderVars) {
|
||||||
// TODO: Hot Groups? Featured Groups? Official Groups?
|
// TODO: Hot Groups? Featured Groups? Official Groups?
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
var menu = WidgetMenu{"Guilds", []WidgetMenuItem{
|
var menu = common.WidgetMenu{"Guilds", []common.WidgetMenuItem{
|
||||||
WidgetMenuItem{"Create Guild", "/guild/create/", false},
|
common.WidgetMenuItem{"Create Guild", "/guild/create/", false},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
err := templates.ExecuteTemplate(&b, "widget_menu.html", menu)
|
err := common.Templates.ExecuteTemplate(&b, "widget_menu.html", menu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
common.LogError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if themes[headerVars.ThemeName].Sidebars == "left" {
|
if common.Themes[headerVars.ThemeName].Sidebars == "left" {
|
||||||
headerVars.Widgets.LeftSidebar = template.HTML(string(b.Bytes()))
|
headerVars.Widgets.LeftSidebar = template.HTML(string(b.Bytes()))
|
||||||
} else if themes[headerVars.ThemeName].Sidebars == "right" || themes[headerVars.ThemeName].Sidebars == "both" {
|
} else if common.Themes[headerVars.ThemeName].Sidebars == "right" || common.Themes[headerVars.ThemeName].Sidebars == "both" {
|
||||||
headerVars.Widgets.RightSidebar = template.HTML(string(b.Bytes()))
|
headerVars.Widgets.RightSidebar = template.HTML(string(b.Bytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Do this properly via the widget system
|
// TODO: Do this properly via the widget system
|
||||||
// TODO: Make a better more customisable group widget system
|
// TODO: Make a better more customisable group widget system
|
||||||
func GuildWidgets(headerVars *HeaderVars, guildItem *Guild) (success bool) {
|
func GuildWidgets(headerVars *common.HeaderVars, guildItem *Guild) (success bool) {
|
||||||
return false // Disabled until the next commit
|
return false // Disabled until the next commit
|
||||||
|
|
||||||
/*var b bytes.Buffer
|
/*var b bytes.Buffer
|
||||||
|
@ -144,7 +147,7 @@ func GuildWidgets(headerVars *HeaderVars, guildItem *Guild) (success bool) {
|
||||||
|
|
||||||
err := templates.ExecuteTemplate(&b, "widget_menu.html", menu)
|
err := templates.ExecuteTemplate(&b, "widget_menu.html", menu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
common.LogError(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,16 +165,16 @@ func GuildWidgets(headerVars *HeaderVars, guildItem *Guild) (success bool) {
|
||||||
Custom Pages
|
Custom Pages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func routeGuildList(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func RouteGuildList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
headerVars, ferr := UserCheck(w, r, &user)
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
guildsCommonAreaWidgets(headerVars)
|
CommonAreaWidgets(headerVars)
|
||||||
|
|
||||||
rows, err := guildsListStmt.Query()
|
rows, err := ListStmt.Query()
|
||||||
if err != nil && err != ErrNoRows {
|
if err != nil && err != common.ErrNoRows {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
|
@ -180,31 +183,31 @@ func routeGuildList(w http.ResponseWriter, r *http.Request, user User) RouteErro
|
||||||
guildItem := &Guild{ID: 0}
|
guildItem := &Guild{ID: 0}
|
||||||
err := rows.Scan(&guildItem.ID, &guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
err := rows.Scan(&guildItem.ID, &guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
guildItem.Link = guildsBuildGuildURL(nameToSlug(guildItem.Name), guildItem.ID)
|
guildItem.Link = BuildGuildURL(common.NameToSlug(guildItem.Name), guildItem.ID)
|
||||||
guildList = append(guildList, guildItem)
|
guildList = append(guildList, guildItem)
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := GuildListPage{"Guild List", user, headerVars, guildList}
|
pi := ListPage{"Guild List", user, headerVars, guildList}
|
||||||
err = RunThemeTemplate(headerVars.ThemeName, "guilds_guild_list", pi, w)
|
err = common.RunThemeTemplate(headerVars.ThemeName, "guilds_guild_list", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGuild(guildID int) (guildItem *Guild, err error) {
|
func GetGuild(guildID int) (guildItem *Guild, err error) {
|
||||||
guildItem = &Guild{ID: guildID}
|
guildItem = &Guild{ID: guildID}
|
||||||
err = guildsGetGuildStmt.QueryRow(guildID).Scan(&guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &guildItem.MainForumID, &guildItem.Backdrop, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
err = GetGuildStmt.QueryRow(guildID).Scan(&guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &guildItem.MainForumID, &guildItem.Backdrop, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
||||||
return guildItem, err
|
return guildItem, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func middleViewGuild(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
// SEO URLs...
|
// SEO URLs...
|
||||||
halves := strings.Split(r.URL.Path[len("/guild/"):], ".")
|
halves := strings.Split(r.URL.Path[len("/guild/"):], ".")
|
||||||
if len(halves) < 2 {
|
if len(halves) < 2 {
|
||||||
|
@ -212,45 +215,48 @@ func middleViewGuild(w http.ResponseWriter, r *http.Request, user User) RouteErr
|
||||||
}
|
}
|
||||||
guildID, err := strconv.Atoi(halves[1])
|
guildID, err := strconv.Atoi(halves[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("Not a valid guild ID", w, r)
|
return common.PreError("Not a valid guild ID", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
guildItem, err := guildsGetGuild(guildID)
|
guildItem, err := GetGuild(guildID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("Bad guild", w, r, user)
|
return common.LocalError("Bad guild", w, r, user)
|
||||||
}
|
}
|
||||||
if !guildItem.Active {
|
if !guildItem.Active {
|
||||||
return NotFound(w, r)
|
return common.NotFound(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
// TODO: Re-implement this
|
||||||
// Re-route the request to routeForums
|
// Re-route the request to routeForums
|
||||||
var ctx = context.WithValue(r.Context(), "guilds_current_guild", guildItem)
|
//var ctx = context.WithValue(r.Context(), "guilds_current_guild", guildItem)
|
||||||
return routeForum(w, r.WithContext(ctx), user, strconv.Itoa(guildItem.MainForumID))
|
//return routeForum(w, r.WithContext(ctx), user, strconv.Itoa(guildItem.MainForumID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateGuild(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
headerVars, ferr := UserCheck(w, r, &user)
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
// TODO: Add an approval queue mode for group creation
|
// TODO: Add an approval queue mode for group creation
|
||||||
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
guildsCommonAreaWidgets(headerVars)
|
CommonAreaWidgets(headerVars)
|
||||||
|
|
||||||
pi := Page{"Create Guild", user, headerVars, tList, nil}
|
pi := common.Page{"Create Guild", user, headerVars, tList, nil}
|
||||||
err := templates.ExecuteTemplate(w, "guilds_create_guild.html", pi)
|
err := common.Templates.ExecuteTemplate(w, "guilds_create_guild.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateGuildSubmit(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
// TODO: Add an approval queue mode for group creation
|
// TODO: Add an approval queue mode for group creation
|
||||||
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
var guildActive = true
|
var guildActive = true
|
||||||
|
@ -271,37 +277,37 @@ func CreateGuildSubmit(w http.ResponseWriter, r *http.Request, user User) RouteE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the backing forum
|
// Create the backing forum
|
||||||
fid, err := fstore.Create(guildName, "", true, "")
|
fid, err := common.Fstore.Create(guildName, "", true, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := guildsCreateGuildStmt.Exec(guildName, guildDesc, guildActive, guildPrivacy, user.ID, fid)
|
res, err := CreateGuildStmt.Exec(guildName, guildDesc, guildActive, guildPrivacy, user.ID, fid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
lastID, err := res.LastInsertId()
|
lastID, err := res.LastInsertId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the main backing forum to the forum list
|
// Add the main backing forum to the forum list
|
||||||
err = guildsAttachForum(int(lastID), fid)
|
err = AttachForum(int(lastID), fid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = guildsAddMemberStmt.Exec(lastID, user.ID, 2)
|
_, err = AddMemberStmt.Exec(lastID, user.ID, 2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, guildsBuildGuildURL(nameToSlug(guildName), int(lastID)), http.StatusSeeOther)
|
http.Redirect(w, r, BuildGuildURL(common.NameToSlug(guildName), int(lastID)), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MemberList(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
headerVars, ferr := UserCheck(w, r, &user)
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
@ -313,40 +319,40 @@ func MemberList(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
}
|
}
|
||||||
guildID, err := strconv.Atoi(halves[1])
|
guildID, err := strconv.Atoi(halves[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("Not a valid group ID", w, r)
|
return common.PreError("Not a valid group ID", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var guildItem = &Guild{ID: guildID}
|
var guildItem = &Guild{ID: guildID}
|
||||||
var mainForum int // Unused
|
var mainForum int // Unused
|
||||||
err = guildsGetGuildStmt.QueryRow(guildID).Scan(&guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &mainForum, &guildItem.Backdrop, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
err = GetGuildStmt.QueryRow(guildID).Scan(&guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &mainForum, &guildItem.Backdrop, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("Bad group", w, r, user)
|
return common.LocalError("Bad group", w, r, user)
|
||||||
}
|
}
|
||||||
guildItem.Link = guildsBuildGuildURL(nameToSlug(guildItem.Name), guildItem.ID)
|
guildItem.Link = BuildGuildURL(common.NameToSlug(guildItem.Name), guildItem.ID)
|
||||||
|
|
||||||
guildsGuildWidgets(headerVars, guildItem)
|
GuildWidgets(headerVars, guildItem)
|
||||||
|
|
||||||
rows, err := guildsMemberListJoinStmt.Query(guildID)
|
rows, err := MemberListJoinStmt.Query(guildID)
|
||||||
if err != nil && err != ErrNoRows {
|
if err != nil && err != common.ErrNoRows {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var guildMembers []GuildMember
|
var guildMembers []Member
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
guildMember := GuildMember{PostCount: 0}
|
guildMember := Member{PostCount: 0}
|
||||||
err := rows.Scan(&guildMember.User.ID, &guildMember.Rank, &guildMember.PostCount, &guildMember.JoinedAt, &guildMember.User.Name, &guildMember.User.Avatar)
|
err := rows.Scan(&guildMember.User.ID, &guildMember.Rank, &guildMember.PostCount, &guildMember.JoinedAt, &guildMember.User.Name, &guildMember.User.Avatar)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
guildMember.Link = buildProfileURL(nameToSlug(guildMember.User.Name), guildMember.User.ID)
|
guildMember.Link = common.BuildProfileURL(common.NameToSlug(guildMember.User.Name), guildMember.User.ID)
|
||||||
if guildMember.User.Avatar != "" {
|
if guildMember.User.Avatar != "" {
|
||||||
if guildMember.User.Avatar[0] == '.' {
|
if guildMember.User.Avatar[0] == '.' {
|
||||||
guildMember.User.Avatar = "/uploads/avatar_" + strconv.Itoa(guildMember.User.ID) + guildMember.User.Avatar
|
guildMember.User.Avatar = "/uploads/avatar_" + strconv.Itoa(guildMember.User.ID) + guildMember.User.Avatar
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
guildMember.User.Avatar = strings.Replace(config.Noavatar, "{id}", strconv.Itoa(guildMember.User.ID), 1)
|
guildMember.User.Avatar = strings.Replace(common.Config.Noavatar, "{id}", strconv.Itoa(guildMember.User.ID), 1)
|
||||||
}
|
}
|
||||||
guildMember.JoinedAt, _ = relativeTimeFromString(guildMember.JoinedAt)
|
guildMember.JoinedAt, _ = common.RelativeTimeFromString(guildMember.JoinedAt)
|
||||||
if guildItem.Owner == guildMember.User.ID {
|
if guildItem.Owner == guildMember.User.ID {
|
||||||
guildMember.RankString = "Owner"
|
guildMember.RankString = "Owner"
|
||||||
} else {
|
} else {
|
||||||
|
@ -363,31 +369,31 @@ func MemberList(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
rows.Close()
|
rows.Close()
|
||||||
|
|
||||||
pi := GuildMemberListPage{"Guild Member List", user, headerVars, guildMembers, guildItem, 0, 0}
|
pi := MemberListPage{"Guild Member List", user, headerVars, guildMembers, guildItem, 0, 0}
|
||||||
// A plugin with plugins. Pluginception!
|
// A plugin with plugins. Pluginception!
|
||||||
if preRenderHooks["pre_render_guilds_member_list"] != nil {
|
if common.PreRenderHooks["pre_render_guilds_member_list"] != nil {
|
||||||
if runPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = RunThemeTemplate(headerVars.ThemeName, "guilds_member_list", pi, w)
|
err = common.RunThemeTemplate(headerVars.ThemeName, "guilds_member_list", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AttachForum(guildID int, fid int) error {
|
func AttachForum(guildID int, fid int) error {
|
||||||
_, err := guildsAttachForumStmt.Exec(guildID, fid)
|
_, err := AttachForumStmt.Exec(guildID, fid)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnattachForum(fid int) error {
|
func UnattachForum(fid int) error {
|
||||||
_, err := guildsAttachForumStmt.Exec(fid)
|
_, err := AttachForumStmt.Exec(fid)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,16 +409,16 @@ func BuildGuildURL(slug string, id int) string {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Prebuild this template
|
// TODO: Prebuild this template
|
||||||
func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *User, data interface{}) (halt bool) {
|
func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *common.User, data interface{}) (halt bool) {
|
||||||
pi := data.(*ForumPage)
|
pi := data.(*common.ForumPage)
|
||||||
if pi.Header.ExtData.items != nil {
|
if pi.Header.ExtData.Items != nil {
|
||||||
if guildData, ok := pi.Header.ExtData.items["guilds_current_group"]; ok {
|
if guildData, ok := pi.Header.ExtData.Items["guilds_current_group"]; ok {
|
||||||
guildItem := guildData.(*Guild)
|
guildItem := guildData.(*Guild)
|
||||||
|
|
||||||
guildpi := GuildPage{pi.Title, pi.CurrentUser, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage}
|
guildpi := Page{pi.Title, pi.CurrentUser, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage}
|
||||||
err := templates.ExecuteTemplate(w, "guilds_view_guild.html", guildpi)
|
err := common.Templates.ExecuteTemplate(w, "guilds_view_guild.html", guildpi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
common.LogError(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -422,10 +428,10 @@ func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *User, data
|
||||||
}
|
}
|
||||||
|
|
||||||
func TrowAssign(args ...interface{}) interface{} {
|
func TrowAssign(args ...interface{}) interface{} {
|
||||||
var forum = args[1].(*Forum)
|
var forum = args[1].(*common.Forum)
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
var topicItem = args[0].(*TopicsRow)
|
var topicItem = args[0].(*common.TopicsRow)
|
||||||
topicItem.ForumLink = "/guild/" + strings.TrimPrefix(topicItem.ForumLink, getForumURLPrefix())
|
topicItem.ForumLink = "/guild/" + strings.TrimPrefix(topicItem.ForumLink, common.GetForumURLPrefix())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -433,7 +439,7 @@ func TrowAssign(args ...interface{}) interface{} {
|
||||||
// TODO: It would be nice, if you could select one of the boards in the group from that drop-down rather than just the one you got linked from
|
// TODO: It would be nice, if you could select one of the boards in the group from that drop-down rather than just the one you got linked from
|
||||||
func TopicCreatePreLoop(args ...interface{}) interface{} {
|
func TopicCreatePreLoop(args ...interface{}) interface{} {
|
||||||
var fid = args[2].(int)
|
var fid = args[2].(int)
|
||||||
if fstore.DirtyGet(fid).ParentType == "guild" {
|
if common.Fstore.DirtyGet(fid).ParentType == "guild" {
|
||||||
var strictmode = args[5].(*bool)
|
var strictmode = args[5].(*bool)
|
||||||
*strictmode = true
|
*strictmode = true
|
||||||
}
|
}
|
||||||
|
@ -443,27 +449,27 @@ func TopicCreatePreLoop(args ...interface{}) interface{} {
|
||||||
// TODO: Add privacy options
|
// TODO: Add privacy options
|
||||||
// TODO: Add support for multiple boards and add per-board simplified permissions
|
// TODO: Add support for multiple boards and add per-board simplified permissions
|
||||||
// TODO: Take isJs into account for routes which expect JSON responses
|
// TODO: Take isJs into account for routes which expect JSON responses
|
||||||
func ForumCheck(args ...interface{}) (skip bool, rerr RouteError) {
|
func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
|
||||||
var r = args[1].(*http.Request)
|
var r = args[1].(*http.Request)
|
||||||
var fid = args[3].(*int)
|
var fid = args[3].(*int)
|
||||||
var forum = fstore.DirtyGet(*fid)
|
var forum = common.Fstore.DirtyGet(*fid)
|
||||||
|
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
var err error
|
var err error
|
||||||
var w = args[0].(http.ResponseWriter)
|
var w = args[0].(http.ResponseWriter)
|
||||||
guildItem, ok := r.Context().Value("guilds_current_group").(*Guild)
|
guildItem, ok := r.Context().Value("guilds_current_group").(*Guild)
|
||||||
if !ok {
|
if !ok {
|
||||||
guildItem, err = guildsGetGuild(forum.ParentID)
|
guildItem, err = GetGuild(forum.ParentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, InternalError(errors.New("Unable to find the parent group for a forum"), w, r)
|
return true, common.InternalError(errors.New("Unable to find the parent group for a forum"), w, r)
|
||||||
}
|
}
|
||||||
if !guildItem.Active {
|
if !guildItem.Active {
|
||||||
return true, NotFound(w, r)
|
return true, common.NotFound(w, r)
|
||||||
}
|
}
|
||||||
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
|
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = args[2].(*User)
|
var user = args[2].(*common.User)
|
||||||
var rank int
|
var rank int
|
||||||
var posts int
|
var posts int
|
||||||
var joinedAt string
|
var joinedAt string
|
||||||
|
@ -472,32 +478,32 @@ func ForumCheck(args ...interface{}) (skip bool, rerr RouteError) {
|
||||||
|
|
||||||
// Clear the default group permissions
|
// Clear the default group permissions
|
||||||
// TODO: Do this more efficiently, doing it quick and dirty for now to get this out quickly
|
// TODO: Do this more efficiently, doing it quick and dirty for now to get this out quickly
|
||||||
overrideForumPerms(&user.Perms, false)
|
common.OverrideForumPerms(&user.Perms, false)
|
||||||
user.Perms.ViewTopic = true
|
user.Perms.ViewTopic = true
|
||||||
|
|
||||||
err = guildsGetMemberStmt.QueryRow(guildItem.ID, user.ID).Scan(&rank, &posts, &joinedAt)
|
err = GetMemberStmt.QueryRow(guildItem.ID, user.ID).Scan(&rank, &posts, &joinedAt)
|
||||||
if err != nil && err != ErrNoRows {
|
if err != nil && err != common.ErrNoRows {
|
||||||
return true, InternalError(err, w, r)
|
return true, common.InternalError(err, w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
// TODO: Should we let admins / guests into public groups?
|
// TODO: Should we let admins / guests into public groups?
|
||||||
return true, LocalError("You're not part of this group!", w, r, *user)
|
return true, common.LocalError("You're not part of this group!", w, r, *user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement bans properly by adding the Local Ban API in the next commit
|
// TODO: Implement bans properly by adding the Local Ban API in the next commit
|
||||||
// TODO: How does this even work? Refactor it along with the rest of this plugin!
|
// TODO: How does this even work? Refactor it along with the rest of this plugin!
|
||||||
if rank < 0 {
|
if rank < 0 {
|
||||||
return true, LocalError("You've been banned from this group!", w, r, *user)
|
return true, common.LocalError("You've been banned from this group!", w, r, *user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic permissions for members, more complicated permissions coming in the next commit!
|
// Basic permissions for members, more complicated permissions coming in the next commit!
|
||||||
if guildItem.Owner == user.ID {
|
if guildItem.Owner == user.ID {
|
||||||
overrideForumPerms(&user.Perms, true)
|
common.OverrideForumPerms(&user.Perms, true)
|
||||||
} else if rank == 0 {
|
} else if rank == 0 {
|
||||||
user.Perms.LikeItem = true
|
user.Perms.LikeItem = true
|
||||||
user.Perms.CreateTopic = true
|
user.Perms.CreateTopic = true
|
||||||
user.Perms.CreateReply = true
|
user.Perms.CreateReply = true
|
||||||
} else {
|
} else {
|
||||||
overrideForumPerms(&user.Perms, true)
|
common.OverrideForumPerms(&user.Perms, true)
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
@ -509,28 +515,28 @@ func ForumCheck(args ...interface{}) (skip bool, rerr RouteError) {
|
||||||
|
|
||||||
func Widgets(args ...interface{}) interface{} {
|
func Widgets(args ...interface{}) interface{} {
|
||||||
var zone = args[0].(string)
|
var zone = args[0].(string)
|
||||||
var headerVars = args[2].(*HeaderVars)
|
var headerVars = args[2].(*common.HeaderVars)
|
||||||
var request = args[3].(*http.Request)
|
var request = args[3].(*http.Request)
|
||||||
|
|
||||||
if zone != "view_forum" {
|
if zone != "view_forum" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var forum = args[1].(*Forum)
|
var forum = args[1].(*common.Forum)
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
// This is why I hate using contexts, all the daisy chains and interface casts x.x
|
// This is why I hate using contexts, all the daisy chains and interface casts x.x
|
||||||
guildItem, ok := request.Context().Value("guilds_current_group").(*Guild)
|
guildItem, ok := request.Context().Value("guilds_current_group").(*Guild)
|
||||||
if !ok {
|
if !ok {
|
||||||
LogError(errors.New("Unable to find a parent group in the context data"))
|
common.LogError(errors.New("Unable to find a parent group in the context data"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if headerVars.ExtData.items == nil {
|
if headerVars.ExtData.Items == nil {
|
||||||
headerVars.ExtData.items = make(map[string]interface{})
|
headerVars.ExtData.Items = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
headerVars.ExtData.items["guilds_current_group"] = guildItem
|
headerVars.ExtData.Items["guilds_current_group"] = guildItem
|
||||||
|
|
||||||
return guildsGuildWidgets(headerVars, guildItem)
|
return GuildWidgets(headerVars, guildItem)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
363
gen_mssql.go
363
gen_mssql.go
|
@ -5,6 +5,7 @@ package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
type Stmts struct {
|
type Stmts struct {
|
||||||
|
@ -12,21 +13,14 @@ type Stmts struct {
|
||||||
getSettings *sql.Stmt
|
getSettings *sql.Stmt
|
||||||
getSetting *sql.Stmt
|
getSetting *sql.Stmt
|
||||||
getFullSetting *sql.Stmt
|
getFullSetting *sql.Stmt
|
||||||
getFullSettings *sql.Stmt
|
|
||||||
getPlugins *sql.Stmt
|
|
||||||
getThemes *sql.Stmt
|
|
||||||
getWidgets *sql.Stmt
|
|
||||||
isPluginActive *sql.Stmt
|
isPluginActive *sql.Stmt
|
||||||
getUsersOffset *sql.Stmt
|
getUsersOffset *sql.Stmt
|
||||||
getWordFilters *sql.Stmt
|
|
||||||
isThemeDefault *sql.Stmt
|
isThemeDefault *sql.Stmt
|
||||||
getModlogs *sql.Stmt
|
getModlogs *sql.Stmt
|
||||||
getModlogsOffset *sql.Stmt
|
getModlogsOffset *sql.Stmt
|
||||||
getReplyTID *sql.Stmt
|
getReplyTID *sql.Stmt
|
||||||
getTopicFID *sql.Stmt
|
getTopicFID *sql.Stmt
|
||||||
getUserReplyUID *sql.Stmt
|
getUserReplyUID *sql.Stmt
|
||||||
hasLikedTopic *sql.Stmt
|
|
||||||
hasLikedReply *sql.Stmt
|
|
||||||
getUserName *sql.Stmt
|
getUserName *sql.Stmt
|
||||||
getEmailsByUser *sql.Stmt
|
getEmailsByUser *sql.Stmt
|
||||||
getTopicBasic *sql.Stmt
|
getTopicBasic *sql.Stmt
|
||||||
|
@ -34,20 +28,14 @@ type Stmts struct {
|
||||||
forumEntryExists *sql.Stmt
|
forumEntryExists *sql.Stmt
|
||||||
groupEntryExists *sql.Stmt
|
groupEntryExists *sql.Stmt
|
||||||
getForumTopicsOffset *sql.Stmt
|
getForumTopicsOffset *sql.Stmt
|
||||||
getExpiredScheduledGroups *sql.Stmt
|
|
||||||
getSync *sql.Stmt
|
|
||||||
getAttachment *sql.Stmt
|
getAttachment *sql.Stmt
|
||||||
getTopicRepliesOffset *sql.Stmt
|
getTopicRepliesOffset *sql.Stmt
|
||||||
getTopicList *sql.Stmt
|
getTopicList *sql.Stmt
|
||||||
getTopicUser *sql.Stmt
|
|
||||||
getTopicByReply *sql.Stmt
|
|
||||||
getTopicReplies *sql.Stmt
|
getTopicReplies *sql.Stmt
|
||||||
getForumTopics *sql.Stmt
|
getForumTopics *sql.Stmt
|
||||||
getProfileReplies *sql.Stmt
|
getProfileReplies *sql.Stmt
|
||||||
getWatchers *sql.Stmt
|
getWatchers *sql.Stmt
|
||||||
createReport *sql.Stmt
|
createReport *sql.Stmt
|
||||||
createActionReply *sql.Stmt
|
|
||||||
createLike *sql.Stmt
|
|
||||||
addActivity *sql.Stmt
|
addActivity *sql.Stmt
|
||||||
notifyOne *sql.Stmt
|
notifyOne *sql.Stmt
|
||||||
addEmail *sql.Stmt
|
addEmail *sql.Stmt
|
||||||
|
@ -55,57 +43,27 @@ type Stmts struct {
|
||||||
addForumPermsToForum *sql.Stmt
|
addForumPermsToForum *sql.Stmt
|
||||||
addPlugin *sql.Stmt
|
addPlugin *sql.Stmt
|
||||||
addTheme *sql.Stmt
|
addTheme *sql.Stmt
|
||||||
addModlogEntry *sql.Stmt
|
|
||||||
addAdminlogEntry *sql.Stmt
|
|
||||||
addAttachment *sql.Stmt
|
addAttachment *sql.Stmt
|
||||||
createWordFilter *sql.Stmt
|
createWordFilter *sql.Stmt
|
||||||
addRepliesToTopic *sql.Stmt
|
|
||||||
removeRepliesFromTopic *sql.Stmt
|
|
||||||
addLikesToTopic *sql.Stmt
|
|
||||||
addLikesToReply *sql.Stmt
|
|
||||||
editTopic *sql.Stmt
|
|
||||||
editReply *sql.Stmt
|
editReply *sql.Stmt
|
||||||
stickTopic *sql.Stmt
|
|
||||||
unstickTopic *sql.Stmt
|
|
||||||
lockTopic *sql.Stmt
|
|
||||||
unlockTopic *sql.Stmt
|
|
||||||
updateLastIP *sql.Stmt
|
|
||||||
updateSession *sql.Stmt
|
|
||||||
setPassword *sql.Stmt
|
|
||||||
setAvatar *sql.Stmt
|
|
||||||
setUsername *sql.Stmt
|
|
||||||
changeGroup *sql.Stmt
|
|
||||||
activateUser *sql.Stmt
|
|
||||||
updateUserLevel *sql.Stmt
|
|
||||||
incrementUserScore *sql.Stmt
|
|
||||||
incrementUserPosts *sql.Stmt
|
|
||||||
incrementUserBigposts *sql.Stmt
|
|
||||||
incrementUserMegaposts *sql.Stmt
|
|
||||||
incrementUserTopics *sql.Stmt
|
|
||||||
editProfileReply *sql.Stmt
|
editProfileReply *sql.Stmt
|
||||||
updateForum *sql.Stmt
|
|
||||||
updateSetting *sql.Stmt
|
updateSetting *sql.Stmt
|
||||||
updatePlugin *sql.Stmt
|
updatePlugin *sql.Stmt
|
||||||
updatePluginInstall *sql.Stmt
|
updatePluginInstall *sql.Stmt
|
||||||
updateTheme *sql.Stmt
|
updateTheme *sql.Stmt
|
||||||
|
updateForum *sql.Stmt
|
||||||
updateUser *sql.Stmt
|
updateUser *sql.Stmt
|
||||||
updateUserGroup *sql.Stmt
|
|
||||||
updateGroupPerms *sql.Stmt
|
updateGroupPerms *sql.Stmt
|
||||||
updateGroupRank *sql.Stmt
|
|
||||||
updateGroup *sql.Stmt
|
updateGroup *sql.Stmt
|
||||||
updateEmail *sql.Stmt
|
updateEmail *sql.Stmt
|
||||||
verifyEmail *sql.Stmt
|
verifyEmail *sql.Stmt
|
||||||
setTempGroup *sql.Stmt
|
setTempGroup *sql.Stmt
|
||||||
updateWordFilter *sql.Stmt
|
updateWordFilter *sql.Stmt
|
||||||
bumpSync *sql.Stmt
|
bumpSync *sql.Stmt
|
||||||
deleteUser *sql.Stmt
|
|
||||||
deleteTopic *sql.Stmt
|
|
||||||
deleteReply *sql.Stmt
|
|
||||||
deleteProfileReply *sql.Stmt
|
deleteProfileReply *sql.Stmt
|
||||||
deleteActivityStreamMatch *sql.Stmt
|
deleteActivityStreamMatch *sql.Stmt
|
||||||
deleteWordFilter *sql.Stmt
|
deleteWordFilter *sql.Stmt
|
||||||
reportExists *sql.Stmt
|
reportExists *sql.Stmt
|
||||||
groupCount *sql.Stmt
|
|
||||||
modlogCount *sql.Stmt
|
modlogCount *sql.Stmt
|
||||||
notifyWatchers *sql.Stmt
|
notifyWatchers *sql.Stmt
|
||||||
|
|
||||||
|
@ -124,7 +82,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_mssql() (err error) {
|
func _gen_mssql() (err error) {
|
||||||
if dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Building the generated statements")
|
log.Print("Building the generated statements")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,34 +114,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getFullSettings statement.")
|
|
||||||
stmts.getFullSettings, err = db.Prepare("SELECT [name],[content],[type],[constraints] FROM [settings]")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [name],[content],[type],[constraints] FROM [settings]")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getPlugins statement.")
|
|
||||||
stmts.getPlugins, err = db.Prepare("SELECT [uname],[active],[installed] FROM [plugins]")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [uname],[active],[installed] FROM [plugins]")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getThemes statement.")
|
|
||||||
stmts.getThemes, err = db.Prepare("SELECT [uname],[default] FROM [themes]")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [uname],[default] FROM [themes]")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getWidgets statement.")
|
|
||||||
stmts.getWidgets, err = db.Prepare("SELECT [position],[side],[type],[active],[location],[data] FROM [widgets] ORDER BY position ASC")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [position],[side],[type],[active],[location],[data] FROM [widgets] ORDER BY position ASC")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing isPluginActive statement.")
|
log.Print("Preparing isPluginActive statement.")
|
||||||
stmts.isPluginActive, err = db.Prepare("SELECT [active] FROM [plugins] WHERE [uname] = ?1")
|
stmts.isPluginActive, err = db.Prepare("SELECT [active] FROM [plugins] WHERE [uname] = ?1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -198,13 +128,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getWordFilters statement.")
|
|
||||||
stmts.getWordFilters, err = db.Prepare("SELECT [wfid],[find],[replacement] FROM [word_filters]")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [wfid],[find],[replacement] FROM [word_filters]")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing isThemeDefault statement.")
|
log.Print("Preparing isThemeDefault statement.")
|
||||||
stmts.isThemeDefault, err = db.Prepare("SELECT [default] FROM [themes] WHERE [uname] = ?1")
|
stmts.isThemeDefault, err = db.Prepare("SELECT [default] FROM [themes] WHERE [uname] = ?1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -247,20 +170,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing hasLikedTopic statement.")
|
|
||||||
stmts.hasLikedTopic, err = db.Prepare("SELECT [targetItem] FROM [likes] WHERE [sentBy] = ?1 AND [targetItem] = ?2 AND [targetType] = 'topics'")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [targetItem] FROM [likes] WHERE [sentBy] = ?1 AND [targetItem] = ?2 AND [targetType] = 'topics'")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing hasLikedReply statement.")
|
|
||||||
stmts.hasLikedReply, err = db.Prepare("SELECT [targetItem] FROM [likes] WHERE [sentBy] = ?1 AND [targetItem] = ?2 AND [targetType] = 'replies'")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [targetItem] FROM [likes] WHERE [sentBy] = ?1 AND [targetItem] = ?2 AND [targetType] = 'replies'")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getUserName statement.")
|
log.Print("Preparing getUserName statement.")
|
||||||
stmts.getUserName, err = db.Prepare("SELECT [name] FROM [users] WHERE [uid] = ?1")
|
stmts.getUserName, err = db.Prepare("SELECT [name] FROM [users] WHERE [uid] = ?1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -310,20 +219,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getExpiredScheduledGroups statement.")
|
|
||||||
stmts.getExpiredScheduledGroups, err = db.Prepare("SELECT [uid] FROM [users_groups_scheduler] WHERE GETDATE() > [revert_at] AND [temporary] = 1")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [uid] FROM [users_groups_scheduler] WHERE GETDATE() > [revert_at] AND [temporary] = 1")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getSync statement.")
|
|
||||||
stmts.getSync, err = db.Prepare("SELECT [last_update] FROM [sync]")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [last_update] FROM [sync]")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getAttachment statement.")
|
log.Print("Preparing getAttachment statement.")
|
||||||
stmts.getAttachment, err = db.Prepare("SELECT [sectionID],[sectionTable],[originID],[originTable],[uploadedBy],[path] FROM [attachments] WHERE [path] = ?1 AND [sectionID] = ?2 AND [sectionTable] = ?3")
|
stmts.getAttachment, err = db.Prepare("SELECT [sectionID],[sectionTable],[originID],[originTable],[uploadedBy],[path] FROM [attachments] WHERE [path] = ?1 AND [sectionID] = ?2 AND [sectionTable] = ?3")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -345,20 +240,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getTopicUser statement.")
|
|
||||||
stmts.getTopicUser, err = db.Prepare("SELECT [topics].[title],[topics].[content],[topics].[createdBy],[topics].[createdAt],[topics].[is_closed],[topics].[sticky],[topics].[parentID],[topics].[ipaddress],[topics].[postCount],[topics].[likeCount],[users].[name],[users].[avatar],[users].[group],[users].[url_prefix],[users].[url_name],[users].[level] FROM [topics] LEFT JOIN [users] ON [topics].[createdBy] = [users].[uid] WHERE [tid] = ?1")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [topics].[title],[topics].[content],[topics].[createdBy],[topics].[createdAt],[topics].[is_closed],[topics].[sticky],[topics].[parentID],[topics].[ipaddress],[topics].[postCount],[topics].[likeCount],[users].[name],[users].[avatar],[users].[group],[users].[url_prefix],[users].[url_name],[users].[level] FROM [topics] LEFT JOIN [users] ON [topics].[createdBy] = [users].[uid] WHERE [tid] = ?1")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getTopicByReply statement.")
|
|
||||||
stmts.getTopicByReply, err = db.Prepare("SELECT [topics].[tid],[topics].[title],[topics].[content],[topics].[createdBy],[topics].[createdAt],[topics].[is_closed],[topics].[sticky],[topics].[parentID],[topics].[ipaddress],[topics].[postCount],[topics].[likeCount],[topics].[data] FROM [replies] LEFT JOIN [topics] ON [replies].[tid] = [topics].[tid] WHERE [rid] = ?1")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT [topics].[tid],[topics].[title],[topics].[content],[topics].[createdBy],[topics].[createdAt],[topics].[is_closed],[topics].[sticky],[topics].[parentID],[topics].[ipaddress],[topics].[postCount],[topics].[likeCount],[topics].[data] FROM [replies] LEFT JOIN [topics] ON [replies].[tid] = [topics].[tid] WHERE [rid] = ?1")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getTopicReplies statement.")
|
log.Print("Preparing getTopicReplies statement.")
|
||||||
stmts.getTopicReplies, err = db.Prepare("SELECT [replies].[rid],[replies].[content],[replies].[createdBy],[replies].[createdAt],[replies].[lastEdit],[replies].[lastEditBy],[users].[avatar],[users].[name],[users].[group],[users].[url_prefix],[users].[url_name],[users].[level],[replies].[ipaddress] FROM [replies] LEFT JOIN [users] ON [replies].[createdBy] = [users].[uid] WHERE [tid] = ?1")
|
stmts.getTopicReplies, err = db.Prepare("SELECT [replies].[rid],[replies].[content],[replies].[createdBy],[replies].[createdAt],[replies].[lastEdit],[replies].[lastEditBy],[users].[avatar],[users].[name],[users].[group],[users].[url_prefix],[users].[url_name],[users].[level],[replies].[ipaddress] FROM [replies] LEFT JOIN [users] ON [replies].[createdBy] = [users].[uid] WHERE [tid] = ?1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -394,20 +275,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing createActionReply statement.")
|
|
||||||
stmts.createActionReply, err = db.Prepare("INSERT INTO [replies] ([tid],[actionType],[ipaddress],[createdBy],[createdAt],[lastUpdated],[content],[parsed_content]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),'','')")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","INSERT INTO [replies] ([tid],[actionType],[ipaddress],[createdBy],[createdAt],[lastUpdated],[content],[parsed_content]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),'','')")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing createLike statement.")
|
|
||||||
stmts.createLike, err = db.Prepare("INSERT INTO [likes] ([weight],[targetItem],[targetType],[sentBy]) VALUES (?,?,?,?)")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","INSERT INTO [likes] ([weight],[targetItem],[targetType],[sentBy]) VALUES (?,?,?,?)")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addActivity statement.")
|
log.Print("Preparing addActivity statement.")
|
||||||
stmts.addActivity, err = db.Prepare("INSERT INTO [activity_stream] ([actor],[targetUser],[event],[elementType],[elementID]) VALUES (?,?,?,?,?)")
|
stmts.addActivity, err = db.Prepare("INSERT INTO [activity_stream] ([actor],[targetUser],[event],[elementType],[elementID]) VALUES (?,?,?,?,?)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -457,20 +324,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing addModlogEntry statement.")
|
|
||||||
stmts.addModlogEntry, err = db.Prepare("INSERT INTO [moderation_logs] ([action],[elementID],[elementType],[ipaddress],[actorID],[doneAt]) VALUES (?,?,?,?,?,GETUTCDATE())")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","INSERT INTO [moderation_logs] ([action],[elementID],[elementType],[ipaddress],[actorID],[doneAt]) VALUES (?,?,?,?,?,GETUTCDATE())")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addAdminlogEntry statement.")
|
|
||||||
stmts.addAdminlogEntry, err = db.Prepare("INSERT INTO [administration_logs] ([action],[elementID],[elementType],[ipaddress],[actorID],[doneAt]) VALUES (?,?,?,?,?,GETUTCDATE())")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","INSERT INTO [administration_logs] ([action],[elementID],[elementType],[ipaddress],[actorID],[doneAt]) VALUES (?,?,?,?,?,GETUTCDATE())")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addAttachment statement.")
|
log.Print("Preparing addAttachment statement.")
|
||||||
stmts.addAttachment, err = db.Prepare("INSERT INTO [attachments] ([sectionID],[sectionTable],[originID],[originTable],[uploadedBy],[path]) VALUES (?,?,?,?,?,?)")
|
stmts.addAttachment, err = db.Prepare("INSERT INTO [attachments] ([sectionID],[sectionTable],[originID],[originTable],[uploadedBy],[path]) VALUES (?,?,?,?,?,?)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -485,41 +338,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing addRepliesToTopic statement.")
|
|
||||||
stmts.addRepliesToTopic, err = db.Prepare("UPDATE [topics] SET [postCount] = [postCount] + ?,[lastReplyBy] = ?,[lastReplyAt] = GETUTCDATE() WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [postCount] = [postCount] + ?,[lastReplyBy] = ?,[lastReplyAt] = GETUTCDATE() WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing removeRepliesFromTopic statement.")
|
|
||||||
stmts.removeRepliesFromTopic, err = db.Prepare("UPDATE [topics] SET [postCount] = [postCount] - ? WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [postCount] = [postCount] - ? WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addLikesToTopic statement.")
|
|
||||||
stmts.addLikesToTopic, err = db.Prepare("UPDATE [topics] SET [likeCount] = [likeCount] + ? WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [likeCount] = [likeCount] + ? WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addLikesToReply statement.")
|
|
||||||
stmts.addLikesToReply, err = db.Prepare("UPDATE [replies] SET [likeCount] = [likeCount] + ? WHERE [rid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [replies] SET [likeCount] = [likeCount] + ? WHERE [rid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editTopic statement.")
|
|
||||||
stmts.editTopic, err = db.Prepare("UPDATE [topics] SET [title] = ?,[content] = ?,[parsed_content] = ? WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [title] = ?,[content] = ?,[parsed_content] = ? WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editReply statement.")
|
log.Print("Preparing editReply statement.")
|
||||||
stmts.editReply, err = db.Prepare("UPDATE [replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
stmts.editReply, err = db.Prepare("UPDATE [replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -527,125 +345,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing stickTopic statement.")
|
|
||||||
stmts.stickTopic, err = db.Prepare("UPDATE [topics] SET [sticky] = 1 WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [sticky] = 1 WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing unstickTopic statement.")
|
|
||||||
stmts.unstickTopic, err = db.Prepare("UPDATE [topics] SET [sticky] = 0 WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [sticky] = 0 WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing lockTopic statement.")
|
|
||||||
stmts.lockTopic, err = db.Prepare("UPDATE [topics] SET [is_closed] = 1 WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [is_closed] = 1 WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing unlockTopic statement.")
|
|
||||||
stmts.unlockTopic, err = db.Prepare("UPDATE [topics] SET [is_closed] = 0 WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [topics] SET [is_closed] = 0 WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateLastIP statement.")
|
|
||||||
stmts.updateLastIP, err = db.Prepare("UPDATE [users] SET [last_ip] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [last_ip] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateSession statement.")
|
|
||||||
stmts.updateSession, err = db.Prepare("UPDATE [users] SET [session] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [session] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setPassword statement.")
|
|
||||||
stmts.setPassword, err = db.Prepare("UPDATE [users] SET [password] = ?,[salt] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [password] = ?,[salt] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setAvatar statement.")
|
|
||||||
stmts.setAvatar, err = db.Prepare("UPDATE [users] SET [avatar] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [avatar] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setUsername statement.")
|
|
||||||
stmts.setUsername, err = db.Prepare("UPDATE [users] SET [name] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [name] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing changeGroup statement.")
|
|
||||||
stmts.changeGroup, err = db.Prepare("UPDATE [users] SET [group] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [group] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing activateUser statement.")
|
|
||||||
stmts.activateUser, err = db.Prepare("UPDATE [users] SET [active] = 1 WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [active] = 1 WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateUserLevel statement.")
|
|
||||||
stmts.updateUserLevel, err = db.Prepare("UPDATE [users] SET [level] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [level] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserScore statement.")
|
|
||||||
stmts.incrementUserScore, err = db.Prepare("UPDATE [users] SET [score] = [score] + ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [score] = [score] + ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserPosts statement.")
|
|
||||||
stmts.incrementUserPosts, err = db.Prepare("UPDATE [users] SET [posts] = [posts] + ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [posts] = [posts] + ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserBigposts statement.")
|
|
||||||
stmts.incrementUserBigposts, err = db.Prepare("UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserMegaposts statement.")
|
|
||||||
stmts.incrementUserMegaposts, err = db.Prepare("UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ?,[megaposts] = [megaposts] + ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ?,[megaposts] = [megaposts] + ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserTopics statement.")
|
|
||||||
stmts.incrementUserTopics, err = db.Prepare("UPDATE [users] SET [topics] = [topics] + ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [topics] = [topics] + ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editProfileReply statement.")
|
log.Print("Preparing editProfileReply statement.")
|
||||||
stmts.editProfileReply, err = db.Prepare("UPDATE [users_replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
stmts.editProfileReply, err = db.Prepare("UPDATE [users_replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -653,13 +352,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateForum statement.")
|
|
||||||
stmts.updateForum, err = db.Prepare("UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateSetting statement.")
|
log.Print("Preparing updateSetting statement.")
|
||||||
stmts.updateSetting, err = db.Prepare("UPDATE [settings] SET [content] = ? WHERE [name] = ?")
|
stmts.updateSetting, err = db.Prepare("UPDATE [settings] SET [content] = ? WHERE [name] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -688,6 +380,13 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing updateForum statement.")
|
||||||
|
stmts.updateForum, err = db.Prepare("UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
||||||
|
if err != nil {
|
||||||
|
log.Print("Bad Query: ","UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateUser statement.")
|
log.Print("Preparing updateUser statement.")
|
||||||
stmts.updateUser, err = db.Prepare("UPDATE [users] SET [name] = ?,[email] = ?,[group] = ? WHERE [uid] = ?")
|
stmts.updateUser, err = db.Prepare("UPDATE [users] SET [name] = ?,[email] = ?,[group] = ? WHERE [uid] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -695,13 +394,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateUserGroup statement.")
|
|
||||||
stmts.updateUserGroup, err = db.Prepare("UPDATE [users] SET [group] = ? WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users] SET [group] = ? WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateGroupPerms statement.")
|
log.Print("Preparing updateGroupPerms statement.")
|
||||||
stmts.updateGroupPerms, err = db.Prepare("UPDATE [users_groups] SET [permissions] = ? WHERE [gid] = ?")
|
stmts.updateGroupPerms, err = db.Prepare("UPDATE [users_groups] SET [permissions] = ? WHERE [gid] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -709,13 +401,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateGroupRank statement.")
|
|
||||||
stmts.updateGroupRank, err = db.Prepare("UPDATE [users_groups] SET [is_admin] = ?,[is_mod] = ?,[is_banned] = ? WHERE [gid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [users_groups] SET [is_admin] = ?,[is_mod] = ?,[is_banned] = ? WHERE [gid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateGroup statement.")
|
log.Print("Preparing updateGroup statement.")
|
||||||
stmts.updateGroup, err = db.Prepare("UPDATE [users_groups] SET [name] = ?,[tag] = ? WHERE [gid] = ?")
|
stmts.updateGroup, err = db.Prepare("UPDATE [users_groups] SET [name] = ?,[tag] = ? WHERE [gid] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -758,27 +443,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing deleteUser statement.")
|
|
||||||
stmts.deleteUser, err = db.Prepare("DELETE FROM [users] WHERE [uid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","DELETE FROM [users] WHERE [uid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing deleteTopic statement.")
|
|
||||||
stmts.deleteTopic, err = db.Prepare("DELETE FROM [topics] WHERE [tid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","DELETE FROM [topics] WHERE [tid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing deleteReply statement.")
|
|
||||||
stmts.deleteReply, err = db.Prepare("DELETE FROM [replies] WHERE [rid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","DELETE FROM [replies] WHERE [rid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing deleteProfileReply statement.")
|
log.Print("Preparing deleteProfileReply statement.")
|
||||||
stmts.deleteProfileReply, err = db.Prepare("DELETE FROM [users_replies] WHERE [rid] = ?")
|
stmts.deleteProfileReply, err = db.Prepare("DELETE FROM [users_replies] WHERE [rid] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -807,13 +471,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing groupCount statement.")
|
|
||||||
stmts.groupCount, err = db.Prepare("SELECT COUNT(*) AS [count] FROM [users_groups]")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","SELECT COUNT(*) AS [count] FROM [users_groups]")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing modlogCount statement.")
|
log.Print("Preparing modlogCount statement.")
|
||||||
stmts.modlogCount, err = db.Prepare("SELECT COUNT(*) AS [count] FROM [moderation_logs]")
|
stmts.modlogCount, err = db.Prepare("SELECT COUNT(*) AS [count] FROM [moderation_logs]")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
318
gen_mysql.go
318
gen_mysql.go
|
@ -6,6 +6,7 @@ package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
import "./common"
|
||||||
//import "./query_gen/lib"
|
//import "./query_gen/lib"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
|
@ -14,21 +15,14 @@ type Stmts struct {
|
||||||
getSettings *sql.Stmt
|
getSettings *sql.Stmt
|
||||||
getSetting *sql.Stmt
|
getSetting *sql.Stmt
|
||||||
getFullSetting *sql.Stmt
|
getFullSetting *sql.Stmt
|
||||||
getFullSettings *sql.Stmt
|
|
||||||
getPlugins *sql.Stmt
|
|
||||||
getThemes *sql.Stmt
|
|
||||||
getWidgets *sql.Stmt
|
|
||||||
isPluginActive *sql.Stmt
|
isPluginActive *sql.Stmt
|
||||||
getUsersOffset *sql.Stmt
|
getUsersOffset *sql.Stmt
|
||||||
getWordFilters *sql.Stmt
|
|
||||||
isThemeDefault *sql.Stmt
|
isThemeDefault *sql.Stmt
|
||||||
getModlogs *sql.Stmt
|
getModlogs *sql.Stmt
|
||||||
getModlogsOffset *sql.Stmt
|
getModlogsOffset *sql.Stmt
|
||||||
getReplyTID *sql.Stmt
|
getReplyTID *sql.Stmt
|
||||||
getTopicFID *sql.Stmt
|
getTopicFID *sql.Stmt
|
||||||
getUserReplyUID *sql.Stmt
|
getUserReplyUID *sql.Stmt
|
||||||
hasLikedTopic *sql.Stmt
|
|
||||||
hasLikedReply *sql.Stmt
|
|
||||||
getUserName *sql.Stmt
|
getUserName *sql.Stmt
|
||||||
getEmailsByUser *sql.Stmt
|
getEmailsByUser *sql.Stmt
|
||||||
getTopicBasic *sql.Stmt
|
getTopicBasic *sql.Stmt
|
||||||
|
@ -36,20 +30,14 @@ type Stmts struct {
|
||||||
forumEntryExists *sql.Stmt
|
forumEntryExists *sql.Stmt
|
||||||
groupEntryExists *sql.Stmt
|
groupEntryExists *sql.Stmt
|
||||||
getForumTopicsOffset *sql.Stmt
|
getForumTopicsOffset *sql.Stmt
|
||||||
getExpiredScheduledGroups *sql.Stmt
|
|
||||||
getSync *sql.Stmt
|
|
||||||
getAttachment *sql.Stmt
|
getAttachment *sql.Stmt
|
||||||
getTopicRepliesOffset *sql.Stmt
|
getTopicRepliesOffset *sql.Stmt
|
||||||
getTopicList *sql.Stmt
|
getTopicList *sql.Stmt
|
||||||
getTopicUser *sql.Stmt
|
|
||||||
getTopicByReply *sql.Stmt
|
|
||||||
getTopicReplies *sql.Stmt
|
getTopicReplies *sql.Stmt
|
||||||
getForumTopics *sql.Stmt
|
getForumTopics *sql.Stmt
|
||||||
getProfileReplies *sql.Stmt
|
getProfileReplies *sql.Stmt
|
||||||
getWatchers *sql.Stmt
|
getWatchers *sql.Stmt
|
||||||
createReport *sql.Stmt
|
createReport *sql.Stmt
|
||||||
createActionReply *sql.Stmt
|
|
||||||
createLike *sql.Stmt
|
|
||||||
addActivity *sql.Stmt
|
addActivity *sql.Stmt
|
||||||
notifyOne *sql.Stmt
|
notifyOne *sql.Stmt
|
||||||
addEmail *sql.Stmt
|
addEmail *sql.Stmt
|
||||||
|
@ -57,57 +45,27 @@ type Stmts struct {
|
||||||
addForumPermsToForum *sql.Stmt
|
addForumPermsToForum *sql.Stmt
|
||||||
addPlugin *sql.Stmt
|
addPlugin *sql.Stmt
|
||||||
addTheme *sql.Stmt
|
addTheme *sql.Stmt
|
||||||
addModlogEntry *sql.Stmt
|
|
||||||
addAdminlogEntry *sql.Stmt
|
|
||||||
addAttachment *sql.Stmt
|
addAttachment *sql.Stmt
|
||||||
createWordFilter *sql.Stmt
|
createWordFilter *sql.Stmt
|
||||||
addRepliesToTopic *sql.Stmt
|
|
||||||
removeRepliesFromTopic *sql.Stmt
|
|
||||||
addLikesToTopic *sql.Stmt
|
|
||||||
addLikesToReply *sql.Stmt
|
|
||||||
editTopic *sql.Stmt
|
|
||||||
editReply *sql.Stmt
|
editReply *sql.Stmt
|
||||||
stickTopic *sql.Stmt
|
|
||||||
unstickTopic *sql.Stmt
|
|
||||||
lockTopic *sql.Stmt
|
|
||||||
unlockTopic *sql.Stmt
|
|
||||||
updateLastIP *sql.Stmt
|
|
||||||
updateSession *sql.Stmt
|
|
||||||
setPassword *sql.Stmt
|
|
||||||
setAvatar *sql.Stmt
|
|
||||||
setUsername *sql.Stmt
|
|
||||||
changeGroup *sql.Stmt
|
|
||||||
activateUser *sql.Stmt
|
|
||||||
updateUserLevel *sql.Stmt
|
|
||||||
incrementUserScore *sql.Stmt
|
|
||||||
incrementUserPosts *sql.Stmt
|
|
||||||
incrementUserBigposts *sql.Stmt
|
|
||||||
incrementUserMegaposts *sql.Stmt
|
|
||||||
incrementUserTopics *sql.Stmt
|
|
||||||
editProfileReply *sql.Stmt
|
editProfileReply *sql.Stmt
|
||||||
updateForum *sql.Stmt
|
|
||||||
updateSetting *sql.Stmt
|
updateSetting *sql.Stmt
|
||||||
updatePlugin *sql.Stmt
|
updatePlugin *sql.Stmt
|
||||||
updatePluginInstall *sql.Stmt
|
updatePluginInstall *sql.Stmt
|
||||||
updateTheme *sql.Stmt
|
updateTheme *sql.Stmt
|
||||||
|
updateForum *sql.Stmt
|
||||||
updateUser *sql.Stmt
|
updateUser *sql.Stmt
|
||||||
updateUserGroup *sql.Stmt
|
|
||||||
updateGroupPerms *sql.Stmt
|
updateGroupPerms *sql.Stmt
|
||||||
updateGroupRank *sql.Stmt
|
|
||||||
updateGroup *sql.Stmt
|
updateGroup *sql.Stmt
|
||||||
updateEmail *sql.Stmt
|
updateEmail *sql.Stmt
|
||||||
verifyEmail *sql.Stmt
|
verifyEmail *sql.Stmt
|
||||||
setTempGroup *sql.Stmt
|
setTempGroup *sql.Stmt
|
||||||
updateWordFilter *sql.Stmt
|
updateWordFilter *sql.Stmt
|
||||||
bumpSync *sql.Stmt
|
bumpSync *sql.Stmt
|
||||||
deleteUser *sql.Stmt
|
|
||||||
deleteTopic *sql.Stmt
|
|
||||||
deleteReply *sql.Stmt
|
|
||||||
deleteProfileReply *sql.Stmt
|
deleteProfileReply *sql.Stmt
|
||||||
deleteActivityStreamMatch *sql.Stmt
|
deleteActivityStreamMatch *sql.Stmt
|
||||||
deleteWordFilter *sql.Stmt
|
deleteWordFilter *sql.Stmt
|
||||||
reportExists *sql.Stmt
|
reportExists *sql.Stmt
|
||||||
groupCount *sql.Stmt
|
|
||||||
modlogCount *sql.Stmt
|
modlogCount *sql.Stmt
|
||||||
notifyWatchers *sql.Stmt
|
notifyWatchers *sql.Stmt
|
||||||
|
|
||||||
|
@ -126,7 +84,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_mysql() (err error) {
|
func _gen_mysql() (err error) {
|
||||||
if dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Building the generated statements")
|
log.Print("Building the generated statements")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,30 +112,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getFullSettings statement.")
|
|
||||||
stmts.getFullSettings, err = db.Prepare("SELECT `name`,`content`,`type`,`constraints` FROM `settings`")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getPlugins statement.")
|
|
||||||
stmts.getPlugins, err = db.Prepare("SELECT `uname`,`active`,`installed` FROM `plugins`")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getThemes statement.")
|
|
||||||
stmts.getThemes, err = db.Prepare("SELECT `uname`,`default` FROM `themes`")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getWidgets statement.")
|
|
||||||
stmts.getWidgets, err = db.Prepare("SELECT `position`,`side`,`type`,`active`,`location`,`data` FROM `widgets` ORDER BY position ASC")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing isPluginActive statement.")
|
log.Print("Preparing isPluginActive statement.")
|
||||||
stmts.isPluginActive, err = db.Prepare("SELECT `active` FROM `plugins` WHERE `uname` = ?")
|
stmts.isPluginActive, err = db.Prepare("SELECT `active` FROM `plugins` WHERE `uname` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -190,12 +124,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getWordFilters statement.")
|
|
||||||
stmts.getWordFilters, err = db.Prepare("SELECT `wfid`,`find`,`replacement` FROM `word_filters`")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing isThemeDefault statement.")
|
log.Print("Preparing isThemeDefault statement.")
|
||||||
stmts.isThemeDefault, err = db.Prepare("SELECT `default` FROM `themes` WHERE `uname` = ?")
|
stmts.isThemeDefault, err = db.Prepare("SELECT `default` FROM `themes` WHERE `uname` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -232,18 +160,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing hasLikedTopic statement.")
|
|
||||||
stmts.hasLikedTopic, err = db.Prepare("SELECT `targetItem` FROM `likes` WHERE `sentBy` = ? AND `targetItem` = ? AND `targetType` = 'topics'")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing hasLikedReply statement.")
|
|
||||||
stmts.hasLikedReply, err = db.Prepare("SELECT `targetItem` FROM `likes` WHERE `sentBy` = ? AND `targetItem` = ? AND `targetType` = 'replies'")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getUserName statement.")
|
log.Print("Preparing getUserName statement.")
|
||||||
stmts.getUserName, err = db.Prepare("SELECT `name` FROM `users` WHERE `uid` = ?")
|
stmts.getUserName, err = db.Prepare("SELECT `name` FROM `users` WHERE `uid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -286,18 +202,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getExpiredScheduledGroups statement.")
|
|
||||||
stmts.getExpiredScheduledGroups, err = db.Prepare("SELECT `uid` FROM `users_groups_scheduler` WHERE UTC_TIMESTAMP() > `revert_at` AND `temporary` = 1")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getSync statement.")
|
|
||||||
stmts.getSync, err = db.Prepare("SELECT `last_update` FROM `sync`")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getAttachment statement.")
|
log.Print("Preparing getAttachment statement.")
|
||||||
stmts.getAttachment, err = db.Prepare("SELECT `sectionID`,`sectionTable`,`originID`,`originTable`,`uploadedBy`,`path` FROM `attachments` WHERE `path` = ? AND `sectionID` = ? AND `sectionTable` = ?")
|
stmts.getAttachment, err = db.Prepare("SELECT `sectionID`,`sectionTable`,`originID`,`originTable`,`uploadedBy`,`path` FROM `attachments` WHERE `path` = ? AND `sectionID` = ? AND `sectionTable` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -316,18 +220,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing getTopicUser statement.")
|
|
||||||
stmts.getTopicUser, err = db.Prepare("SELECT `topics`.`title`, `topics`.`content`, `topics`.`createdBy`, `topics`.`createdAt`, `topics`.`is_closed`, `topics`.`sticky`, `topics`.`parentID`, `topics`.`ipaddress`, `topics`.`postCount`, `topics`.`likeCount`, `users`.`name`, `users`.`avatar`, `users`.`group`, `users`.`url_prefix`, `users`.`url_name`, `users`.`level` FROM `topics` LEFT JOIN `users` ON `topics`.`createdBy` = `users`.`uid` WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getTopicByReply statement.")
|
|
||||||
stmts.getTopicByReply, err = db.Prepare("SELECT `topics`.`tid`, `topics`.`title`, `topics`.`content`, `topics`.`createdBy`, `topics`.`createdAt`, `topics`.`is_closed`, `topics`.`sticky`, `topics`.`parentID`, `topics`.`ipaddress`, `topics`.`postCount`, `topics`.`likeCount`, `topics`.`data` FROM `replies` LEFT JOIN `topics` ON `replies`.`tid` = `topics`.`tid` WHERE `rid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getTopicReplies statement.")
|
log.Print("Preparing getTopicReplies statement.")
|
||||||
stmts.getTopicReplies, err = db.Prepare("SELECT `replies`.`rid`, `replies`.`content`, `replies`.`createdBy`, `replies`.`createdAt`, `replies`.`lastEdit`, `replies`.`lastEditBy`, `users`.`avatar`, `users`.`name`, `users`.`group`, `users`.`url_prefix`, `users`.`url_name`, `users`.`level`, `replies`.`ipaddress` FROM `replies` LEFT JOIN `users` ON `replies`.`createdBy` = `users`.`uid` WHERE `tid` = ?")
|
stmts.getTopicReplies, err = db.Prepare("SELECT `replies`.`rid`, `replies`.`content`, `replies`.`createdBy`, `replies`.`createdAt`, `replies`.`lastEdit`, `replies`.`lastEditBy`, `users`.`avatar`, `users`.`name`, `users`.`group`, `users`.`url_prefix`, `users`.`url_name`, `users`.`level`, `replies`.`ipaddress` FROM `replies` LEFT JOIN `users` ON `replies`.`createdBy` = `users`.`uid` WHERE `tid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -358,18 +250,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing createActionReply statement.")
|
|
||||||
stmts.createActionReply, err = db.Prepare("INSERT INTO `replies`(`tid`,`actionType`,`ipaddress`,`createdBy`,`createdAt`,`lastUpdated`,`content`,`parsed_content`) VALUES (?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'','')")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing createLike statement.")
|
|
||||||
stmts.createLike, err = db.Prepare("INSERT INTO `likes`(`weight`,`targetItem`,`targetType`,`sentBy`) VALUES (?,?,?,?)")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addActivity statement.")
|
log.Print("Preparing addActivity statement.")
|
||||||
stmts.addActivity, err = db.Prepare("INSERT INTO `activity_stream`(`actor`,`targetUser`,`event`,`elementType`,`elementID`) VALUES (?,?,?,?,?)")
|
stmts.addActivity, err = db.Prepare("INSERT INTO `activity_stream`(`actor`,`targetUser`,`event`,`elementType`,`elementID`) VALUES (?,?,?,?,?)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -412,18 +292,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing addModlogEntry statement.")
|
|
||||||
stmts.addModlogEntry, err = db.Prepare("INSERT INTO `moderation_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,UTC_TIMESTAMP())")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addAdminlogEntry statement.")
|
|
||||||
stmts.addAdminlogEntry, err = db.Prepare("INSERT INTO `administration_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,UTC_TIMESTAMP())")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addAttachment statement.")
|
log.Print("Preparing addAttachment statement.")
|
||||||
stmts.addAttachment, err = db.Prepare("INSERT INTO `attachments`(`sectionID`,`sectionTable`,`originID`,`originTable`,`uploadedBy`,`path`) VALUES (?,?,?,?,?,?)")
|
stmts.addAttachment, err = db.Prepare("INSERT INTO `attachments`(`sectionID`,`sectionTable`,`originID`,`originTable`,`uploadedBy`,`path`) VALUES (?,?,?,?,?,?)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -436,156 +304,18 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing addRepliesToTopic statement.")
|
|
||||||
stmts.addRepliesToTopic, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyBy` = ?,`lastReplyAt` = UTC_TIMESTAMP() WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing removeRepliesFromTopic statement.")
|
|
||||||
stmts.removeRepliesFromTopic, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` - ? WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addLikesToTopic statement.")
|
|
||||||
stmts.addLikesToTopic, err = db.Prepare("UPDATE `topics` SET `likeCount` = `likeCount` + ? WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addLikesToReply statement.")
|
|
||||||
stmts.addLikesToReply, err = db.Prepare("UPDATE `replies` SET `likeCount` = `likeCount` + ? WHERE `rid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editTopic statement.")
|
|
||||||
stmts.editTopic, err = db.Prepare("UPDATE `topics` SET `title` = ?,`content` = ?,`parsed_content` = ? WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editReply statement.")
|
log.Print("Preparing editReply statement.")
|
||||||
stmts.editReply, err = db.Prepare("UPDATE `replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
stmts.editReply, err = db.Prepare("UPDATE `replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing stickTopic statement.")
|
|
||||||
stmts.stickTopic, err = db.Prepare("UPDATE `topics` SET `sticky` = 1 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing unstickTopic statement.")
|
|
||||||
stmts.unstickTopic, err = db.Prepare("UPDATE `topics` SET `sticky` = 0 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing lockTopic statement.")
|
|
||||||
stmts.lockTopic, err = db.Prepare("UPDATE `topics` SET `is_closed` = 1 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing unlockTopic statement.")
|
|
||||||
stmts.unlockTopic, err = db.Prepare("UPDATE `topics` SET `is_closed` = 0 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateLastIP statement.")
|
|
||||||
stmts.updateLastIP, err = db.Prepare("UPDATE `users` SET `last_ip` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateSession statement.")
|
|
||||||
stmts.updateSession, err = db.Prepare("UPDATE `users` SET `session` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setPassword statement.")
|
|
||||||
stmts.setPassword, err = db.Prepare("UPDATE `users` SET `password` = ?,`salt` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setAvatar statement.")
|
|
||||||
stmts.setAvatar, err = db.Prepare("UPDATE `users` SET `avatar` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setUsername statement.")
|
|
||||||
stmts.setUsername, err = db.Prepare("UPDATE `users` SET `name` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing changeGroup statement.")
|
|
||||||
stmts.changeGroup, err = db.Prepare("UPDATE `users` SET `group` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing activateUser statement.")
|
|
||||||
stmts.activateUser, err = db.Prepare("UPDATE `users` SET `active` = 1 WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateUserLevel statement.")
|
|
||||||
stmts.updateUserLevel, err = db.Prepare("UPDATE `users` SET `level` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserScore statement.")
|
|
||||||
stmts.incrementUserScore, err = db.Prepare("UPDATE `users` SET `score` = `score` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserPosts statement.")
|
|
||||||
stmts.incrementUserPosts, err = db.Prepare("UPDATE `users` SET `posts` = `posts` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserBigposts statement.")
|
|
||||||
stmts.incrementUserBigposts, err = db.Prepare("UPDATE `users` SET `posts` = `posts` + ?,`bigposts` = `bigposts` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserMegaposts statement.")
|
|
||||||
stmts.incrementUserMegaposts, err = db.Prepare("UPDATE `users` SET `posts` = `posts` + ?,`bigposts` = `bigposts` + ?,`megaposts` = `megaposts` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserTopics statement.")
|
|
||||||
stmts.incrementUserTopics, err = db.Prepare("UPDATE `users` SET `topics` = `topics` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editProfileReply statement.")
|
log.Print("Preparing editProfileReply statement.")
|
||||||
stmts.editProfileReply, err = db.Prepare("UPDATE `users_replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
stmts.editProfileReply, err = db.Prepare("UPDATE `users_replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateForum statement.")
|
|
||||||
stmts.updateForum, err = db.Prepare("UPDATE `forums` SET `name` = ?,`desc` = ?,`active` = ?,`preset` = ? WHERE `fid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateSetting statement.")
|
log.Print("Preparing updateSetting statement.")
|
||||||
stmts.updateSetting, err = db.Prepare("UPDATE `settings` SET `content` = ? WHERE `name` = ?")
|
stmts.updateSetting, err = db.Prepare("UPDATE `settings` SET `content` = ? WHERE `name` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -610,30 +340,24 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing updateForum statement.")
|
||||||
|
stmts.updateForum, err = db.Prepare("UPDATE `forums` SET `name` = ?,`desc` = ?,`active` = ?,`preset` = ? WHERE `fid` = ?")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateUser statement.")
|
log.Print("Preparing updateUser statement.")
|
||||||
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateUserGroup statement.")
|
|
||||||
stmts.updateUserGroup, err = db.Prepare("UPDATE `users` SET `group` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateGroupPerms statement.")
|
log.Print("Preparing updateGroupPerms statement.")
|
||||||
stmts.updateGroupPerms, err = db.Prepare("UPDATE `users_groups` SET `permissions` = ? WHERE `gid` = ?")
|
stmts.updateGroupPerms, err = db.Prepare("UPDATE `users_groups` SET `permissions` = ? WHERE `gid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateGroupRank statement.")
|
|
||||||
stmts.updateGroupRank, err = db.Prepare("UPDATE `users_groups` SET `is_admin` = ?,`is_mod` = ?,`is_banned` = ? WHERE `gid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateGroup statement.")
|
log.Print("Preparing updateGroup statement.")
|
||||||
stmts.updateGroup, err = db.Prepare("UPDATE `users_groups` SET `name` = ?,`tag` = ? WHERE `gid` = ?")
|
stmts.updateGroup, err = db.Prepare("UPDATE `users_groups` SET `name` = ?,`tag` = ? WHERE `gid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -670,24 +394,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing deleteUser statement.")
|
|
||||||
stmts.deleteUser, err = db.Prepare("DELETE FROM `users` WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing deleteTopic statement.")
|
|
||||||
stmts.deleteTopic, err = db.Prepare("DELETE FROM `topics` WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing deleteReply statement.")
|
|
||||||
stmts.deleteReply, err = db.Prepare("DELETE FROM `replies` WHERE `rid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing deleteProfileReply statement.")
|
log.Print("Preparing deleteProfileReply statement.")
|
||||||
stmts.deleteProfileReply, err = db.Prepare("DELETE FROM `users_replies` WHERE `rid` = ?")
|
stmts.deleteProfileReply, err = db.Prepare("DELETE FROM `users_replies` WHERE `rid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -712,12 +418,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing groupCount statement.")
|
|
||||||
stmts.groupCount, err = db.Prepare("SELECT COUNT(*) AS `count` FROM `users_groups`")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing modlogCount statement.")
|
log.Print("Preparing modlogCount statement.")
|
||||||
stmts.modlogCount, err = db.Prepare("SELECT COUNT(*) AS `count` FROM `moderation_logs`")
|
stmts.modlogCount, err = db.Prepare("SELECT COUNT(*) AS `count` FROM `moderation_logs`")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
185
gen_pgsql.go
185
gen_pgsql.go
|
@ -5,42 +5,19 @@ package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
type Stmts struct {
|
type Stmts struct {
|
||||||
addRepliesToTopic *sql.Stmt
|
|
||||||
removeRepliesFromTopic *sql.Stmt
|
|
||||||
addLikesToTopic *sql.Stmt
|
|
||||||
addLikesToReply *sql.Stmt
|
|
||||||
editTopic *sql.Stmt
|
|
||||||
editReply *sql.Stmt
|
editReply *sql.Stmt
|
||||||
stickTopic *sql.Stmt
|
|
||||||
unstickTopic *sql.Stmt
|
|
||||||
lockTopic *sql.Stmt
|
|
||||||
unlockTopic *sql.Stmt
|
|
||||||
updateLastIP *sql.Stmt
|
|
||||||
updateSession *sql.Stmt
|
|
||||||
setPassword *sql.Stmt
|
|
||||||
setAvatar *sql.Stmt
|
|
||||||
setUsername *sql.Stmt
|
|
||||||
changeGroup *sql.Stmt
|
|
||||||
activateUser *sql.Stmt
|
|
||||||
updateUserLevel *sql.Stmt
|
|
||||||
incrementUserScore *sql.Stmt
|
|
||||||
incrementUserPosts *sql.Stmt
|
|
||||||
incrementUserBigposts *sql.Stmt
|
|
||||||
incrementUserMegaposts *sql.Stmt
|
|
||||||
incrementUserTopics *sql.Stmt
|
|
||||||
editProfileReply *sql.Stmt
|
editProfileReply *sql.Stmt
|
||||||
updateForum *sql.Stmt
|
|
||||||
updateSetting *sql.Stmt
|
updateSetting *sql.Stmt
|
||||||
updatePlugin *sql.Stmt
|
updatePlugin *sql.Stmt
|
||||||
updatePluginInstall *sql.Stmt
|
updatePluginInstall *sql.Stmt
|
||||||
updateTheme *sql.Stmt
|
updateTheme *sql.Stmt
|
||||||
|
updateForum *sql.Stmt
|
||||||
updateUser *sql.Stmt
|
updateUser *sql.Stmt
|
||||||
updateUserGroup *sql.Stmt
|
|
||||||
updateGroupPerms *sql.Stmt
|
updateGroupPerms *sql.Stmt
|
||||||
updateGroupRank *sql.Stmt
|
|
||||||
updateGroup *sql.Stmt
|
updateGroup *sql.Stmt
|
||||||
updateEmail *sql.Stmt
|
updateEmail *sql.Stmt
|
||||||
verifyEmail *sql.Stmt
|
verifyEmail *sql.Stmt
|
||||||
|
@ -63,160 +40,22 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_pgsql() (err error) {
|
func _gen_pgsql() (err error) {
|
||||||
if dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Building the generated statements")
|
log.Print("Building the generated statements")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing addRepliesToTopic statement.")
|
|
||||||
stmts.addRepliesToTopic, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyBy` = ?,`lastReplyAt` = LOCALTIMESTAMP() WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing removeRepliesFromTopic statement.")
|
|
||||||
stmts.removeRepliesFromTopic, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` - ? WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addLikesToTopic statement.")
|
|
||||||
stmts.addLikesToTopic, err = db.Prepare("UPDATE `topics` SET `likeCount` = `likeCount` + ? WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing addLikesToReply statement.")
|
|
||||||
stmts.addLikesToReply, err = db.Prepare("UPDATE `replies` SET `likeCount` = `likeCount` + ? WHERE `rid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editTopic statement.")
|
|
||||||
stmts.editTopic, err = db.Prepare("UPDATE `topics` SET `title` = ?,`content` = ?,`parsed_content` = ? WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editReply statement.")
|
log.Print("Preparing editReply statement.")
|
||||||
stmts.editReply, err = db.Prepare("UPDATE `replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
stmts.editReply, err = db.Prepare("UPDATE `replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing stickTopic statement.")
|
|
||||||
stmts.stickTopic, err = db.Prepare("UPDATE `topics` SET `sticky` = 1 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing unstickTopic statement.")
|
|
||||||
stmts.unstickTopic, err = db.Prepare("UPDATE `topics` SET `sticky` = 0 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing lockTopic statement.")
|
|
||||||
stmts.lockTopic, err = db.Prepare("UPDATE `topics` SET `is_closed` = 1 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing unlockTopic statement.")
|
|
||||||
stmts.unlockTopic, err = db.Prepare("UPDATE `topics` SET `is_closed` = 0 WHERE `tid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateLastIP statement.")
|
|
||||||
stmts.updateLastIP, err = db.Prepare("UPDATE `users` SET `last_ip` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateSession statement.")
|
|
||||||
stmts.updateSession, err = db.Prepare("UPDATE `users` SET `session` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setPassword statement.")
|
|
||||||
stmts.setPassword, err = db.Prepare("UPDATE `users` SET `password` = ?,`salt` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setAvatar statement.")
|
|
||||||
stmts.setAvatar, err = db.Prepare("UPDATE `users` SET `avatar` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing setUsername statement.")
|
|
||||||
stmts.setUsername, err = db.Prepare("UPDATE `users` SET `name` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing changeGroup statement.")
|
|
||||||
stmts.changeGroup, err = db.Prepare("UPDATE `users` SET `group` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing activateUser statement.")
|
|
||||||
stmts.activateUser, err = db.Prepare("UPDATE `users` SET `active` = 1 WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateUserLevel statement.")
|
|
||||||
stmts.updateUserLevel, err = db.Prepare("UPDATE `users` SET `level` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserScore statement.")
|
|
||||||
stmts.incrementUserScore, err = db.Prepare("UPDATE `users` SET `score` = `score` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserPosts statement.")
|
|
||||||
stmts.incrementUserPosts, err = db.Prepare("UPDATE `users` SET `posts` = `posts` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserBigposts statement.")
|
|
||||||
stmts.incrementUserBigposts, err = db.Prepare("UPDATE `users` SET `posts` = `posts` + ?,`bigposts` = `bigposts` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserMegaposts statement.")
|
|
||||||
stmts.incrementUserMegaposts, err = db.Prepare("UPDATE `users` SET `posts` = `posts` + ?,`bigposts` = `bigposts` + ?,`megaposts` = `megaposts` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing incrementUserTopics statement.")
|
|
||||||
stmts.incrementUserTopics, err = db.Prepare("UPDATE `users` SET `topics` = `topics` + ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editProfileReply statement.")
|
log.Print("Preparing editProfileReply statement.")
|
||||||
stmts.editProfileReply, err = db.Prepare("UPDATE `users_replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
stmts.editProfileReply, err = db.Prepare("UPDATE `users_replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateForum statement.")
|
|
||||||
stmts.updateForum, err = db.Prepare("UPDATE `forums` SET `name` = ?,`desc` = ?,`active` = ?,`preset` = ? WHERE `fid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateSetting statement.")
|
log.Print("Preparing updateSetting statement.")
|
||||||
stmts.updateSetting, err = db.Prepare("UPDATE `settings` SET `content` = ? WHERE `name` = ?")
|
stmts.updateSetting, err = db.Prepare("UPDATE `settings` SET `content` = ? WHERE `name` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -241,30 +80,24 @@ func _gen_pgsql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing updateForum statement.")
|
||||||
|
stmts.updateForum, err = db.Prepare("UPDATE `forums` SET `name` = ?,`desc` = ?,`active` = ?,`preset` = ? WHERE `fid` = ?")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateUser statement.")
|
log.Print("Preparing updateUser statement.")
|
||||||
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateUserGroup statement.")
|
|
||||||
stmts.updateUserGroup, err = db.Prepare("UPDATE `users` SET `group` = ? WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateGroupPerms statement.")
|
log.Print("Preparing updateGroupPerms statement.")
|
||||||
stmts.updateGroupPerms, err = db.Prepare("UPDATE `users_groups` SET `permissions` = ? WHERE `gid` = ?")
|
stmts.updateGroupPerms, err = db.Prepare("UPDATE `users_groups` SET `permissions` = ? WHERE `gid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateGroupRank statement.")
|
|
||||||
stmts.updateGroupRank, err = db.Prepare("UPDATE `users_groups` SET `is_admin` = ?,`is_mod` = ?,`is_banned` = ? WHERE `gid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateGroup statement.")
|
log.Print("Preparing updateGroup statement.")
|
||||||
stmts.updateGroup, err = db.Prepare("UPDATE `users_groups` SET `name` = ?,`tag` = ? WHERE `gid` = ?")
|
stmts.updateGroup, err = db.Prepare("UPDATE `users_groups` SET `name` = ?,`tag` = ? WHERE `gid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -2,17 +2,21 @@
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "log"
|
import (
|
||||||
import "strings"
|
"log"
|
||||||
import "sync"
|
"strings"
|
||||||
import "errors"
|
"sync"
|
||||||
import "net/http"
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"./common"
|
||||||
|
)
|
||||||
|
|
||||||
var ErrNoRoute = errors.New("That route doesn't exist.")
|
var ErrNoRoute = errors.New("That route doesn't exist.")
|
||||||
|
|
||||||
type GenRouter struct {
|
type GenRouter struct {
|
||||||
UploadHandler func(http.ResponseWriter, *http.Request)
|
UploadHandler func(http.ResponseWriter, *http.Request)
|
||||||
extra_routes map[string]func(http.ResponseWriter, *http.Request, User) RouteError
|
extra_routes map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
@ -20,26 +24,26 @@ type GenRouter struct {
|
||||||
func NewGenRouter(uploads http.Handler) *GenRouter {
|
func NewGenRouter(uploads http.Handler) *GenRouter {
|
||||||
return &GenRouter{
|
return &GenRouter{
|
||||||
UploadHandler: http.StripPrefix("/uploads/",uploads).ServeHTTP,
|
UploadHandler: http.StripPrefix("/uploads/",uploads).ServeHTTP,
|
||||||
extra_routes: make(map[string]func(http.ResponseWriter, *http.Request, User) RouteError),
|
extra_routes: make(map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (router *GenRouter) handleError(err RouteError, w http.ResponseWriter, r *http.Request, user User) {
|
func (router *GenRouter) handleError(err common.RouteError, w http.ResponseWriter, r *http.Request, user common.User) {
|
||||||
if err.Handled() {
|
if err.Handled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err.Type() == "system" {
|
if err.Type() == "system" {
|
||||||
InternalErrorJSQ(err,w,r,err.Json())
|
common.InternalErrorJSQ(err, w, r, err.JSON())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
LocalErrorJSQ(err.Error(),w,r,user,err.Json())
|
common.LocalErrorJSQ(err.Error(), w, r, user,err.JSON())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (router *GenRouter) Handle(_ string, _ http.Handler) {
|
func (router *GenRouter) Handle(_ string, _ http.Handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (router *GenRouter) HandleFunc(pattern string, handle func(http.ResponseWriter, *http.Request, User) RouteError) {
|
func (router *GenRouter) HandleFunc(pattern string, handle func(http.ResponseWriter, *http.Request, common.User) common.RouteError) {
|
||||||
router.Lock()
|
router.Lock()
|
||||||
router.extra_routes[pattern] = handle
|
router.extra_routes[pattern] = handle
|
||||||
router.Unlock()
|
router.Unlock()
|
||||||
|
@ -52,7 +56,7 @@ func (router *GenRouter) RemoveFunc(pattern string) error {
|
||||||
router.Unlock()
|
router.Unlock()
|
||||||
return ErrNoRoute
|
return ErrNoRoute
|
||||||
}
|
}
|
||||||
delete(router.extra_routes,pattern)
|
delete(router.extra_routes, pattern)
|
||||||
router.Unlock()
|
router.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -75,7 +79,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("before routeStatic")
|
log.Print("before routeStatic")
|
||||||
log.Print("prefix: ", prefix)
|
log.Print("prefix: ", prefix)
|
||||||
log.Print("req.URL.Path: ", req.URL.Path)
|
log.Print("req.URL.Path: ", req.URL.Path)
|
||||||
|
@ -85,25 +89,25 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
if prefix == "/static" {
|
if prefix == "/static" {
|
||||||
req.URL.Path += extra_data
|
req.URL.Path += extra_data
|
||||||
routeStatic(w,req)
|
routeStatic(w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("before PreRoute")
|
log.Print("before PreRoute")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deal with the session stuff, etc.
|
// Deal with the session stuff, etc.
|
||||||
user, ok := PreRoute(w,req)
|
user, ok := common.PreRoute(w, req)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("after PreRoute")
|
log.Print("after PreRoute")
|
||||||
}
|
}
|
||||||
|
|
||||||
var err RouteError
|
var err common.RouteError
|
||||||
switch(prefix) {
|
switch(prefix) {
|
||||||
case "/api":
|
case "/api":
|
||||||
err = routeAPI(w,req,user)
|
err = routeAPI(w,req,user)
|
||||||
|
@ -136,19 +140,19 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/report":
|
case "/report":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = NoBanned(w,req,user)
|
err = common.NoBanned(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -164,7 +168,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
case "/topics":
|
case "/topics":
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/topics/create/":
|
case "/topics/create/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -178,7 +182,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/panel":
|
case "/panel":
|
||||||
err = SuperModOnly(w,req,user)
|
err = common.SuperModOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -260,7 +264,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
case "/user":
|
case "/user":
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/user/edit/critical/":
|
case "/user/edit/critical/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -268,13 +272,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeAccountEditCritical(w,req,user)
|
err = routeAccountEditCritical(w,req,user)
|
||||||
case "/user/edit/critical/submit/":
|
case "/user/edit/critical/submit/":
|
||||||
err = NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -282,7 +286,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeAccountEditCriticalSubmit(w,req,user)
|
err = routeAccountEditCriticalSubmit(w,req,user)
|
||||||
case "/user/edit/avatar/":
|
case "/user/edit/avatar/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -290,7 +294,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeAccountEditAvatar(w,req,user)
|
err = routeAccountEditAvatar(w,req,user)
|
||||||
case "/user/edit/avatar/submit/":
|
case "/user/edit/avatar/submit/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -298,7 +302,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeAccountEditAvatarSubmit(w,req,user)
|
err = routeAccountEditAvatarSubmit(w,req,user)
|
||||||
case "/user/edit/username/":
|
case "/user/edit/username/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -306,7 +310,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeAccountEditUsername(w,req,user)
|
err = routeAccountEditUsername(w,req,user)
|
||||||
case "/user/edit/username/submit/":
|
case "/user/edit/username/submit/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -314,7 +318,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeAccountEditUsernameSubmit(w,req,user)
|
err = routeAccountEditUsernameSubmit(w,req,user)
|
||||||
case "/user/edit/email/":
|
case "/user/edit/email/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -322,7 +326,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeAccountEditEmail(w,req,user)
|
err = routeAccountEditEmail(w,req,user)
|
||||||
case "/user/edit/token/":
|
case "/user/edit/token/":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -337,7 +341,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/users":
|
case "/users":
|
||||||
err = MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -345,7 +349,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/users/ban/submit/":
|
case "/users/ban/submit/":
|
||||||
err = NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -353,7 +357,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeBanSubmit(w,req,user)
|
err = routeBanSubmit(w,req,user)
|
||||||
case "/users/unban/":
|
case "/users/unban/":
|
||||||
err = NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -361,7 +365,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
err = routeUnban(w,req,user)
|
err = routeUnban(w,req,user)
|
||||||
case "/users/activate/":
|
case "/users/activate/":
|
||||||
err = NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -376,7 +380,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
case "/uploads":
|
case "/uploads":
|
||||||
if extra_data == "" {
|
if extra_data == "" {
|
||||||
NotFound(w,req)
|
common.NotFound(w,req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.URL.Path += extra_data
|
req.URL.Path += extra_data
|
||||||
|
@ -395,10 +399,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if extra_data != "" {
|
if extra_data != "" {
|
||||||
NotFound(w,req)
|
common.NotFound(w,req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
config.DefaultRoute(w,req,user)
|
common.Config.DefaultRoute(w,req,user)
|
||||||
default:
|
default:
|
||||||
// A fallback for the routes which haven't been converted to the new router yet or plugins
|
// A fallback for the routes which haven't been converted to the new router yet or plugins
|
||||||
router.RLock()
|
router.RLock()
|
||||||
|
@ -413,6 +417,6 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
NotFound(w,req)
|
common.NotFound(w,req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"./common"
|
||||||
"./install/install"
|
"./install/install"
|
||||||
//"runtime/pprof"
|
//"runtime/pprof"
|
||||||
//_ "github.com/go-sql-driver/mysql"
|
//_ "github.com/go-sql-driver/mysql"
|
||||||
|
@ -46,28 +47,28 @@ func ResetTables() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func gloinit() (err error) {
|
func gloinit() (err error) {
|
||||||
dev.DebugMode = false
|
common.Dev.DebugMode = false
|
||||||
//nogrouplog = true
|
//nogrouplog = true
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
|
|
||||||
err = processConfig()
|
err = common.ProcessConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = initThemes()
|
err = common.InitThemes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switchToTestDB()
|
common.SwitchToTestDB()
|
||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
installAdapter, ok = install.Lookup(dbAdapter)
|
installAdapter, ok = install.Lookup(dbAdapter)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("We couldn't find the adapter '" + dbAdapter + "'")
|
return errors.New("We couldn't find the adapter '" + dbAdapter + "'")
|
||||||
}
|
}
|
||||||
installAdapter.SetConfig(dbConfig.Host, dbConfig.Username, dbConfig.Password, dbConfig.Dbname, dbConfig.Port)
|
installAdapter.SetConfig(common.DbConfig.Host, common.DbConfig.Username, common.DbConfig.Password, common.DbConfig.Dbname, common.DbConfig.Port)
|
||||||
|
|
||||||
err = ResetTables()
|
err = ResetTables()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -97,67 +97,69 @@ func main() {
|
||||||
|
|
||||||
configContents := []byte(`package main
|
configContents := []byte(`package main
|
||||||
|
|
||||||
|
import "./common"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Site Info
|
// Site Info
|
||||||
site.ShortName = "` + siteShortName + `" // This should be less than three letters to fit in the navbar
|
common.Site.ShortName = "` + siteShortName + `" // This should be less than three letters to fit in the navbar
|
||||||
site.Name = "` + siteName + `"
|
common.Site.Name = "` + siteName + `"
|
||||||
site.Email = ""
|
common.Site.Email = ""
|
||||||
site.URL = "` + siteURL + `"
|
common.Site.URL = "` + siteURL + `"
|
||||||
site.Port = "` + serverPort + `"
|
common.Site.Port = "` + serverPort + `"
|
||||||
site.EnableSsl = false
|
common.Site.EnableSsl = false
|
||||||
site.EnableEmails = false
|
common.Site.EnableEmails = false
|
||||||
site.HasProxy = false // Cloudflare counts as this, if it's sitting in the middle
|
common.Site.HasProxy = false // Cloudflare counts as this, if it's sitting in the middle
|
||||||
config.SslPrivkey = ""
|
common.Config.SslPrivkey = ""
|
||||||
config.SslFullchain = ""
|
common.Config.SslFullchain = ""
|
||||||
site.Language = "english"
|
common.Site.Language = "english"
|
||||||
|
|
||||||
// Database details
|
// Database details
|
||||||
dbConfig.Host = "` + adap.DBHost() + `"
|
common.DbConfig.Host = "` + adap.DBHost() + `"
|
||||||
dbConfig.Username = "` + adap.DBUsername() + `"
|
common.DbConfig.Username = "` + adap.DBUsername() + `"
|
||||||
dbConfig.Password = "` + adap.DBPassword() + `"
|
common.DbConfig.Password = "` + adap.DBPassword() + `"
|
||||||
dbConfig.Dbname = "` + adap.DBName() + `"
|
common.DbConfig.Dbname = "` + adap.DBName() + `"
|
||||||
dbConfig.Port = "` + adap.DBPort() + `" // You probably won't need to change this
|
common.DbConfig.Port = "` + adap.DBPort() + `" // You probably won't need to change this
|
||||||
|
|
||||||
// Test Database details
|
// Test Database details
|
||||||
dbConfig.TestHost = ""
|
common.DbConfig.TestHost = ""
|
||||||
dbConfig.TestUsername = ""
|
common.DbConfig.TestUsername = ""
|
||||||
dbConfig.TestPassword = ""
|
common.DbConfig.TestPassword = ""
|
||||||
dbConfig.TestDbname = "" // The name of the test database, leave blank to disable. DON'T USE YOUR PRODUCTION DATABASE FOR THIS. LEAVE BLANK IF YOU DON'T KNOW WHAT THIS MEANS.
|
common.DbConfig.TestDbname = "" // The name of the test database, leave blank to disable. DON'T USE YOUR PRODUCTION DATABASE FOR THIS. LEAVE BLANK IF YOU DON'T KNOW WHAT THIS MEANS.
|
||||||
dbConfig.TestPort = ""
|
common.DbConfig.TestPort = ""
|
||||||
|
|
||||||
// Limiters
|
// Limiters
|
||||||
config.MaxRequestSize = 5 * megabyte
|
common.Config.MaxRequestSize = 5 * common.Megabyte
|
||||||
|
|
||||||
// Caching
|
// Caching
|
||||||
config.CacheTopicUser = CACHE_STATIC
|
common.Config.CacheTopicUser = common.CACHE_STATIC
|
||||||
config.UserCacheCapacity = 120 // The max number of users held in memory
|
common.Config.UserCacheCapacity = 120 // The max number of users held in memory
|
||||||
config.TopicCacheCapacity = 200 // The max number of topics held in memory
|
common.Config.TopicCacheCapacity = 200 // The max number of topics held in memory
|
||||||
|
|
||||||
// Email
|
// Email
|
||||||
config.SMTPServer = ""
|
common.Config.SMTPServer = ""
|
||||||
config.SMTPUsername = ""
|
common.Config.SMTPUsername = ""
|
||||||
config.SMTPPassword = ""
|
common.Config.SMTPPassword = ""
|
||||||
config.SMTPPort = "25"
|
common.Config.SMTPPort = "25"
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
config.DefaultRoute = routeTopics
|
common.Config.DefaultRoute = routeTopics
|
||||||
config.DefaultGroup = 3 // Should be a setting in the database
|
common.Config.DefaultGroup = 3 // Should be a setting in the database
|
||||||
config.ActivationGroup = 5 // Should be a setting in the database
|
common.Config.ActivationGroup = 5 // Should be a setting in the database
|
||||||
config.StaffCSS = "staff_post"
|
common.Config.StaffCSS = "staff_post"
|
||||||
config.DefaultForum = 2
|
common.Config.DefaultForum = 2
|
||||||
config.MinifyTemplates = true
|
common.Config.MinifyTemplates = true
|
||||||
config.MultiServer = false // Experimental: Enable Cross-Server Synchronisation and several other features
|
common.Config.MultiServer = false // Experimental: Enable Cross-Server Synchronisation and several other features
|
||||||
|
|
||||||
//config.Noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png"
|
//common.Config.Noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png"
|
||||||
config.Noavatar = "https://api.adorable.io/avatars/285/{id}@{site_url}.png"
|
common.Config.Noavatar = "https://api.adorable.io/avatars/285/{id}@{site_url}.png"
|
||||||
config.ItemsPerPage = 25
|
common.Config.ItemsPerPage = 25
|
||||||
|
|
||||||
// Developer flags
|
// Developer flags
|
||||||
dev.DebugMode = true
|
common.Dev.DebugMode = true
|
||||||
//dev.SuperDebug = true
|
//common.Dev.SuperDebug = true
|
||||||
//dev.TemplateDebug = true
|
//common.Dev.TemplateDebug = true
|
||||||
//dev.Profiling = true
|
//common.Dev.Profiling = true
|
||||||
//dev.TestDB = true
|
//common.Dev.TestDB = true
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
|
116
main.go
116
main.go
|
@ -14,65 +14,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
//"runtime/pprof"
|
//"runtime/pprof"
|
||||||
|
"./common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = Version{Major: 0, Minor: 1, Patch: 0, Tag: "dev"}
|
var version = common.Version{Major: 0, Minor: 1, Patch: 0, Tag: "dev"}
|
||||||
|
|
||||||
const hour int = 60 * 60
|
|
||||||
const day int = hour * 24
|
|
||||||
const week int = day * 7
|
|
||||||
const month int = day * 30
|
|
||||||
const year int = day * 365
|
|
||||||
const kilobyte int = 1024
|
|
||||||
const megabyte int = kilobyte * 1024
|
|
||||||
const gigabyte int = megabyte * 1024
|
|
||||||
const terabyte int = gigabyte * 1024
|
|
||||||
const petabyte int = terabyte * 1024
|
|
||||||
const saltLength int = 32
|
|
||||||
const sessionLength int = 80
|
|
||||||
|
|
||||||
var router *GenRouter
|
var router *GenRouter
|
||||||
var startTime time.Time
|
var startTime time.Time
|
||||||
|
|
||||||
// ? - Make this more customisable?
|
|
||||||
var externalSites = map[string]string{
|
|
||||||
"YT": "https://www.youtube.com/",
|
|
||||||
}
|
|
||||||
|
|
||||||
type StringList []string
|
|
||||||
|
|
||||||
// ? - Should we allow users to upload .php or .go files? It could cause security issues. We could store them with a mangled extension to render them inert
|
|
||||||
// TODO: Let admins manage this from the Control Panel
|
|
||||||
var allowedFileExts = StringList{
|
|
||||||
"png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", "apng", // images
|
|
||||||
|
|
||||||
"txt", "xml", "json", "yaml", "toml", "ini", "md", "html", "rtf", "js", "py", "rb", "css", "scss", "less", "eqcss", "pcss", "java", "ts", "cs", "c", "cc", "cpp", "cxx", "C", "c++", "h", "hh", "hpp", "hxx", "h++", "rs", "rlib", "htaccess", "gitignore", // text
|
|
||||||
|
|
||||||
"mp3", "mp4", "avi", "wmv", "webm", // video
|
|
||||||
|
|
||||||
"otf", "woff2", "woff", "ttf", "eot", // fonts
|
|
||||||
}
|
|
||||||
var imageFileExts = StringList{
|
|
||||||
"png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", "apng",
|
|
||||||
}
|
|
||||||
var archiveFileExts = StringList{
|
|
||||||
"bz2", "zip", "gz", "7z", "tar", "cab",
|
|
||||||
}
|
|
||||||
var executableFileExts = StringList{
|
|
||||||
"exe", "jar", "phar", "shar", "iso",
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Write a test for this
|
|
||||||
func (slice StringList) Contains(needle string) bool {
|
|
||||||
for _, item := range slice {
|
|
||||||
if item == needle {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var staticFiles = make(map[string]SFile)
|
|
||||||
var logWriter = io.MultiWriter(os.Stderr)
|
var logWriter = io.MultiWriter(os.Stderr)
|
||||||
|
|
||||||
// TODO: Wrap the globals in here so we can pass pointers to them to subpackages
|
// TODO: Wrap the globals in here so we can pass pointers to them to subpackages
|
||||||
|
@ -128,58 +75,61 @@ func main() {
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
|
|
||||||
log.Print("Processing configuration data")
|
log.Print("Processing configuration data")
|
||||||
err = processConfig()
|
err = common.ProcessConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = initThemes()
|
err = common.InitThemes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = initDatabase()
|
err = InitDatabase()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rstore, err = NewSQLReplyStore()
|
common.Rstore, err = common.NewSQLReplyStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
prstore, err = NewSQLProfileReplyStore()
|
common.Prstore, err = common.NewSQLProfileReplyStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
initTemplates()
|
common.InitTemplates()
|
||||||
|
|
||||||
err = initPhrases()
|
err = common.InitPhrases()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Loading the static files.")
|
log.Print("Loading the static files.")
|
||||||
err = initStaticFiles()
|
err = common.StaticFiles.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Initialising the widgets")
|
log.Print("Initialising the widgets")
|
||||||
err = initWidgets()
|
err = common.InitWidgets()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Initialising the authentication system")
|
log.Print("Initialising the authentication system")
|
||||||
auth = NewDefaultAuth()
|
common.Auth, err = common.NewDefaultAuth()
|
||||||
|
|
||||||
err = LoadWordFilters()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = verifyConfig()
|
err = common.LoadWordFilters()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = common.VerifyConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -195,18 +145,18 @@ func main() {
|
||||||
//log.Print("Running the second ticker")
|
//log.Print("Running the second ticker")
|
||||||
// TODO: Add a plugin hook here
|
// TODO: Add a plugin hook here
|
||||||
|
|
||||||
err := handleExpiredScheduledGroups()
|
err := common.HandleExpiredScheduledGroups()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
common.LogError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle delayed moderation tasks
|
// TODO: Handle delayed moderation tasks
|
||||||
// TODO: Handle the daily clean-up. Move this to a 24 hour task?
|
// TODO: Handle the daily clean-up. Move this to a 24 hour task?
|
||||||
|
|
||||||
// Sync with the database, if there are any changes
|
// Sync with the database, if there are any changes
|
||||||
err = handleServerSync()
|
err = common.HandleServerSync()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(err)
|
common.LogError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Manage the TopicStore, UserStore, and ForumStore
|
// TODO: Manage the TopicStore, UserStore, and ForumStore
|
||||||
|
@ -264,7 +214,7 @@ func main() {
|
||||||
router.HandleFunc("/ws/", routeWebsockets)
|
router.HandleFunc("/ws/", routeWebsockets)
|
||||||
|
|
||||||
log.Print("Initialising the plugins")
|
log.Print("Initialising the plugins")
|
||||||
initPlugins()
|
common.InitPlugins()
|
||||||
|
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
|
@ -274,17 +224,17 @@ func main() {
|
||||||
|
|
||||||
// TODO: Let users run *both* HTTP and HTTPS
|
// TODO: Let users run *both* HTTP and HTTPS
|
||||||
log.Print("Initialising the HTTP server")
|
log.Print("Initialising the HTTP server")
|
||||||
if !site.EnableSsl {
|
if !common.Site.EnableSsl {
|
||||||
if site.Port == "" {
|
if common.Site.Port == "" {
|
||||||
site.Port = "80"
|
common.Site.Port = "80"
|
||||||
}
|
}
|
||||||
log.Print("Listening on port " + site.Port)
|
log.Print("Listening on port " + common.Site.Port)
|
||||||
err = http.ListenAndServe(":"+site.Port, router)
|
err = http.ListenAndServe(":"+common.Site.Port, router)
|
||||||
} else {
|
} else {
|
||||||
if site.Port == "" {
|
if common.Site.Port == "" {
|
||||||
site.Port = "443"
|
common.Site.Port = "443"
|
||||||
}
|
}
|
||||||
if site.Port == "80" || site.Port == "443" {
|
if common.Site.Port == "80" || common.Site.Port == "443" {
|
||||||
// We should also run the server on port 80
|
// We should also run the server on port 80
|
||||||
// TODO: Redirect to port 443
|
// TODO: Redirect to port 443
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -295,8 +245,8 @@ func main() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
log.Print("Listening on port " + site.Port)
|
log.Printf("Listening on port %s", common.Site.Port)
|
||||||
err = http.ListenAndServeTLS(":"+site.Port, config.SslFullchain, config.SslPrivkey, router)
|
err = http.ListenAndServeTLS(":"+common.Site.Port, common.Config.SslFullchain, common.Config.SslPrivkey, router)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Why did the server stop?
|
// Why did the server stop?
|
||||||
|
|
548
member_routes.go
548
member_routes.go
File diff suppressed because it is too large
Load Diff
130
misc_test.go
130
misc_test.go
|
@ -8,6 +8,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"./common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func recordMustExist(t *testing.T, err error, errmsg string, args ...interface{}) {
|
func recordMustExist(t *testing.T, err error, errmsg string, args ...interface{}) {
|
||||||
|
@ -47,22 +49,22 @@ func TestUserStore(t *testing.T) {
|
||||||
userStoreTest(t, 3)
|
userStoreTest(t, 3)
|
||||||
}
|
}
|
||||||
func userStoreTest(t *testing.T, newUserID int) {
|
func userStoreTest(t *testing.T, newUserID int) {
|
||||||
ucache, hasCache := users.(UserCache)
|
ucache, hasCache := common.Users.(UserCache)
|
||||||
// Go doesn't have short-circuiting, so this'll allow us to do one liner tests
|
// Go doesn't have short-circuiting, so this'll allow us to do one liner tests
|
||||||
if !hasCache {
|
if !hasCache {
|
||||||
ucache = &NullUserStore{}
|
ucache = &NullUserStore{}
|
||||||
}
|
}
|
||||||
expect(t, (!hasCache || ucache.Length() == 0), fmt.Sprintf("The initial ucache length should be zero, not %d", ucache.Length()))
|
expect(t, (!hasCache || ucache.Length() == 0), fmt.Sprintf("The initial ucache length should be zero, not %d", ucache.Length()))
|
||||||
|
|
||||||
_, err := users.Get(-1)
|
_, err := common.Users.Get(-1)
|
||||||
recordMustNotExist(t, err, "UID #-1 shouldn't exist")
|
recordMustNotExist(t, err, "UID #-1 shouldn't exist")
|
||||||
expect(t, !hasCache || ucache.Length() == 0, fmt.Sprintf("We found %d items in the user cache and it's supposed to be empty", ucache.Length()))
|
expect(t, !hasCache || ucache.Length() == 0, fmt.Sprintf("We found %d items in the user cache and it's supposed to be empty", ucache.Length()))
|
||||||
|
|
||||||
_, err = users.Get(0)
|
_, err = common.Users.Get(0)
|
||||||
recordMustNotExist(t, err, "UID #0 shouldn't exist")
|
recordMustNotExist(t, err, "UID #0 shouldn't exist")
|
||||||
expect(t, !hasCache || ucache.Length() == 0, fmt.Sprintf("We found %d items in the user cache and it's supposed to be empty", ucache.Length()))
|
expect(t, !hasCache || ucache.Length() == 0, fmt.Sprintf("We found %d items in the user cache and it's supposed to be empty", ucache.Length()))
|
||||||
|
|
||||||
user, err := users.Get(1)
|
user, err := common.Users.Get(1)
|
||||||
recordMustExist(t, err, "Couldn't find UID #1")
|
recordMustExist(t, err, "Couldn't find UID #1")
|
||||||
|
|
||||||
expect(t, user.ID == 1, fmt.Sprintf("user.ID should be 1. Got '%d' instead.", user.ID))
|
expect(t, user.ID == 1, fmt.Sprintf("user.ID should be 1. Got '%d' instead.", user.ID))
|
||||||
|
@ -74,7 +76,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expect(t, user.IsMod, "Admin should be a mod")
|
expect(t, user.IsMod, "Admin should be a mod")
|
||||||
expect(t, !user.IsBanned, "Admin should not be banned")
|
expect(t, !user.IsBanned, "Admin should not be banned")
|
||||||
|
|
||||||
_, err = users.Get(newUserID)
|
_, err = common.Users.Get(newUserID)
|
||||||
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't exist", newUserID))
|
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't exist", newUserID))
|
||||||
|
|
||||||
if hasCache {
|
if hasCache {
|
||||||
|
@ -103,7 +105,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
|
|
||||||
// TODO: Lock onto the specific error type. Is this even possible without sacrificing the detailed information in the error message?
|
// TODO: Lock onto the specific error type. Is this even possible without sacrificing the detailed information in the error message?
|
||||||
var userList map[int]*User
|
var userList map[int]*User
|
||||||
userList, _ = users.BulkGetMap([]int{-1})
|
userList, _ = common.Users.BulkGetMap([]int{-1})
|
||||||
if len(userList) > 0 {
|
if len(userList) > 0 {
|
||||||
t.Error("There shouldn't be any results for UID #-1")
|
t.Error("There shouldn't be any results for UID #-1")
|
||||||
}
|
}
|
||||||
|
@ -112,7 +114,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||||
}
|
}
|
||||||
|
|
||||||
userList, _ = users.BulkGetMap([]int{0})
|
userList, _ = common.Users.BulkGetMap([]int{0})
|
||||||
if len(userList) > 0 {
|
if len(userList) > 0 {
|
||||||
t.Error("There shouldn't be any results for UID #0")
|
t.Error("There shouldn't be any results for UID #0")
|
||||||
}
|
}
|
||||||
|
@ -121,7 +123,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||||
}
|
}
|
||||||
|
|
||||||
userList, _ = users.BulkGetMap([]int{1})
|
userList, _ = common.Users.BulkGetMap([]int{1})
|
||||||
if len(userList) == 0 {
|
if len(userList) == 0 {
|
||||||
t.Error("The returned map is empty for UID #1")
|
t.Error("The returned map is empty for UID #1")
|
||||||
} else if len(userList) > 1 {
|
} else if len(userList) > 1 {
|
||||||
|
@ -151,19 +153,19 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
|
|
||||||
expect(t, !users.Exists(-1), "UID #-1 shouldn't exist")
|
expect(t, !users.Exists(-1), "UID #-1 shouldn't exist")
|
||||||
expect(t, !users.Exists(0), "UID #0 shouldn't exist")
|
expect(t, !users.Exists(0), "UID #0 shouldn't exist")
|
||||||
expect(t, users.Exists(1), "UID #1 should exist")
|
expect(t, common.Users.Exists(1), "UID #1 should exist")
|
||||||
expect(t, !users.Exists(newUserID), fmt.Sprintf("UID #%d shouldn't exist", newUserID))
|
expect(t, !users.Exists(newUserID), fmt.Sprintf("UID #%d shouldn't exist", newUserID))
|
||||||
|
|
||||||
expect(t, !hasCache || ucache.Length() == 0, fmt.Sprintf("User cache length should be 0, not %d", ucache.Length()))
|
expect(t, !hasCache || ucache.Length() == 0, fmt.Sprintf("User cache length should be 0, not %d", ucache.Length()))
|
||||||
expectIntToBeX(t, users.GlobalCount(), 1, "The number of users should be one, not %d")
|
expectIntToBeX(t, common.Users.GlobalCount(), 1, "The number of users should be one, not %d")
|
||||||
|
|
||||||
var awaitingActivation = 5
|
var awaitingActivation = 5
|
||||||
uid, err := users.Create("Sam", "ReallyBadPassword", "sam@localhost.loc", awaitingActivation, false)
|
uid, err := common.Users.Create("Sam", "ReallyBadPassword", "sam@localhost.loc", awaitingActivation, false)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, uid == newUserID, fmt.Sprintf("The UID of the new user should be %d", newUserID))
|
expect(t, uid == newUserID, fmt.Sprintf("The UID of the new user should be %d", newUserID))
|
||||||
expect(t, users.Exists(newUserID), fmt.Sprintf("UID #%d should exist", newUserID))
|
expect(t, common.Users.Exists(newUserID), fmt.Sprintf("UID #%d should exist", newUserID))
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
if user.ID != newUserID {
|
if user.ID != newUserID {
|
||||||
t.Errorf("The UID of the user record should be %d", newUserID)
|
t.Errorf("The UID of the user record should be %d", newUserID)
|
||||||
|
@ -195,7 +197,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
|
|
||||||
expect(t, user.ID == newUserID, fmt.Sprintf("The UID of the user record should be %d, not %d", newUserID, user.ID))
|
expect(t, user.ID == newUserID, fmt.Sprintf("The UID of the user record should be %d, not %d", newUserID, user.ID))
|
||||||
|
@ -221,7 +223,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
if user.ID != newUserID {
|
if user.ID != newUserID {
|
||||||
t.Errorf("The UID of the user record should be %d", newUserID)
|
t.Errorf("The UID of the user record should be %d", newUserID)
|
||||||
|
@ -247,7 +249,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
||||||
|
|
||||||
|
@ -270,7 +272,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, user.Group == config.DefaultGroup, "Someone's mutated this pointer elsewhere")
|
expect(t, user.Group == config.DefaultGroup, "Someone's mutated this pointer elsewhere")
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
||||||
var user2 *User = getDummyUser()
|
var user2 *User = getDummyUser()
|
||||||
|
@ -293,7 +295,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, user.Group == 1, "Someone's mutated this pointer elsewhere")
|
expect(t, user.Group == 1, "Someone's mutated this pointer elsewhere")
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
||||||
user2 = getDummyUser()
|
user2 = getDummyUser()
|
||||||
|
@ -316,7 +318,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, user.Group == 2, "Someone's mutated this pointer elsewhere")
|
expect(t, user.Group == 2, "Someone's mutated this pointer elsewhere")
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
||||||
user2 = getDummyUser()
|
user2 = getDummyUser()
|
||||||
|
@ -340,7 +342,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, user.Group == 3, "Someone's mutated this pointer elsewhere")
|
expect(t, user.Group == 3, "Someone's mutated this pointer elsewhere")
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
||||||
user2 = getDummyUser()
|
user2 = getDummyUser()
|
||||||
|
@ -363,7 +365,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, user.Group == 4, "Someone's mutated this pointer elsewhere")
|
expect(t, user.Group == 4, "Someone's mutated this pointer elsewhere")
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
||||||
user2 = getDummyUser()
|
user2 = getDummyUser()
|
||||||
|
@ -386,7 +388,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, user.Group == 5, "Someone's mutated this pointer elsewhere")
|
expect(t, user.Group == 5, "Someone's mutated this pointer elsewhere")
|
||||||
|
|
||||||
user, err = users.Get(newUserID)
|
user, err = common.Users.Get(newUserID)
|
||||||
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
|
||||||
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
expectIntToBeX(t, user.ID, newUserID, "The UID of the user record should be %d")
|
||||||
user2 = getDummyUser()
|
user2 = getDummyUser()
|
||||||
|
@ -419,7 +421,7 @@ func userStoreTest(t *testing.T, newUserID int) {
|
||||||
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
recordMustNotExist(t, err, "UID #%d shouldn't be in the cache", newUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = users.Get(newUserID)
|
_, err = common.Users.Get(newUserID)
|
||||||
recordMustNotExist(t, err, "UID #%d shouldn't exist", newUserID)
|
recordMustNotExist(t, err, "UID #%d shouldn't exist", newUserID)
|
||||||
|
|
||||||
// TODO: Add tests for the Cache* methods
|
// TODO: Add tests for the Cache* methods
|
||||||
|
@ -515,13 +517,13 @@ func topicStoreTest(t *testing.T) {
|
||||||
var topic *Topic
|
var topic *Topic
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
_, err = topics.Get(-1)
|
_, err = common.Topics.Get(-1)
|
||||||
recordMustNotExist(t, err, "TID #-1 shouldn't exist")
|
recordMustNotExist(t, err, "TID #-1 shouldn't exist")
|
||||||
|
|
||||||
_, err = topics.Get(0)
|
_, err = common.Topics.Get(0)
|
||||||
recordMustNotExist(t, err, "TID #0 shouldn't exist")
|
recordMustNotExist(t, err, "TID #0 shouldn't exist")
|
||||||
|
|
||||||
topic, err = topics.Get(1)
|
topic, err = common.Topics.Get(1)
|
||||||
recordMustExist(t, err, "Couldn't find TID #1")
|
recordMustExist(t, err, "Couldn't find TID #1")
|
||||||
|
|
||||||
if topic.ID != 1 {
|
if topic.ID != 1 {
|
||||||
|
@ -530,22 +532,22 @@ func topicStoreTest(t *testing.T) {
|
||||||
|
|
||||||
// TODO: Add BulkGetMap() to the TopicStore
|
// TODO: Add BulkGetMap() to the TopicStore
|
||||||
|
|
||||||
ok := topics.Exists(-1)
|
ok := common.Topics.Exists(-1)
|
||||||
if ok {
|
if ok {
|
||||||
t.Error("TID #-1 shouldn't exist")
|
t.Error("TID #-1 shouldn't exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = topics.Exists(0)
|
ok = common.Topics.Exists(0)
|
||||||
if ok {
|
if ok {
|
||||||
t.Error("TID #0 shouldn't exist")
|
t.Error("TID #0 shouldn't exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = topics.Exists(1)
|
ok = common.Topics.Exists(1)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error("TID #1 should exist")
|
t.Error("TID #1 should exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
count := topics.GlobalCount()
|
count := common.Topics.GlobalCount()
|
||||||
if count <= 0 {
|
if count <= 0 {
|
||||||
t.Error("The number of topics should be bigger than zero")
|
t.Error("The number of topics should be bigger than zero")
|
||||||
t.Error("count", count)
|
t.Error("count", count)
|
||||||
|
@ -620,11 +622,11 @@ func TestGroupStore(t *testing.T) {
|
||||||
initPlugins()
|
initPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := gstore.Get(-1)
|
_, err := common.Gstore.Get(-1)
|
||||||
recordMustNotExist(t, err, "GID #-1 shouldn't exist")
|
recordMustNotExist(t, err, "GID #-1 shouldn't exist")
|
||||||
|
|
||||||
// TODO: Refactor the group store to remove GID #0
|
// TODO: Refactor the group store to remove GID #0
|
||||||
group, err := gstore.Get(0)
|
group, err := common.Gstore.Get(0)
|
||||||
recordMustExist(t, err, "Couldn't find GID #0")
|
recordMustExist(t, err, "Couldn't find GID #0")
|
||||||
|
|
||||||
if group.ID != 0 {
|
if group.ID != 0 {
|
||||||
|
@ -632,31 +634,31 @@ func TestGroupStore(t *testing.T) {
|
||||||
}
|
}
|
||||||
expect(t, group.Name == "Unknown", fmt.Sprintf("GID #0 is named '%s' and not 'Unknown'", group.Name))
|
expect(t, group.Name == "Unknown", fmt.Sprintf("GID #0 is named '%s' and not 'Unknown'", group.Name))
|
||||||
|
|
||||||
group, err = gstore.Get(1)
|
group, err = common.Gstore.Get(1)
|
||||||
recordMustExist(t, err, "Couldn't find GID #1")
|
recordMustExist(t, err, "Couldn't find GID #1")
|
||||||
|
|
||||||
if group.ID != 1 {
|
if group.ID != 1 {
|
||||||
t.Errorf("group.ID doesn't not match the requested GID. Got '%d' instead.'", group.ID)
|
t.Errorf("group.ID doesn't not match the requested GID. Got '%d' instead.'", group.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
ok := gstore.Exists(-1)
|
ok := common.Gstore.Exists(-1)
|
||||||
expect(t, !ok, "GID #-1 shouldn't exist")
|
expect(t, !ok, "GID #-1 shouldn't exist")
|
||||||
|
|
||||||
// 0 aka Unknown, for system posts and other oddities
|
// 0 aka Unknown, for system posts and other oddities
|
||||||
ok = gstore.Exists(0)
|
ok = common.Gstore.Exists(0)
|
||||||
expect(t, ok, "GID #0 should exist")
|
expect(t, ok, "GID #0 should exist")
|
||||||
|
|
||||||
ok = gstore.Exists(1)
|
ok = common.Gstore.Exists(1)
|
||||||
expect(t, ok, "GID #1 should exist")
|
expect(t, ok, "GID #1 should exist")
|
||||||
|
|
||||||
var isAdmin = true
|
var isAdmin = true
|
||||||
var isMod = true
|
var isMod = true
|
||||||
var isBanned = false
|
var isBanned = false
|
||||||
gid, err := gstore.Create("Testing", "Test", isAdmin, isMod, isBanned)
|
gid, err := common.Gstore.Create("Testing", "Test", isAdmin, isMod, isBanned)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, gstore.Exists(gid), "The group we just made doesn't exist")
|
expect(t, common.Gstore.Exists(gid), "The group we just made doesn't exist")
|
||||||
|
|
||||||
group, err = gstore.Get(gid)
|
group, err = common.Gstore.Get(gid)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
||||||
expect(t, group.IsAdmin, "This should be an admin group")
|
expect(t, group.IsAdmin, "This should be an admin group")
|
||||||
|
@ -666,11 +668,11 @@ func TestGroupStore(t *testing.T) {
|
||||||
isAdmin = false
|
isAdmin = false
|
||||||
isMod = true
|
isMod = true
|
||||||
isBanned = true
|
isBanned = true
|
||||||
gid, err = gstore.Create("Testing 2", "Test", isAdmin, isMod, isBanned)
|
gid, err = common.Gstore.Create("Testing 2", "Test", isAdmin, isMod, isBanned)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, gstore.Exists(gid), "The group we just made doesn't exist")
|
expect(t, common.Gstore.Exists(gid), "The group we just made doesn't exist")
|
||||||
|
|
||||||
group, err = gstore.Get(gid)
|
group, err = common.Gstore.Get(gid)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
||||||
expect(t, !group.IsAdmin, "This should not be an admin group")
|
expect(t, !group.IsAdmin, "This should not be an admin group")
|
||||||
|
@ -681,7 +683,7 @@ func TestGroupStore(t *testing.T) {
|
||||||
err = group.ChangeRank(false, false, true)
|
err = group.ChangeRank(false, false, true)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
|
|
||||||
group, err = gstore.Get(gid)
|
group, err = common.Gstore.Get(gid)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
||||||
expect(t, !group.IsAdmin, "This shouldn't be an admin group")
|
expect(t, !group.IsAdmin, "This shouldn't be an admin group")
|
||||||
|
@ -691,7 +693,7 @@ func TestGroupStore(t *testing.T) {
|
||||||
err = group.ChangeRank(true, true, true)
|
err = group.ChangeRank(true, true, true)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
|
|
||||||
group, err = gstore.Get(gid)
|
group, err = common.Gstore.Get(gid)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
||||||
expect(t, group.IsAdmin, "This should be an admin group")
|
expect(t, group.IsAdmin, "This should be an admin group")
|
||||||
|
@ -701,7 +703,7 @@ func TestGroupStore(t *testing.T) {
|
||||||
err = group.ChangeRank(false, true, true)
|
err = group.ChangeRank(false, true, true)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
|
|
||||||
group, err = gstore.Get(gid)
|
group, err = common.Gstore.Get(gid)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
||||||
expect(t, !group.IsAdmin, "This shouldn't be an admin group")
|
expect(t, !group.IsAdmin, "This shouldn't be an admin group")
|
||||||
|
@ -709,9 +711,9 @@ func TestGroupStore(t *testing.T) {
|
||||||
expect(t, !group.IsBanned, "This shouldn't be a ban group")
|
expect(t, !group.IsBanned, "This shouldn't be a ban group")
|
||||||
|
|
||||||
// Make sure the data is static
|
// Make sure the data is static
|
||||||
gstore.Reload(gid)
|
common.Gstore.Reload(gid)
|
||||||
|
|
||||||
group, err = gstore.Get(gid)
|
group, err = common.Gstore.Get(gid)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
expect(t, group.ID == gid, "The group ID should match the requested ID")
|
||||||
expect(t, !group.IsAdmin, "This shouldn't be an admin group")
|
expect(t, !group.IsAdmin, "This shouldn't be an admin group")
|
||||||
|
@ -731,13 +733,13 @@ func TestReplyStore(t *testing.T) {
|
||||||
initPlugins()
|
initPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := rstore.Get(-1)
|
_, err := common.Rstore.Get(-1)
|
||||||
recordMustNotExist(t, err, "RID #-1 shouldn't exist")
|
recordMustNotExist(t, err, "RID #-1 shouldn't exist")
|
||||||
|
|
||||||
_, err = rstore.Get(0)
|
_, err = common.Rstore.Get(0)
|
||||||
recordMustNotExist(t, err, "RID #0 shouldn't exist")
|
recordMustNotExist(t, err, "RID #0 shouldn't exist")
|
||||||
|
|
||||||
reply, err := rstore.Get(1)
|
reply, err := common.Rstore.Get(1)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, reply.ID == 1, fmt.Sprintf("RID #1 has the wrong ID. It should be 1 not %d", reply.ID))
|
expect(t, reply.ID == 1, fmt.Sprintf("RID #1 has the wrong ID. It should be 1 not %d", reply.ID))
|
||||||
expect(t, reply.ParentID == 1, fmt.Sprintf("The parent topic of RID #1 should be 1 not %d", reply.ParentID))
|
expect(t, reply.ParentID == 1, fmt.Sprintf("The parent topic of RID #1 should be 1 not %d", reply.ParentID))
|
||||||
|
@ -745,18 +747,18 @@ func TestReplyStore(t *testing.T) {
|
||||||
expect(t, reply.Content == "A reply!", fmt.Sprintf("The contents of RID #1 should be 'A reply!' not %s", reply.Content))
|
expect(t, reply.Content == "A reply!", fmt.Sprintf("The contents of RID #1 should be 'A reply!' not %s", reply.Content))
|
||||||
expect(t, reply.IPAddress == "::1", fmt.Sprintf("The IPAddress of RID#1 should be '::1' not %s", reply.IPAddress))
|
expect(t, reply.IPAddress == "::1", fmt.Sprintf("The IPAddress of RID#1 should be '::1' not %s", reply.IPAddress))
|
||||||
|
|
||||||
_, err = rstore.Get(2)
|
_, err = common.Rstore.Get(2)
|
||||||
recordMustNotExist(t, err, "RID #2 shouldn't exist")
|
recordMustNotExist(t, err, "RID #2 shouldn't exist")
|
||||||
|
|
||||||
// TODO: Test Create and Get
|
// TODO: Test Create and Get
|
||||||
//Create(tid int, content string, ipaddress string, fid int, uid int) (id int, err error)
|
//Create(tid int, content string, ipaddress string, fid int, uid int) (id int, err error)
|
||||||
topic, err := topics.Get(1)
|
topic, err := common.Topics.Get(1)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
rid, err := rstore.Create(topic, "Fofofo", "::1", 1)
|
rid, err := common.Rstore.Create(topic, "Fofofo", "::1", 1)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, rid == 2, fmt.Sprintf("The next reply ID should be 2 not %d", rid))
|
expect(t, rid == 2, fmt.Sprintf("The next reply ID should be 2 not %d", rid))
|
||||||
|
|
||||||
reply, err = rstore.Get(2)
|
reply, err = common.Rstore.Get(2)
|
||||||
expectNilErr(t, err)
|
expectNilErr(t, err)
|
||||||
expect(t, reply.ID == 2, fmt.Sprintf("RID #2 has the wrong ID. It should be 2 not %d", reply.ID))
|
expect(t, reply.ID == 2, fmt.Sprintf("RID #2 has the wrong ID. It should be 2 not %d", reply.ID))
|
||||||
expect(t, reply.ParentID == 1, fmt.Sprintf("The parent topic of RID #2 should be 1 not %d", reply.ParentID))
|
expect(t, reply.ParentID == 1, fmt.Sprintf("The parent topic of RID #2 should be 1 not %d", reply.ParentID))
|
||||||
|
@ -773,21 +775,21 @@ func TestProfileReplyStore(t *testing.T) {
|
||||||
initPlugins()
|
initPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := prstore.Get(-1)
|
_, err := common.Prstore.Get(-1)
|
||||||
recordMustNotExist(t, err, "PRID #-1 shouldn't exist")
|
recordMustNotExist(t, err, "PRID #-1 shouldn't exist")
|
||||||
|
|
||||||
_, err = prstore.Get(0)
|
_, err = common.Prstore.Get(0)
|
||||||
recordMustNotExist(t, err, "PRID #0 shouldn't exist")
|
recordMustNotExist(t, err, "PRID #0 shouldn't exist")
|
||||||
|
|
||||||
_, err = prstore.Get(1)
|
_, err = common.Prstore.Get(1)
|
||||||
recordMustNotExist(t, err, "PRID #1 shouldn't exist")
|
recordMustNotExist(t, err, "PRID #1 shouldn't exist")
|
||||||
|
|
||||||
var profileID = 1
|
var profileID = 1
|
||||||
prid, err := prstore.Create(profileID, "Haha", 1, "::1")
|
prid, err := common.Prstore.Create(profileID, "Haha", 1, "::1")
|
||||||
expect(t, err == nil, "Unable to create a profile reply")
|
expect(t, err == nil, "Unable to create a profile reply")
|
||||||
expect(t, prid == 1, "The first profile reply should have an ID of 1")
|
expect(t, prid == 1, "The first profile reply should have an ID of 1")
|
||||||
|
|
||||||
profileReply, err := prstore.Get(1)
|
profileReply, err := common.Prstore.Get(1)
|
||||||
expect(t, err == nil, "PRID #1 should exist")
|
expect(t, err == nil, "PRID #1 should exist")
|
||||||
expect(t, profileReply.ID == 1, fmt.Sprintf("The profile reply should have an ID of 1 not %d", profileReply.ID))
|
expect(t, profileReply.ID == 1, fmt.Sprintf("The profile reply should have an ID of 1 not %d", profileReply.ID))
|
||||||
expect(t, profileReply.ParentID == 1, fmt.Sprintf("The parent ID of the profile reply should be 1 not %d", profileReply.ParentID))
|
expect(t, profileReply.ParentID == 1, fmt.Sprintf("The parent ID of the profile reply should be 1 not %d", profileReply.ParentID))
|
||||||
|
@ -826,7 +828,7 @@ func TestSlugs(t *testing.T) {
|
||||||
|
|
||||||
for _, item := range msgList {
|
for _, item := range msgList {
|
||||||
t.Log("Testing string '" + item.Msg + "'")
|
t.Log("Testing string '" + item.Msg + "'")
|
||||||
res = nameToSlug(item.Msg)
|
res = common.NameToSlug(item.Msg)
|
||||||
if res != item.Expects {
|
if res != item.Expects {
|
||||||
t.Error("Bad output:", "'"+res+"'")
|
t.Error("Bad output:", "'"+res+"'")
|
||||||
t.Error("Expected:", item.Expects)
|
t.Error("Expected:", item.Expects)
|
||||||
|
@ -846,7 +848,7 @@ func TestAuth(t *testing.T) {
|
||||||
realPassword = "Madame Cassandra's Mystic Orb"
|
realPassword = "Madame Cassandra's Mystic Orb"
|
||||||
t.Log("Set realPassword to '" + realPassword + "'")
|
t.Log("Set realPassword to '" + realPassword + "'")
|
||||||
t.Log("Hashing the real password")
|
t.Log("Hashing the real password")
|
||||||
hashedPassword, err = BcryptGeneratePasswordNoSalt(realPassword)
|
hashedPassword, err = common.BcryptGeneratePasswordNoSalt(realPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -854,7 +856,7 @@ func TestAuth(t *testing.T) {
|
||||||
password = realPassword
|
password = realPassword
|
||||||
t.Log("Testing password '" + password + "'")
|
t.Log("Testing password '" + password + "'")
|
||||||
t.Log("Testing salt '" + salt + "'")
|
t.Log("Testing salt '" + salt + "'")
|
||||||
err = CheckPassword(hashedPassword, password, salt)
|
err = common.CheckPassword(hashedPassword, password, salt)
|
||||||
if err == ErrMismatchedHashAndPassword {
|
if err == ErrMismatchedHashAndPassword {
|
||||||
t.Error("The two don't match")
|
t.Error("The two don't match")
|
||||||
} else if err == ErrPasswordTooLong {
|
} else if err == ErrPasswordTooLong {
|
||||||
|
@ -866,7 +868,7 @@ func TestAuth(t *testing.T) {
|
||||||
password = "hahaha"
|
password = "hahaha"
|
||||||
t.Log("Testing password '" + password + "'")
|
t.Log("Testing password '" + password + "'")
|
||||||
t.Log("Testing salt '" + salt + "'")
|
t.Log("Testing salt '" + salt + "'")
|
||||||
err = CheckPassword(hashedPassword, password, salt)
|
err = common.CheckPassword(hashedPassword, password, salt)
|
||||||
if err == ErrPasswordTooLong {
|
if err == ErrPasswordTooLong {
|
||||||
t.Error("CheckPassword thinks the password is too long")
|
t.Error("CheckPassword thinks the password is too long")
|
||||||
} else if err == nil {
|
} else if err == nil {
|
||||||
|
@ -876,7 +878,7 @@ func TestAuth(t *testing.T) {
|
||||||
password = "Madame Cassandra's Mystic"
|
password = "Madame Cassandra's Mystic"
|
||||||
t.Log("Testing password '" + password + "'")
|
t.Log("Testing password '" + password + "'")
|
||||||
t.Log("Testing salt '" + salt + "'")
|
t.Log("Testing salt '" + salt + "'")
|
||||||
err = CheckPassword(hashedPassword, password, salt)
|
err = common.CheckPassword(hashedPassword, password, salt)
|
||||||
if err == ErrPasswordTooLong {
|
if err == ErrPasswordTooLong {
|
||||||
t.Error("CheckPassword thinks the password is too long")
|
t.Error("CheckPassword thinks the password is too long")
|
||||||
} else if err == nil {
|
} else if err == nil {
|
||||||
|
|
364
mod_routes.go
364
mod_routes.go
|
@ -9,48 +9,50 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"./common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
func routeEditTopic(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeEditTopic(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("Bad Form", w, r)
|
return common.PreError("Bad Form", w, r)
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
|
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/edit/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/edit/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreErrorJSQ("The provided TopicID is not a valid number.", w, r, isJs)
|
return common.PreErrorJSQ("The provided TopicID is not a valid number.", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := topics.Get(tid)
|
topic, err := common.Topics.Get(tid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreErrorJSQ("The topic you tried to edit doesn't exist.", w, r, isJs)
|
return common.PreErrorJSQ("The topic you tried to edit doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.EditTopic {
|
if !user.Perms.ViewTopic || !user.Perms.EditTopic {
|
||||||
return NoPermissionsJSQ(w, r, user, isJs)
|
return common.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
topicName := r.PostFormValue("topic_name")
|
topicName := r.PostFormValue("topic_name")
|
||||||
topicContent := html.EscapeString(r.PostFormValue("topic_content"))
|
topicContent := html.EscapeString(r.PostFormValue("topic_content"))
|
||||||
err = topic.Update(topicName, topicContent)
|
err = topic.Update(topicName, topicContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fstore.UpdateLastTopic(topic.ID, user.ID, topic.ParentID)
|
err = common.Fstore.UpdateLastTopic(topic.ID, user.ID, topic.ParentID)
|
||||||
if err != nil && err != ErrNoRows {
|
if err != nil && err != ErrNoRows {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
|
@ -63,204 +65,204 @@ func routeEditTopic(w http.ResponseWriter, r *http.Request, user User) RouteErro
|
||||||
|
|
||||||
// TODO: Add support for soft-deletion and add a permission for hard delete in addition to the usual
|
// TODO: Add support for soft-deletion and add a permission for hard delete in addition to the usual
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
func routeDeleteTopic(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeDeleteTopic(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
// TODO: Move this to some sort of middleware
|
// TODO: Move this to some sort of middleware
|
||||||
var tids []int
|
var tids []int
|
||||||
var isJs = false
|
var isJs = false
|
||||||
if r.Header.Get("Content-type") == "application/json" {
|
if r.Header.Get("Content-type") == "application/json" {
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
return PreErrorJS("No request body", w, r)
|
return common.PreErrorJS("No request body", w, r)
|
||||||
}
|
}
|
||||||
//log.Print("r.Body: ", r.Body)
|
//log.Print("r.Body: ", r.Body)
|
||||||
err := json.NewDecoder(r.Body).Decode(&tids)
|
err := json.NewDecoder(r.Body).Decode(&tids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//log.Print("parse err: ", err)
|
//log.Print("parse err: ", err)
|
||||||
return PreErrorJS("We weren't able to parse your data", w, r)
|
return common.PreErrorJS("We weren't able to parse your data", w, r)
|
||||||
}
|
}
|
||||||
isJs = true
|
isJs = true
|
||||||
} else {
|
} else {
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/delete/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/delete/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("The provided TopicID is not a valid number.", w, r)
|
return common.PreError("The provided TopicID is not a valid number.", w, r)
|
||||||
}
|
}
|
||||||
tids = append(tids, tid)
|
tids = append(tids, tid)
|
||||||
}
|
}
|
||||||
if len(tids) == 0 {
|
if len(tids) == 0 {
|
||||||
return LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
|
return common.LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tid := range tids {
|
for _, tid := range tids {
|
||||||
topic, err := topics.Get(tid)
|
topic, err := common.Topics.Get(tid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreErrorJSQ("The topic you tried to delete doesn't exist.", w, r, isJs)
|
return common.PreErrorJSQ("The topic you tried to delete doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
|
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
|
||||||
return NoPermissionsJSQ(w, r, user, isJs)
|
return common.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We might be able to handle this err better
|
// We might be able to handle this err better
|
||||||
err = topic.Delete()
|
err = topic.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("delete", tid, "topic", user.LastIP, user.ID)
|
err = common.AddModLog("delete", tid, "topic", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? - We might need to add soft-delete before we can do an action reply for this
|
// ? - We might need to add soft-delete before we can do an action reply for this
|
||||||
/*_, err = stmts.createActionReply.Exec(tid,"delete",ipaddress,user.ID)
|
/*_, err = stmts.createActionReply.Exec(tid,"delete",ipaddress,user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err,w,r,isJs)
|
return common.InternalErrorJSQ(err,w,r,isJs)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
log.Printf("Topic #%d was deleted by User #%d", tid, user.ID)
|
log.Printf("Topic #%d was deleted by common.User #%d", tid, user.ID)
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeStickTopic(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeStickTopic(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/stick/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/stick/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("The provided TopicID is not a valid number.", w, r)
|
return common.PreError("The provided TopicID is not a valid number.", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := topics.Get(tid)
|
topic, err := common.Topics.Get(tid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreError("The topic you tried to pin doesn't exist.", w, r)
|
return common.PreError("The topic you tried to pin doesn't exist.", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
|
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = topic.Stick()
|
err = topic.Stick()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("stick", tid, "topic", user.LastIP, user.ID)
|
err = common.AddModLog("stick", tid, "topic", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = topic.CreateActionReply("stick", user.LastIP, user)
|
err = topic.CreateActionReply("stick", user.LastIP, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeUnstickTopic(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeUnstickTopic(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/unstick/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/unstick/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("The provided TopicID is not a valid number.", w, r)
|
return common.PreError("The provided TopicID is not a valid number.", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := topics.Get(tid)
|
topic, err := common.Topics.Get(tid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreError("The topic you tried to unpin doesn't exist.", w, r)
|
return common.PreError("The topic you tried to unpin doesn't exist.", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
|
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = topic.Unstick()
|
err = topic.Unstick()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("unstick", tid, "topic", user.LastIP, user.ID)
|
err = common.AddModLog("unstick", tid, "topic", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = topic.CreateActionReply("unstick", user.LastIP, user)
|
err = topic.CreateActionReply("unstick", user.LastIP, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeLockTopic(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeLockTopic(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
// TODO: Move this to some sort of middleware
|
// TODO: Move this to some sort of middleware
|
||||||
var tids []int
|
var tids []int
|
||||||
var isJs = false
|
var isJs = false
|
||||||
if r.Header.Get("Content-type") == "application/json" {
|
if r.Header.Get("Content-type") == "application/json" {
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
return PreErrorJS("No request body", w, r)
|
return common.PreErrorJS("No request body", w, r)
|
||||||
}
|
}
|
||||||
err := json.NewDecoder(r.Body).Decode(&tids)
|
err := json.NewDecoder(r.Body).Decode(&tids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreErrorJS("We weren't able to parse your data", w, r)
|
return common.PreErrorJS("We weren't able to parse your data", w, r)
|
||||||
}
|
}
|
||||||
isJs = true
|
isJs = true
|
||||||
} else {
|
} else {
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/lock/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/lock/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("The provided TopicID is not a valid number.", w, r)
|
return common.PreError("The provided TopicID is not a valid number.", w, r)
|
||||||
}
|
}
|
||||||
tids = append(tids, tid)
|
tids = append(tids, tid)
|
||||||
}
|
}
|
||||||
if len(tids) == 0 {
|
if len(tids) == 0 {
|
||||||
return LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
|
return common.LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tid := range tids {
|
for _, tid := range tids {
|
||||||
topic, err := topics.Get(tid)
|
topic, err := common.Topics.Get(tid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreErrorJSQ("The topic you tried to lock doesn't exist.", w, r, isJs)
|
return common.PreErrorJSQ("The topic you tried to lock doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
||||||
return NoPermissionsJSQ(w, r, user, isJs)
|
return common.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = topic.Lock()
|
err = topic.Lock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("lock", tid, "topic", user.LastIP, user.ID)
|
err = common.AddModLog("lock", tid, "topic", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
err = topic.CreateActionReply("lock", user.LastIP, user)
|
err = topic.CreateActionReply("lock", user.LastIP, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,40 +272,40 @@ func routeLockTopic(w http.ResponseWriter, r *http.Request, user User) RouteErro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeUnlockTopic(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeUnlockTopic(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/unlock/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/unlock/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("The provided TopicID is not a valid number.", w, r)
|
return common.PreError("The provided TopicID is not a valid number.", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := topics.Get(tid)
|
topic, err := common.Topics.Get(tid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreError("The topic you tried to unlock doesn't exist.", w, r)
|
return common.PreError("The topic you tried to unlock doesn't exist.", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = topic.Unlock()
|
err = topic.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("unlock", tid, "topic", user.LastIP, user.ID)
|
err = common.AddModLog("unlock", tid, "topic", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = topic.CreateActionReply("unlock", user.LastIP, user)
|
err = topic.CreateActionReply("unlock", user.LastIP, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
|
@ -312,46 +314,46 @@ func routeUnlockTopic(w http.ResponseWriter, r *http.Request, user User) RouteEr
|
||||||
|
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
||||||
func routeReplyEditSubmit(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("Bad Form", w, r)
|
return common.PreError("Bad Form", w, r)
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
|
|
||||||
rid, err := strconv.Atoi(r.URL.Path[len("/reply/edit/submit/"):])
|
rid, err := strconv.Atoi(r.URL.Path[len("/reply/edit/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
return common.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Reply ID..
|
// Get the Reply ID..
|
||||||
var tid int
|
var tid int
|
||||||
err = stmts.getReplyTID.QueryRow(rid).Scan(&tid)
|
err = stmts.getReplyTID.QueryRow(rid).Scan(&tid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
var fid int
|
var fid int
|
||||||
err = stmts.getTopicFID.QueryRow(tid).Scan(&fid)
|
err = stmts.getTopicFID.QueryRow(tid).Scan(&fid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
return common.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, fid)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, fid)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.EditReply {
|
if !user.Perms.ViewTopic || !user.Perms.EditReply {
|
||||||
return NoPermissionsJSQ(w, r, user, isJs)
|
return common.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
content := html.EscapeString(preparseMessage(r.PostFormValue("edit_item")))
|
content := html.EscapeString(common.PreparseMessage(r.PostFormValue("edit_item")))
|
||||||
_, err = stmts.editReply.Exec(content, parseMessage(content, fid, "forums"), rid)
|
_, err = stmts.editReply.Exec(content, common.ParseMessage(content, fid, "forums"), rid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
|
@ -364,99 +366,99 @@ func routeReplyEditSubmit(w http.ResponseWriter, r *http.Request, user User) Rou
|
||||||
|
|
||||||
// TODO: Refactor this
|
// TODO: Refactor this
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
func routeReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreError("Bad Form", w, r)
|
return common.PreError("Bad Form", w, r)
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
isJs := (r.PostFormValue("isJs") == "1")
|
||||||
|
|
||||||
rid, err := strconv.Atoi(r.URL.Path[len("/reply/delete/submit/"):])
|
rid, err := strconv.Atoi(r.URL.Path[len("/reply/delete/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
return common.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := rstore.Get(rid)
|
reply, err := common.Rstore.Get(rid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, isJs)
|
return common.PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
var fid int
|
var fid int
|
||||||
err = stmts.getTopicFID.QueryRow(reply.ParentID).Scan(&fid)
|
err = stmts.getTopicFID.QueryRow(reply.ParentID).Scan(&fid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
return common.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := SimpleForumUserCheck(w, r, &user, fid)
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, fid)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
||||||
return NoPermissionsJSQ(w, r, user, isJs)
|
return common.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Delete()
|
err = reply.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.Printf("Reply #%d was deleted by User #%d", rid, user.ID)
|
//log.Printf("Reply #%d was deleted by common.User #%d", rid, user.ID)
|
||||||
if !isJs {
|
if !isJs {
|
||||||
//http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
|
//http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
w.Write(successJSONBytes)
|
w.Write(successJSONBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
replyCreator, err := users.Get(reply.CreatedBy)
|
replyCreator, err := common.Users.Get(reply.CreatedBy)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
wcount := wordCount(reply.Content)
|
wcount := common.WordCount(reply.Content)
|
||||||
err = replyCreator.decreasePostStats(wcount, false)
|
err = replyCreator.DecreasePostStats(wcount, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
} else if err != ErrNoRows {
|
} else if err != ErrNoRows {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("delete", reply.ParentID, "reply", user.LastIP, user.ID)
|
err = common.AddModLog("delete", reply.ParentID, "reply", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("Bad Form", w, r, user)
|
return common.LocalError("Bad Form", w, r, user)
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
|
|
||||||
rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/edit/submit/"):])
|
rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/edit/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
return common.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Reply ID..
|
// Get the Reply ID..
|
||||||
var uid int
|
var uid int
|
||||||
err = stmts.getUserReplyUID.QueryRow(rid).Scan(&uid)
|
err = stmts.getUserReplyUID.QueryRow(rid).Scan(&uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.ID != uid && !user.Perms.EditReply {
|
if user.ID != uid && !user.Perms.EditReply {
|
||||||
return NoPermissionsJSQ(w, r, user, isJs)
|
return common.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
content := html.EscapeString(preparseMessage(r.PostFormValue("edit_item")))
|
content := html.EscapeString(common.PreparseMessage(r.PostFormValue("edit_item")))
|
||||||
_, err = stmts.editProfileReply.Exec(content, parseMessage(content, 0, ""), rid)
|
_, err = stmts.editProfileReply.Exec(content, common.ParseMessage(content, 0, ""), rid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
|
@ -467,35 +469,35 @@ func routeProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user Us
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("Bad Form", w, r, user)
|
return common.LocalError("Bad Form", w, r, user)
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
isJs := (r.PostFormValue("isJs") == "1")
|
||||||
|
|
||||||
rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/delete/submit/"):])
|
rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/delete/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
return common.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
var uid int
|
var uid int
|
||||||
err = stmts.getUserReplyUID.QueryRow(rid).Scan(&uid)
|
err = stmts.getUserReplyUID.QueryRow(rid).Scan(&uid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return LocalErrorJSQ("The reply you tried to delete doesn't exist.", w, r, user, isJs)
|
return common.LocalErrorJSQ("The reply you tried to delete doesn't exist.", w, r, user, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.ID != uid && !user.Perms.DeleteReply {
|
if user.ID != uid && !user.Perms.DeleteReply {
|
||||||
return NoPermissionsJSQ(w, r, user, isJs)
|
return common.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmts.deleteProfileReply.Exec(rid)
|
_, err = stmts.deleteProfileReply.Exec(rid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
//log.Printf("The profile post '%d' was deleted by User #%d", rid, user.ID)
|
//log.Printf("The profile post '%d' was deleted by common.User #%d", rid, user.ID)
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
//http.Redirect(w,r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)
|
//http.Redirect(w,r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)
|
||||||
|
@ -505,13 +507,13 @@ func routeProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeIps(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeIps(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
headerVars, ferr := UserCheck(w, r, &user)
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewIPs {
|
if !user.Perms.ViewIPs {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ip = r.FormValue("ip")
|
var ip = r.FormValue("ip")
|
||||||
|
@ -520,56 +522,56 @@ func routeIps(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
|
|
||||||
rows, err := stmts.findUsersByIPUsers.Query(ip)
|
rows, err := stmts.findUsersByIPUsers.Query(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err := rows.Scan(&uid)
|
err := rows.Scan(&uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
reqUserList[uid] = true
|
reqUserList[uid] = true
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
rows2, err := stmts.findUsersByIPTopics.Query(ip)
|
rows2, err := stmts.findUsersByIPTopics.Query(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows2.Close()
|
defer rows2.Close()
|
||||||
|
|
||||||
for rows2.Next() {
|
for rows2.Next() {
|
||||||
err := rows2.Scan(&uid)
|
err := rows2.Scan(&uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
reqUserList[uid] = true
|
reqUserList[uid] = true
|
||||||
}
|
}
|
||||||
err = rows2.Err()
|
err = rows2.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
rows3, err := stmts.findUsersByIPReplies.Query(ip)
|
rows3, err := stmts.findUsersByIPReplies.Query(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows3.Close()
|
defer rows3.Close()
|
||||||
|
|
||||||
for rows3.Next() {
|
for rows3.Next() {
|
||||||
err := rows3.Scan(&uid)
|
err := rows3.Scan(&uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
reqUserList[uid] = true
|
reqUserList[uid] = true
|
||||||
}
|
}
|
||||||
err = rows3.Err()
|
err = rows3.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the user ID map to a slice, then bulk load the users
|
// Convert the user ID map to a slice, then bulk load the users
|
||||||
|
@ -581,68 +583,68 @@ func routeIps(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What if a user is deleted via the Control Panel?
|
// TODO: What if a user is deleted via the Control Panel?
|
||||||
userList, err := users.BulkGetMap(idSlice)
|
userList, err := common.Users.BulkGetMap(idSlice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := IPSearchPage{"IP Search", user, headerVars, userList, ip}
|
pi := common.IPSearchPage{"IP Search", user, headerVars, userList, ip}
|
||||||
if preRenderHooks["pre_render_ips"] != nil {
|
if common.PreRenderHooks["pre_render_ips"] != nil {
|
||||||
if runPreRenderHook("pre_render_ips", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_ips", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = templates.ExecuteTemplate(w, "ip-search.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "ip-search.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeBanSubmit(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeBanSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
if !user.Perms.BanUsers {
|
if !user.Perms.BanUsers {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/submit/"):])
|
uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("The provided User ID is not a valid number.", w, r, user)
|
return common.LocalError("The provided common.User ID is not a valid number.", w, r, user)
|
||||||
}
|
}
|
||||||
/*if uid == -2 {
|
/*if uid == -2 {
|
||||||
return LocalError("Stop trying to ban Merlin! Ban admin! Bad! No!",w,r,user)
|
return common.LocalError("Stop trying to ban Merlin! Ban admin! Bad! No!",w,r,user)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
targetUser, err := users.Get(uid)
|
targetUser, err := common.Users.Get(uid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return LocalError("The user you're trying to ban no longer exists.", w, r, user)
|
return common.LocalError("The user you're trying to ban no longer exists.", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
|
// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
|
||||||
if targetUser.IsSuperAdmin || targetUser.IsAdmin || targetUser.IsMod {
|
if targetUser.IsSuperAdmin || targetUser.IsAdmin || targetUser.IsMod {
|
||||||
return LocalError("You may not ban another staff member.", w, r, user)
|
return common.LocalError("You may not ban another staff member.", w, r, user)
|
||||||
}
|
}
|
||||||
if uid == user.ID {
|
if uid == user.ID {
|
||||||
return LocalError("Why are you trying to ban yourself? Stop that.", w, r, user)
|
return common.LocalError("Why are you trying to ban yourself? Stop that.", w, r, user)
|
||||||
}
|
}
|
||||||
if targetUser.IsBanned {
|
if targetUser.IsBanned {
|
||||||
return LocalError("The user you're trying to unban is already banned.", w, r, user)
|
return common.LocalError("The user you're trying to unban is already banned.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
durationDays, err := strconv.Atoi(r.FormValue("ban-duration-days"))
|
durationDays, err := strconv.Atoi(r.FormValue("ban-duration-days"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("You can only use whole numbers for the number of days", w, r, user)
|
return common.LocalError("You can only use whole numbers for the number of days", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
durationWeeks, err := strconv.Atoi(r.FormValue("ban-duration-weeks"))
|
durationWeeks, err := strconv.Atoi(r.FormValue("ban-duration-weeks"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("You can only use whole numbers for the number of weeks", w, r, user)
|
return common.LocalError("You can only use whole numbers for the number of weeks", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
durationMonths, err := strconv.Atoi(r.FormValue("ban-duration-months"))
|
durationMonths, err := strconv.Atoi(r.FormValue("ban-duration-months"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("You can only use whole numbers for the number of months", w, r, user)
|
return common.LocalError("You can only use whole numbers for the number of months", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
var duration time.Duration
|
var duration time.Duration
|
||||||
|
@ -650,95 +652,95 @@ func routeBanSubmit(w http.ResponseWriter, r *http.Request, user User) RouteErro
|
||||||
duration, _ = time.ParseDuration("0")
|
duration, _ = time.ParseDuration("0")
|
||||||
} else {
|
} else {
|
||||||
var seconds int
|
var seconds int
|
||||||
seconds += durationDays * day
|
seconds += durationDays * common.Day
|
||||||
seconds += durationWeeks * week
|
seconds += durationWeeks * common.Week
|
||||||
seconds += durationMonths * month
|
seconds += durationMonths * common.Month
|
||||||
duration, _ = time.ParseDuration(strconv.Itoa(seconds) + "s")
|
duration, _ = time.ParseDuration(strconv.Itoa(seconds) + "s")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = targetUser.Ban(duration, user.ID)
|
err = targetUser.Ban(duration, user.ID)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return LocalError("The user you're trying to ban no longer exists.", w, r, user)
|
return common.LocalError("The user you're trying to ban no longer exists.", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("ban", uid, "user", user.LastIP, user.ID)
|
err = common.AddModLog("ban", uid, "user", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
|
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeUnban(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeUnban(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
if !user.Perms.BanUsers {
|
if !user.Perms.BanUsers {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, err := strconv.Atoi(r.URL.Path[len("/users/unban/"):])
|
uid, err := strconv.Atoi(r.URL.Path[len("/users/unban/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("The provided User ID is not a valid number.", w, r, user)
|
return common.LocalError("The provided common.User ID is not a valid number.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser, err := users.Get(uid)
|
targetUser, err := common.Users.Get(uid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return LocalError("The user you're trying to unban no longer exists.", w, r, user)
|
return common.LocalError("The user you're trying to unban no longer exists.", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !targetUser.IsBanned {
|
if !targetUser.IsBanned {
|
||||||
return LocalError("The user you're trying to unban isn't banned.", w, r, user)
|
return common.LocalError("The user you're trying to unban isn't banned.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = targetUser.Unban()
|
err = targetUser.Unban()
|
||||||
if err == ErrNoTempGroup {
|
if err == common.ErrNoTempGroup {
|
||||||
return LocalError("The user you're trying to unban is not banned", w, r, user)
|
return common.LocalError("The user you're trying to unban is not banned", w, r, user)
|
||||||
} else if err == ErrNoRows {
|
} else if err == ErrNoRows {
|
||||||
return LocalError("The user you're trying to unban no longer exists.", w, r, user)
|
return common.LocalError("The user you're trying to unban no longer exists.", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("unban", uid, "user", user.LastIP, user.ID)
|
err = common.AddModLog("unban", uid, "user", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
|
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeActivate(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeActivate(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
if !user.Perms.ActivateUsers {
|
if !user.Perms.ActivateUsers {
|
||||||
return NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, err := strconv.Atoi(r.URL.Path[len("/users/activate/"):])
|
uid, err := strconv.Atoi(r.URL.Path[len("/users/activate/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("The provided User ID is not a valid number.", w, r, user)
|
return common.LocalError("The provided common.User ID is not a valid number.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser, err := users.Get(uid)
|
targetUser, err := common.Users.Get(uid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return LocalError("The account you're trying to activate no longer exists.", w, r, user)
|
return common.LocalError("The account you're trying to activate no longer exists.", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if targetUser.Active {
|
if targetUser.Active {
|
||||||
return LocalError("The account you're trying to activate has already been activated.", w, r, user)
|
return common.LocalError("The account you're trying to activate has already been activated.", w, r, user)
|
||||||
}
|
}
|
||||||
err = targetUser.Activate()
|
err = targetUser.Activate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addModLog("activate", targetUser.ID, "user", user.LastIP, user.ID)
|
err = common.AddModLog("activate", targetUser.ID, "user", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, "/user/"+strconv.Itoa(targetUser.ID), http.StatusSeeOther)
|
http.Redirect(w, r, "/user/"+strconv.Itoa(targetUser.ID), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
|
|
20
mysql.go
20
mysql.go
|
@ -8,12 +8,16 @@
|
||||||
*/
|
*/
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "log"
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
|
||||||
//import "time"
|
//import "time"
|
||||||
import "database/sql"
|
|
||||||
import _ "github.com/go-sql-driver/mysql"
|
"./common"
|
||||||
import "./query_gen/lib"
|
"./query_gen/lib"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
var dbCollation = "utf8mb4_general_ci"
|
var dbCollation = "utf8mb4_general_ci"
|
||||||
|
|
||||||
|
@ -24,13 +28,13 @@ func init() {
|
||||||
|
|
||||||
func initMySQL() (err error) {
|
func initMySQL() (err error) {
|
||||||
var _dbpassword string
|
var _dbpassword string
|
||||||
if dbConfig.Password != "" {
|
if common.DbConfig.Password != "" {
|
||||||
_dbpassword = ":" + dbConfig.Password
|
_dbpassword = ":" + common.DbConfig.Password
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this bit to the query gen lib
|
// TODO: Move this bit to the query gen lib
|
||||||
// Open the database connection
|
// Open the database connection
|
||||||
db, err = sql.Open("mysql", dbConfig.Username+_dbpassword+"@tcp("+dbConfig.Host+":"+dbConfig.Port+")/"+dbConfig.Dbname+"?collation="+dbCollation+"&parseTime=true")
|
db, err = sql.Open("mysql", common.DbConfig.Username+_dbpassword+"@tcp("+common.DbConfig.Host+":"+common.DbConfig.Port+")/"+common.DbConfig.Dbname+"?collation="+dbCollation+"&parseTime=true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
1058
panel_routes.go
1058
panel_routes.go
File diff suppressed because it is too large
Load Diff
|
@ -10,9 +10,11 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"./common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var random *rand.Rand
|
var bbcodeRandom *rand.Rand
|
||||||
var bbcodeInvalidNumber []byte
|
var bbcodeInvalidNumber []byte
|
||||||
var bbcodeNoNegative []byte
|
var bbcodeNoNegative []byte
|
||||||
var bbcodeMissingTag []byte
|
var bbcodeMissingTag []byte
|
||||||
|
@ -27,12 +29,12 @@ var bbcodeQuotes *regexp.Regexp
|
||||||
var bbcodeCode *regexp.Regexp
|
var bbcodeCode *regexp.Regexp
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugins["bbcode"] = NewPlugin("bbcode", "BBCode", "Azareal", "http://github.com/Azareal", "", "", "", initBbcode, nil, deactivateBbcode, nil, nil)
|
common.Plugins["bbcode"] = common.NewPlugin("bbcode", "BBCode", "Azareal", "http://github.com/Azareal", "", "", "", initBbcode, nil, deactivateBbcode, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initBbcode() error {
|
func initBbcode() error {
|
||||||
//plugins["bbcode"].AddHook("parse_assign", bbcode_parse_without_code)
|
//plugins["bbcode"].AddHook("parse_assign", bbcode_parse_without_code)
|
||||||
plugins["bbcode"].AddHook("parse_assign", bbcodeFullParse)
|
common.Plugins["bbcode"].AddHook("parse_assign", bbcodeFullParse)
|
||||||
|
|
||||||
bbcodeInvalidNumber = []byte("<span style='color: red;'>[Invalid Number]</span>")
|
bbcodeInvalidNumber = []byte("<span style='color: red;'>[Invalid Number]</span>")
|
||||||
bbcodeNoNegative = []byte("<span style='color: red;'>[No Negative Numbers]</span>")
|
bbcodeNoNegative = []byte("<span style='color: red;'>[No Negative Numbers]</span>")
|
||||||
|
@ -48,13 +50,12 @@ func initBbcode() error {
|
||||||
bbcodeQuotes = regexp.MustCompile(`\[quote\](.*)\[/quote\]`)
|
bbcodeQuotes = regexp.MustCompile(`\[quote\](.*)\[/quote\]`)
|
||||||
bbcodeCode = regexp.MustCompile(`\[code\](.*)\[/code\]`)
|
bbcodeCode = regexp.MustCompile(`\[code\](.*)\[/code\]`)
|
||||||
|
|
||||||
random = rand.New(rand.NewSource(time.Now().UnixNano()))
|
bbcodeRandom = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateBbcode() {
|
func deactivateBbcode() {
|
||||||
//plugins["bbcode"].RemoveHook("parse_assign", bbcode_parse_without_code)
|
common.Plugins["bbcode"].RemoveHook("parse_assign", bbcodeFullParse)
|
||||||
plugins["bbcode"].RemoveHook("parse_assign", bbcodeFullParse)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func bbcodeRegexParse(msg string) string {
|
func bbcodeRegexParse(msg string) string {
|
||||||
|
@ -213,7 +214,7 @@ func bbcodeFullParse(msg string) string {
|
||||||
var complexBbc bool
|
var complexBbc bool
|
||||||
|
|
||||||
msgbytes := []byte(msg)
|
msgbytes := []byte(msg)
|
||||||
msgbytes = append(msgbytes, spaceGap...)
|
msgbytes = append(msgbytes, common.SpaceGap...)
|
||||||
//log.Print("BBCode Simple Pre:","`"+string(msgbytes)+"`")
|
//log.Print("BBCode Simple Pre:","`"+string(msgbytes)+"`")
|
||||||
//log.Print("----")
|
//log.Print("----")
|
||||||
|
|
||||||
|
@ -306,7 +307,7 @@ func bbcodeFullParse(msg string) string {
|
||||||
if hasS {
|
if hasS {
|
||||||
msgbytes = append(bytes.TrimSpace(msgbytes), closeStrike...)
|
msgbytes = append(bytes.TrimSpace(msgbytes), closeStrike...)
|
||||||
}
|
}
|
||||||
msgbytes = append(msgbytes, spaceGap...)
|
msgbytes = append(msgbytes, common.SpaceGap...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if complexBbc {
|
if complexBbc {
|
||||||
|
@ -357,21 +358,21 @@ func bbcodeParseURL(i int, start int, lastTag int, msgbytes []byte, outbytes []b
|
||||||
start = i + 5
|
start = i + 5
|
||||||
outbytes = append(outbytes, msgbytes[lastTag:i]...)
|
outbytes = append(outbytes, msgbytes[lastTag:i]...)
|
||||||
i = start
|
i = start
|
||||||
i += partialURLBytesLen(msgbytes[start:])
|
i += common.PartialURLBytesLen(msgbytes[start:])
|
||||||
//log.Print("Partial Bytes: ", string(msgbytes[start:]))
|
//log.Print("Partial Bytes: ", string(msgbytes[start:]))
|
||||||
//log.Print("-----")
|
//log.Print("-----")
|
||||||
if !bytes.Equal(msgbytes[i:i+6], []byte("[/url]")) {
|
if !bytes.Equal(msgbytes[i:i+6], []byte("[/url]")) {
|
||||||
//log.Print("Invalid Bytes: ", string(msgbytes[i:i+6]))
|
//log.Print("Invalid Bytes: ", string(msgbytes[i:i+6]))
|
||||||
//log.Print("-----")
|
//log.Print("-----")
|
||||||
outbytes = append(outbytes, invalidURL...)
|
outbytes = append(outbytes, common.InvalidURL...)
|
||||||
return i, start, lastTag, outbytes
|
return i, start, lastTag, outbytes
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, urlOpen...)
|
outbytes = append(outbytes, common.UrlOpen...)
|
||||||
outbytes = append(outbytes, msgbytes[start:i]...)
|
outbytes = append(outbytes, msgbytes[start:i]...)
|
||||||
outbytes = append(outbytes, urlOpen2...)
|
outbytes = append(outbytes, common.UrlOpen2...)
|
||||||
outbytes = append(outbytes, msgbytes[start:i]...)
|
outbytes = append(outbytes, msgbytes[start:i]...)
|
||||||
outbytes = append(outbytes, urlClose...)
|
outbytes = append(outbytes, common.UrlClose...)
|
||||||
i += 6
|
i += 6
|
||||||
lastTag = i
|
lastTag = i
|
||||||
|
|
||||||
|
@ -411,7 +412,7 @@ func bbcodeParseRand(i int, start int, lastTag int, msgbytes []byte, outbytes []
|
||||||
if number == 0 {
|
if number == 0 {
|
||||||
dat = []byte("0")
|
dat = []byte("0")
|
||||||
} else {
|
} else {
|
||||||
dat = []byte(strconv.FormatInt((random.Int63n(number)), 10))
|
dat = []byte(strconv.FormatInt((bbcodeRandom.Int63n(number)), 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
outbytes = append(outbytes, dat...)
|
outbytes = append(outbytes, dat...)
|
||||||
|
|
100
plugin_guilds.go
100
plugin_guilds.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
//"fmt"
|
//"fmt"
|
||||||
|
|
||||||
|
"./common"
|
||||||
"./extend/guilds/lib"
|
"./extend/guilds/lib"
|
||||||
"./query_gen/lib"
|
"./query_gen/lib"
|
||||||
)
|
)
|
||||||
|
@ -11,75 +12,58 @@ import (
|
||||||
|
|
||||||
// TODO: Add a plugin interface instead of having a bunch of argument to AddPlugin?
|
// TODO: Add a plugin interface instead of having a bunch of argument to AddPlugin?
|
||||||
func init() {
|
func init() {
|
||||||
plugins["guilds"] = NewPlugin("guilds", "Guilds", "Azareal", "http://github.com/Azareal", "", "", "", initGuilds, nil, deactivateGuilds, installGuilds, nil)
|
common.Plugins["guilds"] = common.NewPlugin("guilds", "Guilds", "Azareal", "http://github.com/Azareal", "", "", "", initGuilds, nil, deactivateGuilds, installGuilds, nil)
|
||||||
|
|
||||||
// TODO: Is it possible to avoid doing this when the plugin isn't activated?
|
// TODO: Is it possible to avoid doing this when the plugin isn't activated?
|
||||||
prebuildTmplList = append(prebuildTmplList, guilds.PrebuildTmplList)
|
common.PrebuildTmplList = append(common.PrebuildTmplList, guilds.PrebuildTmplList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initGuilds() (err error) {
|
func initGuilds() (err error) {
|
||||||
plugins["guilds"].AddHook("intercept_build_widgets", guilds.Widgets)
|
common.Plugins["guilds"].AddHook("intercept_build_widgets", guilds.Widgets)
|
||||||
plugins["guilds"].AddHook("trow_assign", guilds.TrowAssign)
|
common.Plugins["guilds"].AddHook("trow_assign", guilds.TrowAssign)
|
||||||
plugins["guilds"].AddHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
|
common.Plugins["guilds"].AddHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
|
||||||
plugins["guilds"].AddHook("pre_render_view_forum", guilds.PreRenderViewForum)
|
common.Plugins["guilds"].AddHook("pre_render_view_forum", guilds.PreRenderViewForum)
|
||||||
plugins["guilds"].AddHook("simple_forum_check_pre_perms", guilds.ForumCheck)
|
common.Plugins["guilds"].AddHook("simple_forum_check_pre_perms", guilds.ForumCheck)
|
||||||
plugins["guilds"].AddHook("forum_check_pre_perms", guilds.ForumCheck)
|
common.Plugins["guilds"].AddHook("forum_check_pre_perms", guilds.ForumCheck)
|
||||||
// TODO: Auto-grant this perm to admins upon installation?
|
// TODO: Auto-grant this perm to admins upon installation?
|
||||||
registerPluginPerm("CreateGuild")
|
common.RegisterPluginPerm("CreateGuild")
|
||||||
router.HandleFunc("/guilds/", guilds.GuildList)
|
router.HandleFunc("/guilds/", guilds.RouteGuildList)
|
||||||
router.HandleFunc("/guild/", guilds.ViewGuild)
|
router.HandleFunc("/guild/", guilds.MiddleViewGuild)
|
||||||
router.HandleFunc("/guild/create/", guilds.CreateGuild)
|
router.HandleFunc("/guild/create/", guilds.RouteCreateGuild)
|
||||||
router.HandleFunc("/guild/create/submit/", guilds.CreateGuildSubmit)
|
router.HandleFunc("/guild/create/submit/", guilds.RouteCreateGuildSubmit)
|
||||||
router.HandleFunc("/guild/members/", guilds.MemberList)
|
router.HandleFunc("/guild/members/", guilds.RouteMemberList)
|
||||||
|
|
||||||
guilds.ListStmt, err = qgen.Builder.SimpleSelect("guilds", "guildID, name, desc, active, privacy, joinable, owner, memberCount, createdAt, lastUpdateTime", "", "", "")
|
acc := qgen.Builder.Accumulator()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.GetGuildStmt, err = qgen.Builder.SimpleSelect("guilds", "name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime", "guildID = ?", "", "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.MemberListStmt, err = qgen.Builder.SimpleSelect("guilds_members", "guildID, uid, rank, posts, joinedAt", "", "", "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.MemberListJoinStmt, err = qgen.Builder.SimpleLeftJoin("guilds_members", "users", "users.uid, guilds_members.rank, guilds_members.posts, guilds_members.joinedAt, users.name, users.avatar", "guilds_members.uid = users.uid", "guilds_members.guildID = ?", "guilds_members.rank DESC, guilds_members.joinedat ASC", "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.GetMemberStmt, err = qgen.Builder.SimpleSelect("guilds_members", "rank, posts, joinedAt", "guildID = ? AND uid = ?", "", "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.CreateGuildStmt, err = qgen.Builder.SimpleInsert("guilds", "name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime", "?,?,?,?,1,?,1,?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP()")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.AttachForumStmt, err = qgen.Builder.SimpleUpdate("forums", "parentID = ?, parentType = 'guild'", "fid = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.UnattachForumStmt, err = qgen.Builder.SimpleUpdate("forums", "parentID = 0, parentType = ''", "fid = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
guilds.AddMemberStmt, err = qgen.Builder.SimpleInsert("guilds_members", "guildID, uid, rank, posts, joinedAt", "?,?,?,0,UTC_TIMESTAMP()")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
guilds.ListStmt = acc.SimpleSelect("guilds", "guildID, name, desc, active, privacy, joinable, owner, memberCount, createdAt, lastUpdateTime", "", "", "")
|
||||||
|
|
||||||
|
guilds.GetGuildStmt = acc.SimpleSelect("guilds", "name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime", "guildID = ?", "", "")
|
||||||
|
|
||||||
|
guilds.MemberListStmt = acc.SimpleSelect("guilds_members", "guildID, uid, rank, posts, joinedAt", "", "", "")
|
||||||
|
|
||||||
|
guilds.MemberListJoinStmt = acc.SimpleLeftJoin("guilds_members", "users", "users.uid, guilds_members.rank, guilds_members.posts, guilds_members.joinedAt, users.name, users.avatar", "guilds_members.uid = users.uid", "guilds_members.guildID = ?", "guilds_members.rank DESC, guilds_members.joinedat ASC", "")
|
||||||
|
|
||||||
|
guilds.GetMemberStmt = acc.SimpleSelect("guilds_members", "rank, posts, joinedAt", "guildID = ? AND uid = ?", "", "")
|
||||||
|
|
||||||
|
guilds.CreateGuildStmt = acc.SimpleInsert("guilds", "name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime", "?,?,?,?,1,?,1,?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP()")
|
||||||
|
|
||||||
|
guilds.AttachForumStmt = acc.SimpleUpdate("forums", "parentID = ?, parentType = 'guild'", "fid = ?")
|
||||||
|
|
||||||
|
guilds.UnattachForumStmt = acc.SimpleUpdate("forums", "parentID = 0, parentType = ''", "fid = ?")
|
||||||
|
|
||||||
|
guilds.AddMemberStmt = acc.SimpleInsert("guilds_members", "guildID, uid, rank, posts, joinedAt", "?,?,?,0,UTC_TIMESTAMP()")
|
||||||
|
|
||||||
|
return acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateGuilds() {
|
func deactivateGuilds() {
|
||||||
plugins["guilds"].RemoveHook("intercept_build_widgets", guilds.Widgets)
|
common.Plugins["guilds"].RemoveHook("intercept_build_widgets", guilds.Widgets)
|
||||||
plugins["guilds"].RemoveHook("trow_assign", guilds.TrowAssign)
|
common.Plugins["guilds"].RemoveHook("trow_assign", guilds.TrowAssign)
|
||||||
plugins["guilds"].RemoveHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
|
common.Plugins["guilds"].RemoveHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
|
||||||
plugins["guilds"].RemoveHook("pre_render_view_forum", guilds.PreRenderViewForum)
|
common.Plugins["guilds"].RemoveHook("pre_render_view_forum", guilds.PreRenderViewForum)
|
||||||
plugins["guilds"].RemoveHook("simple_forum_check_pre_perms", guilds.ForumCheck)
|
common.Plugins["guilds"].RemoveHook("simple_forum_check_pre_perms", guilds.ForumCheck)
|
||||||
plugins["guilds"].RemoveHook("forum_check_pre_perms", guilds.ForumCheck)
|
common.Plugins["guilds"].RemoveHook("forum_check_pre_perms", guilds.ForumCheck)
|
||||||
deregisterPluginPerm("CreateGuild")
|
common.DeregisterPluginPerm("CreateGuild")
|
||||||
_ = router.RemoveFunc("/guilds/")
|
_ = router.RemoveFunc("/guilds/")
|
||||||
_ = router.RemoveFunc("/guild/")
|
_ = router.RemoveFunc("/guild/")
|
||||||
_ = router.RemoveFunc("/guild/create/")
|
_ = router.RemoveFunc("/guild/create/")
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "./common"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugins["heythere"] = NewPlugin("heythere", "Hey There", "Azareal", "http://github.com/Azareal", "", "", "", initHeythere, nil, deactivateHeythere, nil, nil)
|
common.Plugins["heythere"] = common.NewPlugin("heythere", "Hey There", "Azareal", "http://github.com/Azareal", "", "", "", initHeythere, nil, deactivateHeythere, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// init_heythere is separate from init() as we don't want the plugin to run if the plugin is disabled
|
// init_heythere is separate from init() as we don't want the plugin to run if the plugin is disabled
|
||||||
func initHeythere() error {
|
func initHeythere() error {
|
||||||
plugins["heythere"].AddHook("topic_reply_row_assign", heythereReply)
|
common.Plugins["heythere"].AddHook("topic_reply_row_assign", heythereReply)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateHeythere() {
|
func deactivateHeythere() {
|
||||||
plugins["heythere"].RemoveHook("topic_reply_row_assign", heythereReply)
|
common.Plugins["heythere"].RemoveHook("topic_reply_row_assign", heythereReply)
|
||||||
}
|
}
|
||||||
|
|
||||||
func heythereReply(data ...interface{}) interface{} {
|
func heythereReply(data ...interface{}) interface{} {
|
||||||
currentUser := data[0].(*TopicPage).CurrentUser
|
currentUser := data[0].(*common.TopicPage).CurrentUser
|
||||||
reply := data[1].(*ReplyUser)
|
reply := data[1].(*common.ReplyUser)
|
||||||
reply.Content = "Hey there, " + currentUser.Name + "!"
|
reply.Content = "Hey there, " + currentUser.Name + "!"
|
||||||
reply.ContentHtml = "Hey there, " + currentUser.Name + "!"
|
reply.ContentHtml = "Hey there, " + currentUser.Name + "!"
|
||||||
reply.Tag = "Auto"
|
reply.Tag = "Auto"
|
||||||
|
|
|
@ -4,6 +4,8 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"./common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var markdownMaxDepth = 25 // How deep the parser will go when parsing Markdown strings
|
var markdownMaxDepth = 25 // How deep the parser will go when parsing Markdown strings
|
||||||
|
@ -19,11 +21,11 @@ var markdownStrikeTagOpen []byte
|
||||||
var markdownStrikeTagClose []byte
|
var markdownStrikeTagClose []byte
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugins["markdown"] = NewPlugin("markdown", "Markdown", "Azareal", "http://github.com/Azareal", "", "", "", initMarkdown, nil, deactivateMarkdown, nil, nil)
|
common.Plugins["markdown"] = common.NewPlugin("markdown", "Markdown", "Azareal", "http://github.com/Azareal", "", "", "", initMarkdown, nil, deactivateMarkdown, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initMarkdown() error {
|
func initMarkdown() error {
|
||||||
plugins["markdown"].AddHook("parse_assign", markdownParse)
|
common.Plugins["markdown"].AddHook("parse_assign", markdownParse)
|
||||||
|
|
||||||
markdownUnclosedElement = []byte("<span style='color: red;'>[Unclosed Element]</span>")
|
markdownUnclosedElement = []byte("<span style='color: red;'>[Unclosed Element]</span>")
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ func initMarkdown() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateMarkdown() {
|
func deactivateMarkdown() {
|
||||||
plugins["markdown"].RemoveHook("parse_assign", markdownParse)
|
common.Plugins["markdown"].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.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "./common"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
/*
|
/*
|
||||||
The UName field should match the name in the URL minus plugin_ and the file extension. The same name as the map index. Please choose a unique name which won't clash with any other plugins.
|
The UName field should match the name in the URL minus plugin_ and the file extension. The same name as the map index. Please choose a unique name which won't clash with any other plugins.
|
||||||
|
@ -26,7 +28,7 @@ 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.
|
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.
|
||||||
*/
|
*/
|
||||||
plugins["skeleton"] = NewPlugin("skeleton", "Skeleton", "Azareal", "", "", "", "", initSkeleton, activateSkeleton, deactivateSkeleton, nil, nil)
|
common.Plugins["skeleton"] = common.NewPlugin("skeleton", "Skeleton", "Azareal", "", "", "", "", initSkeleton, activateSkeleton, deactivateSkeleton, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initSkeleton() error { return nil }
|
func initSkeleton() error { return nil }
|
||||||
|
|
|
@ -37,6 +37,10 @@ func (build *builder) GetAdapter() DB_Adapter {
|
||||||
return build.adapter
|
return build.adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (build *builder) Begin() (*sql.Tx, error) {
|
||||||
|
return build.conn.Begin()
|
||||||
|
}
|
||||||
|
|
||||||
func (build *builder) Tx(handler func(*TransactionBuilder) error) error {
|
func (build *builder) Tx(handler func(*TransactionBuilder) error) error {
|
||||||
tx, err := build.conn.Begin()
|
tx, err := build.conn.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,101 +54,60 @@ func (build *builder) Tx(handler func(*TransactionBuilder) error) error {
|
||||||
return tx.Commit()
|
return tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleSelect(table string, columns string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
func (build *builder) prepare(res string, err error) (*sql.Stmt, error) {
|
||||||
res, err := build.adapter.SimpleSelect("_builder", table, columns, where, orderby, limit)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stmt, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return build.conn.Prepare(res)
|
return build.conn.Prepare(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (build *builder) SimpleSelect(table string, columns string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
||||||
|
return build.prepare(build.adapter.SimpleSelect("_builder", table, columns, where, orderby, limit))
|
||||||
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleCount(table string, where string, limit string) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleCount(table string, where string, limit string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleCount("_builder", table, where, limit)
|
return build.prepare(build.adapter.SimpleCount("_builder", table, where, limit))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleLeftJoin(table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleLeftJoin(table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleLeftJoin("_builder", table1, table2, columns, joiners, where, orderby, limit)
|
return build.prepare(build.adapter.SimpleLeftJoin("_builder", table1, table2, columns, joiners, where, orderby, limit))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleInnerJoin(table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleInnerJoin(table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleInnerJoin("_builder", table1, table2, columns, joiners, where, orderby, limit)
|
return build.prepare(build.adapter.SimpleInnerJoin("_builder", table1, table2, columns, joiners, where, orderby, limit))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) CreateTable(table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (stmt *sql.Stmt, err error) {
|
func (build *builder) CreateTable(table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.CreateTable("_builder", table, charset, collation, columns, keys)
|
return build.prepare(build.adapter.CreateTable("_builder", table, charset, collation, columns, keys))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleInsert(table string, columns string, fields string) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleInsert(table string, columns string, fields string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleInsert("_builder", table, columns, fields)
|
return build.prepare(build.adapter.SimpleInsert("_builder", table, columns, fields))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleInsertSelect(ins DB_Insert, sel DB_Select) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleInsertSelect(ins DB_Insert, sel DB_Select) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleInsertSelect("_builder", ins, sel)
|
return build.prepare(build.adapter.SimpleInsertSelect("_builder", ins, sel))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleInsertLeftJoin(ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleInsertLeftJoin(ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleInsertLeftJoin("_builder", ins, sel)
|
return build.prepare(build.adapter.SimpleInsertLeftJoin("_builder", ins, sel))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleInsertInnerJoin(ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleInsertInnerJoin(ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleInsertInnerJoin("_builder", ins, sel)
|
return build.prepare(build.adapter.SimpleInsertInnerJoin("_builder", ins, sel))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleUpdate(table string, set string, where string) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleUpdate(table string, set string, where string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleUpdate("_builder", table, set, where)
|
return build.prepare(build.adapter.SimpleUpdate("_builder", table, set, where))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleDelete(table string, where string) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleDelete(table string, where string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleDelete("_builder", table, where)
|
return build.prepare(build.adapter.SimpleDelete("_builder", table, where))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// I don't know why you need this, but here it is x.x
|
// I don't know why you need this, but here it is x.x
|
||||||
func (build *builder) Purge(table string) (stmt *sql.Stmt, err error) {
|
func (build *builder) Purge(table string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.Purge("_builder", table)
|
return build.prepare(build.adapter.Purge("_builder", table))
|
||||||
if err != nil {
|
|
||||||
return stmt, err
|
|
||||||
}
|
|
||||||
return build.conn.Prepare(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These ones support transactions
|
// These ones support transactions
|
||||||
|
|
|
@ -1098,6 +1098,7 @@ package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
type Stmts struct {
|
type Stmts struct {
|
||||||
|
@ -1117,7 +1118,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_mssql() (err error) {
|
func _gen_mssql() (err error) {
|
||||||
if dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Building the generated statements")
|
log.Print("Building the generated statements")
|
||||||
}
|
}
|
||||||
` + body + `
|
` + body + `
|
||||||
|
|
|
@ -590,6 +590,7 @@ package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
import "./common"
|
||||||
//import "./query_gen/lib"
|
//import "./query_gen/lib"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
|
@ -610,7 +611,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_mysql() (err error) {
|
func _gen_mysql() (err error) {
|
||||||
if dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Building the generated statements")
|
log.Print("Building the generated statements")
|
||||||
}
|
}
|
||||||
` + body + `
|
` + body + `
|
||||||
|
|
|
@ -346,6 +346,7 @@ package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
type Stmts struct {
|
type Stmts struct {
|
||||||
|
@ -365,7 +366,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_pgsql() (err error) {
|
func _gen_pgsql() (err error) {
|
||||||
if dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Building the generated statements")
|
log.Print("Building the generated statements")
|
||||||
}
|
}
|
||||||
` + body + `
|
` + body + `
|
||||||
|
|
|
@ -230,20 +230,12 @@ func writeSelects(adapter qgen.DB_Adapter) error {
|
||||||
|
|
||||||
adapter.SimpleSelect("getFullSetting", "settings", "name, type, constraints", "name = ?", "", "")
|
adapter.SimpleSelect("getFullSetting", "settings", "name, type, constraints", "name = ?", "", "")
|
||||||
|
|
||||||
adapter.SimpleSelect("getFullSettings", "settings", "name, content, type, constraints", "", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("getThemes", "themes", "uname, default", "", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("getWidgets", "widgets", "position, side, type, active, location, data", "", "position ASC", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("isPluginActive", "plugins", "active", "uname = ?", "", "")
|
adapter.SimpleSelect("isPluginActive", "plugins", "active", "uname = ?", "", "")
|
||||||
|
|
||||||
//adapter.SimpleSelect("isPluginInstalled","plugins","installed","uname = ?","","")
|
//adapter.SimpleSelect("isPluginInstalled","plugins","installed","uname = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("getUsersOffset", "users", "uid, name, group, active, is_super_admin, avatar", "", "uid ASC", "?,?")
|
adapter.SimpleSelect("getUsersOffset", "users", "uid, name, group, active, is_super_admin, avatar", "", "uid ASC", "?,?")
|
||||||
|
|
||||||
adapter.SimpleSelect("getWordFilters", "word_filters", "wfid, find, replacement", "", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("isThemeDefault", "themes", "default", "uname = ?", "", "")
|
adapter.SimpleSelect("isThemeDefault", "themes", "default", "uname = ?", "", "")
|
||||||
|
|
||||||
adapter.SimpleSelect("getModlogs", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "", "", "")
|
adapter.SimpleSelect("getModlogs", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "", "", "")
|
||||||
|
@ -256,10 +248,6 @@ func writeSelects(adapter qgen.DB_Adapter) error {
|
||||||
|
|
||||||
adapter.SimpleSelect("getUserReplyUID", "users_replies", "uid", "rid = ?", "", "")
|
adapter.SimpleSelect("getUserReplyUID", "users_replies", "uid", "rid = ?", "", "")
|
||||||
|
|
||||||
adapter.SimpleSelect("hasLikedTopic", "likes", "targetItem", "sentBy = ? and targetItem = ? and targetType = 'topics'", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("hasLikedReply", "likes", "targetItem", "sentBy = ? and targetItem = ? and targetType = 'replies'", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("getUserName", "users", "name", "uid = ?", "", "")
|
adapter.SimpleSelect("getUserName", "users", "name", "uid = ?", "", "")
|
||||||
|
|
||||||
adapter.SimpleSelect("getEmailsByUser", "emails", "email, validated, token", "uid = ?", "", "")
|
adapter.SimpleSelect("getEmailsByUser", "emails", "email, validated, token", "uid = ?", "", "")
|
||||||
|
@ -274,10 +262,6 @@ func writeSelects(adapter qgen.DB_Adapter) error {
|
||||||
|
|
||||||
adapter.SimpleSelect("getForumTopicsOffset", "topics", "tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount", "parentID = ?", "sticky DESC, lastReplyAt DESC, createdBy DESC", "?,?")
|
adapter.SimpleSelect("getForumTopicsOffset", "topics", "tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount", "parentID = ?", "sticky DESC, lastReplyAt DESC, createdBy DESC", "?,?")
|
||||||
|
|
||||||
adapter.SimpleSelect("getExpiredScheduledGroups", "users_groups_scheduler", "uid", "UTC_TIMESTAMP() > revert_at AND temporary = 1", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("getSync", "sync", "last_update", "", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleSelect("getAttachment", "attachments", "sectionID, sectionTable, originID, originTable, uploadedBy, path", "path = ? AND sectionID = ? AND sectionTable = ?", "", "")
|
adapter.SimpleSelect("getAttachment", "attachments", "sectionID, sectionTable, originID, originTable, uploadedBy, path", "path = ? AND sectionID = ? AND sectionTable = ?", "", "")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -288,11 +272,6 @@ func writeLeftJoins(adapter qgen.DB_Adapter) error {
|
||||||
|
|
||||||
adapter.SimpleLeftJoin("getTopicList", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC", "")
|
adapter.SimpleLeftJoin("getTopicList", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC", "")
|
||||||
|
|
||||||
// TODO: Can we get rid of this?
|
|
||||||
adapter.SimpleLeftJoin("getTopicUser", "topics", "users", "topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level", "topics.createdBy = users.uid", "tid = ?", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleLeftJoin("getTopicByReply", "replies", "topics", "topics.tid, topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, topics.data", "replies.tid = topics.tid", "rid = ?", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleLeftJoin("getTopicReplies", "replies", "users", "replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress", "replies.createdBy = users.uid", "tid = ?", "", "")
|
adapter.SimpleLeftJoin("getTopicReplies", "replies", "users", "replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress", "replies.createdBy = users.uid", "tid = ?", "", "")
|
||||||
|
|
||||||
adapter.SimpleLeftJoin("getForumTopics", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "topics.parentID = ?", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc", "")
|
adapter.SimpleLeftJoin("getForumTopics", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "topics.parentID = ?", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc", "")
|
||||||
|
@ -314,10 +293,6 @@ func writeInnerJoins(adapter qgen.DB_Adapter) (err error) {
|
||||||
func writeInserts(adapter qgen.DB_Adapter) error {
|
func writeInserts(adapter qgen.DB_Adapter) error {
|
||||||
adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'")
|
adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'")
|
||||||
|
|
||||||
adapter.SimpleInsert("createActionReply", "replies", "tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''")
|
|
||||||
|
|
||||||
adapter.SimpleInsert("createLike", "likes", "weight, targetItem, targetType, sentBy", "?,?,?,?")
|
|
||||||
|
|
||||||
adapter.SimpleInsert("addActivity", "activity_stream", "actor, targetUser, event, elementType, elementID", "?,?,?,?,?")
|
adapter.SimpleInsert("addActivity", "activity_stream", "actor, targetUser, event, elementType, elementID", "?,?,?,?,?")
|
||||||
|
|
||||||
adapter.SimpleInsert("notifyOne", "activity_stream_matches", "watcher, asid", "?,?")
|
adapter.SimpleInsert("notifyOne", "activity_stream_matches", "watcher, asid", "?,?")
|
||||||
|
@ -332,10 +307,6 @@ func writeInserts(adapter qgen.DB_Adapter) error {
|
||||||
|
|
||||||
adapter.SimpleInsert("addTheme", "themes", "uname, default", "?,?")
|
adapter.SimpleInsert("addTheme", "themes", "uname, default", "?,?")
|
||||||
|
|
||||||
adapter.SimpleInsert("addModlogEntry", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "?,?,?,?,?,UTC_TIMESTAMP()")
|
|
||||||
|
|
||||||
adapter.SimpleInsert("addAdminlogEntry", "administration_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "?,?,?,?,?,UTC_TIMESTAMP()")
|
|
||||||
|
|
||||||
adapter.SimpleInsert("addAttachment", "attachments", "sectionID, sectionTable, originID, originTable, uploadedBy, path", "?,?,?,?,?,?")
|
adapter.SimpleInsert("addAttachment", "attachments", "sectionID, sectionTable, originID, originTable, uploadedBy, path", "?,?,?,?,?,?")
|
||||||
|
|
||||||
adapter.SimpleInsert("createWordFilter", "word_filters", "find, replacement", "?,?")
|
adapter.SimpleInsert("createWordFilter", "word_filters", "find, replacement", "?,?")
|
||||||
|
@ -363,56 +334,10 @@ func writeReplaces(adapter qgen.DB_Adapter) (err error) {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
func writeUpdates(adapter qgen.DB_Adapter) error {
|
func writeUpdates(adapter qgen.DB_Adapter) error {
|
||||||
adapter.SimpleUpdate("addRepliesToTopic", "topics", "postCount = postCount + ?, lastReplyBy = ?, lastReplyAt = UTC_TIMESTAMP()", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("removeRepliesFromTopic", "topics", "postCount = postCount - ?", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("addLikesToTopic", "topics", "likeCount = likeCount + ?", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("addLikesToReply", "replies", "likeCount = likeCount + ?", "rid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("editTopic", "topics", "title = ?, content = ?, parsed_content = ?", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("editReply", "replies", "content = ?, parsed_content = ?", "rid = ?")
|
adapter.SimpleUpdate("editReply", "replies", "content = ?, parsed_content = ?", "rid = ?")
|
||||||
|
|
||||||
adapter.SimpleUpdate("stickTopic", "topics", "sticky = 1", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("unstickTopic", "topics", "sticky = 0", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("lockTopic", "topics", "is_closed = 1", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("unlockTopic", "topics", "is_closed = 0", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateLastIP", "users", "last_ip = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateSession", "users", "session = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("setPassword", "users", "password = ?, salt = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("setAvatar", "users", "avatar = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("setUsername", "users", "name = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("changeGroup", "users", "group = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("activateUser", "users", "active = 1", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateUserLevel", "users", "level = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("incrementUserScore", "users", "score = score + ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("incrementUserPosts", "users", "posts = posts + ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("incrementUserBigposts", "users", "posts = posts + ?, bigposts = bigposts + ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("incrementUserMegaposts", "users", "posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("incrementUserTopics", "users", "topics = topics + ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("editProfileReply", "users_replies", "content = ?, parsed_content = ?", "rid = ?")
|
adapter.SimpleUpdate("editProfileReply", "users_replies", "content = ?, parsed_content = ?", "rid = ?")
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateForum", "forums", "name = ?, desc = ?, active = ?, preset = ?", "fid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateSetting", "settings", "content = ?", "name = ?")
|
adapter.SimpleUpdate("updateSetting", "settings", "content = ?", "name = ?")
|
||||||
|
|
||||||
adapter.SimpleUpdate("updatePlugin", "plugins", "active = ?", "uname = ?")
|
adapter.SimpleUpdate("updatePlugin", "plugins", "active = ?", "uname = ?")
|
||||||
|
@ -421,14 +346,12 @@ func writeUpdates(adapter qgen.DB_Adapter) error {
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateTheme", "themes", "default = ?", "uname = ?")
|
adapter.SimpleUpdate("updateTheme", "themes", "default = ?", "uname = ?")
|
||||||
|
|
||||||
|
adapter.SimpleUpdate("updateForum", "forums", "name = ?, desc = ?, active = ?, preset = ?", "fid = ?")
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateUser", "users", "name = ?, email = ?, group = ?", "uid = ?")
|
adapter.SimpleUpdate("updateUser", "users", "name = ?, email = ?, group = ?", "uid = ?")
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateUserGroup", "users", "group = ?", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateGroupPerms", "users_groups", "permissions = ?", "gid = ?")
|
adapter.SimpleUpdate("updateGroupPerms", "users_groups", "permissions = ?", "gid = ?")
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateGroupRank", "users_groups", "is_admin = ?, is_mod = ?, is_banned = ?", "gid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateGroup", "users_groups", "name = ?, tag = ?", "gid = ?")
|
adapter.SimpleUpdate("updateGroup", "users_groups", "name = ?, tag = ?", "gid = ?")
|
||||||
|
|
||||||
adapter.SimpleUpdate("updateEmail", "emails", "email = ?, uid = ?, validated = ?, token = ?", "email = ?")
|
adapter.SimpleUpdate("updateEmail", "emails", "email = ?, uid = ?, validated = ?, token = ?", "email = ?")
|
||||||
|
@ -445,12 +368,6 @@ func writeUpdates(adapter qgen.DB_Adapter) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeDeletes(adapter qgen.DB_Adapter) error {
|
func writeDeletes(adapter qgen.DB_Adapter) error {
|
||||||
adapter.SimpleDelete("deleteUser", "users", "uid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleDelete("deleteTopic", "topics", "tid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleDelete("deleteReply", "replies", "rid = ?")
|
|
||||||
|
|
||||||
adapter.SimpleDelete("deleteProfileReply", "users_replies", "rid = ?")
|
adapter.SimpleDelete("deleteProfileReply", "users_replies", "rid = ?")
|
||||||
|
|
||||||
//adapter.SimpleDelete("deleteForumPermsByForum", "forums_permissions", "fid = ?")
|
//adapter.SimpleDelete("deleteForumPermsByForum", "forums_permissions", "fid = ?")
|
||||||
|
@ -466,8 +383,6 @@ func writeDeletes(adapter qgen.DB_Adapter) error {
|
||||||
func writeSimpleCounts(adapter qgen.DB_Adapter) error {
|
func writeSimpleCounts(adapter qgen.DB_Adapter) error {
|
||||||
adapter.SimpleCount("reportExists", "topics", "data = ? AND data != '' AND parentID = 1", "")
|
adapter.SimpleCount("reportExists", "topics", "data = ? AND data != '' AND parentID = 1", "")
|
||||||
|
|
||||||
adapter.SimpleCount("groupCount", "users_groups", "", "")
|
|
||||||
|
|
||||||
adapter.SimpleCount("modlogCount", "moderation_logs", "", "")
|
adapter.SimpleCount("modlogCount", "moderation_logs", "", "")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
12
router.go
12
router.go
|
@ -2,9 +2,13 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
//import "fmt"
|
//import "fmt"
|
||||||
import "strings"
|
import (
|
||||||
import "sync"
|
"net/http"
|
||||||
import "net/http"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"./common"
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: Support the new handler signatures created by our efforts to move the PreRoute middleware into the generated router
|
// TODO: Support the new handler signatures created by our efforts to move the PreRoute middleware into the generated router
|
||||||
// nolint Stop linting the uselessness of this file, we never know when we might need this file again
|
// nolint Stop linting the uselessness of this file, we never know when we might need this file again
|
||||||
|
@ -59,5 +63,5 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//log.Print("req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')]",req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')])
|
//log.Print("req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')]",req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')])
|
||||||
NotFound(w, req)
|
common.NotFound(w, req)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ func main() {
|
||||||
out += "\n\t\t\t\t\t" + runnable.Contents
|
out += "\n\t\t\t\t\t" + runnable.Contents
|
||||||
} else {
|
} else {
|
||||||
out += `
|
out += `
|
||||||
err = ` + runnable.Contents + `(w,req,user)
|
err = common.` + runnable.Contents + `(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -65,7 +65,7 @@ func main() {
|
||||||
out += "\t\t\t" + runnable.Contents
|
out += "\t\t\t" + runnable.Contents
|
||||||
} else {
|
} else {
|
||||||
out += `
|
out += `
|
||||||
err = ` + runnable.Contents + `(w,req,user)
|
err = common.` + runnable.Contents + `(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -89,7 +89,7 @@ func main() {
|
||||||
out += "\n\t\t\t\t\t" + runnable.Contents
|
out += "\n\t\t\t\t\t" + runnable.Contents
|
||||||
} else {
|
} else {
|
||||||
out += `
|
out += `
|
||||||
err = ` + runnable.Contents + `(w,req,user)
|
err = common.` + runnable.Contents + `(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -113,7 +113,7 @@ func main() {
|
||||||
out += "\n\t\t\t\t\t" + runnable.Contents
|
out += "\n\t\t\t\t\t" + runnable.Contents
|
||||||
} else {
|
} else {
|
||||||
out += `
|
out += `
|
||||||
err = ` + runnable.Contents + `(w,req,user)
|
err = common.` + runnable.Contents + `(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -137,17 +137,21 @@ func main() {
|
||||||
|
|
||||||
fileData += `package main
|
fileData += `package main
|
||||||
|
|
||||||
import "log"
|
import (
|
||||||
import "strings"
|
"log"
|
||||||
import "sync"
|
"strings"
|
||||||
import "errors"
|
"sync"
|
||||||
import "net/http"
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"./common"
|
||||||
|
)
|
||||||
|
|
||||||
var ErrNoRoute = errors.New("That route doesn't exist.")
|
var ErrNoRoute = errors.New("That route doesn't exist.")
|
||||||
|
|
||||||
type GenRouter struct {
|
type GenRouter struct {
|
||||||
UploadHandler func(http.ResponseWriter, *http.Request)
|
UploadHandler func(http.ResponseWriter, *http.Request)
|
||||||
extra_routes map[string]func(http.ResponseWriter, *http.Request, User) RouteError
|
extra_routes map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
@ -155,26 +159,26 @@ type GenRouter struct {
|
||||||
func NewGenRouter(uploads http.Handler) *GenRouter {
|
func NewGenRouter(uploads http.Handler) *GenRouter {
|
||||||
return &GenRouter{
|
return &GenRouter{
|
||||||
UploadHandler: http.StripPrefix("/uploads/",uploads).ServeHTTP,
|
UploadHandler: http.StripPrefix("/uploads/",uploads).ServeHTTP,
|
||||||
extra_routes: make(map[string]func(http.ResponseWriter, *http.Request, User) RouteError),
|
extra_routes: make(map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (router *GenRouter) handleError(err RouteError, w http.ResponseWriter, r *http.Request, user User) {
|
func (router *GenRouter) handleError(err common.RouteError, w http.ResponseWriter, r *http.Request, user common.User) {
|
||||||
if err.Handled() {
|
if err.Handled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err.Type() == "system" {
|
if err.Type() == "system" {
|
||||||
InternalErrorJSQ(err,w,r,err.Json())
|
common.InternalErrorJSQ(err, w, r, err.JSON())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
LocalErrorJSQ(err.Error(),w,r,user,err.Json())
|
common.LocalErrorJSQ(err.Error(), w, r, user,err.JSON())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (router *GenRouter) Handle(_ string, _ http.Handler) {
|
func (router *GenRouter) Handle(_ string, _ http.Handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (router *GenRouter) HandleFunc(pattern string, handle func(http.ResponseWriter, *http.Request, User) RouteError) {
|
func (router *GenRouter) HandleFunc(pattern string, handle func(http.ResponseWriter, *http.Request, common.User) common.RouteError) {
|
||||||
router.Lock()
|
router.Lock()
|
||||||
router.extra_routes[pattern] = handle
|
router.extra_routes[pattern] = handle
|
||||||
router.Unlock()
|
router.Unlock()
|
||||||
|
@ -187,7 +191,7 @@ func (router *GenRouter) RemoveFunc(pattern string) error {
|
||||||
router.Unlock()
|
router.Unlock()
|
||||||
return ErrNoRoute
|
return ErrNoRoute
|
||||||
}
|
}
|
||||||
delete(router.extra_routes,pattern)
|
delete(router.extra_routes, pattern)
|
||||||
router.Unlock()
|
router.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -210,7 +214,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("before routeStatic")
|
log.Print("before routeStatic")
|
||||||
log.Print("prefix: ", prefix)
|
log.Print("prefix: ", prefix)
|
||||||
log.Print("req.URL.Path: ", req.URL.Path)
|
log.Print("req.URL.Path: ", req.URL.Path)
|
||||||
|
@ -220,29 +224,29 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
if prefix == "/static" {
|
if prefix == "/static" {
|
||||||
req.URL.Path += extra_data
|
req.URL.Path += extra_data
|
||||||
routeStatic(w,req)
|
routeStatic(w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("before PreRoute")
|
log.Print("before PreRoute")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deal with the session stuff, etc.
|
// Deal with the session stuff, etc.
|
||||||
user, ok := PreRoute(w,req)
|
user, ok := common.PreRoute(w, req)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("after PreRoute")
|
log.Print("after PreRoute")
|
||||||
}
|
}
|
||||||
|
|
||||||
var err RouteError
|
var err common.RouteError
|
||||||
switch(prefix) {` + out + `
|
switch(prefix) {` + out + `
|
||||||
case "/uploads":
|
case "/uploads":
|
||||||
if extra_data == "" {
|
if extra_data == "" {
|
||||||
NotFound(w,req)
|
common.NotFound(w,req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.URL.Path += extra_data
|
req.URL.Path += extra_data
|
||||||
|
@ -261,10 +265,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if extra_data != "" {
|
if extra_data != "" {
|
||||||
NotFound(w,req)
|
common.NotFound(w,req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
config.DefaultRoute(w,req,user)
|
common.Config.DefaultRoute(w,req,user)
|
||||||
default:
|
default:
|
||||||
// A fallback for the routes which haven't been converted to the new router yet or plugins
|
// A fallback for the routes which haven't been converted to the new router yet or plugins
|
||||||
router.RLock()
|
router.RLock()
|
||||||
|
@ -279,7 +283,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
NotFound(w,req)
|
common.NotFound(w,req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
|
@ -1,230 +0,0 @@
|
||||||
// +build !no_templategen
|
|
||||||
|
|
||||||
// Code generated by Gosora. More below:
|
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
|
||||||
package main
|
|
||||||
import "net/http"
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
template_forum_handle = template_forum
|
|
||||||
//o_template_forum_handle = template_forum
|
|
||||||
ctemplates = append(ctemplates,"forum")
|
|
||||||
tmplPtrMap["forum"] = &template_forum_handle
|
|
||||||
tmplPtrMap["o_forum"] = template_forum
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func template_forum(tmpl_forum_vars ForumPage, w http.ResponseWriter) error {
|
|
||||||
w.Write(header_0)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.Title))
|
|
||||||
w.Write(header_1)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.Header.Site.Name))
|
|
||||||
w.Write(header_2)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.Header.ThemeName))
|
|
||||||
w.Write(header_3)
|
|
||||||
if len(tmpl_forum_vars.Header.Stylesheets) != 0 {
|
|
||||||
for _, item := range tmpl_forum_vars.Header.Stylesheets {
|
|
||||||
w.Write(header_4)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_6)
|
|
||||||
if len(tmpl_forum_vars.Header.Scripts) != 0 {
|
|
||||||
for _, item := range tmpl_forum_vars.Header.Scripts {
|
|
||||||
w.Write(header_7)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_9)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
|
|
||||||
w.Write(header_10)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.Header.Site.URL))
|
|
||||||
w.Write(header_11)
|
|
||||||
if !tmpl_forum_vars.CurrentUser.IsSuperMod {
|
|
||||||
w.Write(header_12)
|
|
||||||
}
|
|
||||||
w.Write(header_13)
|
|
||||||
w.Write(menu_0)
|
|
||||||
w.Write(menu_1)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.Header.Site.ShortName))
|
|
||||||
w.Write(menu_2)
|
|
||||||
if tmpl_forum_vars.CurrentUser.Loggedin {
|
|
||||||
w.Write(menu_3)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.CurrentUser.Link))
|
|
||||||
w.Write(menu_4)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
|
|
||||||
w.Write(menu_5)
|
|
||||||
} else {
|
|
||||||
w.Write(menu_6)
|
|
||||||
}
|
|
||||||
w.Write(menu_7)
|
|
||||||
w.Write(header_14)
|
|
||||||
if tmpl_forum_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(header_15)
|
|
||||||
}
|
|
||||||
w.Write(header_16)
|
|
||||||
if len(tmpl_forum_vars.Header.NoticeList) != 0 {
|
|
||||||
for _, item := range tmpl_forum_vars.Header.NoticeList {
|
|
||||||
w.Write(header_17)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_18)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tmpl_forum_vars.Page > 1 {
|
|
||||||
w.Write(forum_0)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
|
|
||||||
w.Write(forum_1)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Page - 1)))
|
|
||||||
w.Write(forum_2)
|
|
||||||
}
|
|
||||||
if tmpl_forum_vars.LastPage != tmpl_forum_vars.Page {
|
|
||||||
w.Write(forum_3)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
|
|
||||||
w.Write(forum_4)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Page + 1)))
|
|
||||||
w.Write(forum_5)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
|
|
||||||
w.Write(forum_6)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Page + 1)))
|
|
||||||
w.Write(forum_7)
|
|
||||||
}
|
|
||||||
w.Write(forum_8)
|
|
||||||
if tmpl_forum_vars.CurrentUser.ID != 0 {
|
|
||||||
w.Write(forum_9)
|
|
||||||
}
|
|
||||||
w.Write(forum_10)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.Title))
|
|
||||||
w.Write(forum_11)
|
|
||||||
if tmpl_forum_vars.CurrentUser.ID != 0 {
|
|
||||||
if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
|
|
||||||
w.Write(forum_12)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
|
|
||||||
w.Write(forum_13)
|
|
||||||
w.Write(forum_14)
|
|
||||||
} else {
|
|
||||||
w.Write(forum_15)
|
|
||||||
}
|
|
||||||
w.Write(forum_16)
|
|
||||||
}
|
|
||||||
w.Write(forum_17)
|
|
||||||
if tmpl_forum_vars.CurrentUser.ID != 0 {
|
|
||||||
w.Write(forum_18)
|
|
||||||
if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
|
|
||||||
w.Write(forum_19)
|
|
||||||
if tmpl_forum_vars.CurrentUser.Avatar != "" {
|
|
||||||
w.Write(forum_20)
|
|
||||||
w.Write([]byte(tmpl_forum_vars.CurrentUser.Avatar))
|
|
||||||
w.Write(forum_21)
|
|
||||||
}
|
|
||||||
w.Write(forum_22)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
|
|
||||||
w.Write(forum_23)
|
|
||||||
if tmpl_forum_vars.CurrentUser.Perms.UploadFiles {
|
|
||||||
w.Write(forum_24)
|
|
||||||
}
|
|
||||||
w.Write(forum_25)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(forum_26)
|
|
||||||
if len(tmpl_forum_vars.ItemList) != 0 {
|
|
||||||
for _, item := range tmpl_forum_vars.ItemList {
|
|
||||||
w.Write(forum_27)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(forum_28)
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(forum_29)
|
|
||||||
} else {
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(forum_30)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(forum_31)
|
|
||||||
if item.Creator.Avatar != "" {
|
|
||||||
w.Write(forum_32)
|
|
||||||
w.Write([]byte(item.Creator.Link))
|
|
||||||
w.Write(forum_33)
|
|
||||||
w.Write([]byte(item.Creator.Avatar))
|
|
||||||
w.Write(forum_34)
|
|
||||||
}
|
|
||||||
w.Write(forum_35)
|
|
||||||
w.Write([]byte(item.Link))
|
|
||||||
w.Write(forum_36)
|
|
||||||
w.Write([]byte(item.Title))
|
|
||||||
w.Write(forum_37)
|
|
||||||
w.Write([]byte(item.Creator.Link))
|
|
||||||
w.Write(forum_38)
|
|
||||||
w.Write([]byte(item.Creator.Name))
|
|
||||||
w.Write(forum_39)
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(forum_40)
|
|
||||||
}
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(forum_41)
|
|
||||||
}
|
|
||||||
w.Write(forum_42)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.PostCount)))
|
|
||||||
w.Write(forum_43)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.LikeCount)))
|
|
||||||
w.Write(forum_44)
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(forum_45)
|
|
||||||
} else {
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(forum_46)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(forum_47)
|
|
||||||
if item.LastUser.Avatar != "" {
|
|
||||||
w.Write(forum_48)
|
|
||||||
w.Write([]byte(item.LastUser.Link))
|
|
||||||
w.Write(forum_49)
|
|
||||||
w.Write([]byte(item.LastUser.Avatar))
|
|
||||||
w.Write(forum_50)
|
|
||||||
}
|
|
||||||
w.Write(forum_51)
|
|
||||||
w.Write([]byte(item.LastUser.Link))
|
|
||||||
w.Write(forum_52)
|
|
||||||
w.Write([]byte(item.LastUser.Name))
|
|
||||||
w.Write(forum_53)
|
|
||||||
w.Write([]byte(item.RelativeLastReplyAt))
|
|
||||||
w.Write(forum_54)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w.Write(forum_55)
|
|
||||||
if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
|
|
||||||
w.Write(forum_56)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
|
|
||||||
w.Write(forum_57)
|
|
||||||
}
|
|
||||||
w.Write(forum_58)
|
|
||||||
}
|
|
||||||
w.Write(forum_59)
|
|
||||||
w.Write(footer_0)
|
|
||||||
if len(tmpl_forum_vars.Header.Themes) != 0 {
|
|
||||||
for _, item := range tmpl_forum_vars.Header.Themes {
|
|
||||||
if !item.HideFromThemes {
|
|
||||||
w.Write(footer_1)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(footer_2)
|
|
||||||
if tmpl_forum_vars.Header.ThemeName == item.Name {
|
|
||||||
w.Write(footer_3)
|
|
||||||
}
|
|
||||||
w.Write(footer_4)
|
|
||||||
w.Write([]byte(item.FriendlyName))
|
|
||||||
w.Write(footer_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(footer_6)
|
|
||||||
if tmpl_forum_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(footer_7)
|
|
||||||
w.Write([]byte(string(tmpl_forum_vars.Header.Widgets.RightSidebar)))
|
|
||||||
w.Write(footer_8)
|
|
||||||
}
|
|
||||||
w.Write(footer_9)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
// +build !no_templategen
|
|
||||||
|
|
||||||
// Code generated by Gosora. More below:
|
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
|
||||||
package main
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
template_forums_handle = template_forums
|
|
||||||
//o_template_forums_handle = template_forums
|
|
||||||
ctemplates = append(ctemplates,"forums")
|
|
||||||
tmplPtrMap["forums"] = &template_forums_handle
|
|
||||||
tmplPtrMap["o_forums"] = template_forums
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func template_forums(tmpl_forums_vars ForumsPage, w http.ResponseWriter) error {
|
|
||||||
w.Write(header_0)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.Title))
|
|
||||||
w.Write(header_1)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.Header.Site.Name))
|
|
||||||
w.Write(header_2)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.Header.ThemeName))
|
|
||||||
w.Write(header_3)
|
|
||||||
if len(tmpl_forums_vars.Header.Stylesheets) != 0 {
|
|
||||||
for _, item := range tmpl_forums_vars.Header.Stylesheets {
|
|
||||||
w.Write(header_4)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_6)
|
|
||||||
if len(tmpl_forums_vars.Header.Scripts) != 0 {
|
|
||||||
for _, item := range tmpl_forums_vars.Header.Scripts {
|
|
||||||
w.Write(header_7)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_9)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
|
|
||||||
w.Write(header_10)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.Header.Site.URL))
|
|
||||||
w.Write(header_11)
|
|
||||||
if !tmpl_forums_vars.CurrentUser.IsSuperMod {
|
|
||||||
w.Write(header_12)
|
|
||||||
}
|
|
||||||
w.Write(header_13)
|
|
||||||
w.Write(menu_0)
|
|
||||||
w.Write(menu_1)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.Header.Site.ShortName))
|
|
||||||
w.Write(menu_2)
|
|
||||||
if tmpl_forums_vars.CurrentUser.Loggedin {
|
|
||||||
w.Write(menu_3)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.CurrentUser.Link))
|
|
||||||
w.Write(menu_4)
|
|
||||||
w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
|
|
||||||
w.Write(menu_5)
|
|
||||||
} else {
|
|
||||||
w.Write(menu_6)
|
|
||||||
}
|
|
||||||
w.Write(menu_7)
|
|
||||||
w.Write(header_14)
|
|
||||||
if tmpl_forums_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(header_15)
|
|
||||||
}
|
|
||||||
w.Write(header_16)
|
|
||||||
if len(tmpl_forums_vars.Header.NoticeList) != 0 {
|
|
||||||
for _, item := range tmpl_forums_vars.Header.NoticeList {
|
|
||||||
w.Write(header_17)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_18)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(forums_0)
|
|
||||||
if len(tmpl_forums_vars.ItemList) != 0 {
|
|
||||||
for _, item := range tmpl_forums_vars.ItemList {
|
|
||||||
w.Write(forums_1)
|
|
||||||
if item.Desc != "" || item.LastTopic.Title != "" {
|
|
||||||
w.Write(forums_2)
|
|
||||||
}
|
|
||||||
w.Write(forums_3)
|
|
||||||
w.Write([]byte(item.Link))
|
|
||||||
w.Write(forums_4)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(forums_5)
|
|
||||||
if item.Desc != "" {
|
|
||||||
w.Write(forums_6)
|
|
||||||
w.Write([]byte(item.Desc))
|
|
||||||
w.Write(forums_7)
|
|
||||||
} else {
|
|
||||||
w.Write(forums_8)
|
|
||||||
}
|
|
||||||
w.Write(forums_9)
|
|
||||||
if item.LastReplyer.Avatar != "" {
|
|
||||||
w.Write(forums_10)
|
|
||||||
w.Write([]byte(item.LastReplyer.Avatar))
|
|
||||||
w.Write(forums_11)
|
|
||||||
}
|
|
||||||
w.Write(forums_12)
|
|
||||||
w.Write([]byte(item.LastTopic.Link))
|
|
||||||
w.Write(forums_13)
|
|
||||||
if item.LastTopic.Title != "" {
|
|
||||||
w.Write([]byte(item.LastTopic.Title))
|
|
||||||
} else {
|
|
||||||
w.Write(forums_14)
|
|
||||||
}
|
|
||||||
w.Write(forums_15)
|
|
||||||
if item.LastTopicTime != "" {
|
|
||||||
w.Write(forums_16)
|
|
||||||
w.Write([]byte(item.LastTopicTime))
|
|
||||||
w.Write(forums_17)
|
|
||||||
}
|
|
||||||
w.Write(forums_18)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w.Write(forums_19)
|
|
||||||
}
|
|
||||||
w.Write(forums_20)
|
|
||||||
w.Write(footer_0)
|
|
||||||
if len(tmpl_forums_vars.Header.Themes) != 0 {
|
|
||||||
for _, item := range tmpl_forums_vars.Header.Themes {
|
|
||||||
if !item.HideFromThemes {
|
|
||||||
w.Write(footer_1)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(footer_2)
|
|
||||||
if tmpl_forums_vars.Header.ThemeName == item.Name {
|
|
||||||
w.Write(footer_3)
|
|
||||||
}
|
|
||||||
w.Write(footer_4)
|
|
||||||
w.Write([]byte(item.FriendlyName))
|
|
||||||
w.Write(footer_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(footer_6)
|
|
||||||
if tmpl_forums_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(footer_7)
|
|
||||||
w.Write([]byte(string(tmpl_forums_vars.Header.Widgets.RightSidebar)))
|
|
||||||
w.Write(footer_8)
|
|
||||||
}
|
|
||||||
w.Write(footer_9)
|
|
||||||
return nil
|
|
||||||
}
|
|
1022
template_list.go
1022
template_list.go
File diff suppressed because it is too large
Load Diff
|
@ -1,188 +0,0 @@
|
||||||
// +build !no_templategen
|
|
||||||
|
|
||||||
// Code generated by Gosora. More below:
|
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
|
||||||
package main
|
|
||||||
import "net/http"
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
template_profile_handle = template_profile
|
|
||||||
//o_template_profile_handle = template_profile
|
|
||||||
ctemplates = append(ctemplates,"profile")
|
|
||||||
tmplPtrMap["profile"] = &template_profile_handle
|
|
||||||
tmplPtrMap["o_profile"] = template_profile
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func template_profile(tmpl_profile_vars ProfilePage, w http.ResponseWriter) error {
|
|
||||||
w.Write(header_0)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.Title))
|
|
||||||
w.Write(header_1)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.Header.Site.Name))
|
|
||||||
w.Write(header_2)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.Header.ThemeName))
|
|
||||||
w.Write(header_3)
|
|
||||||
if len(tmpl_profile_vars.Header.Stylesheets) != 0 {
|
|
||||||
for _, item := range tmpl_profile_vars.Header.Stylesheets {
|
|
||||||
w.Write(header_4)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_6)
|
|
||||||
if len(tmpl_profile_vars.Header.Scripts) != 0 {
|
|
||||||
for _, item := range tmpl_profile_vars.Header.Scripts {
|
|
||||||
w.Write(header_7)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_9)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
|
|
||||||
w.Write(header_10)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.Header.Site.URL))
|
|
||||||
w.Write(header_11)
|
|
||||||
if !tmpl_profile_vars.CurrentUser.IsSuperMod {
|
|
||||||
w.Write(header_12)
|
|
||||||
}
|
|
||||||
w.Write(header_13)
|
|
||||||
w.Write(menu_0)
|
|
||||||
w.Write(menu_1)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.Header.Site.ShortName))
|
|
||||||
w.Write(menu_2)
|
|
||||||
if tmpl_profile_vars.CurrentUser.Loggedin {
|
|
||||||
w.Write(menu_3)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.CurrentUser.Link))
|
|
||||||
w.Write(menu_4)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
|
|
||||||
w.Write(menu_5)
|
|
||||||
} else {
|
|
||||||
w.Write(menu_6)
|
|
||||||
}
|
|
||||||
w.Write(menu_7)
|
|
||||||
w.Write(header_14)
|
|
||||||
if tmpl_profile_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(header_15)
|
|
||||||
}
|
|
||||||
w.Write(header_16)
|
|
||||||
if len(tmpl_profile_vars.Header.NoticeList) != 0 {
|
|
||||||
for _, item := range tmpl_profile_vars.Header.NoticeList {
|
|
||||||
w.Write(header_17)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_18)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(profile_0)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Avatar))
|
|
||||||
w.Write(profile_1)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Name))
|
|
||||||
w.Write(profile_2)
|
|
||||||
if tmpl_profile_vars.ProfileOwner.Tag != "" {
|
|
||||||
w.Write(profile_3)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Tag))
|
|
||||||
w.Write(profile_4)
|
|
||||||
}
|
|
||||||
w.Write(profile_5)
|
|
||||||
if tmpl_profile_vars.CurrentUser.IsSuperMod && !tmpl_profile_vars.ProfileOwner.IsSuperMod {
|
|
||||||
w.Write(profile_6)
|
|
||||||
if tmpl_profile_vars.ProfileOwner.IsBanned {
|
|
||||||
w.Write(profile_7)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
|
|
||||||
w.Write(profile_8)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
|
|
||||||
w.Write(profile_9)
|
|
||||||
} else {
|
|
||||||
w.Write(profile_10)
|
|
||||||
}
|
|
||||||
w.Write(profile_11)
|
|
||||||
}
|
|
||||||
w.Write(profile_12)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
|
|
||||||
w.Write(profile_13)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
|
|
||||||
w.Write(profile_14)
|
|
||||||
if tmpl_profile_vars.CurrentUser.Perms.BanUsers {
|
|
||||||
w.Write(profile_15)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
|
|
||||||
w.Write(profile_16)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
|
|
||||||
w.Write(profile_17)
|
|
||||||
w.Write(profile_18)
|
|
||||||
}
|
|
||||||
w.Write(profile_19)
|
|
||||||
if len(tmpl_profile_vars.ItemList) != 0 {
|
|
||||||
for _, item := range tmpl_profile_vars.ItemList {
|
|
||||||
w.Write(profile_20)
|
|
||||||
w.Write([]byte(item.ClassName))
|
|
||||||
w.Write(profile_21)
|
|
||||||
if item.Avatar != "" {
|
|
||||||
w.Write(profile_22)
|
|
||||||
w.Write([]byte(item.Avatar))
|
|
||||||
w.Write(profile_23)
|
|
||||||
if item.ContentLines <= 5 {
|
|
||||||
w.Write(profile_24)
|
|
||||||
}
|
|
||||||
w.Write(profile_25)
|
|
||||||
}
|
|
||||||
w.Write(profile_26)
|
|
||||||
w.Write([]byte(item.ContentHtml))
|
|
||||||
w.Write(profile_27)
|
|
||||||
w.Write([]byte(item.UserLink))
|
|
||||||
w.Write(profile_28)
|
|
||||||
w.Write([]byte(item.CreatedByName))
|
|
||||||
w.Write(profile_29)
|
|
||||||
if tmpl_profile_vars.CurrentUser.IsMod {
|
|
||||||
w.Write(profile_30)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(profile_31)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(profile_32)
|
|
||||||
}
|
|
||||||
w.Write(profile_33)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(profile_34)
|
|
||||||
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
|
|
||||||
w.Write(profile_35)
|
|
||||||
if item.Tag != "" {
|
|
||||||
w.Write(profile_36)
|
|
||||||
w.Write([]byte(item.Tag))
|
|
||||||
w.Write(profile_37)
|
|
||||||
}
|
|
||||||
w.Write(profile_38)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(profile_39)
|
|
||||||
if !tmpl_profile_vars.CurrentUser.IsBanned {
|
|
||||||
w.Write(profile_40)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
|
|
||||||
w.Write(profile_41)
|
|
||||||
}
|
|
||||||
w.Write(profile_42)
|
|
||||||
w.Write(profile_43)
|
|
||||||
w.Write(footer_0)
|
|
||||||
if len(tmpl_profile_vars.Header.Themes) != 0 {
|
|
||||||
for _, item := range tmpl_profile_vars.Header.Themes {
|
|
||||||
if !item.HideFromThemes {
|
|
||||||
w.Write(footer_1)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(footer_2)
|
|
||||||
if tmpl_profile_vars.Header.ThemeName == item.Name {
|
|
||||||
w.Write(footer_3)
|
|
||||||
}
|
|
||||||
w.Write(footer_4)
|
|
||||||
w.Write([]byte(item.FriendlyName))
|
|
||||||
w.Write(footer_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(footer_6)
|
|
||||||
if tmpl_profile_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(footer_7)
|
|
||||||
w.Write([]byte(string(tmpl_profile_vars.Header.Widgets.RightSidebar)))
|
|
||||||
w.Write(footer_8)
|
|
||||||
}
|
|
||||||
w.Write(footer_9)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,323 +0,0 @@
|
||||||
// +build !no_templategen
|
|
||||||
|
|
||||||
// Code generated by Gosora. More below:
|
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
|
||||||
package main
|
|
||||||
import "strconv"
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
template_topic_handle = template_topic
|
|
||||||
//o_template_topic_handle = template_topic
|
|
||||||
ctemplates = append(ctemplates,"topic")
|
|
||||||
tmplPtrMap["topic"] = &template_topic_handle
|
|
||||||
tmplPtrMap["o_topic"] = template_topic
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func template_topic(tmpl_topic_vars TopicPage, w http.ResponseWriter) error {
|
|
||||||
w.Write(header_0)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Title))
|
|
||||||
w.Write(header_1)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Header.Site.Name))
|
|
||||||
w.Write(header_2)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Header.ThemeName))
|
|
||||||
w.Write(header_3)
|
|
||||||
if len(tmpl_topic_vars.Header.Stylesheets) != 0 {
|
|
||||||
for _, item := range tmpl_topic_vars.Header.Stylesheets {
|
|
||||||
w.Write(header_4)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_6)
|
|
||||||
if len(tmpl_topic_vars.Header.Scripts) != 0 {
|
|
||||||
for _, item := range tmpl_topic_vars.Header.Scripts {
|
|
||||||
w.Write(header_7)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_9)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
|
|
||||||
w.Write(header_10)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Header.Site.URL))
|
|
||||||
w.Write(header_11)
|
|
||||||
if !tmpl_topic_vars.CurrentUser.IsSuperMod {
|
|
||||||
w.Write(header_12)
|
|
||||||
}
|
|
||||||
w.Write(header_13)
|
|
||||||
w.Write(menu_0)
|
|
||||||
w.Write(menu_1)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Header.Site.ShortName))
|
|
||||||
w.Write(menu_2)
|
|
||||||
if tmpl_topic_vars.CurrentUser.Loggedin {
|
|
||||||
w.Write(menu_3)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.CurrentUser.Link))
|
|
||||||
w.Write(menu_4)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
|
|
||||||
w.Write(menu_5)
|
|
||||||
} else {
|
|
||||||
w.Write(menu_6)
|
|
||||||
}
|
|
||||||
w.Write(menu_7)
|
|
||||||
w.Write(header_14)
|
|
||||||
if tmpl_topic_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(header_15)
|
|
||||||
}
|
|
||||||
w.Write(header_16)
|
|
||||||
if len(tmpl_topic_vars.Header.NoticeList) != 0 {
|
|
||||||
for _, item := range tmpl_topic_vars.Header.NoticeList {
|
|
||||||
w.Write(header_17)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_18)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topic_0)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_1)
|
|
||||||
if tmpl_topic_vars.Page > 1 {
|
|
||||||
w.Write(topic_2)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_3)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Page - 1)))
|
|
||||||
w.Write(topic_4)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_5)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Page - 1)))
|
|
||||||
w.Write(topic_6)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.LastPage != tmpl_topic_vars.Page {
|
|
||||||
w.Write(topic_7)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_8)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Page + 1)))
|
|
||||||
w.Write(topic_9)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_10)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Page + 1)))
|
|
||||||
w.Write(topic_11)
|
|
||||||
}
|
|
||||||
w.Write(topic_12)
|
|
||||||
if tmpl_topic_vars.Topic.Sticky {
|
|
||||||
w.Write(topic_13)
|
|
||||||
} else {
|
|
||||||
if tmpl_topic_vars.Topic.IsClosed {
|
|
||||||
w.Write(topic_14)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topic_15)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.Title))
|
|
||||||
w.Write(topic_16)
|
|
||||||
if tmpl_topic_vars.Topic.IsClosed {
|
|
||||||
w.Write(topic_17)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.EditTopic {
|
|
||||||
w.Write(topic_18)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.Title))
|
|
||||||
w.Write(topic_19)
|
|
||||||
}
|
|
||||||
w.Write(topic_20)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.ClassName))
|
|
||||||
w.Write(topic_21)
|
|
||||||
if tmpl_topic_vars.Topic.Avatar != "" {
|
|
||||||
w.Write(topic_22)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.Avatar))
|
|
||||||
w.Write(topic_23)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Header.ThemeName))
|
|
||||||
w.Write(topic_24)
|
|
||||||
if tmpl_topic_vars.Topic.ContentLines <= 5 {
|
|
||||||
w.Write(topic_25)
|
|
||||||
}
|
|
||||||
w.Write(topic_26)
|
|
||||||
}
|
|
||||||
w.Write(topic_27)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.ContentHTML))
|
|
||||||
w.Write(topic_28)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.Content))
|
|
||||||
w.Write(topic_29)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.UserLink))
|
|
||||||
w.Write(topic_30)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.CreatedByName))
|
|
||||||
w.Write(topic_31)
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.LikeItem {
|
|
||||||
w.Write(topic_32)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_33)
|
|
||||||
if tmpl_topic_vars.Topic.Liked {
|
|
||||||
w.Write(topic_34)
|
|
||||||
}
|
|
||||||
w.Write(topic_35)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.EditTopic {
|
|
||||||
w.Write(topic_36)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_37)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.DeleteTopic {
|
|
||||||
w.Write(topic_38)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_39)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.CloseTopic {
|
|
||||||
if tmpl_topic_vars.Topic.IsClosed {
|
|
||||||
w.Write(topic_40)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_41)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_42)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_43)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.PinTopic {
|
|
||||||
if tmpl_topic_vars.Topic.Sticky {
|
|
||||||
w.Write(topic_44)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_45)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_46)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_47)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.ViewIPs {
|
|
||||||
w.Write(topic_48)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.IPAddress))
|
|
||||||
w.Write(topic_49)
|
|
||||||
}
|
|
||||||
w.Write(topic_50)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_51)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
|
|
||||||
w.Write(topic_52)
|
|
||||||
if tmpl_topic_vars.Topic.LikeCount > 0 {
|
|
||||||
w.Write(topic_53)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.LikeCount)))
|
|
||||||
w.Write(topic_54)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.Topic.Tag != "" {
|
|
||||||
w.Write(topic_55)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Topic.Tag))
|
|
||||||
w.Write(topic_56)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_57)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.Level)))
|
|
||||||
w.Write(topic_58)
|
|
||||||
}
|
|
||||||
w.Write(topic_59)
|
|
||||||
if len(tmpl_topic_vars.ItemList) != 0 {
|
|
||||||
for _, item := range tmpl_topic_vars.ItemList {
|
|
||||||
if item.ActionType != "" {
|
|
||||||
w.Write(topic_60)
|
|
||||||
w.Write([]byte(item.ActionIcon))
|
|
||||||
w.Write(topic_61)
|
|
||||||
w.Write([]byte(item.ActionType))
|
|
||||||
w.Write(topic_62)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_63)
|
|
||||||
w.Write([]byte(item.ClassName))
|
|
||||||
w.Write(topic_64)
|
|
||||||
if item.Avatar != "" {
|
|
||||||
w.Write(topic_65)
|
|
||||||
w.Write([]byte(item.Avatar))
|
|
||||||
w.Write(topic_66)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.Header.ThemeName))
|
|
||||||
w.Write(topic_67)
|
|
||||||
if item.ContentLines <= 5 {
|
|
||||||
w.Write(topic_68)
|
|
||||||
}
|
|
||||||
w.Write(topic_69)
|
|
||||||
}
|
|
||||||
w.Write(topic_70)
|
|
||||||
w.Write(topic_71)
|
|
||||||
w.Write([]byte(item.ContentHtml))
|
|
||||||
w.Write(topic_72)
|
|
||||||
w.Write([]byte(item.UserLink))
|
|
||||||
w.Write(topic_73)
|
|
||||||
w.Write([]byte(item.CreatedByName))
|
|
||||||
w.Write(topic_74)
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.LikeItem {
|
|
||||||
w.Write(topic_75)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_76)
|
|
||||||
if item.Liked {
|
|
||||||
w.Write(topic_77)
|
|
||||||
}
|
|
||||||
w.Write(topic_78)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
|
|
||||||
w.Write(topic_79)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_80)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.DeleteReply {
|
|
||||||
w.Write(topic_81)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_82)
|
|
||||||
}
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.ViewIPs {
|
|
||||||
w.Write(topic_83)
|
|
||||||
w.Write([]byte(item.IPAddress))
|
|
||||||
w.Write(topic_84)
|
|
||||||
}
|
|
||||||
w.Write(topic_85)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_86)
|
|
||||||
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
|
|
||||||
w.Write(topic_87)
|
|
||||||
if item.LikeCount > 0 {
|
|
||||||
w.Write(topic_88)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.LikeCount)))
|
|
||||||
w.Write(topic_89)
|
|
||||||
}
|
|
||||||
if item.Tag != "" {
|
|
||||||
w.Write(topic_90)
|
|
||||||
w.Write([]byte(item.Tag))
|
|
||||||
w.Write(topic_91)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_92)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.Level)))
|
|
||||||
w.Write(topic_93)
|
|
||||||
}
|
|
||||||
w.Write(topic_94)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topic_95)
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
|
|
||||||
w.Write(topic_96)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
|
||||||
w.Write(topic_97)
|
|
||||||
if tmpl_topic_vars.CurrentUser.Perms.UploadFiles {
|
|
||||||
w.Write(topic_98)
|
|
||||||
}
|
|
||||||
w.Write(topic_99)
|
|
||||||
}
|
|
||||||
w.Write(topic_100)
|
|
||||||
w.Write(footer_0)
|
|
||||||
if len(tmpl_topic_vars.Header.Themes) != 0 {
|
|
||||||
for _, item := range tmpl_topic_vars.Header.Themes {
|
|
||||||
if !item.HideFromThemes {
|
|
||||||
w.Write(footer_1)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(footer_2)
|
|
||||||
if tmpl_topic_vars.Header.ThemeName == item.Name {
|
|
||||||
w.Write(footer_3)
|
|
||||||
}
|
|
||||||
w.Write(footer_4)
|
|
||||||
w.Write([]byte(item.FriendlyName))
|
|
||||||
w.Write(footer_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(footer_6)
|
|
||||||
if tmpl_topic_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(footer_7)
|
|
||||||
w.Write([]byte(string(tmpl_topic_vars.Header.Widgets.RightSidebar)))
|
|
||||||
w.Write(footer_8)
|
|
||||||
}
|
|
||||||
w.Write(footer_9)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,329 +0,0 @@
|
||||||
// +build !no_templategen
|
|
||||||
|
|
||||||
// Code generated by Gosora. More below:
|
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
|
||||||
package main
|
|
||||||
import "strconv"
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
template_topic_alt_handle = template_topic_alt
|
|
||||||
//o_template_topic_alt_handle = template_topic_alt
|
|
||||||
ctemplates = append(ctemplates,"topic_alt")
|
|
||||||
tmplPtrMap["topic_alt"] = &template_topic_alt_handle
|
|
||||||
tmplPtrMap["o_topic_alt"] = template_topic_alt
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func template_topic_alt(tmpl_topic_alt_vars TopicPage, w http.ResponseWriter) error {
|
|
||||||
w.Write(header_0)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Title))
|
|
||||||
w.Write(header_1)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Header.Site.Name))
|
|
||||||
w.Write(header_2)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Header.ThemeName))
|
|
||||||
w.Write(header_3)
|
|
||||||
if len(tmpl_topic_alt_vars.Header.Stylesheets) != 0 {
|
|
||||||
for _, item := range tmpl_topic_alt_vars.Header.Stylesheets {
|
|
||||||
w.Write(header_4)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_6)
|
|
||||||
if len(tmpl_topic_alt_vars.Header.Scripts) != 0 {
|
|
||||||
for _, item := range tmpl_topic_alt_vars.Header.Scripts {
|
|
||||||
w.Write(header_7)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_9)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
|
|
||||||
w.Write(header_10)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Header.Site.URL))
|
|
||||||
w.Write(header_11)
|
|
||||||
if !tmpl_topic_alt_vars.CurrentUser.IsSuperMod {
|
|
||||||
w.Write(header_12)
|
|
||||||
}
|
|
||||||
w.Write(header_13)
|
|
||||||
w.Write(menu_0)
|
|
||||||
w.Write(menu_1)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Header.Site.ShortName))
|
|
||||||
w.Write(menu_2)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Loggedin {
|
|
||||||
w.Write(menu_3)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Link))
|
|
||||||
w.Write(menu_4)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
|
|
||||||
w.Write(menu_5)
|
|
||||||
} else {
|
|
||||||
w.Write(menu_6)
|
|
||||||
}
|
|
||||||
w.Write(menu_7)
|
|
||||||
w.Write(header_14)
|
|
||||||
if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(header_15)
|
|
||||||
}
|
|
||||||
w.Write(header_16)
|
|
||||||
if len(tmpl_topic_alt_vars.Header.NoticeList) != 0 {
|
|
||||||
for _, item := range tmpl_topic_alt_vars.Header.NoticeList {
|
|
||||||
w.Write(header_17)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_18)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.Page > 1 {
|
|
||||||
w.Write(topic_alt_0)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_1)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Page - 1)))
|
|
||||||
w.Write(topic_alt_2)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_3)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Page - 1)))
|
|
||||||
w.Write(topic_alt_4)
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.LastPage != tmpl_topic_alt_vars.Page {
|
|
||||||
w.Write(topic_alt_5)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_6)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Page + 1)))
|
|
||||||
w.Write(topic_alt_7)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_8)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Page + 1)))
|
|
||||||
w.Write(topic_alt_9)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_10)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_11)
|
|
||||||
if tmpl_topic_alt_vars.Topic.Sticky {
|
|
||||||
w.Write(topic_alt_12)
|
|
||||||
} else {
|
|
||||||
if tmpl_topic_alt_vars.Topic.IsClosed {
|
|
||||||
w.Write(topic_alt_13)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_14)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
|
|
||||||
w.Write(topic_alt_15)
|
|
||||||
if tmpl_topic_alt_vars.Topic.IsClosed {
|
|
||||||
w.Write(topic_alt_16)
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.EditTopic {
|
|
||||||
w.Write(topic_alt_17)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
|
|
||||||
w.Write(topic_alt_18)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_19)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.Avatar))
|
|
||||||
w.Write(topic_alt_20)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.UserLink))
|
|
||||||
w.Write(topic_alt_21)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedByName))
|
|
||||||
w.Write(topic_alt_22)
|
|
||||||
if tmpl_topic_alt_vars.Topic.Tag != "" {
|
|
||||||
w.Write(topic_alt_23)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.Tag))
|
|
||||||
w.Write(topic_alt_24)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_alt_25)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.Level)))
|
|
||||||
w.Write(topic_alt_26)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_27)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.ContentHTML))
|
|
||||||
w.Write(topic_alt_28)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.Content))
|
|
||||||
w.Write(topic_alt_29)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Loggedin {
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.LikeItem {
|
|
||||||
w.Write(topic_alt_30)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_31)
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.EditTopic {
|
|
||||||
w.Write(topic_alt_32)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_33)
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteTopic {
|
|
||||||
w.Write(topic_alt_34)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_35)
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.CloseTopic {
|
|
||||||
if tmpl_topic_alt_vars.Topic.IsClosed {
|
|
||||||
w.Write(topic_alt_36)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_37)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_alt_38)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_39)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.PinTopic {
|
|
||||||
if tmpl_topic_alt_vars.Topic.Sticky {
|
|
||||||
w.Write(topic_alt_40)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_41)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_alt_42)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_43)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_44)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_45)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
|
|
||||||
w.Write(topic_alt_46)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_47)
|
|
||||||
if tmpl_topic_alt_vars.Topic.LikeCount > 0 {
|
|
||||||
w.Write(topic_alt_48)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.LikeCount)))
|
|
||||||
w.Write(topic_alt_49)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_50)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.RelativeCreatedAt))
|
|
||||||
w.Write(topic_alt_51)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
|
|
||||||
w.Write(topic_alt_52)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.Topic.IPAddress))
|
|
||||||
w.Write(topic_alt_53)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_54)
|
|
||||||
if len(tmpl_topic_alt_vars.ItemList) != 0 {
|
|
||||||
for _, item := range tmpl_topic_alt_vars.ItemList {
|
|
||||||
w.Write(topic_alt_55)
|
|
||||||
if item.ActionType != "" {
|
|
||||||
w.Write(topic_alt_56)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_57)
|
|
||||||
w.Write([]byte(item.Avatar))
|
|
||||||
w.Write(topic_alt_58)
|
|
||||||
w.Write([]byte(item.UserLink))
|
|
||||||
w.Write(topic_alt_59)
|
|
||||||
w.Write([]byte(item.CreatedByName))
|
|
||||||
w.Write(topic_alt_60)
|
|
||||||
if item.Tag != "" {
|
|
||||||
w.Write(topic_alt_61)
|
|
||||||
w.Write([]byte(item.Tag))
|
|
||||||
w.Write(topic_alt_62)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_alt_63)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.Level)))
|
|
||||||
w.Write(topic_alt_64)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_65)
|
|
||||||
if item.ActionType != "" {
|
|
||||||
w.Write(topic_alt_66)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_67)
|
|
||||||
if item.ActionType != "" {
|
|
||||||
w.Write(topic_alt_68)
|
|
||||||
w.Write([]byte(item.ActionIcon))
|
|
||||||
w.Write(topic_alt_69)
|
|
||||||
w.Write([]byte(item.ActionType))
|
|
||||||
w.Write(topic_alt_70)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_alt_71)
|
|
||||||
w.Write([]byte(item.ContentHtml))
|
|
||||||
w.Write(topic_alt_72)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Loggedin {
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.LikeItem {
|
|
||||||
w.Write(topic_alt_73)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_alt_74)
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
|
|
||||||
w.Write(topic_alt_75)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_alt_76)
|
|
||||||
}
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
|
|
||||||
w.Write(topic_alt_77)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_alt_78)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_79)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topic_alt_80)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
|
|
||||||
w.Write(topic_alt_81)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_82)
|
|
||||||
if item.LikeCount > 0 {
|
|
||||||
w.Write(topic_alt_83)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.LikeCount)))
|
|
||||||
w.Write(topic_alt_84)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_85)
|
|
||||||
w.Write([]byte(item.RelativeCreatedAt))
|
|
||||||
w.Write(topic_alt_86)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
|
|
||||||
w.Write(topic_alt_87)
|
|
||||||
w.Write([]byte(item.IPAddress))
|
|
||||||
w.Write(topic_alt_88)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_89)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_90)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_91)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply {
|
|
||||||
w.Write(topic_alt_92)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Avatar))
|
|
||||||
w.Write(topic_alt_93)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Link))
|
|
||||||
w.Write(topic_alt_94)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Name))
|
|
||||||
w.Write(topic_alt_95)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Tag != "" {
|
|
||||||
w.Write(topic_alt_96)
|
|
||||||
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Tag))
|
|
||||||
w.Write(topic_alt_97)
|
|
||||||
} else {
|
|
||||||
w.Write(topic_alt_98)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.Level)))
|
|
||||||
w.Write(topic_alt_99)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_100)
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
|
||||||
w.Write(topic_alt_101)
|
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.UploadFiles {
|
|
||||||
w.Write(topic_alt_102)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_103)
|
|
||||||
}
|
|
||||||
w.Write(topic_alt_104)
|
|
||||||
w.Write(footer_0)
|
|
||||||
if len(tmpl_topic_alt_vars.Header.Themes) != 0 {
|
|
||||||
for _, item := range tmpl_topic_alt_vars.Header.Themes {
|
|
||||||
if !item.HideFromThemes {
|
|
||||||
w.Write(footer_1)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(footer_2)
|
|
||||||
if tmpl_topic_alt_vars.Header.ThemeName == item.Name {
|
|
||||||
w.Write(footer_3)
|
|
||||||
}
|
|
||||||
w.Write(footer_4)
|
|
||||||
w.Write([]byte(item.FriendlyName))
|
|
||||||
w.Write(footer_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(footer_6)
|
|
||||||
if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(footer_7)
|
|
||||||
w.Write([]byte(string(tmpl_topic_alt_vars.Header.Widgets.RightSidebar)))
|
|
||||||
w.Write(footer_8)
|
|
||||||
}
|
|
||||||
w.Write(footer_9)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,226 +0,0 @@
|
||||||
// +build !no_templategen
|
|
||||||
|
|
||||||
// Code generated by Gosora. More below:
|
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
|
||||||
package main
|
|
||||||
import "net/http"
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
template_topics_handle = template_topics
|
|
||||||
//o_template_topics_handle = template_topics
|
|
||||||
ctemplates = append(ctemplates,"topics")
|
|
||||||
tmplPtrMap["topics"] = &template_topics_handle
|
|
||||||
tmplPtrMap["o_topics"] = template_topics
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func template_topics(tmpl_topics_vars TopicsPage, w http.ResponseWriter) error {
|
|
||||||
w.Write(header_0)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.Title))
|
|
||||||
w.Write(header_1)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.Header.Site.Name))
|
|
||||||
w.Write(header_2)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.Header.ThemeName))
|
|
||||||
w.Write(header_3)
|
|
||||||
if len(tmpl_topics_vars.Header.Stylesheets) != 0 {
|
|
||||||
for _, item := range tmpl_topics_vars.Header.Stylesheets {
|
|
||||||
w.Write(header_4)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_6)
|
|
||||||
if len(tmpl_topics_vars.Header.Scripts) != 0 {
|
|
||||||
for _, item := range tmpl_topics_vars.Header.Scripts {
|
|
||||||
w.Write(header_7)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(header_9)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
|
|
||||||
w.Write(header_10)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.Header.Site.URL))
|
|
||||||
w.Write(header_11)
|
|
||||||
if !tmpl_topics_vars.CurrentUser.IsSuperMod {
|
|
||||||
w.Write(header_12)
|
|
||||||
}
|
|
||||||
w.Write(header_13)
|
|
||||||
w.Write(menu_0)
|
|
||||||
w.Write(menu_1)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.Header.Site.ShortName))
|
|
||||||
w.Write(menu_2)
|
|
||||||
if tmpl_topics_vars.CurrentUser.Loggedin {
|
|
||||||
w.Write(menu_3)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.CurrentUser.Link))
|
|
||||||
w.Write(menu_4)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
|
|
||||||
w.Write(menu_5)
|
|
||||||
} else {
|
|
||||||
w.Write(menu_6)
|
|
||||||
}
|
|
||||||
w.Write(menu_7)
|
|
||||||
w.Write(header_14)
|
|
||||||
if tmpl_topics_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(header_15)
|
|
||||||
}
|
|
||||||
w.Write(header_16)
|
|
||||||
if len(tmpl_topics_vars.Header.NoticeList) != 0 {
|
|
||||||
for _, item := range tmpl_topics_vars.Header.NoticeList {
|
|
||||||
w.Write(header_17)
|
|
||||||
w.Write([]byte(item))
|
|
||||||
w.Write(header_18)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topics_0)
|
|
||||||
if tmpl_topics_vars.CurrentUser.ID != 0 {
|
|
||||||
w.Write(topics_1)
|
|
||||||
}
|
|
||||||
w.Write(topics_2)
|
|
||||||
if tmpl_topics_vars.CurrentUser.ID != 0 {
|
|
||||||
if len(tmpl_topics_vars.ForumList) != 0 {
|
|
||||||
w.Write(topics_3)
|
|
||||||
w.Write(topics_4)
|
|
||||||
} else {
|
|
||||||
w.Write(topics_5)
|
|
||||||
}
|
|
||||||
w.Write(topics_6)
|
|
||||||
}
|
|
||||||
w.Write(topics_7)
|
|
||||||
if tmpl_topics_vars.CurrentUser.ID != 0 {
|
|
||||||
w.Write(topics_8)
|
|
||||||
if len(tmpl_topics_vars.ForumList) != 0 {
|
|
||||||
w.Write(topics_9)
|
|
||||||
if tmpl_topics_vars.CurrentUser.Avatar != "" {
|
|
||||||
w.Write(topics_10)
|
|
||||||
w.Write([]byte(tmpl_topics_vars.CurrentUser.Avatar))
|
|
||||||
w.Write(topics_11)
|
|
||||||
}
|
|
||||||
w.Write(topics_12)
|
|
||||||
if len(tmpl_topics_vars.ForumList) != 0 {
|
|
||||||
for _, item := range tmpl_topics_vars.ForumList {
|
|
||||||
w.Write(topics_13)
|
|
||||||
if item.ID == tmpl_topics_vars.DefaultForum {
|
|
||||||
w.Write(topics_14)
|
|
||||||
}
|
|
||||||
w.Write(topics_15)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topics_16)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(topics_17)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topics_18)
|
|
||||||
if tmpl_topics_vars.CurrentUser.Perms.UploadFiles {
|
|
||||||
w.Write(topics_19)
|
|
||||||
}
|
|
||||||
w.Write(topics_20)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topics_21)
|
|
||||||
if len(tmpl_topics_vars.TopicList) != 0 {
|
|
||||||
for _, item := range tmpl_topics_vars.TopicList {
|
|
||||||
w.Write(topics_22)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topics_23)
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(topics_24)
|
|
||||||
} else {
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(topics_25)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topics_26)
|
|
||||||
if item.Creator.Avatar != "" {
|
|
||||||
w.Write(topics_27)
|
|
||||||
w.Write([]byte(item.Creator.Link))
|
|
||||||
w.Write(topics_28)
|
|
||||||
w.Write([]byte(item.Creator.Avatar))
|
|
||||||
w.Write(topics_29)
|
|
||||||
}
|
|
||||||
w.Write(topics_30)
|
|
||||||
w.Write([]byte(item.Link))
|
|
||||||
w.Write(topics_31)
|
|
||||||
w.Write([]byte(item.Title))
|
|
||||||
w.Write(topics_32)
|
|
||||||
if item.ForumName != "" {
|
|
||||||
w.Write(topics_33)
|
|
||||||
w.Write([]byte(item.ForumLink))
|
|
||||||
w.Write(topics_34)
|
|
||||||
w.Write([]byte(item.ForumName))
|
|
||||||
w.Write(topics_35)
|
|
||||||
}
|
|
||||||
w.Write(topics_36)
|
|
||||||
w.Write([]byte(item.Creator.Link))
|
|
||||||
w.Write(topics_37)
|
|
||||||
w.Write([]byte(item.Creator.Name))
|
|
||||||
w.Write(topics_38)
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(topics_39)
|
|
||||||
}
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(topics_40)
|
|
||||||
}
|
|
||||||
w.Write(topics_41)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.PostCount)))
|
|
||||||
w.Write(topics_42)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.LikeCount)))
|
|
||||||
w.Write(topics_43)
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(topics_44)
|
|
||||||
} else {
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(topics_45)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(topics_46)
|
|
||||||
if item.LastUser.Avatar != "" {
|
|
||||||
w.Write(topics_47)
|
|
||||||
w.Write([]byte(item.LastUser.Link))
|
|
||||||
w.Write(topics_48)
|
|
||||||
w.Write([]byte(item.LastUser.Avatar))
|
|
||||||
w.Write(topics_49)
|
|
||||||
}
|
|
||||||
w.Write(topics_50)
|
|
||||||
w.Write([]byte(item.LastUser.Link))
|
|
||||||
w.Write(topics_51)
|
|
||||||
w.Write([]byte(item.LastUser.Name))
|
|
||||||
w.Write(topics_52)
|
|
||||||
w.Write([]byte(item.RelativeLastReplyAt))
|
|
||||||
w.Write(topics_53)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w.Write(topics_54)
|
|
||||||
if tmpl_topics_vars.CurrentUser.Perms.CreateTopic {
|
|
||||||
w.Write(topics_55)
|
|
||||||
}
|
|
||||||
w.Write(topics_56)
|
|
||||||
}
|
|
||||||
w.Write(topics_57)
|
|
||||||
w.Write(footer_0)
|
|
||||||
if len(tmpl_topics_vars.Header.Themes) != 0 {
|
|
||||||
for _, item := range tmpl_topics_vars.Header.Themes {
|
|
||||||
if !item.HideFromThemes {
|
|
||||||
w.Write(footer_1)
|
|
||||||
w.Write([]byte(item.Name))
|
|
||||||
w.Write(footer_2)
|
|
||||||
if tmpl_topics_vars.Header.ThemeName == item.Name {
|
|
||||||
w.Write(footer_3)
|
|
||||||
}
|
|
||||||
w.Write(footer_4)
|
|
||||||
w.Write([]byte(item.FriendlyName))
|
|
||||||
w.Write(footer_5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.Write(footer_6)
|
|
||||||
if tmpl_topics_vars.Header.Widgets.RightSidebar != "" {
|
|
||||||
w.Write(footer_7)
|
|
||||||
w.Write([]byte(string(tmpl_topics_vars.Header.Widgets.RightSidebar)))
|
|
||||||
w.Write(footer_8)
|
|
||||||
}
|
|
||||||
w.Write(footer_9)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"./common"
|
||||||
"github.com/Azareal/gopsutil/cpu"
|
"github.com/Azareal/gopsutil/cpu"
|
||||||
"github.com/Azareal/gopsutil/mem"
|
"github.com/Azareal/gopsutil/mem"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
@ -25,7 +26,7 @@ import (
|
||||||
|
|
||||||
type WSUser struct {
|
type WSUser struct {
|
||||||
conn *websocket.Conn
|
conn *websocket.Conn
|
||||||
User *User
|
User *common.User
|
||||||
}
|
}
|
||||||
|
|
||||||
type WSHub struct {
|
type WSHub struct {
|
||||||
|
@ -164,13 +165,13 @@ func (hub *WSHub) pushAlerts(users []int, asid int, event string, elementType st
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: How should we handle errors for this?
|
// TODO: How should we handle errors for this?
|
||||||
func routeWebsockets(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func routeWebsockets(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
userptr, err := users.Get(user.ID)
|
userptr, err := common.Users.Get(user.ID)
|
||||||
if err != nil && err != ErrStoreCapacityOverflow {
|
if err != nil && err != common.ErrStoreCapacityOverflow {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,9 +342,9 @@ AdminStatLoop:
|
||||||
onlineUsersColour = "stat_red"
|
onlineUsersColour = "stat_red"
|
||||||
}
|
}
|
||||||
|
|
||||||
totonline, totunit = convertFriendlyUnit(totonline)
|
totonline, totunit = common.ConvertFriendlyUnit(totonline)
|
||||||
uonline, uunit = convertFriendlyUnit(uonline)
|
uonline, uunit = common.ConvertFriendlyUnit(uonline)
|
||||||
gonline, gunit = convertFriendlyUnit(gonline)
|
gonline, gunit = common.ConvertFriendlyUnit(gonline)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cpuerr != nil {
|
if cpuerr != nil {
|
||||||
|
@ -364,8 +365,8 @@ AdminStatLoop:
|
||||||
if ramerr != nil {
|
if ramerr != nil {
|
||||||
ramstr = "Unknown"
|
ramstr = "Unknown"
|
||||||
} else {
|
} else {
|
||||||
totalCount, totalUnit := convertByteUnit(float64(memres.Total))
|
totalCount, totalUnit := common.ConvertByteUnit(float64(memres.Total))
|
||||||
usedCount := convertByteInUnit(float64(memres.Total-memres.Available), totalUnit)
|
usedCount := common.ConvertByteInUnit(float64(memres.Total-memres.Available), totalUnit)
|
||||||
|
|
||||||
// Round totals with .9s up, it's how most people see it anyway. Floats are notoriously imprecise, so do it off 0.85
|
// Round totals with .9s up, it's how most people see it anyway. Floats are notoriously imprecise, so do it off 0.85
|
||||||
var totstr string
|
var totstr string
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "sync/atomic"
|
|
||||||
|
|
||||||
type WordFilter struct {
|
|
||||||
ID int
|
|
||||||
Find string
|
|
||||||
Replacement string
|
|
||||||
}
|
|
||||||
type WordFilterBox map[int]WordFilter
|
|
||||||
|
|
||||||
var wordFilterBox atomic.Value // An atomic value holding a WordFilterBox
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
wordFilterBox.Store(WordFilterBox(make(map[int]WordFilter)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadWordFilters() error {
|
|
||||||
rows, err := stmts.getWordFilters.Query()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
var wordFilters = WordFilterBox(make(map[int]WordFilter))
|
|
||||||
var wfid int
|
|
||||||
var find string
|
|
||||||
var replacement string
|
|
||||||
|
|
||||||
for rows.Next() {
|
|
||||||
err := rows.Scan(&wfid, &find, &replacement)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
wordFilters[wfid] = WordFilter{ID: wfid, Find: find, Replacement: replacement}
|
|
||||||
}
|
|
||||||
wordFilterBox.Store(wordFilters)
|
|
||||||
return rows.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
func addWordFilter(id int, find string, replacement string) {
|
|
||||||
wordFilters := wordFilterBox.Load().(WordFilterBox)
|
|
||||||
wordFilters[id] = WordFilter{ID: id, Find: find, Replacement: replacement}
|
|
||||||
wordFilterBox.Store(wordFilters)
|
|
||||||
}
|
|
Loading…
Reference in New Issue