From fd86d6c221f539666ff6c66b6383562541341454 Mon Sep 17 00:00:00 2001 From: nyne Date: Sat, 6 Dec 2025 16:32:32 +0800 Subject: [PATCH] API for rebuilding search index --- .env.example | 5 ++++- server/api/dev.go | 17 ++++++++++++++++- server/api/resource.go | 6 +++++- server/search/resource.go | 27 +++++++++++++++++++++++++-- server/service/resource.go | 10 +++++++++- 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 3812d87..73b402e 100644 --- a/.env.example +++ b/.env.example @@ -32,4 +32,7 @@ BACKUP_SCHEDULE=0 2 * * * BACKUP_RETENTION_DAYS=30 # Download Configuration -DOWNLOAD_SECRET_KEY=your_download_secret_key_here \ No newline at end of file +DOWNLOAD_SECRET_KEY=your_download_secret_key_here + +# Access Key for Development API +DEV_ACCESS_KEY=your_dev_access_key_here \ No newline at end of file diff --git a/server/api/dev.go b/server/api/dev.go index 367cabc..9c81f21 100644 --- a/server/api/dev.go +++ b/server/api/dev.go @@ -3,12 +3,27 @@ package api import ( "nysoure/server/middleware" + "nysoure/server/search" + "github.com/gofiber/fiber/v3" ) +func rebuildSearchIndex(c fiber.Ctx) error { + err := search.RebuildSearchIndex() + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to rebuild search index: " + err.Error(), + }) + } + return c.JSON(fiber.Map{ + "message": "Search index rebuilt successfully", + }) +} + func AddDevAPI(router fiber.Router) { devGroup := router.Group("/dev") + devGroup.Use(middleware.DevMiddleware()) { - devGroup.Use(middleware.DevMiddleware()) + devGroup.Post("/rebuild_search_index", rebuildSearchIndex) } } diff --git a/server/api/resource.go b/server/api/resource.go index 94d8ee9..3a1904d 100644 --- a/server/api/resource.go +++ b/server/api/resource.go @@ -287,7 +287,11 @@ func handleGetCharactersFromVndb(c fiber.Ctx) error { if vnID == "" { return model.NewRequestError("VNDB ID is required") } - characters, err := service.GetCharactersFromVndb(vnID) + uid, ok := c.Locals("uid").(uint) + if !ok { + return model.NewUnAuthorizedError("You must be logged in to get characters from VNDB") + } + characters, err := service.GetCharactersFromVndb(vnID, uid) if err != nil { return err } diff --git a/server/search/resource.go b/server/search/resource.go index 7ecffd1..d78eec9 100644 --- a/server/search/resource.go +++ b/server/search/resource.go @@ -6,12 +6,19 @@ import ( "nysoure/server/dao" "nysoure/server/model" "nysoure/server/utils" + "os" "strconv" + "sync" "time" "github.com/blevesearch/bleve" ) +var ( + index bleve.Index + mu = sync.RWMutex{} +) + type ResourceParams struct { Id uint Title string @@ -26,9 +33,9 @@ type ResourceCharacter struct { CV string } -var index bleve.Index - func AddResourceToIndex(r model.Resource) error { + mu.RLock() + defer mu.RUnlock() cs := make([]ResourceCharacter, 0, len(r.Characters)) for _, c := range r.Characters { cs = append(cs, ResourceCharacter{ @@ -96,6 +103,8 @@ func init() { } func SearchResource(keyword string) ([]uint, error) { + mu.RLock() + defer mu.RUnlock() query := bleve.NewMatchQuery(keyword) searchRequest := bleve.NewSearchRequest(query) searchResults, err := index.Search(searchRequest) @@ -128,3 +137,17 @@ func IsStopWord(word string) bool { tokens := analyzer.Analyze([]byte(word)) return len(tokens) == 0 } + +func RebuildSearchIndex() error { + mu.Lock() + defer mu.Unlock() + err := index.Close() + if err != nil { + return fmt.Errorf("failed to close search index: %w", err) + } + err = os.Remove(utils.GetStoragePath() + "/resource_index.bleve") + if err != nil { + return fmt.Errorf("failed to remove search index: %w", err) + } + return createIndex() +} diff --git a/server/service/resource.go b/server/service/resource.go index fc04fa9..84e7694 100644 --- a/server/service/resource.go +++ b/server/service/resource.go @@ -615,7 +615,15 @@ func GetPinnedResources() ([]model.ResourceView, error) { return views, nil } -func GetCharactersFromVndb(vnID string) ([]CharacterParams, error) { +func GetCharactersFromVndb(vnID string, uid uint) ([]CharacterParams, error) { + canUpload, err := checkUserCanUpload(uid) + if err != nil { + return nil, err + } + if !canUpload { + return nil, model.NewUnAuthorizedError("You have not permission to fetch characters from VNDB") + } + client := http.Client{} jsonStr := fmt.Sprintf(` {