add search by site:<domain> functionality

pull/5/head
cblgh 2021-10-20 18:55:37 +02:00 zatwierdzone przez Alexander Cobleigh
rodzic bd03b61420
commit e28cdccb7c
3 zmienionych plików z 40 dodań i 6 usunięć

Wyświetl plik

@ -95,6 +95,11 @@ func SearchWordsByScore(db *sql.DB, words []string) []types.PageData {
return searchWords(db, words, true)
}
func SearchWordsBySite(db *sql.DB, words []string, domain string) []types.PageData {
// search words by site is same as search words by score, but adds a domain condition
return searchWords(db, words, true, domain)
}
func SearchWordsByCount(db *sql.DB, words []string) []types.PageData {
return searchWords(db, words, false)
}
@ -190,7 +195,7 @@ func countQuery(db *sql.DB, table string) int {
return count
}
func searchWords(db *sql.DB, words []string, searchByScore bool) []types.PageData {
func searchWords(db *sql.DB, words []string, searchByScore bool, domain ...string) []types.PageData {
var wordlist []string
var args []interface{}
for _, word := range words {
@ -198,6 +203,16 @@ func searchWords(db *sql.DB, words []string, searchByScore bool) []types.PageDat
args = append(args, strings.ToLower(word))
}
// the domains conditional defaults to just 'true' i.e. no domain condition
domains := []string{"1"}
if len(domain) > 0 && domain[0] != "" {
domains = make([]string, 0) // we've got at least one domain! clear domains default
for _, d := range domain {
domains = append(domains, "domain = ?")
args = append(args, d)
}
}
orderType := "SUM(score)"
if !searchByScore {
orderType = "COUNT(*)"
@ -206,12 +221,13 @@ func searchWords(db *sql.DB, words []string, searchByScore bool) []types.PageDat
query := fmt.Sprintf(`
SELECT p.url, p.about, p.title
FROM inv_index inv INNER JOIN pages p ON inv.url = p.url
WHERE %s
WHERE (%s)
AND (%s)
GROUP BY inv.url
ORDER BY %s
DESC
LIMIT 15
`, strings.Join(wordlist, " OR "), orderType)
`, strings.Join(wordlist, " OR "), strings.Join(domains, " OR "), orderType)
stmt, err := db.Prepare(query)
util.Check(err)

Wyświetl plik

@ -1,11 +1,14 @@
{{ template "head" . }}
{{ template "nav" . }}
<main id="results" class="flow2">
<h1>{{ .Data.Title }}</h1>
<h1>{{ .Data.Title }} {{ if ne .Data.Site "" }} for {{ .Data.Site }} {{ end }}</h1>
<form method="GET" class="search">
<label for="search">Search {{ .SiteName }}</label>
<label for="search">Search {{ .SiteName }} </label>
<span class="search__input">
<input type="search" minlength="1" required name="q" placeholder="Search" value="{{ .Data.Query }}" class="search-box" id="search">
{{ if ne .Data.Site "" }}
<input type="hidden" value="{{ .Data.Site }}" name="site">
{{ end }}
<button type="submit" class="search__button" aria-label="Search" title="Search">
<svg viewBox="0 0 420 300" xmlns="http://www.w3.org/2000/svg" baseProfile="full" style="background:var(--secondary)" width="42" height="30" fill="none"><path d="M90 135q60-60 120-60 0 0 0 0 60 0 120 60m-120 60a60 60 0 01-60-60 60 60 0 0160-60 60 60 0 0160 60 60 60 0 01-60 60m45-15h0l30 30m-75-15h0v45m-45-60h0l-30 30" stroke-width="81" stroke-linecap="square" stroke-linejoin="round" stroke="var(--primary)"/></svg>
</button>

Wyświetl plik

@ -27,6 +27,7 @@ type TemplateView struct {
type SearchData struct {
Query string
Title string
Site string
Pages []types.PageData
IsInternal bool
}
@ -60,11 +61,19 @@ func (h RequestHandler) searchRoute(res http.ResponseWriter, req *http.Request)
var query string
view := &TemplateView{}
var domain string
if req.Method == http.MethodGet {
params := req.URL.Query()
if words, exists := params["q"]; exists && words[0] != "" {
query = words[0]
}
if parts, exists := params["site"]; exists && parts[0] != "" {
// make sure we only have the domain, and no protocol prefix
domain = strings.TrimPrefix(parts[0], "https://")
domain = strings.TrimPrefix(domain, "http://")
domain = strings.TrimSuffix(domain, "/")
}
}
if len(query) == 0 {
@ -73,7 +82,12 @@ func (h RequestHandler) searchRoute(res http.ResponseWriter, req *http.Request)
return
}
pages := database.SearchWordsByScore(h.db, util.Inflect(strings.Fields(query)))
var pages []types.PageData
if domain != "" {
pages = database.SearchWordsBySite(h.db, util.Inflect(strings.Fields(query)), domain)
} else {
pages = database.SearchWordsByScore(h.db, util.Inflect(strings.Fields(query)))
}
if useURLTitles {
for i, pageData := range pages {
@ -87,6 +101,7 @@ func (h RequestHandler) searchRoute(res http.ResponseWriter, req *http.Request)
view.Data = SearchData{
Title: "Results",
Query: query,
Site: domain,
Pages: pages,
IsInternal: true,
}