Files
sm-journal-plugin/controllers/api/posts_search.go
Jakub Zych bdd1c1be61 feat(15-03): add journal media upload, RSS, and off-by-default Typesense gate
- POST /_journal/api/v1/media/upload requires access_posts and stays under journal/
- Anonymous GET rss is RSS 2.0 honoring rss_* settings; unpublished posts are omitted
- beachcomber Gate reads search_use_typesense (default false) so a fresh save makes no Typesense HTTP

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-06 19:03:35 +02:00

54 lines
1.6 KiB
Go

package api
import (
"log/slog"
"net/http"
"strconv"
"git.golem15.com/golem15/sm-journal-plugin/models"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/beachcomber"
"gorm.io/gorm"
)
func searchWithEngine(app *backpack.App, r *http.Request, db *gorm.DB, search string, publishedOnly bool, page, perPage int) ([]uint, bool) {
if app == nil || db == nil || !models.SearchGateEnabled() {
return nil, false
}
svc, err := beachcomber.From(app)
if err != nil || svc == nil || svc.Engine() == nil || !svc.Engine().Configured() {
return nil, false
}
var settings models.Settings
if err := db.First(&settings, 1).Error; err != nil {
settings.SearchTitleWeight = 5
settings.SearchExcerptWeight = 3
settings.SearchContentWeight = 1
}
q := beachcomber.Query{
Q: search,
QueryBy: []string{"title", "excerpt", "content"},
QueryByWeights: []int{settings.SearchTitleWeight, settings.SearchExcerptWeight, settings.SearchContentWeight},
SortBy: "_text_match:desc,published_at:desc",
Page: page,
PerPage: perPage,
}
if publishedOnly {
q.FilterBy = "published:=1"
}
res, err := beachcomber.SearchPage(r.Context(), svc.Engine(), svc.IndexName(&models.Post{}), q)
if err != nil {
slog.Default().Warn("journal: Typesense search failed, falling back to DB search", "err", err)
return nil, false
}
ids := make([]uint, 0, len(res.IDs))
for _, raw := range res.IDs {
n, err := strconv.ParseUint(raw, 10, 64)
if err != nil || n == 0 {
continue
}
ids = append(ids, uint(n))
}
return ids, true
}