Compare commits

...

2 Commits

Author SHA1 Message Date
xing
0faac992cf 重构reload config和flush cache 机制 2023-02-17 23:36:54 +08:00
xing
6ad2b3cf64 完善 2023-02-17 00:25:13 +08:00
32 changed files with 270 additions and 279 deletions

View File

@ -8,7 +8,7 @@ import (
) )
type MemoryMapCache[K comparable, V any] struct { type MemoryMapCache[K comparable, V any] struct {
safety.Map[K, mapVal[V]] *safety.Map[K, mapVal[V]]
} }
func NewMemoryMapCacheByFn[K comparable, V any](fn func(...any) (V, error), expireTime time.Duration) *MapCache[K, V] { func NewMemoryMapCacheByFn[K comparable, V any](fn func(...any) (V, error), expireTime time.Duration) *MapCache[K, V] {

2
cache/vars.go vendored
View File

@ -10,7 +10,7 @@ import (
) )
type VarCache[T any] struct { type VarCache[T any] struct {
v safety.Var[vars[T]] v *safety.Var[vars[T]]
} }
type vars[T any] struct { type vars[T any] struct {

View File

@ -0,0 +1,53 @@
package cachemanager
import (
"context"
"github.com/fthvgb1/wp-go/cache"
"time"
)
var ctx = context.Background()
type flush interface {
Flush(ctx context.Context)
}
type clear interface {
ClearExpired(ctx context.Context)
}
var clears []clear
var flushes []flush
func Flush() {
for _, f := range flushes {
f.Flush(ctx)
}
}
func MapCacheBy[K comparable, V any](fn func(...any) (V, error), expireTime time.Duration) *cache.MapCache[K, V] {
m := cache.NewMemoryMapCacheByFn[K, V](fn, expireTime)
FlushPush(m)
ClearPush(m)
return m
}
func MapBatchCacheBy[K comparable, V any](fn func(...any) (map[K]V, error), expireTime time.Duration) *cache.MapCache[K, V] {
m := cache.NewMemoryMapCacheByBatchFn[K, V](fn, expireTime)
FlushPush(m)
ClearPush(m)
return m
}
func FlushPush(f ...flush) {
flushes = append(flushes, f...)
}
func ClearPush(c ...clear) {
clears = append(clears, c...)
}
func ClearExpired() {
for _, c := range clears {
c.ClearExpired(ctx)
}
}

View File

@ -3,6 +3,8 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/fthvgb1/wp-go/internal/cmd/cachemanager"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/cmd/route" "github.com/fthvgb1/wp-go/internal/cmd/route"
"github.com/fthvgb1/wp-go/internal/mail" "github.com/fthvgb1/wp-go/internal/mail"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
@ -25,7 +27,6 @@ import (
var confPath string var confPath string
var address string var address string
var middleWareReloadFn func()
var intReg = regexp.MustCompile(`^\d`) var intReg = regexp.MustCompile(`^\d`)
func init() { func init() {
@ -76,8 +77,7 @@ func cronClearCache() {
for { for {
select { select {
case <-t.C: case <-t.C:
cache.ClearCache() cachemanager.ClearExpired()
plugins.ClearDigestCache()
} }
} }
} }
@ -89,12 +89,11 @@ func flushCache() {
logs.ErrPrintln(err, "发邮件失败") logs.ErrPrintln(err, "发邮件失败")
} }
}() }()
cache.FlushCache() cachemanager.Flush()
plugins.FlushCache()
log.Println("all cache flushed") log.Println("all cache flushed")
} }
func reload() { func reloads() {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
log.Println(r) log.Println(r)
@ -105,12 +104,8 @@ func reload() {
err = wpconfig.InitOptions() err = wpconfig.InitOptions()
logs.ErrPrintln(err, "获取网站设置WpOption失败") logs.ErrPrintln(err, "获取网站设置WpOption失败")
err = wpconfig.InitTerms() err = wpconfig.InitTerms()
wpconfig.FlushModes()
theme.Reload()
logs.ErrPrintln(err, "获取WpTerms表失败") logs.ErrPrintln(err, "获取WpTerms表失败")
if middleWareReloadFn != nil { reload.Reload()
middleWareReloadFn()
}
flushCache() flushCache()
log.Println("reload complete") log.Println("reload complete")
} }
@ -121,7 +116,7 @@ func signalNotify() {
for { for {
switch <-c { switch <-c {
case syscall.SIGUSR1: case syscall.SIGUSR1:
go reload() go reloads()
case syscall.SIGUSR2: case syscall.SIGUSR2:
go flushCache() go flushCache()
} }
@ -130,9 +125,8 @@ func signalNotify() {
func main() { func main() {
go signalNotify() go signalNotify()
Gin, reloadFn := route.SetupRouter() Gin := route.SetupRouter()
c := config.GetConfig() c := config.GetConfig()
middleWareReloadFn = reloadFn
if c.Ssl.Key != "" && c.Ssl.Cert != "" { if c.Ssl.Key != "" && c.Ssl.Cert != "" {
err := Gin.RunTLS(address, c.Ssl.Cert, c.Ssl.Key) err := Gin.RunTLS(address, c.Ssl.Cert, c.Ssl.Key)
if err != nil { if err != nil {

View File

@ -0,0 +1,30 @@
package reload
import "github.com/fthvgb1/wp-go/safety"
var calls []func()
func Vars[T any](defaults T) *safety.Var[T] {
ss := safety.NewVar(defaults)
calls = append(calls, func() {
ss.Store(defaults)
})
return ss
}
func VarsBy[T any](fn func() T) *safety.Var[T] {
ss := safety.NewVar(fn())
calls = append(calls, func() {
ss.Store(fn())
})
return ss
}
func Push(fn ...func()) {
calls = append(calls, fn...)
}
func Reload() {
for _, call := range calls {
call()
}
}

View File

@ -2,6 +2,7 @@ package route
import ( import (
"github.com/fthvgb1/wp-go/internal/actions" "github.com/fthvgb1/wp-go/internal/actions"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/middleware" "github.com/fthvgb1/wp-go/internal/middleware"
"github.com/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints"
@ -16,7 +17,7 @@ import (
"net/http" "net/http"
) )
func SetupRouter() (*gin.Engine, func()) { func SetupRouter() *gin.Engine {
// Disable Console Color // Disable Console Color
// gin.DisableConsoleColor() // gin.DisableConsoleColor()
r := gin.New() r := gin.New()
@ -30,14 +31,12 @@ func SetupRouter() (*gin.Engine, func()) {
r.HTMLRender = theme.GetTemplate() r.HTMLRender = theme.GetTemplate()
wpconfig.SetTemplateFs(theme.TemplateFs) wpconfig.SetTemplateFs(theme.TemplateFs)
siteFlowLimitMiddleware, siteFlow := middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime)
validServerName, reloadValidServerNameFn := middleware.ValidateServerNames()
fl, flReload := middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime)
r.Use( r.Use(
gin.Logger(), gin.Logger(),
validServerName, middleware.ValidateServerNames(),
middleware.RecoverAndSendMail(gin.DefaultErrorWriter), middleware.RecoverAndSendMail(gin.DefaultErrorWriter),
fl, siteFlowLimitMiddleware,
middleware.SetStaticFileCache, middleware.SetStaticFileCache,
) )
//gzip 因为一般会用nginx做反代时自动使用gzip,所以go这边本身可以不用 //gzip 因为一般会用nginx做反代时自动使用gzip,所以go这边本身可以不用
@ -63,8 +62,7 @@ func SetupRouter() (*gin.Engine, func()) {
} }
store := cookie.NewStore([]byte("secret")) store := cookie.NewStore([]byte("secret"))
r.Use(sessions.Sessions("go-wp", store)) r.Use(sessions.Sessions("go-wp", store))
sl, slRload := middleware.SearchLimit(c.SingleIpSearchNum) r.GET("/", middleware.SearchLimit(c.SingleIpSearchNum), actions.ThemeHook(constraints.Home))
r.GET("/", sl, actions.ThemeHook(constraints.Home))
r.GET("/page/:page", actions.ThemeHook(constraints.Home)) r.GET("/page/:page", actions.ThemeHook(constraints.Home))
r.GET("/p/category/:category", actions.ThemeHook(constraints.Category)) r.GET("/p/category/:category", actions.ThemeHook(constraints.Category))
r.GET("/p/category/:category/page/:page", actions.ThemeHook(constraints.Category)) r.GET("/p/category/:category/page/:page", actions.ThemeHook(constraints.Category))
@ -79,16 +77,14 @@ func SetupRouter() (*gin.Engine, func()) {
r.GET("/p/:id/feed", actions.PostFeed) r.GET("/p/:id/feed", actions.PostFeed)
r.GET("/feed", actions.Feed) r.GET("/feed", actions.Feed)
r.GET("/comments/feed", actions.CommentsFeed) r.GET("/comments/feed", actions.CommentsFeed)
cfl, _ := middleware.FlowLimit(c.MaxRequestSleepNum, 5, c.CacheTime.SleepTime) commentMiddleWare, _ := middleware.FlowLimit(c.MaxRequestSleepNum, 5, c.CacheTime.SleepTime)
r.POST("/comment", cfl, actions.PostComment) r.POST("/comment", commentMiddleWare, actions.PostComment)
if c.Pprof != "" { if c.Pprof != "" {
pprof.Register(r, c.Pprof) pprof.Register(r, c.Pprof)
} }
fn := func() { reload.Push(func() {
reloadValidServerNameFn()
c := config.GetConfig() c := config.GetConfig()
flReload(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime) siteFlow(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime)
slRload(c.SingleIpSearchNum) })
} return r
return r, fn
} }

View File

@ -1,9 +1,16 @@
package middleware package middleware
import "github.com/gin-gonic/gin" import (
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/gin-gonic/gin"
)
func SearchLimit(num int64) (func(ctx *gin.Context), func(int64)) { func SearchLimit(num int64) func(ctx *gin.Context) {
fn, reFn := IpLimit(num) fn, reFn := IpLimit(num)
reload.Push(func() {
reFn(config.GetConfig().SingleIpSearchNum)
})
return func(c *gin.Context) { return func(c *gin.Context) {
if c.Query("s") != "" { if c.Query("s") != "" {
fn(c) fn(c)
@ -11,5 +18,5 @@ func SearchLimit(num int64) (func(ctx *gin.Context), func(int64)) {
c.Next() c.Next()
} }
}, reFn }
} }

View File

@ -1,35 +1,33 @@
package middleware package middleware
import ( import (
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/safety"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http" "net/http"
"strings" "strings"
) )
func ValidateServerNames() (func(ctx *gin.Context), func()) { func ValidateServerNames() func(ctx *gin.Context) {
var serverName safety.Map[string, struct{}] sites := reload.VarsBy(func() map[string]struct{} {
fn := func() {
r := config.GetConfig().TrustServerNames r := config.GetConfig().TrustServerNames
m := map[string]struct{}{}
if len(r) > 0 { if len(r) > 0 {
for _, name := range r { for _, name := range r {
serverName.Store(name, struct{}{}) m[name] = struct{}{}
} }
} else {
serverName.Flush()
} }
return m
})
}
fn()
return func(c *gin.Context) { return func(c *gin.Context) {
if serverName.Len() > 0 { m := sites.Load()
if _, ok := serverName.Load(strings.Split(c.Request.Host, ":")[0]); !ok { if len(m) > 0 && !maps.IsExists(m, strings.Split(c.Request.Host, ":")[0]) {
c.Status(http.StatusForbidden) c.Status(http.StatusForbidden)
c.Abort() c.Abort()
return return
}
} }
c.Next() c.Next()
}, fn }
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/fthvgb1/wp-go/cache" "github.com/fthvgb1/wp-go/cache"
"github.com/fthvgb1/wp-go/helper" "github.com/fthvgb1/wp-go/helper"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
"github.com/fthvgb1/wp-go/internal/cmd/cachemanager"
"github.com/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/dao" "github.com/fthvgb1/wp-go/internal/pkg/dao"
@ -54,17 +55,17 @@ func InitActionsCommonCache() {
fn: dao.Archives, fn: dao.Archives,
} }
searchPostIdsCache = cache.NewMemoryMapCacheByFn[string](dao.SearchPostIds, c.CacheTime.SearchPostCacheTime) searchPostIdsCache = cachemanager.MapCacheBy[string](dao.SearchPostIds, c.CacheTime.SearchPostCacheTime)
postListIdsCache = cache.NewMemoryMapCacheByFn[string](dao.SearchPostIds, c.CacheTime.PostListCacheTime) postListIdsCache = cachemanager.MapCacheBy[string](dao.SearchPostIds, c.CacheTime.PostListCacheTime)
monthPostsCache = cache.NewMemoryMapCacheByFn[string](dao.MonthPost, c.CacheTime.MonthPostCacheTime) monthPostsCache = cachemanager.MapCacheBy[string](dao.MonthPost, c.CacheTime.MonthPostCacheTime)
postContextCache = cache.NewMemoryMapCacheByFn[uint64](dao.GetPostContext, c.CacheTime.ContextPostCacheTime) postContextCache = cachemanager.MapCacheBy[uint64](dao.GetPostContext, c.CacheTime.ContextPostCacheTime)
postsCache = cache.NewMemoryMapCacheByBatchFn(dao.GetPostsByIds, c.CacheTime.PostDataCacheTime) postsCache = cachemanager.MapBatchCacheBy(dao.GetPostsByIds, c.CacheTime.PostDataCacheTime)
postMetaCache = cache.NewMemoryMapCacheByBatchFn(dao.GetPostMetaByPostIds, c.CacheTime.PostDataCacheTime) postMetaCache = cachemanager.MapBatchCacheBy(dao.GetPostMetaByPostIds, c.CacheTime.PostDataCacheTime)
categoryAndTagsCaches = cache.NewVarCache(dao.CategoriesAndTags, c.CacheTime.CategoryCacheTime) categoryAndTagsCaches = cache.NewVarCache(dao.CategoriesAndTags, c.CacheTime.CategoryCacheTime)
@ -72,63 +73,33 @@ func InitActionsCommonCache() {
recentCommentsCaches = cache.NewVarCache(dao.RecentComments, c.CacheTime.RecentCommentsCacheTime) recentCommentsCaches = cache.NewVarCache(dao.RecentComments, c.CacheTime.RecentCommentsCacheTime)
postCommentCaches = cache.NewMemoryMapCacheByFn[uint64](dao.PostComments, c.CacheTime.PostCommentsCacheTime) postCommentCaches = cachemanager.MapCacheBy[uint64](dao.PostComments, c.CacheTime.PostCommentsCacheTime)
maxPostIdCache = cache.NewVarCache(dao.GetMaxPostId, c.CacheTime.MaxPostIdCacheTime) maxPostIdCache = cache.NewVarCache(dao.GetMaxPostId, c.CacheTime.MaxPostIdCacheTime)
usersCache = cache.NewMemoryMapCacheByFn[uint64](dao.GetUserById, c.CacheTime.UserInfoCacheTime) usersCache = cachemanager.MapCacheBy[uint64](dao.GetUserById, c.CacheTime.UserInfoCacheTime)
usersNameCache = cache.NewMemoryMapCacheByFn[string](dao.GetUserByName, c.CacheTime.UserInfoCacheTime) usersNameCache = cachemanager.MapCacheBy[string](dao.GetUserByName, c.CacheTime.UserInfoCacheTime)
commentsCache = cache.NewMemoryMapCacheByBatchFn(dao.GetCommentByIds, c.CacheTime.CommentsCacheTime) commentsCache = cachemanager.MapBatchCacheBy(dao.GetCommentByIds, c.CacheTime.CommentsCacheTime)
allUsernameCache = cache.NewVarCache(dao.AllUsername, c.CacheTime.UserInfoCacheTime) allUsernameCache = cache.NewVarCache(dao.AllUsername, c.CacheTime.UserInfoCacheTime)
headerImagesCache = cache.NewMemoryMapCacheByFn[string](getHeaderImages, c.CacheTime.ThemeHeaderImagCacheTime) headerImagesCache = cachemanager.MapCacheBy[string](getHeaderImages, c.CacheTime.ThemeHeaderImagCacheTime)
feedCache = cache.NewVarCache(feed, time.Hour) feedCache = cache.NewVarCache(feed, time.Hour)
postFeedCache = cache.NewMemoryMapCacheByFn[string](postFeed, time.Hour) postFeedCache = cachemanager.MapCacheBy[string](postFeed, time.Hour)
commentsFeedCache = cache.NewVarCache(commentsFeed, time.Hour) commentsFeedCache = cache.NewVarCache(commentsFeed, time.Hour)
newCommentCache = cache.NewMemoryMapCacheByFn[string, string](nil, 15*time.Minute) newCommentCache = cachemanager.MapCacheBy[string, string](nil, 15*time.Minute)
ctx = context.Background() ctx = context.Background()
InitFeed() InitFeed()
} }
func ClearCache() {
searchPostIdsCache.ClearExpired(ctx)
searchPostIdsCache.ClearExpired(ctx)
postsCache.ClearExpired(ctx)
postMetaCache.ClearExpired(ctx)
postListIdsCache.ClearExpired(ctx)
monthPostsCache.ClearExpired(ctx)
postContextCache.ClearExpired(ctx)
usersCache.ClearExpired(ctx)
commentsCache.ClearExpired(ctx)
usersNameCache.ClearExpired(ctx)
postFeedCache.ClearExpired(ctx)
newCommentCache.ClearExpired(ctx)
headerImagesCache.ClearExpired(ctx)
}
func FlushCache() {
searchPostIdsCache.Flush(ctx)
postsCache.Flush(ctx)
postMetaCache.Flush(ctx)
postListIdsCache.Flush(ctx)
monthPostsCache.Flush(ctx)
postContextCache.Flush(ctx)
usersCache.Flush(ctx)
commentsCache.Flush(ctx)
usersCache.Flush(ctx)
postFeedCache.Flush(ctx)
newCommentCache.Flush(ctx)
headerImagesCache.Flush(ctx)
}
func Archives(ctx context.Context) (r []models.PostArchive) { func Archives(ctx context.Context) (r []models.PostArchive) {
return archivesCaches.getArchiveCache(ctx) return archivesCaches.getArchiveCache(ctx)
} }

View File

@ -13,4 +13,6 @@ const (
Error404 Error404
ParamError ParamError
InternalErr InternalErr
Defaults = "default"
) )

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/fthvgb1/wp-go/cache" "github.com/fthvgb1/wp-go/cache"
"github.com/fthvgb1/wp-go/internal/cmd/cachemanager"
"github.com/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/plugin/digest" "github.com/fthvgb1/wp-go/plugin/digest"
@ -12,18 +13,9 @@ import (
) )
var digestCache *cache.MapCache[uint64, string] var digestCache *cache.MapCache[uint64, string]
var ctx context.Context
func InitDigestCache() { func InitDigestCache() {
ctx = context.Background() digestCache = cachemanager.MapCacheBy[uint64](digestRaw, config.GetConfig().CacheTime.DigestCacheTime)
digestCache = cache.NewMemoryMapCacheByFn[uint64](digestRaw, config.GetConfig().CacheTime.DigestCacheTime)
}
func ClearDigestCache() {
digestCache.ClearExpired(ctx)
}
func FlushCache() {
digestCache.Flush(ctx)
} }
func digestRaw(arg ...any) (string, error) { func digestRaw(arg ...any) (string, error) {

View File

@ -3,12 +3,13 @@ package common
import ( import (
"fmt" "fmt"
"github.com/fthvgb1/wp-go/helper/html" "github.com/fthvgb1/wp-go/helper/html"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/safety"
) )
var css = safety.NewVar("default") var css = reload.Vars(constraints.Defaults)
func (h *Handle) CalCustomCss() (r string) { func (h *Handle) CalCustomCss() (r string) {
mods, err := wpconfig.GetThemeMods(h.Theme) mods, err := wpconfig.GetThemeMods(h.Theme)
@ -25,7 +26,7 @@ func (h *Handle) CalCustomCss() (r string) {
func (h *Handle) CustomCss() { func (h *Handle) CustomCss() {
cs := css.Load() cs := css.Load()
if cs == "default" { if cs == constraints.Defaults {
cs = h.CalCustomCss() cs = h.CalCustomCss()
css.Store(cs) css.Store(cs)
} }

View File

@ -4,12 +4,13 @@ import (
"fmt" "fmt"
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/safety"
) )
var logo = safety.NewVar("default") var logo = reload.Vars(constraints.Defaults)
func (h *Handle) CalCustomLogo() (r string) { func (h *Handle) CalCustomLogo() (r string) {
mods, err := wpconfig.GetThemeMods(h.Theme) mods, err := wpconfig.GetThemeMods(h.Theme)
@ -50,7 +51,7 @@ func (h *Handle) CalCustomLogo() (r string) {
func (h *Handle) CustomLogo() { func (h *Handle) CustomLogo() {
s := logo.Load() s := logo.Load()
if s == "default" { if s == constraints.Defaults {
s = h.CalCustomLogo() s = h.CalCustomLogo()
logo.Store(s) logo.Store(s)
} }

View File

@ -105,7 +105,6 @@ func (d *DetailHandle) Render() {
if d.Templ == "" { if d.Templ == "" {
d.Templ = fmt.Sprintf("%s/posts/detail.gohtml", d.Theme) d.Templ = fmt.Sprintf("%s/posts/detail.gohtml", d.Theme)
} }
d.CustomBackGround()
d.C.HTML(d.Code, d.Templ, d.GinH) d.C.HTML(d.Code, d.Templ, d.GinH)
} }

View File

@ -119,7 +119,6 @@ func (i *IndexHandle) Render() {
if i.Templ == "" { if i.Templ == "" {
i.Templ = fmt.Sprintf("%s/posts/index.gohtml", i.Theme) i.Templ = fmt.Sprintf("%s/posts/index.gohtml", i.Theme)
} }
i.CustomBackGround()
i.C.HTML(i.Code, i.Templ, i.GinH) i.C.HTML(i.Code, i.Templ, i.GinH)
} }

View File

@ -1,7 +0,0 @@
package common
func Reload() {
backgroud.Store("default")
icon.Store("default")
css.Store("default")
}

View File

@ -4,13 +4,14 @@ import (
"fmt" "fmt"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/safety"
"strings" "strings"
) )
var icon = safety.NewVar("default") var icon = reload.Vars(constraints.Defaults)
var sizes = []string{"site_icon-270", "site_icon-32", "site_icon-192", "site_icon-180"} var sizes = []string{"site_icon-270", "site_icon-32", "site_icon-192", "site_icon-180"}
func (h *Handle) CalSiteIcon() (r string) { func (h *Handle) CalSiteIcon() (r string) {
@ -44,7 +45,7 @@ func (h *Handle) CalSiteIcon() (r string) {
func (h *Handle) SiteIcon() { func (h *Handle) SiteIcon() {
s := icon.Load() s := icon.Load()
if s == "default" { if s == constraints.Defaults {
s = h.CalSiteIcon() s = h.CalSiteIcon()
icon.Store(s) icon.Store(s)
} }

View File

@ -1,7 +1,4 @@
{{define "common/head"}} {{define "common/head"}}
{{if .customBackground}}
{{.customBackground|unescaped}}
{{end}}
{{if .customHeader}} {{if .customHeader}}
{{.customHeader|unescaped}} {{.customHeader|unescaped}}
{{end}} {{end}}

View File

@ -2,7 +2,6 @@ package theme
import ( import (
"github.com/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/internal/theme/common"
"github.com/fthvgb1/wp-go/internal/theme/twentyfifteen" "github.com/fthvgb1/wp-go/internal/theme/twentyfifteen"
"github.com/fthvgb1/wp-go/internal/theme/twentyseventeen" "github.com/fthvgb1/wp-go/internal/theme/twentyseventeen"
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
@ -13,11 +12,6 @@ func InitTheme() {
addThemeHookFunc(twentyseventeen.ThemeName, twentyseventeen.Hook) addThemeHookFunc(twentyseventeen.ThemeName, twentyseventeen.Hook)
} }
func Reload() {
twentyfifteen.Reload()
common.Reload()
}
func GetTemplateName() string { func GetTemplateName() string {
tmlp := config.GetConfig().Theme tmlp := config.GetConfig().Theme
if tmlp == "" { if tmlp == "" {

View File

@ -1,12 +1,13 @@
package common package twentyfifteen
import ( import (
"fmt" "fmt"
"github.com/fthvgb1/wp-go/helper" "github.com/fthvgb1/wp-go/helper"
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/safety"
) )
var postx = map[string]string{ var postx = map[string]string{
@ -31,45 +32,45 @@ var repeat = map[string]string{
"no-repeat": "no-repeat", "no-repeat": "no-repeat",
} }
var backgroud = safety.NewVar("default") var backgroud = reload.Vars(constraints.Defaults)
func (h *Handle) CustomBackGround() { func (h *handle) CustomBackGround() {
b := backgroud.Load() b := backgroud.Load()
if b == "default" { if b == constraints.Defaults {
b = h.CalCustomBackGround() b = h.CalCustomBackGround()
backgroud.Store(b) backgroud.Store(b)
} }
h.GinH["customBackground"] = b h.IndexHandle.GinH["customBackground"] = b
} }
func (h *Handle) CalCustomBackGround() (r string) { func (h *handle) CalCustomBackGround() (r string) {
mods, err := wpconfig.GetThemeMods(h.Theme) mods, err := wpconfig.GetThemeMods(h.IndexHandle.Theme)
if err != nil { if err != nil {
return return
} }
if mods.BackgroundImage == "" && mods.BackgroundColor == mods.ThemeSupport.CustomBackground.DefaultColor { if mods.BackgroundImage == "" && mods.BackgroundColor == themesupport.CustomBackground.DefaultColor {
return return
} }
s := str.NewBuilder() s := str.NewBuilder()
if mods.BackgroundImage != "" { if mods.BackgroundImage != "" {
s.Sprintf(` background-image: url("%s");`, helper.CutUrlHost(mods.BackgroundImage)) s.Sprintf(` background-image: url("%s");`, helper.CutUrlHost(mods.BackgroundImage))
} }
backgroundPositionX := helper.Defaults(mods.BackgroundPositionX, mods.ThemeSupport.CustomBackground.DefaultPositionX) backgroundPositionX := helper.Defaults(mods.BackgroundPositionX, themesupport.CustomBackground.DefaultPositionX)
backgroundPositionX = maps.WithDefaultVal(postx, backgroundPositionX, "left") backgroundPositionX = maps.WithDefaultVal(postx, backgroundPositionX, "left")
backgroundPositionY := helper.Defaults(mods.BackgroundPositionY, mods.ThemeSupport.CustomBackground.DefaultPositionY) backgroundPositionY := helper.Defaults(mods.BackgroundPositionY, themesupport.CustomBackground.DefaultPositionY)
backgroundPositionY = maps.WithDefaultVal(posty, backgroundPositionY, "top") backgroundPositionY = maps.WithDefaultVal(posty, backgroundPositionY, "top")
positon := fmt.Sprintf(" background-position: %s %s;", backgroundPositionX, backgroundPositionY) positon := fmt.Sprintf(" background-position: %s %s;", backgroundPositionX, backgroundPositionY)
siz := helper.DefaultVal(mods.BackgroundSize, mods.ThemeSupport.CustomBackground.DefaultSize) siz := helper.DefaultVal(mods.BackgroundSize, themesupport.CustomBackground.DefaultSize)
siz = maps.WithDefaultVal(size, siz, "auto") siz = maps.WithDefaultVal(size, siz, "auto")
siz = fmt.Sprintf(" background-size: %s;", siz) siz = fmt.Sprintf(" background-size: %s;", siz)
repeats := helper.Defaults(mods.BackgroundRepeat, mods.ThemeSupport.CustomBackground.DefaultRepeat) repeats := helper.Defaults(mods.BackgroundRepeat, themesupport.CustomBackground.DefaultRepeat)
repeats = maps.WithDefaultVal(repeat, repeats, "repeat") repeats = maps.WithDefaultVal(repeat, repeats, "repeat")
repeats = fmt.Sprintf(" background-repeat: %s;", repeats) repeats = fmt.Sprintf(" background-repeat: %s;", repeats)
attachment := helper.Defaults(mods.BackgroundAttachment, mods.ThemeSupport.CustomBackground.DefaultAttachment) attachment := helper.Defaults(mods.BackgroundAttachment, themesupport.CustomBackground.DefaultAttachment)
attachment = helper.Or(attachment == "fixed", "fixed", "scroll") attachment = helper.Or(attachment == "fixed", "fixed", "scroll")
attachment = fmt.Sprintf(" background-attachment: %s;", attachment) attachment = fmt.Sprintf(" background-attachment: %s;", attachment)
s.WriteString(positon, siz, repeats, attachment) s.WriteString(positon, siz, repeats, attachment)

View File

@ -2,7 +2,8 @@ package twentyfifteen
import ( import (
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/safety" "github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
) )
var style = `<style type="text/css" id="twentyfifteen-header-css">` var style = `<style type="text/css" id="twentyfifteen-header-css">`
@ -79,11 +80,7 @@ var imgStyle = `.site-header {
} }
}` }`
var header = safety.NewVar("default") var header = reload.Vars(constraints.Defaults)
func Reload() {
header.Store("default")
}
func (h *handle) CalCustomHeader() (r string, rand bool) { func (h *handle) CalCustomHeader() (r string, rand bool) {
img, rand := h.IndexHandle.GetCustomHeader() img, rand := h.IndexHandle.GetCustomHeader()
@ -112,7 +109,7 @@ func (h *handle) CalCustomHeader() (r string, rand bool) {
func (h *handle) CustomHeader() { func (h *handle) CustomHeader() {
headers := header.Load() headers := header.Load()
if headers == "default" { if headers == constraints.Defaults {
headerss, rand := h.CalCustomHeader() headerss, rand := h.CalCustomHeader()
headers = headerss headers = headerss
if !rand { if !rand {

View File

@ -60,4 +60,8 @@
{{template "common/head" .}} {{template "common/head" .}}
{{if .customBackground}}
{{.customBackground|unescaped}}
{{end}}
{{end}} {{end}}

View File

@ -0,0 +1,33 @@
package twentyfifteen
type themeSupport struct {
CustomBackground customBackground `json:"custom-background"`
EditorColorPalette []EditorColorPalette `json:"editor-color-palette"`
EditorGradientPresets []EditorGradientPresets `json:"editor-gradient-presets"`
}
type customBackground struct {
DefaultImage string `json:"default-image"`
DefaultPreset string `json:"default-preset"`
DefaultPositionX string `json:"default-position-x"`
DefaultPositionY string `json:"default-position-y"`
DefaultSize string `json:"default-size"`
DefaultRepeat string `json:"default-repeat"`
DefaultAttachment string `json:"default-attachment"`
DefaultColor string `json:"default-color"`
WpHeadCallback string `json:"wp-head-callback"`
AdminHeadCallback string `json:"admin-head-callback"`
AdminPreviewCallback string `json:"admin-preview-callback"`
}
type EditorColorPalette struct {
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
}
type EditorGradientPresets struct {
Name string `json:"name"`
Slug string `json:"slug"`
Gradient string `json:"gradient"`
}
var themesupport = themeSupport{}

View File

@ -37,10 +37,12 @@ func Hook(h *common.Handle) {
func (h *handle) Index() { func (h *handle) Index() {
h.CustomHeader() h.CustomHeader()
h.CustomBackGround()
h.Indexs() h.Indexs()
} }
func (h *handle) Detail() { func (h *handle) Detail() {
h.CustomHeader() h.CustomHeader()
h.CustomBackGround()
h.Details() h.Details()
} }

View File

@ -0,0 +1,17 @@
package twentyseventeen
type themeSupport struct {
}
type EditorColorPalette struct {
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
}
type EditorGradientPresets struct {
Name string `json:"name"`
Slug string `json:"slug"`
Gradient string `json:"gradient"`
}
var themesupport = themeSupport{}

View File

@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/phphelper" "github.com/fthvgb1/wp-go/internal/phphelper"
"github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/safety" "github.com/fthvgb1/wp-go/safety"
@ -103,11 +104,13 @@ func Thumbnail(metadata models.WpAttachmentMetadata, Type, host string, except .
return return
} }
var themeModes = safety.Map[string, ThemeMod]{} var themeModes = func() *safety.Map[string, ThemeMod] {
m := safety.NewMap[string, ThemeMod]()
func FlushModes() { reload.Push(func() {
themeModes.Flush() m.Flush()
} })
return m
}()
func GetThemeMods(theme string) (r ThemeMod, err error) { func GetThemeMods(theme string) (r ThemeMod, err error) {
r, ok := themeModes.Load(theme) r, ok := themeModes.Load(theme)

View File

@ -1,27 +1,22 @@
package wpconfig package wpconfig
type ThemeSupport struct { type ThemeSupport struct {
CoreBlockPatterns bool `json:"core-block-patterns"` CoreBlockPatterns bool `json:"core-block-patterns"`
WidgetsBlockEditor bool `json:"widgets-block-editor"` WidgetsBlockEditor bool `json:"widgets-block-editor"`
AutomaticFeedLinks bool `json:"automatic-feed-links"` AutomaticFeedLinks bool `json:"automatic-feed-links"`
TitleTag bool TitleTag bool `json:"title-tag"`
CustomLineHeight bool `json:"title-tag"` PostThumbnails bool `json:"post-thumbnails"`
PostThumbnails bool `json:"post-thumbnails"` Menus bool `json:"menus"`
Menus bool `json:"menus"` HTML5 []string `json:"html5"`
HTML5 []string `json:"html5"` PostFormats []string `json:"post-formats"`
PostFormats []string `json:"post-formats"` CustomLogo CustomLogo `json:"custom-logo"`
CustomLogo CustomLogo `json:"custom-logo"` CustomizeSelectiveRefreshWidgets bool `json:"customize-selective-refresh-widgets"`
CustomBackground CustomBackground `json:"custom-background"` EditorStyle bool `json:"editor-style"`
EditorStyle bool `json:"editor-style"` EditorStyles bool `json:"editor-styles"`
EditorStyles bool `json:"editor-styles"` WpBlockStyles bool `json:"wp-block-styles"`
WpBlockStyles bool `json:"wp-block-styles"` ResponsiveEmbeds bool `json:"responsive-embeds"`
ResponsiveEmbeds bool `json:"responsive-embeds"` CustomHeader CustomHeader `json:"custom-header"`
EditorColorPalette []EditorColorPalette `json:"editor-color-palette"` Widgets bool `json:"widgets"`
EditorGradientPresets []EditorGradientPresets `json:"editor-gradient-presets"`
CustomizeSelectiveRefreshWidgets bool `json:"customize-selective-refresh-widgets"`
StarterContent StarterContent `json:"starter-content"`
CustomHeader CustomHeader `json:"custom-header"`
Widgets bool `json:"widgets"`
} }
type CustomLogo struct { type CustomLogo struct {
Width int `json:"width"` Width int `json:"width"`
@ -31,102 +26,7 @@ type CustomLogo struct {
HeaderText string `json:"header-text"` HeaderText string `json:"header-text"`
UnlinkHomepageLogo bool `json:"unlink-homepage-logo"` UnlinkHomepageLogo bool `json:"unlink-homepage-logo"`
} }
type Widgets struct {
Sidebar1 []string `json:"sidebar-1"`
Sidebar2 []string `json:"sidebar-2"`
Sidebar3 []string `json:"sidebar-3"`
}
type About struct {
Thumbnail string `json:"thumbnail"`
}
type Contact struct {
Thumbnail string `json:"thumbnail"`
}
type Blog struct {
Thumbnail string `json:"thumbnail"`
}
type HomepageSection struct {
Thumbnail string `json:"thumbnail"`
}
type CustomBackground struct {
DefaultImage string `json:"default-image"`
DefaultPreset string `json:"default-preset"`
DefaultPositionX string `json:"default-position-x"`
DefaultPositionY string `json:"default-position-y"`
DefaultSize string `json:"default-size"`
DefaultRepeat string `json:"default-repeat"`
DefaultAttachment string `json:"default-attachment"`
DefaultColor string `json:"default-color"`
WpHeadCallback string `json:"wp-head-callback"`
AdminHeadCallback string `json:"admin-head-callback"`
AdminPreviewCallback string `json:"admin-preview-callback"`
}
type EditorColorPalette struct {
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
}
type EditorGradientPresets struct {
Name string `json:"name"`
Slug string `json:"slug"`
Gradient string `json:"gradient"`
}
type Posts struct {
Num0 string `json:"0"`
About About `json:"about"`
Contact Contact `json:"contact"`
Blog Blog `json:"blog"`
HomepageSection HomepageSection `json:"homepage-section"`
}
type ImageEspresso struct {
PostTitle string `json:"post_title"`
File string `json:"file"`
}
type ImageSandwich struct {
PostTitle string `json:"post_title"`
File string `json:"file"`
}
type ImageCoffee struct {
PostTitle string `json:"post_title"`
File string `json:"file"`
}
type Attachments struct {
ImageEspresso ImageEspresso `json:"image-espresso"`
ImageSandwich ImageSandwich `json:"image-sandwich"`
ImageCoffee ImageCoffee `json:"image-coffee"`
}
type Option struct {
ShowOnFront string `json:"show_on_front"`
PageOnFront string `json:"page_on_front"`
PageForPosts string `json:"page_for_posts"`
}
type ThemeMods struct {
Panel1 string `json:"panel_1"`
Panel2 string `json:"panel_2"`
Panel3 string `json:"panel_3"`
Panel4 string `json:"panel_4"`
}
type Top struct {
Name string `json:"name"`
Items []string `json:"items"`
}
type Social struct {
Name string `json:"name"`
Items []string `json:"items"`
}
type NavMenus struct {
Top Top `json:"top"`
Social Social `json:"social"`
}
type StarterContent struct {
Widgets Widgets `json:"widgets"`
Posts Posts `json:"posts"`
Attachments Attachments `json:"attachments"`
Options Option `json:"options"`
ThemeMods ThemeMods `json:"theme_mods"`
NavMenus NavMenus `json:"nav_menus"`
}
type CustomHeader struct { type CustomHeader struct {
DefaultImage string `json:"default-image"` DefaultImage string `json:"default-image"`
RandomDefault bool `json:"random-default"` RandomDefault bool `json:"random-default"`

View File

@ -58,8 +58,8 @@ type Map[K comparable, V any] struct {
expunged unsafe.Pointer expunged unsafe.Pointer
} }
func NewMap[K comparable, V any]() Map[K, V] { func NewMap[K comparable, V any]() *Map[K, V] {
return Map[K, V]{ return &Map[K, V]{
expunged: unsafe.Pointer(new(any)), expunged: unsafe.Pointer(new(any)),
} }
} }

View File

@ -16,7 +16,7 @@ func TestMap_Load(t *testing.T) {
m.Store(1, 1) m.Store(1, 1)
type testCase[K comparable, V any] struct { type testCase[K comparable, V any] struct {
name string name string
m Map[K, V] m *Map[K, V]
args args[K] args args[K]
wantValue V wantValue V
wantOk bool wantOk bool

View File

@ -3,7 +3,7 @@ package safety
import "sync" import "sync"
type Slice[T any] struct { type Slice[T any] struct {
Var[[]T] *Var[[]T]
mu sync.Mutex mu sync.Mutex
} }

View File

@ -10,8 +10,8 @@ type Var[T any] struct {
p unsafe.Pointer p unsafe.Pointer
} }
func NewVar[T any](val T) Var[T] { func NewVar[T any](val T) *Var[T] {
return Var[T]{val: val, p: unsafe.Pointer(&val)} return &Var[T]{val: val, p: unsafe.Pointer(&val)}
} }
func (r *Var[T]) Load() T { func (r *Var[T]) Load() T {

View File

@ -39,6 +39,12 @@ func TestVar_Load(t *testing.T) {
} }
}) })
} }
r := NewVar("ff")
fmt.Println(r.Load())
q := r
fmt.Println(q.Load())
q.Store("xx")
fmt.Println(r.Load(), q.Load())
} }
func TestVar_Delete(t *testing.T) { func TestVar_Delete(t *testing.T) {