完善post feed及加缓存
This commit is contained in:
parent
05ddebd012
commit
7c4f4f10fc
152
actions/feed.go
152
actions/feed.go
@ -6,24 +6,32 @@ import (
|
|||||||
"github/fthvgb1/wp-go/actions/common"
|
"github/fthvgb1/wp-go/actions/common"
|
||||||
"github/fthvgb1/wp-go/cache"
|
"github/fthvgb1/wp-go/cache"
|
||||||
"github/fthvgb1/wp-go/helper"
|
"github/fthvgb1/wp-go/helper"
|
||||||
|
"github/fthvgb1/wp-go/logs"
|
||||||
"github/fthvgb1/wp-go/models"
|
"github/fthvgb1/wp-go/models"
|
||||||
"github/fthvgb1/wp-go/plugins"
|
"github/fthvgb1/wp-go/plugins"
|
||||||
"github/fthvgb1/wp-go/rss2"
|
"github/fthvgb1/wp-go/rss2"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var feedCache = cache.NewSliceCache[string](feed, time.Hour)
|
var feedCache = cache.NewSliceCache[string](feed, time.Hour)
|
||||||
|
var postFeedCache = cache.NewMapCacheByFn[string, string](postFeed, time.Hour)
|
||||||
var tmp = "Mon, 02 Jan 2006 15:04:05 GMT"
|
var tmp = "Mon, 02 Jan 2006 15:04:05 GMT"
|
||||||
|
var templateRss rss2.Rss2
|
||||||
|
|
||||||
func FeedCached(c *gin.Context) {
|
func InitFeed() {
|
||||||
if !isCacheExpired(c, feedCache.SetTime()) {
|
templateRss = rss2.Rss2{
|
||||||
c.Status(http.StatusNotModified)
|
Title: models.Options["blogname"],
|
||||||
c.Abort()
|
AtomLink: fmt.Sprintf("%s/feed", models.Options["home"]),
|
||||||
return
|
Link: models.Options["siteurl"],
|
||||||
|
Description: models.Options["blogdescription"],
|
||||||
|
Language: "zh-CN",
|
||||||
|
UpdatePeriod: "hourly",
|
||||||
|
UpdateFrequency: 1,
|
||||||
|
Generator: models.Options["home"],
|
||||||
}
|
}
|
||||||
c.Next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isCacheExpired(c *gin.Context, lastTime time.Time) bool {
|
func isCacheExpired(c *gin.Context, lastTime time.Time) bool {
|
||||||
@ -41,19 +49,11 @@ func isCacheExpired(c *gin.Context, lastTime time.Time) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Feed(c *gin.Context) {
|
func Feed(c *gin.Context) {
|
||||||
s, err := feedCache.GetCache(c, time.Second, c)
|
if !isCacheExpired(c, feedCache.SetTime()) {
|
||||||
if err != nil {
|
c.Status(http.StatusNotModified)
|
||||||
c.Status(http.StatusInternalServerError)
|
} else {
|
||||||
c.Abort()
|
setFeed(feedCache, c)
|
||||||
c.Error(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
lastTimeGMT := feedCache.SetTime().Format(tmp)
|
|
||||||
eTag := helper.StringMd5(lastTimeGMT)
|
|
||||||
c.Header("Content-Type", "application/rss+xml; charset=UTF-8")
|
|
||||||
c.Header("Last-Modified", lastTimeGMT)
|
|
||||||
c.Header("ETag", eTag)
|
|
||||||
c.String(http.StatusOK, s[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func feed(arg ...any) (xml []string, err error) {
|
func feed(arg ...any) (xml []string, err error) {
|
||||||
@ -66,19 +66,8 @@ func feed(arg ...any) (xml []string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rs := rss2.Rss2{
|
rs := templateRss
|
||||||
Title: models.Options["blogname"],
|
rs.LastBuildDate = time.Now().Format(time.RFC1123Z)
|
||||||
AtomLink: fmt.Sprintf("%s/feed", models.Options["home"]),
|
|
||||||
Link: models.Options["siteurl"],
|
|
||||||
Description: models.Options["blogdescription"],
|
|
||||||
LastBuildDate: time.Now().Format(time.RFC1123Z),
|
|
||||||
Language: "zh-CN",
|
|
||||||
UpdatePeriod: "hourly",
|
|
||||||
UpdateFrequency: 1,
|
|
||||||
Generator: models.Options["home"],
|
|
||||||
Items: nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
rs.Items = helper.SliceMap(posts, func(t models.WpPosts) rss2.Item {
|
rs.Items = helper.SliceMap(posts, func(t models.WpPosts) rss2.Item {
|
||||||
desc := "无法提供摘要。这是一篇受保护的文章。"
|
desc := "无法提供摘要。这是一篇受保护的文章。"
|
||||||
common.PasswordProjectTitle(&t)
|
common.PasswordProjectTitle(&t)
|
||||||
@ -112,3 +101,104 @@ func feed(arg ...any) (xml []string, err error) {
|
|||||||
xml = []string{rs.GetXML()}
|
xml = []string{rs.GetXML()}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setFeed(sliceCache *cache.SliceCache[string], c *gin.Context) {
|
||||||
|
s, err := sliceCache.GetCache(c, time.Second, c)
|
||||||
|
if err != nil {
|
||||||
|
c.Status(http.StatusInternalServerError)
|
||||||
|
c.Abort()
|
||||||
|
c.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastTimeGMT := sliceCache.SetTime().Format(tmp)
|
||||||
|
eTag := helper.StringMd5(lastTimeGMT)
|
||||||
|
c.Header("Content-Type", "application/rss+xml; charset=UTF-8")
|
||||||
|
c.Header("Last-Modified", lastTimeGMT)
|
||||||
|
c.Header("ETag", eTag)
|
||||||
|
c.String(http.StatusOK, s[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func PostFeed(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
if !isCacheExpired(c, postFeedCache.GetSetTime(id)) {
|
||||||
|
c.Status(http.StatusNotModified)
|
||||||
|
} else {
|
||||||
|
s, err := postFeedCache.GetCache(c, id, time.Second, c, id)
|
||||||
|
if err != nil {
|
||||||
|
c.Status(http.StatusInternalServerError)
|
||||||
|
c.Abort()
|
||||||
|
c.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastTimeGMT := postFeedCache.GetSetTime(id).Format(tmp)
|
||||||
|
eTag := helper.StringMd5(lastTimeGMT)
|
||||||
|
c.Header("Content-Type", "application/rss+xml; charset=UTF-8")
|
||||||
|
c.Header("Last-Modified", lastTimeGMT)
|
||||||
|
c.Header("ETag", eTag)
|
||||||
|
c.String(http.StatusOK, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func postFeed(arg ...any) (x string, err error) {
|
||||||
|
c := arg[0].(*gin.Context)
|
||||||
|
id := arg[1].(string)
|
||||||
|
Id := 0
|
||||||
|
if id != "" {
|
||||||
|
Id, err = strconv.Atoi(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ID := uint64(Id)
|
||||||
|
maxId, err := common.GetMaxPostId(c)
|
||||||
|
logs.ErrPrintln(err, "get max post id")
|
||||||
|
if ID > maxId || err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
post, err := common.GetPostAndCache(c, ID)
|
||||||
|
if post.Id == 0 || err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
common.PasswordProjectTitle(&post)
|
||||||
|
comments, err := common.PostComments(c, post.Id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rs := templateRss
|
||||||
|
|
||||||
|
rs.Title = fmt.Sprintf("《%s》的评论", post.PostTitle)
|
||||||
|
rs.AtomLink = fmt.Sprintf("%s/p/%d/feed", models.Options["siteurl"], post.Id)
|
||||||
|
rs.Link = fmt.Sprintf("%s/p/%d", models.Options["siteurl"], post.Id)
|
||||||
|
rs.LastBuildDate = time.Now().Format(time.RFC1123Z)
|
||||||
|
if post.PostPassword != "" {
|
||||||
|
if len(comments) > 0 {
|
||||||
|
common.PasswdProjectContent(&post)
|
||||||
|
t := comments[len(comments)-1]
|
||||||
|
rs.Items = []rss2.Item{
|
||||||
|
{
|
||||||
|
Title: fmt.Sprintf("评价者:%s", t.CommentAuthor),
|
||||||
|
Link: fmt.Sprintf("%s/p/%d#comment-%d", models.Options["siteurl"], post.Id, t.CommentId),
|
||||||
|
Creator: t.CommentAuthor,
|
||||||
|
PubDate: t.CommentDateGmt.Format(time.RFC1123Z),
|
||||||
|
Guid: fmt.Sprintf("%s#comment-%d", post.Guid, t.CommentId),
|
||||||
|
Description: "评论受保护:要查看请输入密码。",
|
||||||
|
Content: post.PostContent,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rs.Items = helper.SliceMap(comments, func(t models.WpComments) rss2.Item {
|
||||||
|
return rss2.Item{
|
||||||
|
Title: fmt.Sprintf("评价者:%s", t.CommentAuthor),
|
||||||
|
Link: fmt.Sprintf("%s/p/%d#comment-%d", models.Options["siteurl"], post.Id, t.CommentId),
|
||||||
|
Creator: t.CommentAuthor,
|
||||||
|
PubDate: t.CommentDateGmt.Format(time.RFC1123Z),
|
||||||
|
Guid: fmt.Sprintf("%s#comment-%d", post.Guid, t.CommentId),
|
||||||
|
Content: t.CommentContent,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
x = rs.GetXML()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
8
cache/map.go
vendored
8
cache/map.go
vendored
@ -30,6 +30,14 @@ func (m *MapCache[K, V]) SetCacheFunc(fn func(...any) (V, error)) {
|
|||||||
m.setCacheFunc = fn
|
m.setCacheFunc = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MapCache[K, V]) GetSetTime(k K) (t time.Time) {
|
||||||
|
r, ok := m.data[k]
|
||||||
|
if ok {
|
||||||
|
t = r.setTime
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) SetCacheBatchFunc(fn func(...any) (map[K]V, error)) {
|
func (m *MapCache[K, V]) SetCacheBatchFunc(fn func(...any) (map[K]V, error)) {
|
||||||
m.setBatchCacheFn = fn
|
m.setBatchCacheFn = fn
|
||||||
}
|
}
|
||||||
|
3
main.go
3
main.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github/fthvgb1/wp-go/actions"
|
||||||
"github/fthvgb1/wp-go/actions/common"
|
"github/fthvgb1/wp-go/actions/common"
|
||||||
"github/fthvgb1/wp-go/db"
|
"github/fthvgb1/wp-go/db"
|
||||||
"github/fthvgb1/wp-go/models"
|
"github/fthvgb1/wp-go/models"
|
||||||
@ -30,7 +31,7 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
actions.InitFeed()
|
||||||
common.InitActionsCommonCache()
|
common.InitActionsCommonCache()
|
||||||
plugins.InitDigestCache()
|
plugins.InitDigestCache()
|
||||||
go cronClearCache()
|
go cronClearCache()
|
||||||
|
@ -52,7 +52,8 @@ func SetupRouter() *gin.Engine {
|
|||||||
r.GET("/p/date/:year/:month/page/:page", actions.Index)
|
r.GET("/p/date/:year/:month/page/:page", actions.Index)
|
||||||
r.POST("/login", actions.Login)
|
r.POST("/login", actions.Login)
|
||||||
r.GET("/p/:id", actions.Detail)
|
r.GET("/p/:id", actions.Detail)
|
||||||
r.GET("/feed", actions.FeedCached, actions.Feed)
|
r.GET("/p/:id/feed", actions.PostFeed)
|
||||||
|
r.GET("/feed", actions.Feed)
|
||||||
if helper.IsContainInArr(gin.Mode(), []string{gin.DebugMode, gin.TestMode}) {
|
if helper.IsContainInArr(gin.Mode(), []string{gin.DebugMode, gin.TestMode}) {
|
||||||
pprof.Register(r, "dev/pprof")
|
pprof.Register(r, "dev/pprof")
|
||||||
}
|
}
|
||||||
|
26
rss2/rss2.go
26
rss2/rss2.go
@ -42,9 +42,9 @@ var templateItems = `
|
|||||||
{$comments}
|
{$comments}
|
||||||
<dc:creator><![CDATA[{$author}]]></dc:creator>
|
<dc:creator><![CDATA[{$author}]]></dc:creator>
|
||||||
<pubDate>{$pubDate}</pubDate>
|
<pubDate>{$pubDate}</pubDate>
|
||||||
<category><![CDATA[{$category}]]></category>
|
{$category}
|
||||||
<guid isPermaLink="false">{$guid}</guid>
|
<guid isPermaLink="false">{$guid}</guid>
|
||||||
<description><![CDATA[{$description}]]></description>
|
{$description}
|
||||||
<content:encoded><![CDATA[{$content}]]></content:encoded>
|
<content:encoded><![CDATA[{$content}]]></content:encoded>
|
||||||
{$commentRss}
|
{$commentRss}
|
||||||
{$commentNumber}
|
{$commentNumber}
|
||||||
@ -105,12 +105,12 @@ func (i Item) GetXml() (xml string) {
|
|||||||
for k, v := range map[string]string{
|
for k, v := range map[string]string{
|
||||||
"{$title}": i.Title,
|
"{$title}": i.Title,
|
||||||
"{$link}": i.Link,
|
"{$link}": i.Link,
|
||||||
"{$comments}": i.GetComments(),
|
"{$comments}": i.getComments(),
|
||||||
"{$author}": i.Creator,
|
"{$author}": i.Creator,
|
||||||
"{$pubDate}": i.PubDate,
|
"{$pubDate}": i.PubDate,
|
||||||
"{$category}": i.Category,
|
"{$category}": i.getCategory(),
|
||||||
"{$guid}": i.Guid,
|
"{$guid}": i.Guid,
|
||||||
"{$description}": i.Description,
|
"{$description}": i.getDescription(),
|
||||||
"{$content}": i.Content,
|
"{$content}": i.Content,
|
||||||
"{$commentRss}": i.getCommentRss(),
|
"{$commentRss}": i.getCommentRss(),
|
||||||
"{$commentNumber}": i.getSlashComments(),
|
"{$commentNumber}": i.getSlashComments(),
|
||||||
@ -120,7 +120,21 @@ func (i Item) GetXml() (xml string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) GetComments() string {
|
func (i Item) getCategory() string {
|
||||||
|
r := ""
|
||||||
|
if i.Category != "" {
|
||||||
|
r = fmt.Sprintf("<category><![CDATA[%s]]></category>", i.CommentLink)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
func (i Item) getDescription() string {
|
||||||
|
r := ""
|
||||||
|
if i.Description != "" {
|
||||||
|
r = fmt.Sprintf("<description><![CDATA[%s]]></description>", i.Description)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
func (i Item) getComments() string {
|
||||||
r := ""
|
r := ""
|
||||||
if i.CommentLink != "" {
|
if i.CommentLink != "" {
|
||||||
r = fmt.Sprintf("<comments>%s</comments>", i.CommentLink)
|
r = fmt.Sprintf("<comments>%s</comments>", i.CommentLink)
|
||||||
|
Loading…
Reference in New Issue
Block a user