feat(backend): directory scanner — diff, error state, covers, cache sweep, redis lock
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"booklib/internal/auth"
|
||||
"booklib/internal/config"
|
||||
"booklib/internal/redispkg"
|
||||
"booklib/internal/scanner"
|
||||
"booklib/internal/store"
|
||||
)
|
||||
|
||||
@@ -16,6 +17,7 @@ type api struct {
|
||||
cfg *config.Config
|
||||
st *store.Store
|
||||
rdb *redispkg.R
|
||||
sc *scanner.Scanner
|
||||
}
|
||||
|
||||
func err(c *gin.Context, status int, code, msg string) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"booklib/internal/auth"
|
||||
"booklib/internal/db"
|
||||
"booklib/internal/redispkg"
|
||||
"booklib/internal/scanner"
|
||||
"booklib/internal/store"
|
||||
)
|
||||
|
||||
@@ -43,7 +44,8 @@ func setupAPI(t *testing.T) (*store.Store, http.Handler) {
|
||||
cfg := testCfg()
|
||||
cfg.BooksDir = filepath.Clean(os.TempDir())
|
||||
cfg.CacheDir = t.TempDir()
|
||||
r := NewRouter(cfg, st, redispkg.New(os.Getenv("REDIS_URL")))
|
||||
rdb := redispkg.New(os.Getenv("REDIS_URL"))
|
||||
r := NewRouter(cfg, st, rdb, scanner.New(st, cfg, rdb))
|
||||
if u := os.Getenv("REDIS_URL"); u != "" { // 测试卫生: 共享 redis 上重置登录限流桶, 防跨测试累计 429
|
||||
if opt, e := redis.ParseURL(u); e == nil {
|
||||
rc := redis.NewClient(opt)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -82,11 +83,15 @@ func (a *api) getLibrary(c *gin.Context) (store.Library, bool) {
|
||||
}
|
||||
|
||||
func (a *api) scanLibrary(c *gin.Context) {
|
||||
if _, ok := a.getLibrary(c); !ok {
|
||||
lib, ok := a.getLibrary(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
// Task 9 接线: go a.sc.ScanLibraryByID(...)
|
||||
err(c, http.StatusNotImplemented, "not_ready", "scanner not wired yet")
|
||||
if _, ok := a.libRoot(c, lib); !ok {
|
||||
return
|
||||
}
|
||||
go a.sc.ScanLibraryByID(context.WithoutCancel(c), lib.ID)
|
||||
c.JSON(http.StatusAccepted, gin.H{"accepted": true})
|
||||
}
|
||||
|
||||
func (a *api) upload(c *gin.Context) {
|
||||
|
||||
@@ -7,12 +7,13 @@ import (
|
||||
|
||||
"booklib/internal/config"
|
||||
"booklib/internal/redispkg"
|
||||
"booklib/internal/scanner"
|
||||
"booklib/internal/store"
|
||||
)
|
||||
|
||||
func NewRouter(cfg *config.Config, st *store.Store, rdb *redispkg.R) *gin.Engine {
|
||||
func NewRouter(cfg *config.Config, st *store.Store, rdb *redispkg.R, sc *scanner.Scanner) *gin.Engine {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
a := &api{cfg: cfg, st: st, rdb: rdb}
|
||||
a := &api{cfg: cfg, st: st, rdb: rdb, sc: sc}
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery())
|
||||
g := r.Group("/api")
|
||||
|
||||
@@ -15,7 +15,7 @@ func testCfg() *config.Config {
|
||||
}
|
||||
|
||||
func TestHealthz(t *testing.T) {
|
||||
r := NewRouter(testCfg(), nil, redispkg.New(""))
|
||||
r := NewRouter(testCfg(), nil, redispkg.New(""), nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/healthz", nil)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
Reference in New Issue
Block a user