摘要算法完全版
This commit is contained in:
parent
1dc9d796fa
commit
528e8e9348
|
@ -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"])
|
||||||
|
|
|
@ -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
4
cache/map.go
vendored
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
2
main.go
2
main.go
|
@ -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() {
|
||||||
|
|
|
@ -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, "]]>", "]]>", -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
113
plugins/digest.go
Normal 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(`" *|& *|< *|> ?| *`)
|
||||||
|
|
||||||
|
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, "]]>", "]]>", -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)
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user