wp-go/actions/detail.go

269 lines
7.0 KiB
Go
Raw Normal View History

2022-09-18 04:34:48 +00:00
package actions
2022-09-18 14:06:27 +00:00
import (
"fmt"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/actions/common"
2022-09-22 09:21:41 +00:00
"github/fthvgb1/wp-go/helper"
2022-09-27 07:35:34 +00:00
"github/fthvgb1/wp-go/logs"
2022-09-18 14:06:27 +00:00
"github/fthvgb1/wp-go/models"
2022-09-23 13:46:34 +00:00
"github/fthvgb1/wp-go/plugins"
2022-09-22 09:21:41 +00:00
"math/rand"
2022-09-18 14:06:27 +00:00
"net/http"
2022-09-22 09:21:41 +00:00
"net/url"
2022-09-21 13:49:14 +00:00
"sort"
2022-09-18 14:06:27 +00:00
"strconv"
2022-09-21 13:49:14 +00:00
"strings"
2022-09-22 09:21:41 +00:00
"time"
2022-09-18 14:06:27 +00:00
)
2022-09-18 04:34:48 +00:00
2022-09-22 09:21:41 +00:00
type detailHandler struct {
*gin.Context
}
2022-09-18 04:34:48 +00:00
func Detail(c *gin.Context) {
2022-09-18 14:06:27 +00:00
var err error
2022-09-22 09:21:41 +00:00
hh := detailHandler{
c,
}
2022-10-06 13:33:04 +00:00
recent := common.RecentPosts(c, 5)
2022-09-19 11:11:36 +00:00
archive := common.Archives()
2022-09-26 08:35:38 +00:00
categoryItems := common.Categories(c)
2022-10-06 13:33:04 +00:00
recentComments := common.RecentComments(c, 5)
2022-09-19 11:11:36 +00:00
var h = gin.H{
2022-09-21 13:49:14 +00:00
"title": models.Options["blogname"],
"options": models.Options,
"recentPosts": recent,
"archives": archive,
"categories": categoryItems,
"recentComments": recentComments,
2022-09-19 11:11:36 +00:00
}
2022-09-18 14:06:27 +00:00
defer func() {
2022-09-22 09:21:41 +00:00
status := http.StatusOK
2022-09-18 14:06:27 +00:00
if err != nil {
2022-09-22 09:21:41 +00:00
status = http.StatusInternalServerError
2022-09-18 14:06:27 +00:00
c.Error(err)
}
2022-09-22 09:21:41 +00:00
c.HTML(status, "posts/detail.gohtml", h)
2022-09-18 14:06:27 +00:00
}()
2022-09-19 11:11:36 +00:00
id := c.Param("id")
2022-09-18 14:06:27 +00:00
Id := 0
if id != "" {
Id, err = strconv.Atoi(id)
if err != nil {
return
}
}
ID := uint64(Id)
2022-10-04 03:13:14 +00:00
maxId, err := common.GetMaxPostId(c)
logs.ErrPrintln(err, "get max post id")
if ID > maxId || err != nil {
return
}
2022-10-08 08:37:27 +00:00
post, err := common.GetPostById(c, ID)
if post.Id == 0 || err != nil {
return
2022-09-18 14:06:27 +00:00
}
pw := sessions.Default(c).Get("post_password")
2022-09-19 13:31:46 +00:00
showComment := false
if post.CommentCount > 0 || post.CommentStatus == "open" {
showComment = true
}
2022-09-18 14:06:27 +00:00
common.PasswordProjectTitle(&post)
if post.PostPassword != "" && pw != post.PostPassword {
common.PasswdProjectContent(&post)
showComment = false
}
2022-09-23 13:46:34 +00:00
plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post)
2022-09-26 08:35:38 +00:00
comments, err := common.PostComments(c, post.Id)
2022-09-27 07:35:34 +00:00
logs.ErrPrintln(err, "get post comment", post.Id)
2022-09-21 13:49:14 +00:00
commentss := treeComments(comments)
2022-09-27 07:35:34 +00:00
prev, next, err := common.GetContextPost(c, post.Id, post.PostDate)
logs.ErrPrintln(err, "get pre and next post", post.Id, post.PostDate)
2022-09-19 11:11:36 +00:00
h["title"] = fmt.Sprintf("%s-%s", post.PostTitle, models.Options["blogname"])
h["post"] = post
2022-09-19 13:31:46 +00:00
h["showComment"] = showComment
2022-09-19 11:11:36 +00:00
h["prev"] = prev
2022-10-19 14:41:44 +00:00
depth := models.Options["thread_comments_depth"]
d, err := strconv.Atoi(depth)
if err != nil {
logs.ErrPrintln(err, "get comment depth")
d = 5
}
h["comments"] = hh.formatComment(commentss, 1, d)
2022-09-19 11:11:36 +00:00
h["next"] = next
2022-09-18 04:34:48 +00:00
}
2022-09-21 13:49:14 +00:00
type Comment struct {
models.WpComments
Children []*Comment
}
type Comments []*Comment
func (c Comments) Len() int {
return len(c)
}
func (c Comments) Less(i, j int) bool {
return c[i].CommentId < c[j].CommentId
}
func (c Comments) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}
2022-09-22 09:21:41 +00:00
func (d detailHandler) formatComment(comments Comments, depth, maxDepth int) (html string) {
2022-09-21 13:49:14 +00:00
s := strings.Builder{}
2022-09-21 14:15:20 +00:00
if depth > maxDepth {
2022-09-21 13:49:14 +00:00
comments = findComments(comments)
}
sort.Sort(comments)
for i, comment := range comments {
eo := "even"
if (i+1)%2 == 0 {
eo = "odd"
}
p := ""
fl := false
2022-09-21 14:15:20 +00:00
if len(comment.Children) > 0 && depth < maxDepth+1 {
2022-09-21 13:49:14 +00:00
p = "parent"
fl = true
}
2022-09-22 09:21:41 +00:00
s.WriteString(d.formatLi(comment.WpComments, depth, eo, p))
2022-09-21 13:49:14 +00:00
if fl {
depth++
s.WriteString(`<ol class="children">`)
2022-09-22 09:21:41 +00:00
s.WriteString(d.formatComment(comment.Children, depth, maxDepth))
2022-09-21 13:49:14 +00:00
s.WriteString(`</ol>`)
}
s.WriteString("</li><!-- #comment-## -->")
i++
if i >= len(comments) {
break
}
}
html = s.String()
return
}
func findComments(comments Comments) Comments {
var r Comments
for _, comment := range comments {
2022-09-21 14:15:20 +00:00
tmp := *comment
2022-09-21 13:49:14 +00:00
tmp.Children = nil
2022-09-21 14:15:20 +00:00
r = append(r, &tmp)
2022-09-21 13:49:14 +00:00
if len(comment.Children) > 0 {
t := findComments(comment.Children)
r = append(r, t...)
}
}
return r
}
func treeComments(comments []models.WpComments) Comments {
var r = map[uint64]*Comment{
0: {
WpComments: models.WpComments{},
},
}
var top []*Comment
for _, comment := range comments {
c := Comment{
WpComments: comment,
Children: []*Comment{},
}
r[comment.CommentId] = &c
if comment.CommentParent == 0 {
top = append(top, &c)
}
}
for id, son := range r {
if id == son.CommentParent {
continue
}
parent := r[son.CommentParent]
parent.Children = append(parent.Children, son)
}
return top
}
2022-09-22 09:21:41 +00:00
func (d detailHandler) formatLi(comments models.WpComments, depth int, eo, parent string) string {
2022-09-21 13:49:14 +00:00
li := `
<li id="comment-{{CommentId}}" class="comment {{eo}} thread-even depth-{{Depth}} {{parent}}">
<article id="div-comment-{{CommentId}}" class="comment-body">
<footer class="comment-meta">
<div class="comment-author vcard">
<img alt=""
src="{{Gravatar}}"
srcset="{{Gravatar}} 2x"
class="avatar avatar-56 photo" height="56" width="56" loading="lazy">
<b class="fn">
<a href="{{CommentAuthorUrl}}" rel="external nofollow ugc"
class="url">{{CommentAuthor}}</a>
</b>
<span class="says">说道</span></div><!-- .comment-author -->
<div class="comment-metadata">
<a href="/p/{{PostId}}#comment-{{CommentId}}">
<time datetime="{{CommentDateGmt}}">{{CommentDate}}</time>
</a></div><!-- .comment-metadata -->
</footer><!-- .comment-meta -->
<div class="comment-content">
<p>{{CommentContent}}</p>
</div><!-- .comment-content -->
<div class="reply">
<a rel="nofollow" class="comment-reply-link"
href="/p/{{PostId}}?replytocom={{CommentId}}#respond" data-commentid="{{CommentId}}" data-postid="{{PostId}}"
data-belowelement="div-comment-{{CommentId}}" data-respondelement="respond"
data-replyto="回复给{{CommentAuthor}}"
aria-label="回复给{{CommentAuthor}}">回复</a>
</div>
</article><!-- .comment-body -->
`
for k, v := range map[string]string{
"{{CommentId}}": strconv.FormatUint(comments.CommentId, 10),
2022-09-22 09:21:41 +00:00
"{{Depth}}": strconv.Itoa(depth),
"{{Gravatar}}": gravatar(d.Context, comments.CommentAuthorEmail),
2022-09-21 13:49:14 +00:00
"{{CommentAuthorUrl}}": comments.CommentAuthorUrl,
"{{CommentAuthor}}": comments.CommentAuthor,
"{{PostId}}": strconv.FormatUint(comments.CommentPostId, 10),
"{{CommentDateGmt}}": comments.CommentDateGmt.String(),
"{{CommentDate}}": comments.CommentDate.Format("2006-01-02 15:04"),
"{{CommentContent}}": comments.CommentContent,
"{{eo}}": eo,
"{{parent}}": parent,
} {
li = strings.Replace(li, k, v, -1)
}
return li
}
2022-09-22 09:21:41 +00:00
func gravatar(c *gin.Context, email string) (u string) {
email = strings.Trim(email, " \t\n\r\000\x0B")
rand.Seed(time.Now().UnixNano())
num := rand.Intn(3)
h := ""
if email != "" {
h = helper.StringMd5(strings.ToLower(email))
num = int(h[0] % 3)
}
if c.Request.TLS != nil {
u = fmt.Sprintf("%s%s", "https://secure.gravatar.com/avatar/", h)
} else {
u = fmt.Sprintf("http://%d.gravatar.com/avatar/%s", num, h)
}
q := url.Values{}
q.Add("s", "112")
q.Add("d", "mm")
q.Add("r", "g")
u = fmt.Sprintf("%s?%s", u, q.Encode())
return
}