From c66b0080af75dac0393bb03acaaad08de8b78830 Mon Sep 17 00:00:00 2001 From: xing Date: Thu, 12 Jan 2023 20:42:16 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/actions/comment.go | 6 +- internal/actions/common/comments.go | 78 ------ internal/actions/common/common.go | 181 -------------- internal/actions/common/posts.go | 236 ------------------ internal/actions/common/users.go | 35 --- internal/actions/detail.go | 36 +-- internal/actions/feed.go | 49 ++-- internal/actions/index.go | 43 ++-- internal/cache/cache.go | 124 +++++++++ internal/cache/comments.go | 33 +++ .../{actions/common => cache}/postmeta.go | 39 +-- internal/cache/posts.go | 77 ++++++ internal/cache/users.go | 26 ++ {config => internal/config}/config.go | 0 internal/dao/comments.go | 57 +++++ internal/dao/common.go | 55 ++++ internal/dao/postmeta.go | 85 +++++++ internal/dao/posts.go | 169 +++++++++++++ internal/dao/users.go | 23 ++ {db => internal/db}/db.go | 2 +- internal/middleware/sendmail.go | 2 +- internal/middleware/validateservername.go | 2 +- internal/{wp => models}/wp_comments.go | 2 +- internal/{wp => models}/wp_options.go | 2 +- internal/{wp => models}/wp_postmeta.go | 2 +- internal/{wp => models}/wp_posts.go | 2 +- internal/{wp => models}/wp_term_taxonomy.go | 2 +- internal/{wp => models}/wp_terms.go | 2 +- internal/{wp => models}/wp_users.go | 2 +- internal/plugins/digest.go | 55 ++++ {plugins => internal/plugins}/plugins.go | 8 +- internal/plugins/posts.go | 36 +++ internal/route/route.go | 2 +- internal/wpconfig/options.go | 8 +- internal/wpconfig/term.go | 8 +- mail/mail.go | 2 +- mail/mail_test.go | 2 +- main.go | 28 +-- model/model.go | 28 +++ models/model.go => model/parse.go | 26 +- {models => model}/query.go | 2 +- {models => model}/query_test.go | 8 +- {plugins => plugin/digest}/digest.go | 53 +--- plugins/posts.go | 18 -- 44 files changed, 886 insertions(+), 770 deletions(-) delete mode 100644 internal/actions/common/comments.go delete mode 100644 internal/actions/common/common.go delete mode 100644 internal/actions/common/posts.go delete mode 100644 internal/actions/common/users.go create mode 100644 internal/cache/cache.go create mode 100644 internal/cache/comments.go rename internal/{actions/common => cache}/postmeta.go (54%) create mode 100644 internal/cache/posts.go create mode 100644 internal/cache/users.go rename {config => internal/config}/config.go (100%) create mode 100644 internal/dao/comments.go create mode 100644 internal/dao/common.go create mode 100644 internal/dao/postmeta.go create mode 100644 internal/dao/posts.go create mode 100644 internal/dao/users.go rename {db => internal/db}/db.go (97%) rename internal/{wp => models}/wp_comments.go (99%) rename internal/{wp => models}/wp_options.go (97%) rename internal/{wp => models}/wp_postmeta.go (96%) rename internal/{wp => models}/wp_posts.go (99%) rename internal/{wp => models}/wp_term_taxonomy.go (98%) rename internal/{wp => models}/wp_terms.go (97%) rename internal/{wp => models}/wp_users.go (98%) create mode 100644 internal/plugins/digest.go rename {plugins => internal/plugins}/plugins.go (65%) create mode 100644 internal/plugins/posts.go create mode 100644 model/model.go rename models/model.go => model/parse.go (91%) rename {models => model}/query.go (99%) rename {models => model}/query_test.go (98%) rename {plugins => plugin/digest}/digest.go (64%) delete mode 100644 plugins/posts.go diff --git a/internal/actions/comment.go b/internal/actions/comment.go index 351c34f..d637297 100644 --- a/internal/actions/comment.go +++ b/internal/actions/comment.go @@ -6,9 +6,9 @@ import ( "fmt" "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/cache" - "github/fthvgb1/wp-go/config" "github/fthvgb1/wp-go/helper" - "github/fthvgb1/wp-go/internal/actions/common" + cache2 "github/fthvgb1/wp-go/internal/cache" + "github/fthvgb1/wp-go/internal/config" "github/fthvgb1/wp-go/internal/wpconfig" "github/fthvgb1/wp-go/logs" "github/fthvgb1/wp-go/mail" @@ -99,7 +99,7 @@ func PostComment(c *gin.Context) { logs.ErrPrintln(err, "获取文档id", i) return } - post, err := common.GetPostById(cc, id) + post, err := cache2.GetPostById(cc, id) if err != nil { logs.ErrPrintln(err, "获取文档", id) return diff --git a/internal/actions/common/comments.go b/internal/actions/common/comments.go deleted file mode 100644 index b987a76..0000000 --- a/internal/actions/common/comments.go +++ /dev/null @@ -1,78 +0,0 @@ -package common - -import ( - "context" - "github/fthvgb1/wp-go/helper" - "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "strconv" - "time" -) - -func RecentComments(ctx context.Context, n int) (r []wp.Comments) { - r, err := recentCommentsCaches.GetCache(ctx, time.Second, ctx) - if len(r) > n { - r = r[0:n] - } - logs.ErrPrintln(err, "get recent comment") - return -} -func recentComments(a ...any) (r []wp.Comments, err error) { - ctx := a[0].(context.Context) - return models.Find[wp.Comments](ctx, models.SqlBuilder{ - {"comment_approved", "1"}, - {"post_status", "publish"}, - }, "comment_ID,comment_author,comment_post_ID,post_title", "", models.SqlBuilder{{"comment_date_gmt", "desc"}}, models.SqlBuilder{ - {"a", "left join", "wp_posts b", "a.comment_post_ID=b.ID"}, - }, nil, 10) -} - -func PostComments(ctx context.Context, Id uint64) ([]wp.Comments, error) { - ids, err := postCommentCaches.GetCache(ctx, Id, time.Second, ctx, Id) - if err != nil { - return nil, err - } - return GetCommentByIds(ctx, ids) -} - -func postComments(args ...any) ([]uint64, error) { - ctx := args[0].(context.Context) - postId := args[1].(uint64) - r, err := models.Find[wp.Comments](ctx, models.SqlBuilder{ - {"comment_approved", "1"}, - {"comment_post_ID", "=", strconv.FormatUint(postId, 10), "int"}, - }, "comment_ID", "", models.SqlBuilder{ - {"comment_date_gmt", "asc"}, - {"comment_ID", "asc"}, - }, nil, nil, 0) - if err != nil { - return nil, err - } - return helper.SliceMap(r, func(t wp.Comments) uint64 { - return t.CommentId - }), err -} - -func GetCommentById(ctx context.Context, id uint64) (wp.Comments, error) { - return commentsCache.GetCache(ctx, id, time.Second, ctx, id) -} - -func GetCommentByIds(ctx context.Context, ids []uint64) ([]wp.Comments, error) { - return commentsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids) -} - -func getCommentByIds(args ...any) (map[uint64]wp.Comments, error) { - ctx := args[0].(context.Context) - ids := args[1].([]uint64) - m := make(map[uint64]wp.Comments) - r, err := models.SimpleFind[wp.Comments](ctx, models.SqlBuilder{ - {"comment_ID", "in", ""}, {"comment_approved", "1"}, - }, "*", helper.SliceMap(ids, helper.ToAny[uint64])) - if err != nil { - return m, err - } - return helper.SimpleSliceToMap(r, func(t wp.Comments) uint64 { - return t.CommentId - }), err -} diff --git a/internal/actions/common/common.go b/internal/actions/common/common.go deleted file mode 100644 index b5c7320..0000000 --- a/internal/actions/common/common.go +++ /dev/null @@ -1,181 +0,0 @@ -package common - -import ( - "context" - "fmt" - "github/fthvgb1/wp-go/cache" - "github/fthvgb1/wp-go/config" - wp2 "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/internal/wpconfig" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "sync" - "time" -) - -var postContextCache *cache.MapCache[uint64, PostContext] -var archivesCaches *Arch -var categoryCaches *cache.SliceCache[wp2.TermsMy] -var recentPostsCaches *cache.SliceCache[wp2.Posts] -var recentCommentsCaches *cache.SliceCache[wp2.Comments] -var postCommentCaches *cache.MapCache[uint64, []uint64] -var postsCache *cache.MapCache[uint64, wp2.Posts] - -var postMetaCache *cache.MapCache[uint64, map[string]any] - -var monthPostsCache *cache.MapCache[string, []uint64] -var postListIdsCache *cache.MapCache[string, PostIds] -var searchPostIdsCache *cache.MapCache[string, PostIds] -var maxPostIdCache *cache.SliceCache[uint64] -var TotalRaw int64 -var usersCache *cache.MapCache[uint64, wp2.Users] -var usersNameCache *cache.MapCache[string, wp2.Users] -var commentsCache *cache.MapCache[uint64, wp2.Comments] - -func InitActionsCommonCache() { - c := config.Conf.Load() - archivesCaches = &Arch{ - mutex: &sync.Mutex{}, - setCacheFunc: archives, - } - - searchPostIdsCache = cache.NewMapCacheByFn[string, PostIds](searchPostIds, c.SearchPostCacheTime) - - postListIdsCache = cache.NewMapCacheByFn[string, PostIds](searchPostIds, c.PostListCacheTime) - - monthPostsCache = cache.NewMapCacheByFn[string, []uint64](monthPost, c.MonthPostCacheTime) - - postContextCache = cache.NewMapCacheByFn[uint64, PostContext](getPostContext, c.ContextPostCacheTime) - - postsCache = cache.NewMapCacheByBatchFn[uint64, wp2.Posts](getPostsByIds, c.PostDataCacheTime) - - postMetaCache = cache.NewMapCacheByBatchFn[uint64, map[string]any](getPostMetaByPostIds, c.PostDataCacheTime) - - categoryCaches = cache.NewSliceCache[wp2.TermsMy](categories, c.CategoryCacheTime) - - recentPostsCaches = cache.NewSliceCache[wp2.Posts](recentPosts, c.RecentPostCacheTime) - - recentCommentsCaches = cache.NewSliceCache[wp2.Comments](recentComments, c.RecentCommentsCacheTime) - - postCommentCaches = cache.NewMapCacheByFn[uint64, []uint64](postComments, c.PostCommentsCacheTime) - - maxPostIdCache = cache.NewSliceCache[uint64](getMaxPostId, c.MaxPostIdCacheTime) - - usersCache = cache.NewMapCacheByFn[uint64, wp2.Users](getUserById, c.UserInfoCacheTime) - - usersNameCache = cache.NewMapCacheByFn[string, wp2.Users](getUserByName, c.UserInfoCacheTime) - - commentsCache = cache.NewMapCacheByBatchFn[uint64, wp2.Comments](getCommentByIds, c.CommentsCacheTime) -} - -func ClearCache() { - searchPostIdsCache.ClearExpired() - postsCache.ClearExpired() - postMetaCache.ClearExpired() - postListIdsCache.ClearExpired() - monthPostsCache.ClearExpired() - postContextCache.ClearExpired() - usersCache.ClearExpired() - commentsCache.ClearExpired() - usersNameCache.ClearExpired() -} -func FlushCache() { - searchPostIdsCache.Flush() - postsCache.Flush() - postMetaCache.Flush() - postListIdsCache.Flush() - monthPostsCache.Flush() - postContextCache.Flush() - usersCache.Flush() - commentsCache.Flush() - usersCache.Flush() -} - -type PostIds struct { - Ids []uint64 - Length int -} - -type Arch struct { - data []wp2.PostArchive - mutex *sync.Mutex - setCacheFunc func(context.Context) ([]wp2.PostArchive, error) - month time.Month -} - -func (c *Arch) getArchiveCache(ctx context.Context) []wp2.PostArchive { - l := len(c.data) - m := time.Now().Month() - if l > 0 && c.month != m || l < 1 { - r, err := c.setCacheFunc(ctx) - if err != nil { - logs.ErrPrintln(err, "set cache err[%s]") - return nil - } - c.mutex.Lock() - defer c.mutex.Unlock() - c.month = m - c.data = r - } - return c.data -} - -type PostContext struct { - prev wp2.Posts - next wp2.Posts -} - -func archives(ctx context.Context) ([]wp2.PostArchive, error) { - return models.Find[wp2.PostArchive](ctx, models.SqlBuilder{ - {"post_type", "post"}, {"post_status", "publish"}, - }, "YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts", "year,month", models.SqlBuilder{{"year", "desc"}, {"month", "desc"}}, nil, nil, 0) -} - -func Archives(ctx context.Context) (r []wp2.PostArchive) { - return archivesCaches.getArchiveCache(ctx) -} - -func Categories(ctx context.Context) []wp2.TermsMy { - r, err := categoryCaches.GetCache(ctx, time.Second, ctx) - logs.ErrPrintln(err, "get category ") - return r -} - -func categories(a ...any) (terms []wp2.TermsMy, err error) { - ctx := a[0].(context.Context) - var in = []any{"category"} - terms, err = models.Find[wp2.TermsMy](ctx, models.SqlBuilder{ - {"tt.count", ">", "0", "int"}, - {"tt.taxonomy", "in", ""}, - }, "t.term_id", "", models.SqlBuilder{ - {"t.name", "asc"}, - }, models.SqlBuilder{ - {"t", "inner join", "wp_term_taxonomy tt", "t.term_id = tt.term_id"}, - }, nil, 0, in) - for i := 0; i < len(terms); i++ { - if v, ok := wpconfig.Terms.Load(terms[i].Terms.TermId); ok { - terms[i].Terms = v - } - if v, ok := wpconfig.TermTaxonomies.Load(terms[i].Terms.TermId); ok { - terms[i].TermTaxonomy = v - } - } - return -} - -func PasswordProjectTitle(post *wp2.Posts) { - if post.PostPassword != "" { - post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle) - } -} - -func PasswdProjectContent(post *wp2.Posts) { - if post.PostContent != "" { - format := ` -
-

此内容受密码保护。如需查阅,请在下列字段中输入您的密码。

-

-
` - post.PostContent = fmt.Sprintf(format, post.Id, post.Id) - } -} diff --git a/internal/actions/common/posts.go b/internal/actions/common/posts.go deleted file mode 100644 index 54f2d28..0000000 --- a/internal/actions/common/posts.go +++ /dev/null @@ -1,236 +0,0 @@ -package common - -import ( - "context" - "database/sql" - "fmt" - "github.com/gin-gonic/gin" - "github/fthvgb1/wp-go/helper" - "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "strings" - "sync/atomic" - "time" -) - -func GetPostById(ctx context.Context, id uint64) (wp.Posts, error) { - return postsCache.GetCache(ctx, id, time.Second, ctx, id) -} - -func GetPostsByIds(ctx context.Context, ids []uint64) ([]wp.Posts, error) { - return postsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids) -} - -func SearchPost(ctx context.Context, key string, args ...any) (r []wp.Posts, total int, err error) { - ids, err := searchPostIdsCache.GetCache(ctx, key, time.Second, args...) - if err != nil { - return - } - total = ids.Length - r, err = GetPostsByIds(ctx, ids.Ids) - return -} - -func getPostsByIds(ids ...any) (m map[uint64]wp.Posts, err error) { - ctx := ids[0].(context.Context) - m = make(map[uint64]wp.Posts) - id := ids[1].([]uint64) - arg := helper.SliceMap(id, helper.ToAny[uint64]) - rawPosts, err := models.Find[wp.Posts](ctx, models.SqlBuilder{{ - "Id", "in", "", - }}, "a.*,ifnull(d.name,'') category_name,ifnull(taxonomy,'') `taxonomy`", "", nil, models.SqlBuilder{{ - "a", "left join", "wp_term_relationships b", "a.Id=b.object_id", - }, { - "left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", - }, { - "left join", "wp_terms d", "c.term_id=d.term_id", - }}, nil, 0, arg) - if err != nil { - return m, err - } - postsMap := make(map[uint64]wp.Posts) - for i, post := range rawPosts { - v, ok := postsMap[post.Id] - if !ok { - v = rawPosts[i] - } - if post.Taxonomy == "category" { - v.Categories = append(v.Categories, post.CategoryName) - } else if post.Taxonomy == "post_tag" { - v.Tags = append(v.Tags, post.CategoryName) - } - postsMap[post.Id] = v - } - meta, _ := getPostMetaByPostIds(ctx, id) - for k, pp := range postsMap { - if len(pp.Categories) > 0 { - t := make([]string, 0, len(pp.Categories)) - for _, cat := range pp.Categories { - t = append(t, fmt.Sprintf(`%s`, cat, cat)) - } - pp.CategoriesHtml = strings.Join(t, "、") - _, ok := meta[pp.Id] - if ok { - thumb := ToPostThumbnail(ctx, pp.Id) - if thumb.Path != "" { - pp.Thumbnail = thumb - } - } - } - if len(pp.Tags) > 0 { - t := make([]string, 0, len(pp.Tags)) - for _, cat := range pp.Tags { - t = append(t, fmt.Sprintf(``, cat, cat)) - } - pp.TagsHtml = strings.Join(t, "、") - } - m[k] = pp - } - return -} - -func PostLists(ctx context.Context, key string, args ...any) (r []wp.Posts, total int, err error) { - ids, err := postListIdsCache.GetCache(ctx, key, time.Second, args...) - if err != nil { - return - } - total = ids.Length - r, err = GetPostsByIds(ctx, ids.Ids) - return -} - -func searchPostIds(args ...any) (ids PostIds, err error) { - ctx := args[0].(context.Context) - where := args[1].(models.SqlBuilder) - page := args[2].(int) - limit := args[3].(int) - order := args[4].(models.SqlBuilder) - join := args[5].(models.SqlBuilder) - postType := args[6].([]any) - postStatus := args[7].([]any) - res, total, err := models.SimplePagination[wp.Posts](ctx, where, "ID", "", page, limit, order, join, nil, postType, postStatus) - for _, posts := range res { - ids.Ids = append(ids.Ids, posts.Id) - } - ids.Length = total - totalR := int(atomic.LoadInt64(&TotalRaw)) - if total > totalR { - tt := int64(total) - atomic.StoreInt64(&TotalRaw, tt) - } - return -} - -func getMaxPostId(a ...any) ([]uint64, error) { - ctx := a[0].(context.Context) - r, err := models.SimpleFind[wp.Posts](ctx, models.SqlBuilder{{"post_type", "post"}, {"post_status", "publish"}}, "max(ID) ID") - var id uint64 - if len(r) > 0 { - id = r[0].Id - } - return []uint64{id}, err -} - -func GetMaxPostId(ctx *gin.Context) (uint64, error) { - Id, err := maxPostIdCache.GetCache(ctx, time.Second, ctx) - return Id[0], err -} - -func RecentPosts(ctx context.Context, n int) (r []wp.Posts) { - r, err := recentPostsCaches.GetCache(ctx, time.Second, ctx) - if n < len(r) { - r = r[:n] - } - logs.ErrPrintln(err, "get recent post") - return -} -func recentPosts(a ...any) (r []wp.Posts, err error) { - ctx := a[0].(context.Context) - r, err = models.Find[wp.Posts](ctx, models.SqlBuilder{{ - "post_type", "post", - }, {"post_status", "publish"}}, "ID,post_title,post_password", "", models.SqlBuilder{{"post_date", "desc"}}, nil, nil, 10) - for i, post := range r { - if post.PostPassword != "" { - PasswordProjectTitle(&r[i]) - } - } - return -} - -func GetContextPost(ctx context.Context, id uint64, date time.Time) (prev, next wp.Posts, err error) { - postCtx, err := postContextCache.GetCache(ctx, id, time.Second, ctx, date) - if err != nil { - return wp.Posts{}, wp.Posts{}, err - } - prev = postCtx.prev - next = postCtx.next - return -} - -func getPostContext(arg ...any) (r PostContext, err error) { - ctx := arg[0].(context.Context) - t := arg[1].(time.Time) - next, err := models.FirstOne[wp.Posts](ctx, models.SqlBuilder{ - {"post_date", ">", t.Format("2006-01-02 15:04:05")}, - {"post_status", "in", ""}, - {"post_type", "post"}, - }, "ID,post_title,post_password", nil, []any{"publish"}) - if err == sql.ErrNoRows { - err = nil - } - if err != nil { - return - } - prev, err := models.FirstOne[wp.Posts](ctx, models.SqlBuilder{ - {"post_date", "<", t.Format("2006-01-02 15:04:05")}, - {"post_status", "in", ""}, - {"post_type", "post"}, - }, "ID,post_title", models.SqlBuilder{{"post_date", "desc"}}, []any{"publish"}) - if err == sql.ErrNoRows { - err = nil - } - if err != nil { - return - } - r = PostContext{ - prev: prev, - next: next, - } - return -} - -func GetMonthPostIds(ctx context.Context, year, month string, page, limit int, order string) (r []wp.Posts, total int, err error) { - res, err := monthPostsCache.GetCache(ctx, fmt.Sprintf("%s%s", year, month), time.Second, ctx, year, month) - if err != nil { - return - } - if order == "desc" { - res = helper.SliceReverse(res) - } - total = len(res) - rr := helper.SlicePagination(res, page, limit) - r, err = GetPostsByIds(ctx, rr) - return -} - -func monthPost(args ...any) (r []uint64, err error) { - ctx := args[0].(context.Context) - year, month := args[1].(string), args[2].(string) - where := models.SqlBuilder{ - {"post_type", "in", ""}, - {"post_status", "in", ""}, - {"year(post_date)", year}, - {"month(post_date)", month}, - } - postType := []any{"post"} - status := []any{"publish"} - ids, err := models.Find[wp.Posts](ctx, where, "ID", "", models.SqlBuilder{{"Id", "asc"}}, nil, nil, 0, postType, status) - if err != nil { - return - } - for _, post := range ids { - r = append(r, post.Id) - } - return -} diff --git a/internal/actions/common/users.go b/internal/actions/common/users.go deleted file mode 100644 index 505083b..0000000 --- a/internal/actions/common/users.go +++ /dev/null @@ -1,35 +0,0 @@ -package common - -import ( - "context" - "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "time" -) - -func getUserById(a ...any) (r wp.Users, err error) { - ctx := a[0].(context.Context) - uid := a[1].(uint64) - r, err = models.FindOneById[wp.Users](ctx, uid) - return -} - -func GetUserByName(ctx context.Context, username string) (wp.Users, error) { - return usersNameCache.GetCache(ctx, username, time.Second, ctx, username) -} - -func getUserByName(a ...any) (r wp.Users, err error) { - u := a[1].(string) - ctx := a[0].(context.Context) - r, err = models.FirstOne[wp.Users](ctx, models.SqlBuilder{{ - "user_login", u, - }}, "*", nil) - return -} - -func GetUserById(ctx context.Context, uid uint64) wp.Users { - r, err := usersCache.GetCache(ctx, uid, time.Second, ctx, uid) - logs.ErrPrintln(err, "get user", uid) - return r -} diff --git a/internal/actions/detail.go b/internal/actions/detail.go index d02ef66..6f3b9c2 100644 --- a/internal/actions/detail.go +++ b/internal/actions/detail.go @@ -5,11 +5,11 @@ import ( "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/helper" - common2 "github/fthvgb1/wp-go/internal/actions/common" - "github/fthvgb1/wp-go/internal/wp" + "github/fthvgb1/wp-go/internal/cache" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/internal/plugins" "github/fthvgb1/wp-go/internal/wpconfig" "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/plugins" "math/rand" "net/http" "net/url" @@ -28,10 +28,10 @@ func Detail(c *gin.Context) { hh := detailHandler{ c, } - recent := common2.RecentPosts(c, 5) - archive := common2.Archives(c) - categoryItems := common2.Categories(c) - recentComments := common2.RecentComments(c, 5) + recent := cache.RecentPosts(c, 5) + archive := cache.Archives(c) + categoryItems := cache.Categories(c) + recentComments := cache.RecentComments(c, 5) var h = gin.H{ "title": wpconfig.Options.Value("blogname"), "options": wpconfig.Options, @@ -62,12 +62,12 @@ func Detail(c *gin.Context) { } } ID := uint64(Id) - maxId, err := common2.GetMaxPostId(c) + maxId, err := cache.GetMaxPostId(c) logs.ErrPrintln(err, "get max post id") if ID > maxId || err != nil { return } - post, err := common2.GetPostById(c, ID) + post, err := cache.GetPostById(c, ID) if post.Id == 0 || err != nil { return } @@ -76,10 +76,10 @@ func Detail(c *gin.Context) { if post.CommentCount > 0 || post.CommentStatus == "open" { showComment = true } - user := common2.GetUserById(c, post.PostAuthor) - common2.PasswordProjectTitle(&post) + user := cache.GetUserById(c, post.PostAuthor) + plugins.PasswordProjectTitle(&post) if post.PostPassword != "" && pw != post.PostPassword { - common2.PasswdProjectContent(&post) + plugins.PasswdProjectContent(&post) showComment = false } else if s, ok := commentCache.Get(c.Request.URL.RawQuery); ok && s != "" && (post.PostPassword == "" || post.PostPassword != "" && pw == post.PostPassword) { c.Writer.WriteHeader(http.StatusOK) @@ -89,10 +89,10 @@ func Detail(c *gin.Context) { return } plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post) - comments, err := common2.PostComments(c, post.Id) + comments, err := cache.PostComments(c, post.Id) logs.ErrPrintln(err, "get post comment", post.Id) commentss := treeComments(comments) - prev, next, err := common2.GetContextPost(c, post.Id, post.PostDate) + prev, next, err := cache.GetContextPost(c, post.Id, post.PostDate) logs.ErrPrintln(err, "get pre and next post", post.Id, post.PostDate) h["title"] = fmt.Sprintf("%s-%s", post.PostTitle, wpconfig.Options.Value("blogname")) h["post"] = post @@ -110,7 +110,7 @@ func Detail(c *gin.Context) { } type Comment struct { - wp.Comments + models.Comments Children []*Comment } @@ -177,10 +177,10 @@ func findComments(comments Comments) Comments { return r } -func treeComments(comments []wp.Comments) Comments { +func treeComments(comments []models.Comments) Comments { var r = map[uint64]*Comment{ 0: { - Comments: wp.Comments{}, + Comments: models.Comments{}, }, } var top []*Comment @@ -204,7 +204,7 @@ func treeComments(comments []wp.Comments) Comments { return top } -func (d detailHandler) formatLi(comments wp.Comments, depth int, eo, parent string) string { +func (d detailHandler) formatLi(comments models.Comments, depth int, eo, parent string) string { li := `
  • diff --git a/internal/actions/feed.go b/internal/actions/feed.go index 5f5fd1a..c028369 100644 --- a/internal/actions/feed.go +++ b/internal/actions/feed.go @@ -5,11 +5,12 @@ import ( "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/cache" "github/fthvgb1/wp-go/helper" - common2 "github/fthvgb1/wp-go/internal/actions/common" - wp2 "github/fthvgb1/wp-go/internal/wp" + cache2 "github/fthvgb1/wp-go/internal/cache" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/internal/plugins" "github/fthvgb1/wp-go/internal/wpconfig" "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/plugins" + "github/fthvgb1/wp-go/plugin/digest" "github/fthvgb1/wp-go/rss2" "net/http" "strconv" @@ -77,23 +78,23 @@ func Feed(c *gin.Context) { func feed(arg ...any) (xml []string, err error) { c := arg[0].(*gin.Context) - r := common2.RecentPosts(c, 10) - ids := helper.SliceMap(r, func(t wp2.Posts) uint64 { + r := cache2.RecentPosts(c, 10) + ids := helper.SliceMap(r, func(t models.Posts) uint64 { return t.Id }) - posts, err := common2.GetPostsByIds(c, ids) + posts, err := cache2.GetPostsByIds(c, ids) if err != nil { return } rs := templateRss rs.LastBuildDate = time.Now().Format(timeFormat) - rs.Items = helper.SliceMap(posts, func(t wp2.Posts) rss2.Item { + rs.Items = helper.SliceMap(posts, func(t models.Posts) rss2.Item { desc := "无法提供摘要。这是一篇受保护的文章。" - common2.PasswordProjectTitle(&t) + plugins.PasswordProjectTitle(&t) if t.PostPassword != "" { - common2.PasswdProjectContent(&t) + plugins.PasswdProjectContent(&t) } else { - desc = plugins.DigestRaw(t.PostContent, 55, fmt.Sprintf("/p/%d", t.Id)) + desc = digest.Raw(t.PostContent, 55, fmt.Sprintf("/p/%d", t.Id)) } l := "" if t.CommentStatus == "open" && t.CommentCount > 0 { @@ -101,7 +102,7 @@ func feed(arg ...any) (xml []string, err error) { } else if t.CommentStatus == "open" && t.CommentCount == 0 { l = fmt.Sprintf("%s/p/%d#respond", wpconfig.Options.Value("siteurl"), t.Id) } - user := common2.GetUserById(c, t.PostAuthor) + user := cache2.GetUserById(c, t.PostAuthor) return rss2.Item{ Title: t.PostTitle, @@ -157,17 +158,17 @@ func postFeed(arg ...any) (x string, err error) { } } ID := uint64(Id) - maxId, err := common2.GetMaxPostId(c) + maxId, err := cache2.GetMaxPostId(c) logs.ErrPrintln(err, "get max post id") if ID > maxId || err != nil { return } - post, err := common2.GetPostById(c, ID) + post, err := cache2.GetPostById(c, ID) if post.Id == 0 || err != nil { return } - common2.PasswordProjectTitle(&post) - comments, err := common2.PostComments(c, post.Id) + plugins.PasswordProjectTitle(&post) + comments, err := cache2.PostComments(c, post.Id) if err != nil { return } @@ -179,7 +180,7 @@ func postFeed(arg ...any) (x string, err error) { rs.LastBuildDate = time.Now().Format(timeFormat) if post.PostPassword != "" { if len(comments) > 0 { - common2.PasswdProjectContent(&post) + plugins.PasswdProjectContent(&post) t := comments[len(comments)-1] rs.Items = []rss2.Item{ { @@ -194,7 +195,7 @@ func postFeed(arg ...any) (x string, err error) { } } } else { - rs.Items = helper.SliceMap(comments, func(t wp2.Comments) rss2.Item { + rs.Items = helper.SliceMap(comments, func(t models.Comments) rss2.Item { return rss2.Item{ Title: fmt.Sprintf("评价者:%s", t.CommentAuthor), Link: fmt.Sprintf("%s/p/%d#comment-%d", wpconfig.Options.Value("siteurl"), post.Id, t.CommentId), @@ -227,27 +228,27 @@ func CommentsFeed(c *gin.Context) { func commentsFeed(args ...any) (r []string, err error) { c := args[0].(*gin.Context) - commens := common2.RecentComments(c, 10) + commens := cache2.RecentComments(c, 10) rs := templateRss rs.Title = fmt.Sprintf("\"%s\"的评论", wpconfig.Options.Value("blogname")) rs.LastBuildDate = time.Now().Format(timeFormat) rs.AtomLink = fmt.Sprintf("%s/comments/feed", wpconfig.Options.Value("siteurl")) - com, err := common2.GetCommentByIds(c, helper.SliceMap(commens, func(t wp2.Comments) uint64 { + com, err := cache2.GetCommentByIds(c, helper.SliceMap(commens, func(t models.Comments) uint64 { return t.CommentId })) if nil != err { return []string{}, err } - rs.Items = helper.SliceMap(com, func(t wp2.Comments) rss2.Item { - post, _ := common2.GetPostById(c, t.CommentPostId) - common2.PasswordProjectTitle(&post) + rs.Items = helper.SliceMap(com, func(t models.Comments) rss2.Item { + post, _ := cache2.GetPostById(c, t.CommentPostId) + plugins.PasswordProjectTitle(&post) desc := "评论受保护:要查看请输入密码。" content := t.CommentContent if post.PostPassword != "" { - common2.PasswdProjectContent(&post) + plugins.PasswdProjectContent(&post) content = post.PostContent } else { - desc = plugins.ClearHtml(t.CommentContent) + desc = digest.ClearHtml(t.CommentContent) content = desc } return rss2.Item{ diff --git a/internal/actions/index.go b/internal/actions/index.go index 5c7c9be..b7b539d 100644 --- a/internal/actions/index.go +++ b/internal/actions/index.go @@ -5,11 +5,12 @@ import ( "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/helper" - common2 "github/fthvgb1/wp-go/internal/actions/common" - "github/fthvgb1/wp-go/internal/wp" + "github/fthvgb1/wp-go/internal/cache" + dao "github/fthvgb1/wp-go/internal/dao" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/internal/plugins" "github/fthvgb1/wp-go/internal/wpconfig" - "github/fthvgb1/wp-go/models" - "github/fthvgb1/wp-go/plugins" + "github/fthvgb1/wp-go/model" "math" "net/http" "regexp" @@ -31,10 +32,10 @@ type indexHandle struct { totalPage int category string categoryType string - where models.SqlBuilder + where model.SqlBuilder orderBy string order string - join models.SqlBuilder + join model.SqlBuilder postType []any status []any header string @@ -53,12 +54,12 @@ func newIndexHandle(ctx *gin.Context) *indexHandle { paginationStep: 1, titleL: wpconfig.Options.Value("blogname"), titleR: wpconfig.Options.Value("blogdescription"), - where: models.SqlBuilder{ + where: model.SqlBuilder{ {"post_type", "in", ""}, {"post_status", "in", ""}, }, orderBy: "post_date", - join: models.SqlBuilder{}, + join: model.SqlBuilder{}, postType: []any{"post"}, status: []any{"publish"}, scene: plugins.Home, @@ -113,7 +114,7 @@ func (h *indexHandle) parseParams() (err error) { h.category = category username := h.c.Param("author") if username != "" { - user, er := common2.GetUserByName(h.c, username) + user, er := cache.GetUserByName(h.c, username) if er != nil { err = er return @@ -160,7 +161,7 @@ func (h *indexHandle) parseParams() (err error) { h.page = pa } } - total := int(atomic.LoadInt64(&common2.TotalRaw)) + total := int(atomic.LoadInt64(&dao.TotalRaw)) if total > 0 && total < (h.page-1)*h.pageSize { h.page = 1 } @@ -177,13 +178,13 @@ func (h *indexHandle) getTotalPage(totalRaws int) int { func Index(c *gin.Context) { h := newIndexHandle(c) - var postIds []wp.Posts + var postIds []models.Posts var totalRaw int var err error - archive := common2.Archives(c) - recent := common2.RecentPosts(c, 5) - categoryItems := common2.Categories(c) - recentComments := common2.RecentComments(c, 5) + archive := cache.Archives(c) + recent := cache.RecentPosts(c, 5) + categoryItems := cache.Categories(c) + recentComments := cache.RecentComments(c, 5) ginH := gin.H{ "options": wpconfig.Options, "recentPosts": recent, @@ -208,14 +209,14 @@ func Index(c *gin.Context) { } ginH["title"] = h.getTitle() if c.Param("month") != "" { - postIds, totalRaw, err = common2.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order) + postIds, totalRaw, err = cache.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order) if err != nil { return } } else if h.search != "" { - postIds, totalRaw, err = common2.SearchPost(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, models.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status) + postIds, totalRaw, err = cache.SearchPost(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status) } else { - postIds, totalRaw, err = common2.PostLists(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, models.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status) + postIds, totalRaw, err = cache.PostLists(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status) } if err != nil { return @@ -227,16 +228,16 @@ func Index(c *gin.Context) { pw := h.session.Get("post_password") plug := plugins.NewPostPlugin(c, h.scene) for i, post := range postIds { - common2.PasswordProjectTitle(&postIds[i]) + plugins.PasswordProjectTitle(&postIds[i]) if post.PostPassword != "" && pw != post.PostPassword { - common2.PasswdProjectContent(&postIds[i]) + plugins.PasswdProjectContent(&postIds[i]) } else { plugins.ApplyPlugin(plug, &postIds[i]) } } for i, post := range recent { if post.PostPassword != "" && pw != post.PostPassword { - common2.PasswdProjectContent(&recent[i]) + plugins.PasswdProjectContent(&recent[i]) } } q := c.Request.URL.Query().Encode() diff --git a/internal/cache/cache.go b/internal/cache/cache.go new file mode 100644 index 0000000..7ca22bc --- /dev/null +++ b/internal/cache/cache.go @@ -0,0 +1,124 @@ +package cache + +import ( + "context" + "github/fthvgb1/wp-go/cache" + "github/fthvgb1/wp-go/internal/config" + dao "github/fthvgb1/wp-go/internal/dao" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/logs" + "sync" + "time" +) + +var postContextCache *cache.MapCache[uint64, dao.PostContext] +var archivesCaches *Arch +var categoryCaches *cache.SliceCache[models.TermsMy] +var recentPostsCaches *cache.SliceCache[models.Posts] +var recentCommentsCaches *cache.SliceCache[models.Comments] +var postCommentCaches *cache.MapCache[uint64, []uint64] +var postsCache *cache.MapCache[uint64, models.Posts] + +var postMetaCache *cache.MapCache[uint64, map[string]any] + +var monthPostsCache *cache.MapCache[string, []uint64] +var postListIdsCache *cache.MapCache[string, dao.PostIds] +var searchPostIdsCache *cache.MapCache[string, dao.PostIds] +var maxPostIdCache *cache.SliceCache[uint64] + +var usersCache *cache.MapCache[uint64, models.Users] +var usersNameCache *cache.MapCache[string, models.Users] +var commentsCache *cache.MapCache[uint64, models.Comments] + +func InitActionsCommonCache() { + c := config.Conf.Load() + archivesCaches = &Arch{ + mutex: &sync.Mutex{}, + setCacheFunc: dao.Archives, + } + + searchPostIdsCache = cache.NewMapCacheByFn[string, dao.PostIds](dao.SearchPostIds, c.SearchPostCacheTime) + + postListIdsCache = cache.NewMapCacheByFn[string, dao.PostIds](dao.SearchPostIds, c.PostListCacheTime) + + monthPostsCache = cache.NewMapCacheByFn[string, []uint64](dao.MonthPost, c.MonthPostCacheTime) + + postContextCache = cache.NewMapCacheByFn[uint64, dao.PostContext](dao.GetPostContext, c.ContextPostCacheTime) + + postsCache = cache.NewMapCacheByBatchFn[uint64, models.Posts](dao.GetPostsByIds, c.PostDataCacheTime) + + postMetaCache = cache.NewMapCacheByBatchFn[uint64, map[string]any](dao.GetPostMetaByPostIds, c.PostDataCacheTime) + + categoryCaches = cache.NewSliceCache[models.TermsMy](dao.Categories, c.CategoryCacheTime) + + recentPostsCaches = cache.NewSliceCache[models.Posts](dao.RecentPosts, c.RecentPostCacheTime) + + recentCommentsCaches = cache.NewSliceCache[models.Comments](dao.RecentComments, c.RecentCommentsCacheTime) + + postCommentCaches = cache.NewMapCacheByFn[uint64, []uint64](dao.PostComments, c.PostCommentsCacheTime) + + maxPostIdCache = cache.NewSliceCache[uint64](dao.GetMaxPostId, c.MaxPostIdCacheTime) + + usersCache = cache.NewMapCacheByFn[uint64, models.Users](dao.GetUserById, c.UserInfoCacheTime) + + usersNameCache = cache.NewMapCacheByFn[string, models.Users](dao.GetUserByName, c.UserInfoCacheTime) + + commentsCache = cache.NewMapCacheByBatchFn[uint64, models.Comments](dao.GetCommentByIds, c.CommentsCacheTime) +} + +func ClearCache() { + searchPostIdsCache.ClearExpired() + postsCache.ClearExpired() + postMetaCache.ClearExpired() + postListIdsCache.ClearExpired() + monthPostsCache.ClearExpired() + postContextCache.ClearExpired() + usersCache.ClearExpired() + commentsCache.ClearExpired() + usersNameCache.ClearExpired() +} +func FlushCache() { + searchPostIdsCache.Flush() + postsCache.Flush() + postMetaCache.Flush() + postListIdsCache.Flush() + monthPostsCache.Flush() + postContextCache.Flush() + usersCache.Flush() + commentsCache.Flush() + usersCache.Flush() +} + +func Archives(ctx context.Context) (r []models.PostArchive) { + return archivesCaches.getArchiveCache(ctx) +} + +type Arch struct { + data []models.PostArchive + mutex *sync.Mutex + setCacheFunc func(context.Context) ([]models.PostArchive, error) + month time.Month +} + +func (c *Arch) getArchiveCache(ctx context.Context) []models.PostArchive { + l := len(c.data) + m := time.Now().Month() + if l > 0 && c.month != m || l < 1 { + r, err := c.setCacheFunc(ctx) + if err != nil { + logs.ErrPrintln(err, "set cache err[%s]") + return nil + } + c.mutex.Lock() + defer c.mutex.Unlock() + c.month = m + c.data = r + } + return c.data +} + +func Categories(ctx context.Context) []models.TermsMy { + r, err := categoryCaches.GetCache(ctx, time.Second, ctx) + logs.ErrPrintln(err, "get category ") + return r +} diff --git a/internal/cache/comments.go b/internal/cache/comments.go new file mode 100644 index 0000000..06fd0c4 --- /dev/null +++ b/internal/cache/comments.go @@ -0,0 +1,33 @@ +package cache + +import ( + "context" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/logs" + "time" +) + +func RecentComments(ctx context.Context, n int) (r []models.Comments) { + r, err := recentCommentsCaches.GetCache(ctx, time.Second, ctx) + if len(r) > n { + r = r[0:n] + } + logs.ErrPrintln(err, "get recent comment") + return +} + +func PostComments(ctx context.Context, Id uint64) ([]models.Comments, error) { + ids, err := postCommentCaches.GetCache(ctx, Id, time.Second, ctx, Id) + if err != nil { + return nil, err + } + return GetCommentByIds(ctx, ids) +} + +func GetCommentById(ctx context.Context, id uint64) (models.Comments, error) { + return commentsCache.GetCache(ctx, id, time.Second, ctx, id) +} + +func GetCommentByIds(ctx context.Context, ids []uint64) ([]models.Comments, error) { + return commentsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids) +} diff --git a/internal/actions/common/postmeta.go b/internal/cache/postmeta.go similarity index 54% rename from internal/actions/common/postmeta.go rename to internal/cache/postmeta.go index 7657a36..faa0ae0 100644 --- a/internal/actions/common/postmeta.go +++ b/internal/cache/postmeta.go @@ -1,12 +1,9 @@ -package common +package cache import ( "context" - "github.com/leeqvip/gophp" "github/fthvgb1/wp-go/helper" - wp2 "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" + wp2 "github/fthvgb1/wp-go/internal/models" "strconv" "time" ) @@ -59,35 +56,3 @@ func ToPostThumbnail(c context.Context, postId uint64) (r wp2.PostThumbnail) { } return } - -func getPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error) { - r = make(map[uint64]map[string]any) - ctx := args[0].(context.Context) - ids := args[1].([]uint64) - rr, err := models.Find[wp2.Postmeta](ctx, models.SqlBuilder{ - {"post_id", "in", ""}, - }, "*", "", nil, nil, nil, 0, helper.SliceMap(ids, helper.ToAny[uint64])) - if err != nil { - return - } - for _, postmeta := range rr { - if _, ok := r[postmeta.PostId]; !ok { - r[postmeta.PostId] = make(map[string]any) - } - if postmeta.MetaKey == "_wp_attachment_metadata" { - meta, err := gophp.Unserialize([]byte(postmeta.MetaValue)) - if err != nil { - logs.ErrPrintln(err, "反序列化postmeta失败", postmeta.MetaValue) - continue - } - metaVal, ok := meta.(map[string]any) - if ok { - r[postmeta.PostId][postmeta.MetaKey] = metaVal - } - } else { - r[postmeta.PostId][postmeta.MetaKey] = postmeta.MetaValue - } - - } - return -} diff --git a/internal/cache/posts.go b/internal/cache/posts.go new file mode 100644 index 0000000..b85299b --- /dev/null +++ b/internal/cache/posts.go @@ -0,0 +1,77 @@ +package cache + +import ( + "context" + "fmt" + "github.com/gin-gonic/gin" + "github/fthvgb1/wp-go/helper" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/logs" + "time" +) + +func GetPostById(ctx context.Context, id uint64) (models.Posts, error) { + return postsCache.GetCache(ctx, id, time.Second, ctx, id) +} + +func GetPostsByIds(ctx context.Context, ids []uint64) ([]models.Posts, error) { + return postsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids) +} + +func SearchPost(ctx context.Context, key string, args ...any) (r []models.Posts, total int, err error) { + ids, err := searchPostIdsCache.GetCache(ctx, key, time.Second, args...) + if err != nil { + return + } + total = ids.Length + r, err = GetPostsByIds(ctx, ids.Ids) + return +} + +func PostLists(ctx context.Context, key string, args ...any) (r []models.Posts, total int, err error) { + ids, err := postListIdsCache.GetCache(ctx, key, time.Second, args...) + if err != nil { + return + } + total = ids.Length + r, err = GetPostsByIds(ctx, ids.Ids) + return +} + +func GetMaxPostId(ctx *gin.Context) (uint64, error) { + Id, err := maxPostIdCache.GetCache(ctx, time.Second, ctx) + return Id[0], err +} + +func RecentPosts(ctx context.Context, n int) (r []models.Posts) { + r, err := recentPostsCaches.GetCache(ctx, time.Second, ctx) + if n < len(r) { + r = r[:n] + } + logs.ErrPrintln(err, "get recent post") + return +} + +func GetContextPost(ctx context.Context, id uint64, date time.Time) (prev, next models.Posts, err error) { + postCtx, err := postContextCache.GetCache(ctx, id, time.Second, ctx, date) + if err != nil { + return models.Posts{}, models.Posts{}, err + } + prev = postCtx.Prev + next = postCtx.Next + return +} + +func GetMonthPostIds(ctx context.Context, year, month string, page, limit int, order string) (r []models.Posts, total int, err error) { + res, err := monthPostsCache.GetCache(ctx, fmt.Sprintf("%s%s", year, month), time.Second, ctx, year, month) + if err != nil { + return + } + if order == "desc" { + res = helper.SliceReverse(res) + } + total = len(res) + rr := helper.SlicePagination(res, page, limit) + r, err = GetPostsByIds(ctx, rr) + return +} diff --git a/internal/cache/users.go b/internal/cache/users.go new file mode 100644 index 0000000..f7f9b5f --- /dev/null +++ b/internal/cache/users.go @@ -0,0 +1,26 @@ +package cache + +import ( + "context" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/logs" + "github/fthvgb1/wp-go/model" + "time" +) + +func getUserById(a ...any) (r models.Users, err error) { + ctx := a[0].(context.Context) + uid := a[1].(uint64) + r, err = model.FindOneById[models.Users](ctx, uid) + return +} + +func GetUserByName(ctx context.Context, username string) (models.Users, error) { + return usersNameCache.GetCache(ctx, username, time.Second, ctx, username) +} + +func GetUserById(ctx context.Context, uid uint64) models.Users { + r, err := usersCache.GetCache(ctx, uid, time.Second, ctx, uid) + logs.ErrPrintln(err, "get user", uid) + return r +} diff --git a/config/config.go b/internal/config/config.go similarity index 100% rename from config/config.go rename to internal/config/config.go diff --git a/internal/dao/comments.go b/internal/dao/comments.go new file mode 100644 index 0000000..cc9e975 --- /dev/null +++ b/internal/dao/comments.go @@ -0,0 +1,57 @@ +package common + +import ( + "context" + "github/fthvgb1/wp-go/helper" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/model" + "strconv" +) + +// RecentComments +// param context.Context +func RecentComments(a ...any) (r []models.Comments, err error) { + ctx := a[0].(context.Context) + return model.Find[models.Comments](ctx, model.SqlBuilder{ + {"comment_approved", "1"}, + {"post_status", "publish"}, + }, "comment_ID,comment_author,comment_post_ID,post_title", "", model.SqlBuilder{{"comment_date_gmt", "desc"}}, model.SqlBuilder{ + {"a", "left join", "wp_posts b", "a.comment_post_ID=b.ID"}, + }, nil, 10) +} + +// PostComments +// param1 context.Context +// param2 postId +func PostComments(args ...any) ([]uint64, error) { + ctx := args[0].(context.Context) + postId := args[1].(uint64) + r, err := model.Find[models.Comments](ctx, model.SqlBuilder{ + {"comment_approved", "1"}, + {"comment_post_ID", "=", strconv.FormatUint(postId, 10), "int"}, + }, "comment_ID", "", model.SqlBuilder{ + {"comment_date_gmt", "asc"}, + {"comment_ID", "asc"}, + }, nil, nil, 0) + if err != nil { + return nil, err + } + return helper.SliceMap(r, func(t models.Comments) uint64 { + return t.CommentId + }), err +} + +func GetCommentByIds(args ...any) (map[uint64]models.Comments, error) { + ctx := args[0].(context.Context) + ids := args[1].([]uint64) + m := make(map[uint64]models.Comments) + r, err := model.SimpleFind[models.Comments](ctx, model.SqlBuilder{ + {"comment_ID", "in", ""}, {"comment_approved", "1"}, + }, "*", helper.SliceMap(ids, helper.ToAny[uint64])) + if err != nil { + return m, err + } + return helper.SimpleSliceToMap(r, func(t models.Comments) uint64 { + return t.CommentId + }), err +} diff --git a/internal/dao/common.go b/internal/dao/common.go new file mode 100644 index 0000000..f43d8ec --- /dev/null +++ b/internal/dao/common.go @@ -0,0 +1,55 @@ +package common + +import ( + "context" + "fmt" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/internal/wpconfig" + "github/fthvgb1/wp-go/model" +) + +var TotalRaw int64 + +type PostIds struct { + Ids []uint64 + Length int +} + +type PostContext struct { + Prev models.Posts + Next models.Posts +} + +func PasswordProjectTitle(post *models.Posts) { + if post.PostPassword != "" { + post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle) + } +} + +func Categories(a ...any) (terms []models.TermsMy, err error) { + ctx := a[0].(context.Context) + var in = []any{"category"} + terms, err = model.Find[models.TermsMy](ctx, model.SqlBuilder{ + {"tt.count", ">", "0", "int"}, + {"tt.taxonomy", "in", ""}, + }, "t.term_id", "", model.SqlBuilder{ + {"t.name", "asc"}, + }, model.SqlBuilder{ + {"t", "inner join", "wp_term_taxonomy tt", "t.term_id = tt.term_id"}, + }, nil, 0, in) + for i := 0; i < len(terms); i++ { + if v, ok := wpconfig.Terms.Load(terms[i].Terms.TermId); ok { + terms[i].Terms = v + } + if v, ok := wpconfig.TermTaxonomies.Load(terms[i].Terms.TermId); ok { + terms[i].TermTaxonomy = v + } + } + return +} + +func Archives(ctx context.Context) ([]models.PostArchive, error) { + return model.Find[models.PostArchive](ctx, model.SqlBuilder{ + {"post_type", "post"}, {"post_status", "publish"}, + }, "YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts", "year,month", model.SqlBuilder{{"year", "desc"}, {"month", "desc"}}, nil, nil, 0) +} diff --git a/internal/dao/postmeta.go b/internal/dao/postmeta.go new file mode 100644 index 0000000..1995f52 --- /dev/null +++ b/internal/dao/postmeta.go @@ -0,0 +1,85 @@ +package common + +import ( + "context" + "github.com/leeqvip/gophp" + "github/fthvgb1/wp-go/helper" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/logs" + "github/fthvgb1/wp-go/model" + "strconv" +) + +func GetPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error) { + r = make(map[uint64]map[string]any) + ctx := args[0].(context.Context) + ids := args[1].([]uint64) + rr, err := model.Find[models.Postmeta](ctx, model.SqlBuilder{ + {"post_id", "in", ""}, + }, "*", "", nil, nil, nil, 0, helper.SliceMap(ids, helper.ToAny[uint64])) + if err != nil { + return + } + for _, postmeta := range rr { + if _, ok := r[postmeta.PostId]; !ok { + r[postmeta.PostId] = make(map[string]any) + } + if postmeta.MetaKey == "_wp_attachment_metadata" { + meta, err := gophp.Unserialize([]byte(postmeta.MetaValue)) + if err != nil { + logs.ErrPrintln(err, "反序列化postmeta失败", postmeta.MetaValue) + continue + } + metaVal, ok := meta.(map[string]any) + if ok { + r[postmeta.PostId][postmeta.MetaKey] = metaVal + } + } else { + r[postmeta.PostId][postmeta.MetaKey] = postmeta.MetaValue + } + + } + return +} + +func ToPostThumb(c context.Context, meta map[string]any, postId uint64) (r models.PostThumbnail) { + if meta != nil { + m, ok := meta["_thumbnail_id"] + if ok { + id, err := strconv.ParseUint(m.(string), 10, 64) + if err == nil { + mx, err := GetPostMetaByPostIds(c, []uint64{id}) + if err == nil && mx != nil { + mm, ok := mx[id] + if ok && mm != nil { + f, ok := mm["_wp_attached_file"] + if ok { + ff, ok := f.(string) + if ok && ff != "" { + r.Path = ff + } + } + tt, ok := helper.GetStrMapAnyVal[map[string]any]("_wp_attachment_metadata.sizes.post-thumbnail", mm) + if ok && tt != nil { + width, ok := tt["width"] + if ok { + w, ok := width.(int) + if ok { + r.Width = w + } + } + height, ok := tt["height"] + if ok { + h, ok := height.(int) + if ok { + r.Height = h + } + } + } + } + } + } + } + } + return +} diff --git a/internal/dao/posts.go b/internal/dao/posts.go new file mode 100644 index 0000000..d6cfb69 --- /dev/null +++ b/internal/dao/posts.go @@ -0,0 +1,169 @@ +package common + +import ( + "context" + "database/sql" + "fmt" + "github/fthvgb1/wp-go/helper" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/model" + "strings" + "sync/atomic" + "time" +) + +func GetPostsByIds(ids ...any) (m map[uint64]models.Posts, err error) { + ctx := ids[0].(context.Context) + m = make(map[uint64]models.Posts) + id := ids[1].([]uint64) + arg := helper.SliceMap(id, helper.ToAny[uint64]) + rawPosts, err := model.Find[models.Posts](ctx, model.SqlBuilder{{ + "Id", "in", "", + }}, "a.*,ifnull(d.name,'') category_name,ifnull(taxonomy,'') `taxonomy`", "", nil, model.SqlBuilder{{ + "a", "left join", "wp_term_relationships b", "a.Id=b.object_id", + }, { + "left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", + }, { + "left join", "wp_terms d", "c.term_id=d.term_id", + }}, nil, 0, arg) + if err != nil { + return m, err + } + postsMap := make(map[uint64]models.Posts) + for i, post := range rawPosts { + v, ok := postsMap[post.Id] + if !ok { + v = rawPosts[i] + } + if post.Taxonomy == "category" { + v.Categories = append(v.Categories, post.CategoryName) + } else if post.Taxonomy == "post_tag" { + v.Tags = append(v.Tags, post.CategoryName) + } + postsMap[post.Id] = v + } + meta, _ := GetPostMetaByPostIds(ctx, id) + for k, pp := range postsMap { + if len(pp.Categories) > 0 { + t := make([]string, 0, len(pp.Categories)) + for _, cat := range pp.Categories { + t = append(t, fmt.Sprintf(`%s`, cat, cat)) + } + pp.CategoriesHtml = strings.Join(t, "、") + mm, ok := meta[pp.Id] + if ok { + thumb := ToPostThumb(ctx, mm, pp.Id) + if thumb.Path != "" { + pp.Thumbnail = thumb + } + } + } + if len(pp.Tags) > 0 { + t := make([]string, 0, len(pp.Tags)) + for _, cat := range pp.Tags { + t = append(t, fmt.Sprintf(``, cat, cat)) + } + pp.TagsHtml = strings.Join(t, "、") + } + m[k] = pp + } + return +} + +func SearchPostIds(args ...any) (ids PostIds, err error) { + ctx := args[0].(context.Context) + where := args[1].(model.SqlBuilder) + page := args[2].(int) + limit := args[3].(int) + order := args[4].(model.SqlBuilder) + join := args[5].(model.SqlBuilder) + postType := args[6].([]any) + postStatus := args[7].([]any) + res, total, err := model.SimplePagination[models.Posts](ctx, where, "ID", "", page, limit, order, join, nil, postType, postStatus) + for _, posts := range res { + ids.Ids = append(ids.Ids, posts.Id) + } + ids.Length = total + totalR := int(atomic.LoadInt64(&TotalRaw)) + if total > totalR { + tt := int64(total) + atomic.StoreInt64(&TotalRaw, tt) + } + return +} + +func GetMaxPostId(a ...any) ([]uint64, error) { + ctx := a[0].(context.Context) + r, err := model.SimpleFind[models.Posts](ctx, model.SqlBuilder{{"post_type", "post"}, {"post_status", "publish"}}, "max(ID) ID") + var id uint64 + if len(r) > 0 { + id = r[0].Id + } + return []uint64{id}, err +} + +func RecentPosts(a ...any) (r []models.Posts, err error) { + ctx := a[0].(context.Context) + r, err = model.Find[models.Posts](ctx, model.SqlBuilder{{ + "post_type", "post", + }, {"post_status", "publish"}}, "ID,post_title,post_password", "", model.SqlBuilder{{"post_date", "desc"}}, nil, nil, 10) + for i, post := range r { + if post.PostPassword != "" { + PasswordProjectTitle(&r[i]) + } + } + return +} + +func GetPostContext(arg ...any) (r PostContext, err error) { + ctx := arg[0].(context.Context) + t := arg[1].(time.Time) + next, err := model.FirstOne[models.Posts](ctx, model.SqlBuilder{ + {"post_date", ">", t.Format("2006-01-02 15:04:05")}, + {"post_status", "in", ""}, + {"post_type", "post"}, + }, "ID,post_title,post_password", nil, []any{"publish"}) + if err == sql.ErrNoRows { + err = nil + } + if err != nil { + return + } + prev, err := model.FirstOne[models.Posts](ctx, model.SqlBuilder{ + {"post_date", "<", t.Format("2006-01-02 15:04:05")}, + {"post_status", "in", ""}, + {"post_type", "post"}, + }, "ID,post_title", model.SqlBuilder{{"post_date", "desc"}}, []any{"publish"}) + if err == sql.ErrNoRows { + err = nil + } + if err != nil { + return + } + r = PostContext{ + Prev: prev, + Next: next, + } + return +} + +func MonthPost(args ...any) (r []uint64, err error) { + ctx := args[0].(context.Context) + year, month := args[1].(string), args[2].(string) + where := model.SqlBuilder{ + {"post_type", "in", ""}, + {"post_status", "in", ""}, + {"year(post_date)", year}, + {"month(post_date)", month}, + } + postType := []any{"post"} + status := []any{"publish"} + ids, err := model.Find[models.Posts](ctx, where, "ID", "", model.SqlBuilder{{"Id", "asc"}}, nil, nil, 0, postType, status) + if err != nil { + return + } + for _, post := range ids { + r = append(r, post.Id) + } + return +} diff --git a/internal/dao/users.go b/internal/dao/users.go new file mode 100644 index 0000000..93e8249 --- /dev/null +++ b/internal/dao/users.go @@ -0,0 +1,23 @@ +package common + +import ( + "context" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/model" +) + +func GetUserById(a ...any) (r models.Users, err error) { + ctx := a[0].(context.Context) + uid := a[1].(uint64) + r, err = model.FindOneById[models.Users](ctx, uid) + return +} + +func GetUserByName(a ...any) (r models.Users, err error) { + u := a[1].(string) + ctx := a[0].(context.Context) + r, err = model.FirstOne[models.Users](ctx, model.SqlBuilder{{ + "user_login", u, + }}, "*", nil) + return +} diff --git a/db/db.go b/internal/db/db.go similarity index 97% rename from db/db.go rename to internal/db/db.go index 2e92206..0eb5f98 100644 --- a/db/db.go +++ b/internal/db/db.go @@ -5,7 +5,7 @@ import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" - "github/fthvgb1/wp-go/config" + "github/fthvgb1/wp-go/internal/config" "log" "os" "strconv" diff --git a/internal/middleware/sendmail.go b/internal/middleware/sendmail.go index ea8266e..884c256 100644 --- a/internal/middleware/sendmail.go +++ b/internal/middleware/sendmail.go @@ -4,7 +4,7 @@ import ( "bytes" "fmt" "github.com/gin-gonic/gin" - "github/fthvgb1/wp-go/config" + "github/fthvgb1/wp-go/internal/config" "github/fthvgb1/wp-go/internal/wpconfig" "github/fthvgb1/wp-go/logs" "github/fthvgb1/wp-go/mail" diff --git a/internal/middleware/validateservername.go b/internal/middleware/validateservername.go index 3c5c726..2d56966 100644 --- a/internal/middleware/validateservername.go +++ b/internal/middleware/validateservername.go @@ -2,7 +2,7 @@ package middleware import ( "github.com/gin-gonic/gin" - "github/fthvgb1/wp-go/config" + "github/fthvgb1/wp-go/internal/config" "github/fthvgb1/wp-go/safety" "net/http" "strings" diff --git a/internal/wp/wp_comments.go b/internal/models/wp_comments.go similarity index 99% rename from internal/wp/wp_comments.go rename to internal/models/wp_comments.go index 654db8d..9ef96e0 100644 --- a/internal/wp/wp_comments.go +++ b/internal/models/wp_comments.go @@ -1,4 +1,4 @@ -package wp +package models import "time" diff --git a/internal/wp/wp_options.go b/internal/models/wp_options.go similarity index 97% rename from internal/wp/wp_options.go rename to internal/models/wp_options.go index f5afa8b..2065636 100644 --- a/internal/wp/wp_options.go +++ b/internal/models/wp_options.go @@ -1,4 +1,4 @@ -package wp +package models type Options struct { OptionId uint64 `gorm:"column:option_id" db:"option_id" json:"option_id" form:"option_id"` diff --git a/internal/wp/wp_postmeta.go b/internal/models/wp_postmeta.go similarity index 96% rename from internal/wp/wp_postmeta.go rename to internal/models/wp_postmeta.go index 81fca8d..e0d6d32 100644 --- a/internal/wp/wp_postmeta.go +++ b/internal/models/wp_postmeta.go @@ -1,4 +1,4 @@ -package wp +package models type Postmeta struct { MetaId uint64 `db:"meta_id" json:"meta_id" form:"meta_id"` diff --git a/internal/wp/wp_posts.go b/internal/models/wp_posts.go similarity index 99% rename from internal/wp/wp_posts.go rename to internal/models/wp_posts.go index 33adf75..fff597b 100644 --- a/internal/wp/wp_posts.go +++ b/internal/models/wp_posts.go @@ -1,4 +1,4 @@ -package wp +package models import "time" diff --git a/internal/wp/wp_term_taxonomy.go b/internal/models/wp_term_taxonomy.go similarity index 98% rename from internal/wp/wp_term_taxonomy.go rename to internal/models/wp_term_taxonomy.go index c388337..23d8458 100644 --- a/internal/wp/wp_term_taxonomy.go +++ b/internal/models/wp_term_taxonomy.go @@ -1,4 +1,4 @@ -package wp +package models type TermTaxonomy struct { TermTaxonomyId uint64 `gorm:"column:term_taxonomy_id" db:"term_taxonomy_id" json:"term_taxonomy_id" form:"term_taxonomy_id"` diff --git a/internal/wp/wp_terms.go b/internal/models/wp_terms.go similarity index 97% rename from internal/wp/wp_terms.go rename to internal/models/wp_terms.go index 8e0334b..eb8a22b 100644 --- a/internal/wp/wp_terms.go +++ b/internal/models/wp_terms.go @@ -1,4 +1,4 @@ -package wp +package models type Terms struct { TermId uint64 `gorm:"column:term_id" db:"term_id" json:"term_id" form:"term_id"` diff --git a/internal/wp/wp_users.go b/internal/models/wp_users.go similarity index 98% rename from internal/wp/wp_users.go rename to internal/models/wp_users.go index 35e4cbb..61a4d69 100644 --- a/internal/wp/wp_users.go +++ b/internal/models/wp_users.go @@ -1,4 +1,4 @@ -package wp +package models import "time" diff --git a/internal/plugins/digest.go b/internal/plugins/digest.go new file mode 100644 index 0000000..1cc88ec --- /dev/null +++ b/internal/plugins/digest.go @@ -0,0 +1,55 @@ +package plugins + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github/fthvgb1/wp-go/cache" + "github/fthvgb1/wp-go/internal/config" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/plugin/digest" + "strings" + "time" +) + +var digestCache *cache.MapCache[uint64, string] + +func InitDigestCache() { + digestCache = cache.NewMapCacheByFn[uint64](digestRaw, config.Conf.Load().DigestCacheTime) +} + +func ClearDigestCache() { + digestCache.ClearExpired() +} +func FlushCache() { + digestCache.Flush() +} + +func digestRaw(arg ...any) (string, error) { + str := arg[0].(string) + id := arg[1].(uint64) + limit := config.Conf.Load().DigestWordCount + if limit < 0 { + return str, nil + } else if limit == 0 { + return "", nil + } + return digest.Raw(str, limit, fmt.Sprintf("/p/%d", id)), nil +} + +func Digest(p *Plugin[models.Posts], c *gin.Context, post *models.Posts, scene uint) { + if scene == Detail { + return + } + if post.PostExcerpt != "" { + post.PostContent = strings.Replace(post.PostExcerpt, "\n", "
    ", -1) + } else { + post.PostContent = DigestCache(c, post.Id, post.PostContent) + + } + p.Next() +} + +func DigestCache(ctx *gin.Context, id uint64, str string) string { + content, _ := digestCache.GetCache(ctx, id, time.Second, str, id) + return content +} diff --git a/plugins/plugins.go b/internal/plugins/plugins.go similarity index 65% rename from plugins/plugins.go rename to internal/plugins/plugins.go index aede422..30a7aff 100644 --- a/plugins/plugins.go +++ b/internal/plugins/plugins.go @@ -12,21 +12,21 @@ const ( Detail ) -type PluginFunc[T any] func(*Plugin[T], *gin.Context, *T, uint) +type Func[T any] func(*Plugin[T], *gin.Context, *T, uint) type Plugin[T any] struct { - calls []PluginFunc[T] + calls []Func[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] { +func NewPlugin[T any](calls []Func[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]) { +func (p *Plugin[T]) Push(call ...Func[T]) { p.calls = append(p.calls, call...) } diff --git a/internal/plugins/posts.go b/internal/plugins/posts.go new file mode 100644 index 0000000..0004e45 --- /dev/null +++ b/internal/plugins/posts.go @@ -0,0 +1,36 @@ +package plugins + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github/fthvgb1/wp-go/internal/models" +) + +func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[models.Posts] { + p := NewPlugin[models.Posts](nil, -1, nil, scene, ctx) + p.Push(Digest) + return p +} + +func ApplyPlugin(p *Plugin[models.Posts], post *models.Posts) { + p.post = post + p.Next() + p.index = -1 +} + +func PasswordProjectTitle(post *models.Posts) { + if post.PostPassword != "" { + post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle) + } +} + +func PasswdProjectContent(post *models.Posts) { + if post.PostContent != "" { + format := ` +
    +

    此内容受密码保护。如需查阅,请在下列字段中输入您的密码。

    +

    +
    ` + post.PostContent = fmt.Sprintf(format, post.Id, post.Id) + } +} diff --git a/internal/route/route.go b/internal/route/route.go index 8829efc..50e2744 100644 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -6,8 +6,8 @@ import ( "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" - "github/fthvgb1/wp-go/config" actions2 "github/fthvgb1/wp-go/internal/actions" + "github/fthvgb1/wp-go/internal/config" middleware2 "github/fthvgb1/wp-go/internal/middleware" "github/fthvgb1/wp-go/internal/static" "github/fthvgb1/wp-go/internal/templates" diff --git a/internal/wpconfig/options.go b/internal/wpconfig/options.go index 8f995dc..4ec373c 100644 --- a/internal/wpconfig/options.go +++ b/internal/wpconfig/options.go @@ -2,8 +2,8 @@ package wpconfig import ( "context" - "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/models" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/model" "github/fthvgb1/wp-go/safety" ) @@ -11,12 +11,12 @@ var Options safety.Map[string, string] func InitOptions() error { ctx := context.Background() - ops, err := models.SimpleFind[wp.Options](ctx, models.SqlBuilder{{"autoload", "yes"}}, "option_name, option_value") + ops, err := model.SimpleFind[models.Options](ctx, model.SqlBuilder{{"autoload", "yes"}}, "option_name, option_value") if err != nil { return err } if len(ops) == 0 { - ops, err = models.SimpleFind[wp.Options](ctx, nil, "option_name, option_value") + ops, err = model.SimpleFind[models.Options](ctx, nil, "option_name, option_value") if err != nil { return err } diff --git a/internal/wpconfig/term.go b/internal/wpconfig/term.go index 0190a05..015b428 100644 --- a/internal/wpconfig/term.go +++ b/internal/wpconfig/term.go @@ -2,8 +2,8 @@ package wpconfig import ( "context" - wp2 "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/models" + wp2 "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/model" "github/fthvgb1/wp-go/safety" ) @@ -12,14 +12,14 @@ var TermTaxonomies safety.Map[uint64, wp2.TermTaxonomy] func InitTerms() (err error) { ctx := context.Background() - terms, err := models.SimpleFind[wp2.Terms](ctx, nil, "*") + terms, err := model.SimpleFind[wp2.Terms](ctx, nil, "*") if err != nil { return err } for _, wpTerms := range terms { Terms.Store(wpTerms.TermId, wpTerms) } - termTax, err := models.SimpleFind[wp2.TermTaxonomy](ctx, nil, "*") + termTax, err := model.SimpleFind[wp2.TermTaxonomy](ctx, nil, "*") if err != nil { return err } diff --git a/mail/mail.go b/mail/mail.go index 47e991a..9990372 100644 --- a/mail/mail.go +++ b/mail/mail.go @@ -4,7 +4,7 @@ import ( "crypto/tls" "fmt" "github.com/soxfmr/gomail" - "github/fthvgb1/wp-go/config" + "github/fthvgb1/wp-go/internal/config" "mime" "path" ) diff --git a/mail/mail_test.go b/mail/mail_test.go index 6546bb5..d86c5df 100644 --- a/mail/mail_test.go +++ b/mail/mail_test.go @@ -1,7 +1,7 @@ package mail import ( - "github/fthvgb1/wp-go/config" + "github/fthvgb1/wp-go/internal/config" "testing" ) diff --git a/main.go b/main.go index 800b1c8..a979eb3 100644 --- a/main.go +++ b/main.go @@ -3,16 +3,16 @@ package main import ( "flag" "fmt" - "github/fthvgb1/wp-go/config" - "github/fthvgb1/wp-go/db" "github/fthvgb1/wp-go/internal/actions" - "github/fthvgb1/wp-go/internal/actions/common" + "github/fthvgb1/wp-go/internal/cache" + "github/fthvgb1/wp-go/internal/config" + "github/fthvgb1/wp-go/internal/db" + "github/fthvgb1/wp-go/internal/plugins" "github/fthvgb1/wp-go/internal/route" - wpconfig2 "github/fthvgb1/wp-go/internal/wpconfig" + "github/fthvgb1/wp-go/internal/wpconfig" "github/fthvgb1/wp-go/logs" "github/fthvgb1/wp-go/mail" - "github/fthvgb1/wp-go/models" - "github/fthvgb1/wp-go/plugins" + "github/fthvgb1/wp-go/model" "log" "math/rand" "os" @@ -44,7 +44,7 @@ func init() { panic(err) } actions.InitFeed() - common.InitActionsCommonCache() + cache.InitActionsCommonCache() plugins.InitDigestCache() go cronClearCache() } @@ -59,12 +59,12 @@ func initConf(c string) (err error) { if err != nil { return } - models.InitDB(db.NewSqlxDb(db.Db)) - err = wpconfig2.InitOptions() + model.InitDB(db.NewSqlxDb(db.Db)) + err = wpconfig.InitOptions() if err != nil { return } - err = wpconfig2.InitTerms() + err = wpconfig.InitTerms() if err != nil { return } @@ -76,7 +76,7 @@ func cronClearCache() { for { select { case <-t.C: - common.ClearCache() + cache.ClearCache() plugins.ClearDigestCache() actions.ClearCache() } @@ -90,7 +90,7 @@ func flushCache() { logs.ErrPrintln(err, "发邮件失败") } }() - common.FlushCache() + cache.FlushCache() plugins.FlushCache() actions.FlushCache() log.Println("all cache flushed") @@ -104,9 +104,9 @@ func reload() { }() err := config.InitConfig(confPath) logs.ErrPrintln(err, "获取配置文件失败", confPath) - err = wpconfig2.InitOptions() + err = wpconfig.InitOptions() logs.ErrPrintln(err, "获取网站设置WpOption失败") - err = wpconfig2.InitTerms() + err = wpconfig.InitTerms() logs.ErrPrintln(err, "获取WpTerms表失败") if middleWareReloadFn != nil { middleWareReloadFn() diff --git a/model/model.go b/model/model.go new file mode 100644 index 0000000..df3ee78 --- /dev/null +++ b/model/model.go @@ -0,0 +1,28 @@ +package model + +import ( + "context" +) + +var _ ParseWhere = SqlBuilder{} +var globalBb dbQuery + +func InitDB(db dbQuery) { + globalBb = db +} + +type Model interface { + PrimaryKey() string + Table() string +} + +type ParseWhere interface { + ParseWhere(*[][]any) (string, []any, error) +} + +type dbQuery interface { + Select(context.Context, any, string, ...any) error + Get(context.Context, any, string, ...any) error +} + +type SqlBuilder [][]string diff --git a/models/model.go b/model/parse.go similarity index 91% rename from models/model.go rename to model/parse.go index e147a06..79352a9 100644 --- a/models/model.go +++ b/model/parse.go @@ -1,36 +1,12 @@ -package models +package model import ( - "context" "fmt" "github/fthvgb1/wp-go/helper" "strconv" "strings" ) -var _ ParseWhere = SqlBuilder{} -var globalBb dbQuery - -func InitDB(db dbQuery) { - globalBb = db -} - -type Model interface { - PrimaryKey() string - Table() string -} - -type ParseWhere interface { - ParseWhere(*[][]any) (string, []any, error) -} - -type dbQuery interface { - Select(context.Context, any, string, ...any) error - Get(context.Context, any, string, ...any) error -} - -type SqlBuilder [][]string - func (w SqlBuilder) parseField(ss []string, s *strings.Builder) { if strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") { s.WriteString("`") diff --git a/models/query.go b/model/query.go similarity index 99% rename from models/query.go rename to model/query.go index 8fa01ef..365df1a 100644 --- a/models/query.go +++ b/model/query.go @@ -1,4 +1,4 @@ -package models +package model import ( "context" diff --git a/models/query_test.go b/model/query_test.go similarity index 98% rename from models/query_test.go rename to model/query_test.go index c594156..9373094 100644 --- a/models/query_test.go +++ b/model/query_test.go @@ -1,10 +1,10 @@ -package models +package model import ( "context" - "github/fthvgb1/wp-go/config" - "github/fthvgb1/wp-go/db" - wp2 "github/fthvgb1/wp-go/internal/wp" + "github/fthvgb1/wp-go/internal/config" + "github/fthvgb1/wp-go/internal/db" + wp2 "github/fthvgb1/wp-go/internal/models" "reflect" "testing" ) diff --git a/plugins/digest.go b/plugin/digest/digest.go similarity index 64% rename from plugins/digest.go rename to plugin/digest/digest.go index 6b0785c..cb04b03 100644 --- a/plugins/digest.go +++ b/plugin/digest/digest.go @@ -1,51 +1,18 @@ -package plugins +package digest import ( "fmt" - "github.com/gin-gonic/gin" - "github/fthvgb1/wp-go/cache" - "github/fthvgb1/wp-go/config" "github/fthvgb1/wp-go/helper" - "github/fthvgb1/wp-go/internal/wp" "regexp" "strings" - "time" "unicode/utf8" ) var removeWpBlock = regexp.MustCompile("") var more = regexp.MustCompile("") -var digestCache *cache.MapCache[uint64, string] + var quto = regexp.MustCompile(`" *|& *|< *|> ?|  *`) -func InitDigestCache() { - digestCache = cache.NewMapCacheByFn[uint64](digestRaw, config.Conf.Load().DigestCacheTime) -} - -func ClearDigestCache() { - digestCache.ClearExpired() -} -func FlushCache() { - digestCache.Flush() -} - -func digestRaw(arg ...any) (string, error) { - str := arg[0].(string) - id := arg[1].(uint64) - limit := config.Conf.Load().DigestWordCount - if limit < 0 { - return str, nil - } else if limit == 0 { - return "", nil - } - return DigestRaw(str, limit, fmt.Sprintf("/p/%d", id)), nil -} - -func DigestCache(ctx *gin.Context, id uint64, str string) string { - content, _ := digestCache.GetCache(ctx, id, time.Second, str, id) - return content -} - func ClearHtml(str string) string { content := removeWpBlock.ReplaceAllString(str, "") content = strings.Trim(content, " \t\n\r\000\x0B") @@ -54,7 +21,7 @@ func ClearHtml(str string) string { return str } -func DigestRaw(str string, limit int, u string) string { +func Raw(str string, limit int, u string) string { if r := more.FindString(str); r != "" { m := strings.Split(str, r) str = m[0] @@ -115,19 +82,5 @@ func DigestRaw(str string, limit int, u string) string { } content = fmt.Sprintf(tmp, content, closeTag, u) } - return content } - -func Digest(p *Plugin[wp.Posts], c *gin.Context, post *wp.Posts, scene uint) { - if scene == Detail { - return - } - if post.PostExcerpt != "" { - post.PostContent = strings.Replace(post.PostExcerpt, "\n", "
    ", -1) - } else { - post.PostContent = DigestCache(c, post.Id, post.PostContent) - - } - p.Next() -} diff --git a/plugins/posts.go b/plugins/posts.go deleted file mode 100644 index 261c758..0000000 --- a/plugins/posts.go +++ /dev/null @@ -1,18 +0,0 @@ -package plugins - -import ( - "github.com/gin-gonic/gin" - "github/fthvgb1/wp-go/internal/wp" -) - -func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[wp.Posts] { - p := NewPlugin[wp.Posts](nil, -1, nil, scene, ctx) - p.Push(Digest) - return p -} - -func ApplyPlugin(p *Plugin[wp.Posts], post *wp.Posts) { - p.post = post - p.Next() - p.index = -1 -}