diff --git a/actions/feed.go b/actions/feed.go
index 484d3bb..c8a6a5b 100644
--- a/actions/feed.go
+++ b/actions/feed.go
@@ -6,24 +6,32 @@ import (
"github/fthvgb1/wp-go/actions/common"
"github/fthvgb1/wp-go/cache"
"github/fthvgb1/wp-go/helper"
+ "github/fthvgb1/wp-go/logs"
"github/fthvgb1/wp-go/models"
"github/fthvgb1/wp-go/plugins"
"github/fthvgb1/wp-go/rss2"
"net/http"
+ "strconv"
"strings"
"time"
)
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 templateRss rss2.Rss2
-func FeedCached(c *gin.Context) {
- if !isCacheExpired(c, feedCache.SetTime()) {
- c.Status(http.StatusNotModified)
- c.Abort()
- return
+func InitFeed() {
+ templateRss = rss2.Rss2{
+ Title: models.Options["blogname"],
+ AtomLink: fmt.Sprintf("%s/feed", models.Options["home"]),
+ 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 {
@@ -41,19 +49,11 @@ func isCacheExpired(c *gin.Context, lastTime time.Time) bool {
}
func Feed(c *gin.Context) {
- s, err := feedCache.GetCache(c, time.Second, c)
- if err != nil {
- c.Status(http.StatusInternalServerError)
- c.Abort()
- c.Error(err)
- return
+ if !isCacheExpired(c, feedCache.SetTime()) {
+ c.Status(http.StatusNotModified)
+ } else {
+ setFeed(feedCache, c)
}
- 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) {
@@ -66,19 +66,8 @@ func feed(arg ...any) (xml []string, err error) {
if err != nil {
return
}
- rs := rss2.Rss2{
- Title: models.Options["blogname"],
- 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 := templateRss
+ rs.LastBuildDate = time.Now().Format(time.RFC1123Z)
rs.Items = helper.SliceMap(posts, func(t models.WpPosts) rss2.Item {
desc := "无法提供摘要。这是一篇受保护的文章。"
common.PasswordProjectTitle(&t)
@@ -112,3 +101,104 @@ func feed(arg ...any) (xml []string, err error) {
xml = []string{rs.GetXML()}
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
+}
diff --git a/cache/map.go b/cache/map.go
index e570dd3..afab49f 100644
--- a/cache/map.go
+++ b/cache/map.go
@@ -30,6 +30,14 @@ func (m *MapCache[K, V]) SetCacheFunc(fn func(...any) (V, error)) {
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)) {
m.setBatchCacheFn = fn
}
diff --git a/main.go b/main.go
index 4d1ea81..5324184 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,7 @@
package main
import (
+ "github/fthvgb1/wp-go/actions"
"github/fthvgb1/wp-go/actions/common"
"github/fthvgb1/wp-go/db"
"github/fthvgb1/wp-go/models"
@@ -30,7 +31,7 @@ func init() {
if err != nil {
panic(err)
}
-
+ actions.InitFeed()
common.InitActionsCommonCache()
plugins.InitDigestCache()
go cronClearCache()
diff --git a/route/route.go b/route/route.go
index 371b0b4..436f15c 100644
--- a/route/route.go
+++ b/route/route.go
@@ -52,7 +52,8 @@ func SetupRouter() *gin.Engine {
r.GET("/p/date/:year/:month/page/:page", actions.Index)
r.POST("/login", actions.Login)
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}) {
pprof.Register(r, "dev/pprof")
}
diff --git a/rss2/rss2.go b/rss2/rss2.go
index 26ad662..1120427 100644
--- a/rss2/rss2.go
+++ b/rss2/rss2.go
@@ -42,9 +42,9 @@ var templateItems = `
{$comments}
{$pubDate}
-
+ {$category}
{$guid}
-
+ {$description}
{$commentRss}
{$commentNumber}
@@ -105,12 +105,12 @@ func (i Item) GetXml() (xml string) {
for k, v := range map[string]string{
"{$title}": i.Title,
"{$link}": i.Link,
- "{$comments}": i.GetComments(),
+ "{$comments}": i.getComments(),
"{$author}": i.Creator,
"{$pubDate}": i.PubDate,
- "{$category}": i.Category,
+ "{$category}": i.getCategory(),
"{$guid}": i.Guid,
- "{$description}": i.Description,
+ "{$description}": i.getDescription(),
"{$content}": i.Content,
"{$commentRss}": i.getCommentRss(),
"{$commentNumber}": i.getSlashComments(),
@@ -120,7 +120,21 @@ func (i Item) GetXml() (xml string) {
return
}
-func (i Item) GetComments() string {
+func (i Item) getCategory() string {
+ r := ""
+ if i.Category != "" {
+ r = fmt.Sprintf("", i.CommentLink)
+ }
+ return r
+}
+func (i Item) getDescription() string {
+ r := ""
+ if i.Description != "" {
+ r = fmt.Sprintf("", i.Description)
+ }
+ return r
+}
+func (i Item) getComments() string {
r := ""
if i.CommentLink != "" {
r = fmt.Sprintf("%s", i.CommentLink)