diff --git a/actions/detail.go b/actions/detail.go index 9860978..da28a1f 100644 --- a/actions/detail.go +++ b/actions/detail.go @@ -8,6 +8,7 @@ import ( "github/fthvgb1/wp-go/actions/common" "github/fthvgb1/wp-go/helper" "github/fthvgb1/wp-go/models" + "github/fthvgb1/wp-go/plugins" "math/rand" "net/http" "net/url" @@ -78,6 +79,7 @@ func Detail(c *gin.Context) { common.PasswdProjectContent(&post) showComment = false } + plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post) comments, err := common.PostComments(ctx, post.Id) commentss := treeComments(comments) prev, next, err := common.GetContextPost(post.Id, post.PostDate) diff --git a/actions/index.go b/actions/index.go index 6065f92..1040fca 100644 --- a/actions/index.go +++ b/actions/index.go @@ -8,6 +8,7 @@ import ( "github/fthvgb1/wp-go/actions/common" "github/fthvgb1/wp-go/helper" "github/fthvgb1/wp-go/models" + "github/fthvgb1/wp-go/plugins" "math" "net/http" "regexp" @@ -35,6 +36,7 @@ type indexHandle struct { status []any header string paginationStep int + scene uint } func newIndexHandle(ctx *gin.Context) *indexHandle { @@ -54,6 +56,7 @@ func newIndexHandle(ctx *gin.Context) *indexHandle { join: models.SqlBuilder{}, postType: []any{"post"}, status: []any{"publish"}, + scene: plugins.Home, } } func (h *indexHandle) setTitleLR(l, r string) { @@ -85,6 +88,7 @@ func (h *indexHandle) parseParams() { ss := fmt.Sprintf("%s年%s月", year, strings.TrimLeft(month, "0")) h.header = fmt.Sprintf("月度归档: %s", ss) h.setTitleLR(ss, models.Options["blogname"]) + h.scene = plugins.Archive } category := h.c.Param("category") if category == "" { @@ -111,6 +115,7 @@ func (h *indexHandle) parseParams() { "left join", "wp_terms d", "c.term_id=d.term_id", }) h.setTitleLR(category, models.Options["blogname"]) + h.scene = plugins.Category } s := h.c.Query("s") if s != "" && strings.Replace(s, " ", "", -1) != "" { @@ -124,6 +129,7 @@ func (h *indexHandle) parseParams() { h.header = fmt.Sprintf("%s的搜索结果", s) h.setTitleLR(helper.StrJoin(`"`, s, `"`, "的搜索结果"), models.Options["blogname"]) h.search = s + h.scene = plugins.Search } else { h.status = append(h.status, "private") } @@ -179,6 +185,8 @@ func Index(c *gin.Context) { } err = common.QueryAndSetPostCache(postIds) pw := h.session.Get("post_password") + c.Set("post_password", pw) + plug := plugins.NewPostPlugin(c, h.scene) for i, v := range postIds { post, _ := common.PostsCache.Load(v.Id) pp := post.(*models.WpPosts) @@ -188,8 +196,11 @@ func Index(c *gin.Context) { common.PasswdProjectContent(&px) } postIds[i] = px + plugins.ApplyPlugin(plug, &postIds[i]) + } for i, post := range recent { + if post.PostPassword != "" && pw != post.PostPassword { common.PasswdProjectContent(&recent[i]) } @@ -201,6 +212,8 @@ func Index(c *gin.Context) { ginH["title"] = h.getTitle() } +var complie = regexp.MustCompile(`(/page)/(\d+)`) + func pagination(currentPage, totalPage, step int, path, query string) (html string) { if totalPage < 2 { return @@ -213,7 +226,7 @@ func pagination(currentPage, totalPage, step int, path, query string) (html stri if currentPage > totalPage { currentPage = totalPage } - r := regexp.MustCompile(`(/page)/(\d+)`) + r := complie start := currentPage - step end := currentPage + step if start < 1 { diff --git a/go.mod b/go.mod index a53835b..717278a 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( ) require ( + github.com/dlclark/regexp2 v1.7.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect diff --git a/helper/func.go b/helper/func.go index 285870f..c07369a 100644 --- a/helper/func.go +++ b/helper/func.go @@ -3,8 +3,10 @@ package helper import ( "crypto/md5" "fmt" + "github.com/dlclark/regexp2" "io" "reflect" + "regexp" "strings" ) @@ -64,6 +66,39 @@ func SlicePagination[T any](arr []T, page, pageSize int) []T { func StringMd5(str string) string { h := md5.New() - io.WriteString(h, str) + _, err := io.WriteString(h, str) + if err != nil { + return "" + } return fmt.Sprintf("%x", h.Sum(nil)) } + +var allHtmlTag = regexp.MustCompile("?.*>") + +func StripTags(str, allowable string) string { + html := "" + if allowable == "" { + return allHtmlTag.ReplaceAllString(str, "") + } + r := strings.Split(allowable, ">") + re := "" + for _, reg := range r { + if reg == "" { + continue + } + tag := strings.TrimLeft(reg, "<") + ree := fmt.Sprintf(`%s|\/%s`, tag, tag) + re = fmt.Sprintf("%s|%s", re, ree) + } + ree := strings.Trim(re, "|") + reg := fmt.Sprintf("<(?!%s).*?>", ree) + compile, err := regexp2.Compile(reg, regexp2.IgnoreCase) + if err != nil { + return str + } + html, err = compile.Replace(str, "", 0, -1) + if err != nil { + return str + } + return html +} diff --git a/helper/func_test.go b/helper/func_test.go index 47c21f7..c288899 100644 --- a/helper/func_test.go +++ b/helper/func_test.go @@ -196,3 +196,31 @@ func TestSlicePagination(t *testing.T) { }) } } + +func TestStripTags(t *testing.T) { + type args struct { + str string + allowable string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "t1", + args: args{ + str: "
pppppffff
", + allowable: "", + }, + want: "
pppppffff
", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := StripTags(tt.args.str, tt.args.allowable); got != tt.want { + t.Errorf("StripTags() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/main.go b/main.go index f428150..9fe5e1a 100644 --- a/main.go +++ b/main.go @@ -13,19 +13,23 @@ func init() { if err != nil { panic(err) } - common.InitCache() + err = db.InitDb() if err != nil { panic(err) } + err = models.InitOptions() if err != nil { panic(err) } + err = models.InitTerms() if err != nil { panic(err) } + + common.InitCache() } func main() { diff --git a/plugins/Excerpt.go b/plugins/Excerpt.go new file mode 100644 index 0000000..c41986b --- /dev/null +++ b/plugins/Excerpt.go @@ -0,0 +1,63 @@ +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("") +var more = regexp.MustCompile("") +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.StripTags(content, "
") + length := utf8.RuneCountInString(content) + 1 + if length > limit { + start, l := 0, limit+1 + end := l + for { + txt := string([]rune(content)[start:end]) + count := 0 + for _, ints := range tag.FindAllStringIndex(txt, -1) { + t := []rune(content[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([]rune(content)[:end]) + content = fmt.Sprintf(`%s...`, content, 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)) + +} diff --git a/plugins/plugins.go b/plugins/plugins.go new file mode 100644 index 0000000..aede422 --- /dev/null +++ b/plugins/plugins.go @@ -0,0 +1,38 @@ +package plugins + +import ( + "github.com/gin-gonic/gin" +) + +const ( + Home = iota + 1 + Archive + Category + Search + Detail +) + +type PluginFunc[T any] func(*Plugin[T], *gin.Context, *T, uint) + +type Plugin[T any] struct { + calls []PluginFunc[T] + index int + post *T + scene uint + c *gin.Context +} + +func NewPlugin[T any](calls []PluginFunc[T], index int, post *T, scene uint, c *gin.Context) *Plugin[T] { + return &Plugin[T]{calls: calls, index: index, post: post, scene: scene, c: c} +} + +func (p *Plugin[T]) Push(call ...PluginFunc[T]) { + p.calls = append(p.calls, call...) +} + +func (p *Plugin[T]) Next() { + p.index++ + for ; p.index < len(p.calls); p.index++ { + p.calls[p.index](p, p.c, p.post, p.scene) + } +} diff --git a/plugins/posts.go b/plugins/posts.go new file mode 100644 index 0000000..1a844d6 --- /dev/null +++ b/plugins/posts.go @@ -0,0 +1,18 @@ +package plugins + +import ( + "github.com/gin-gonic/gin" + "github/fthvgb1/wp-go/models" +) + +func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[models.WpPosts] { + p := NewPlugin[models.WpPosts](nil, -1, nil, scene, ctx) + p.Push(Except) + return p +} + +func ApplyPlugin(p *Plugin[models.WpPosts], post *models.WpPosts) { + p.post = post + p.Next() + p.index = -1 +}