10f4c59cb5
Added the Go and Database versions to the Control Panel Debug Page. Renamed common.TopicsPage to common.TopicListPage. Renamed *HeaderVars to *Header. Added the Paginator struct and refactored the code to use it. io.Writers are now used instead of http.ResponseWriters in transpiled templates for greater flexibility. Added the alert, menu_alerts, and menu_item templates. Added support for more integer types in the arithmetic functions for the transpiled templates. Exported AccSelectBuilder. Added an Each method to AccSelectBuilder. Added column quoting to the order by portions of queries for the MySQL Adapter. Began work on the client side rendering of alerts. Began work on the Menu Manager and associated functionality.
127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
package routes
|
|
|
|
import (
|
|
"database/sql"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"../common"
|
|
"../query_gen/lib"
|
|
)
|
|
|
|
type ProfileStmts struct {
|
|
getReplies *sql.Stmt
|
|
}
|
|
|
|
var profileStmts ProfileStmts
|
|
|
|
// TODO: Move these DbInits into some sort of abstraction
|
|
func init() {
|
|
common.DbInits.Add(func(acc *qgen.Accumulator) error {
|
|
profileStmts = ProfileStmts{
|
|
getReplies: acc.SimpleLeftJoin("users_replies", "users", "users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.group", "users_replies.createdBy = users.uid", "users_replies.uid = ?", "", ""),
|
|
}
|
|
return acc.FirstError()
|
|
})
|
|
}
|
|
|
|
func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
|
header, ferr := common.UserCheck(w, r, &user)
|
|
if ferr != nil {
|
|
return ferr
|
|
}
|
|
|
|
var err error
|
|
var replyCreatedAt time.Time
|
|
var replyContent, replyCreatedByName, replyRelativeCreatedAt, replyAvatar, replyTag, replyClassName string
|
|
var rid, replyCreatedBy, replyLastEdit, replyLastEditBy, replyLines, replyGroup int
|
|
var replyList []common.ReplyUser
|
|
|
|
// SEO URLs...
|
|
// TODO: Do a 301 if it's the wrong username? Do a canonical too?
|
|
halves := strings.Split(r.URL.Path[len("/user/"):], ".")
|
|
if len(halves) < 2 {
|
|
halves = append(halves, halves[0])
|
|
}
|
|
pid, err := strconv.Atoi(halves[1])
|
|
if err != nil {
|
|
return common.LocalError("The provided UserID is not a valid number.", w, r, user)
|
|
}
|
|
|
|
var puser *common.User
|
|
if pid == user.ID {
|
|
user.IsMod = true
|
|
puser = &user
|
|
} else {
|
|
// Fetch the user data
|
|
// TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case?
|
|
puser, err = common.Users.Get(pid)
|
|
if err == sql.ErrNoRows {
|
|
return common.NotFound(w, r, header)
|
|
} else if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
}
|
|
|
|
// Get the replies..
|
|
rows, err := profileStmts.getReplies.Query(puser.ID)
|
|
if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &replyGroup)
|
|
if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
|
|
group, err := common.Groups.Get(replyGroup)
|
|
if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
|
|
replyLines = strings.Count(replyContent, "\n")
|
|
if group.IsMod || group.IsAdmin {
|
|
replyClassName = common.Config.StaffCSS
|
|
} else {
|
|
replyClassName = ""
|
|
}
|
|
replyAvatar = common.BuildAvatar(replyCreatedBy, replyAvatar)
|
|
|
|
if group.Tag != "" {
|
|
replyTag = group.Tag
|
|
} else if puser.ID == replyCreatedBy {
|
|
replyTag = "Profile Owner"
|
|
} else {
|
|
replyTag = ""
|
|
}
|
|
|
|
replyLiked := false
|
|
replyLikeCount := 0
|
|
replyRelativeCreatedAt = common.RelativeTime(replyCreatedAt)
|
|
|
|
// TODO: Add a hook here
|
|
|
|
replyList = append(replyList, common.ReplyUser{rid, puser.ID, replyContent, common.ParseMessage(replyContent, 0, ""), replyCreatedBy, common.BuildProfileURL(common.NameToSlug(replyCreatedByName), replyCreatedBy), replyCreatedByName, replyGroup, replyCreatedAt, replyRelativeCreatedAt, replyLastEdit, replyLastEditBy, replyAvatar, replyClassName, replyLines, replyTag, "", "", "", 0, "", replyLiked, replyLikeCount, "", ""})
|
|
}
|
|
err = rows.Err()
|
|
if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
|
|
// TODO: Add a phrase for this title
|
|
ppage := common.ProfilePage{puser.Name + "'s Profile", user, header, replyList, *puser}
|
|
if common.RunPreRenderHook("pre_render_profile", w, r, &user, &ppage) {
|
|
return nil
|
|
}
|
|
|
|
err = common.RunThemeTemplate(header.Theme.Name, "profile", ppage, w)
|
|
if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
return nil
|
|
}
|