Initial commit
This commit is contained in:
66
scripts/rsw/internal/wiki/search.go
Normal file
66
scripts/rsw/internal/wiki/search.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package wiki
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SearchResult represents a single search hit from the wiki.
|
||||
type SearchResult struct {
|
||||
Title string `json:"title"`
|
||||
Snippet string `json:"snippet"`
|
||||
PageID int `json:"pageid"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
// searchResponse is the raw API response shape for action=query&list=search.
|
||||
type searchResponse struct {
|
||||
Query struct {
|
||||
Search []SearchResult `json:"search"`
|
||||
} `json:"query"`
|
||||
}
|
||||
|
||||
// Search performs a full-text search across wiki pages.
|
||||
func (c *Client) Search(query string, limit int) ([]SearchResult, error) {
|
||||
if limit <= 0 {
|
||||
limit = 10
|
||||
}
|
||||
|
||||
params := url.Values{
|
||||
"action": {"query"},
|
||||
"list": {"search"},
|
||||
"srsearch": {query},
|
||||
"srlimit": {strconv.Itoa(limit)},
|
||||
"srprop": {"snippet|size"},
|
||||
}
|
||||
|
||||
var resp searchResponse
|
||||
if err := c.get(params, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Strip HTML tags from snippets (the API returns <span class="searchmatch">...</span>)
|
||||
for i := range resp.Query.Search {
|
||||
resp.Query.Search[i].Snippet = stripHTML(resp.Query.Search[i].Snippet)
|
||||
}
|
||||
|
||||
return resp.Query.Search, nil
|
||||
}
|
||||
|
||||
// stripHTML removes HTML tags from a string. Lightweight, no external dep.
|
||||
func stripHTML(s string) string {
|
||||
var b strings.Builder
|
||||
inTag := false
|
||||
for _, r := range s {
|
||||
switch {
|
||||
case r == '<':
|
||||
inTag = true
|
||||
case r == '>':
|
||||
inTag = false
|
||||
case !inTag:
|
||||
b.WriteRune(r)
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user