摘要算法完全版

This commit is contained in:
xing 2022-09-26 16:35:38 +08:00
parent 1dc9d796fa
commit 528e8e9348
9 changed files with 135 additions and 87 deletions

View File

@ -1,7 +1,6 @@
package actions package actions
import ( import (
"context"
"fmt" "fmt"
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -27,11 +26,10 @@ func Detail(c *gin.Context) {
hh := detailHandler{ hh := detailHandler{
c, c,
} }
ctx := context.TODO() recent := common.RecentPosts(c)
recent := common.RecentPosts(ctx)
archive := common.Archives() archive := common.Archives()
categoryItems := common.Categories(ctx) categoryItems := common.Categories(c)
recentComments := common.RecentComments(ctx) recentComments := common.RecentComments(c)
var h = gin.H{ var h = gin.H{
"title": models.Options["blogname"], "title": models.Options["blogname"],
"options": models.Options, "options": models.Options,
@ -80,7 +78,7 @@ func Detail(c *gin.Context) {
showComment = false showComment = false
} }
plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post) plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post)
comments, err := common.PostComments(ctx, post.Id) comments, err := common.PostComments(c, post.Id)
commentss := treeComments(comments) commentss := treeComments(comments)
prev, next, err := common.GetContextPost(post.Id, post.PostDate) prev, next, err := common.GetContextPost(post.Id, post.PostDate)
h["title"] = fmt.Sprintf("%s-%s", post.PostTitle, models.Options["blogname"]) h["title"] = fmt.Sprintf("%s-%s", post.PostTitle, models.Options["blogname"])

View File

@ -1,7 +1,6 @@
package actions package actions
import ( import (
"context"
"fmt" "fmt"
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -155,11 +154,10 @@ func (h *indexHandle) getTotalPage(totalRaws int) int {
func Index(c *gin.Context) { func Index(c *gin.Context) {
h := newIndexHandle(c) h := newIndexHandle(c)
h.parseParams() h.parseParams()
ctx := context.TODO()
archive := common.Archives() archive := common.Archives()
recent := common.RecentPosts(ctx) recent := common.RecentPosts(c)
categoryItems := common.Categories(ctx) categoryItems := common.Categories(c)
recentComments := common.RecentComments(ctx) recentComments := common.RecentComments(c)
ginH := gin.H{ ginH := gin.H{
"options": models.Options, "options": models.Options,
"recentPosts": recent, "recentPosts": recent,
@ -185,7 +183,6 @@ func Index(c *gin.Context) {
} }
err = common.QueryAndSetPostCache(postIds) err = common.QueryAndSetPostCache(postIds)
pw := h.session.Get("post_password") pw := h.session.Get("post_password")
c.Set("post_password", pw)
plug := plugins.NewPostPlugin(c, h.scene) plug := plugins.NewPostPlugin(c, h.scene)
for i, v := range postIds { for i, v := range postIds {
post, _ := common.PostsCache.Load(v.Id) post, _ := common.PostsCache.Load(v.Id)

4
cache/map.go vendored
View File

@ -17,11 +17,11 @@ type MapCache[K comparable, V any] struct {
incr int incr int
} }
func NewMapCache[K comparable, V any](fun func(...any) (V, error), duration time.Duration) *MapCache[K, V] { func NewMapCache[K comparable, V any](fun func(...any) (V, error), expireTime time.Duration) *MapCache[K, V] {
return &MapCache[K, V]{ return &MapCache[K, V]{
mutex: &sync.Mutex{}, mutex: &sync.Mutex{},
setCacheFunc: fun, setCacheFunc: fun,
expireTime: duration, expireTime: expireTime,
data: make(map[K]V), data: make(map[K]V),
} }
} }

View File

@ -16,10 +16,14 @@ mysql:
# 连接的生命时长 # 连接的生命时长
connMaxLifetime: 236 connMaxLifetime: 236
# 最近文章缓存时间 # 最近文章缓存时间
recentPostCacheTime: 30m recentPostCacheTime: 5m
# 分类缓存时间 # 分类缓存时间
categoryCacheTime: 30m categoryCacheTime: 5m
# 上下篇缓存时间 # 上下篇缓存时间
contextPostCacheTime: 1h contextPostCacheTime: 10h
# 最近评论缓存时间 # 最近评论缓存时间
recentCommentsCacheTime: 10m recentCommentsCacheTime: 5m
# 摘要缓存时间
digestCacheTime: 5m
# 摘要字数
digestWordCount: 300

View File

@ -4,6 +4,7 @@ import (
"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"
"github/fthvgb1/wp-go/plugins"
"github/fthvgb1/wp-go/route" "github/fthvgb1/wp-go/route"
"github/fthvgb1/wp-go/vars" "github/fthvgb1/wp-go/vars"
) )
@ -30,6 +31,7 @@ func init() {
} }
common.InitCache() common.InitCache()
plugins.InitDigest()
} }
func main() { func main() {

View File

@ -1,68 +0,0 @@
package plugins
import (
"fmt"
"github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/helper"
"github/fthvgb1/wp-go/models"
"regexp"
"strings"
"unicode/utf8"
)
var removeWpBlock = regexp.MustCompile("<!-- /?wp:.*-->")
var more = regexp.MustCompile("<!--more(.*?)?-->")
var tag = regexp.MustCompile(`<.*?>`)
var limit = 300
func ExceptRaw(str string, limit, id int) string {
if r := more.FindString(str); r != "" {
m := strings.Split(str, r)
str = m[0]
return ""
}
content := removeWpBlock.ReplaceAllString(str, "")
content = strings.Trim(content, " \t\n\r\000\x0B")
content = strings.Replace(content, "]]>", "]]&gt;", -1)
content = helper.StripTagsX(content, "<a><b><blockquote><br><cite><code><dd><del><div><dl><dt><em><h1><h2><h3><h4><h5><h6><i><img><li><ol><p><pre><span><strong><ul>")
length := utf8.RuneCountInString(content) + 1
if length > limit {
start, l := 0, limit
end := l
ru := []rune(content)
for {
txt := string(ru[start:end])
count := 0
for _, ints := range tag.FindAllStringIndex(txt, -1) {
t := txt[ints[0]:ints[1]]
count += len(t)
l += len(t)
}
if count > 0 && length > l {
start = end
end += count
} else if count > 0 && length < l {
break
} else {
content = string(ru[:end])
closeTag := helper.CloseHtmlTag(content)
tmp := `%s......%s<p class="read-more"><a href="/p/%d">继续阅读</a></p>`
if strings.Contains(closeTag, "pre") || strings.Contains(closeTag, "code") {
tmp = `%s%s......<p class="read-more"><a href="/p/%d">继续阅读</a></p>`
}
content = fmt.Sprintf(tmp, content, closeTag, id)
break
}
}
}
return content
}
func Except(p *Plugin[models.WpPosts], c *gin.Context, post *models.WpPosts, scene uint) {
if scene == Detail {
return
}
post.PostContent = ExceptRaw(post.PostContent, limit, int(post.Id))
}

113
plugins/digest.go Normal file
View File

@ -0,0 +1,113 @@
package plugins
import (
"fmt"
"github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/cache"
"github/fthvgb1/wp-go/helper"
"github/fthvgb1/wp-go/models"
"github/fthvgb1/wp-go/vars"
"regexp"
"strings"
"time"
"unicode/utf8"
)
var removeWpBlock = regexp.MustCompile("<!-- /?wp:.*-->")
var more = regexp.MustCompile("<!--more(.*?)?-->")
var digestCache *cache.MapCache[uint64, string]
var quto = regexp.MustCompile(`&quot; *|&amp; *|&lt; *|&gt; ?|&nbsp; *`)
func InitDigest() {
digestCache = cache.NewMapCache[uint64](digestRaw, time.Second)
}
func digestRaw(arg ...any) (string, error) {
str := arg[0].(string)
id := arg[1].(uint64)
limit := vars.Conf.DigestWordCount
if limit < 0 {
return str, nil
} else if limit == 0 {
return "", nil
}
return DigestRaw(str, limit, id), nil
}
func DigestCache(ctx *gin.Context, id uint64, str string) string {
content, _ := digestCache.GetCache(ctx, id, time.Second, str, id)
return content
}
func DigestRaw(str string, limit int, id uint64) string {
if r := more.FindString(str); r != "" {
m := strings.Split(str, r)
str = m[0]
return ""
}
content := removeWpBlock.ReplaceAllString(str, "")
content = strings.Trim(content, " \t\n\r\000\x0B")
content = strings.Replace(content, "]]>", "]]&gt;", -1)
content = helper.StripTagsX(content, "<a><b><blockquote><br><cite><code><dd><del><div><dl><dt><em><h1><h2><h3><h4><h5><h6><i><img><li><ol><p><pre><span><strong><ul>")
length := utf8.RuneCountInString(content) + 1
if length > limit {
index := quto.FindAllStringIndex(content, -1)
end := 0
ru := []rune(content)
tagIn := false
total := len(ru)
l, r := '<', '>'
i := -1
for {
i++
for len(index) > 0 {
ints := helper.SliceMap(index[0], func(t int) int {
return utf8.RuneCountInString(content[:t])
})
if ints[0] <= i {
i = i + i - ints[0] + ints[1] - ints[0]
index = index[1:]
end++
continue
} else {
break
}
}
if end >= limit || i >= total-1 {
break
}
if ru[i] == l {
tagIn = true
continue
} else if ru[i] == r {
tagIn = false
continue
}
if tagIn == false {
end++
}
}
if i > total-1 {
i = total - 1
}
content = string(ru[:i])
closeTag := helper.CloseHtmlTag(content)
tmp := `%s......%s<p class="read-more"><a href="/p/%d">继续阅读</a></p>`
if strings.Contains(closeTag, "pre") || strings.Contains(closeTag, "code") {
tmp = `%s%s......<p class="read-more"><a href="/p/%d">继续阅读</a></p>`
}
content = fmt.Sprintf(tmp, content, closeTag, id)
}
return content
}
func Digest(p *Plugin[models.WpPosts], c *gin.Context, post *models.WpPosts, scene uint) {
if scene == Detail {
return
}
//post.PostContent = DigestCache(c, post.Id, post.PostContent)
post.PostContent = DigestRaw(post.PostContent, vars.Conf.DigestWordCount, post.Id)
}

View File

@ -7,7 +7,7 @@ import (
func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[models.WpPosts] { func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[models.WpPosts] {
p := NewPlugin[models.WpPosts](nil, -1, nil, scene, ctx) p := NewPlugin[models.WpPosts](nil, -1, nil, scene, ctx)
p.Push(Except) p.Push(Digest)
return p return p
} }

View File

@ -16,6 +16,8 @@ type Config struct {
ArchiveCacheTime time.Duration `yaml:"archiveCacheTime"` ArchiveCacheTime time.Duration `yaml:"archiveCacheTime"`
ContextPostCacheTime time.Duration `yaml:"contextPostCacheTime"` ContextPostCacheTime time.Duration `yaml:"contextPostCacheTime"`
RecentCommentsCacheTime time.Duration `yaml:"recentCommentsCacheTime"` RecentCommentsCacheTime time.Duration `yaml:"recentCommentsCacheTime"`
DigestCacheTime time.Duration `yaml:"digestCacheTime"`
DigestWordCount int `yaml:"digestWordCount"`
} }
type Mysql struct { type Mysql struct {