added search suggestions to all pages
This commit is contained in:
parent
a520488de8
commit
30aa85d321
8 changed files with 50 additions and 22 deletions
|
@ -25,9 +25,9 @@ func generateOpenSearchXML(config Config) {
|
||||||
|
|
||||||
opensearch := OpenSearchDescription{
|
opensearch := OpenSearchDescription{
|
||||||
Xmlns: "http://a9.com/-/spec/opensearch/1.1/",
|
Xmlns: "http://a9.com/-/spec/opensearch/1.1/",
|
||||||
ShortName: "Search Engine",
|
ShortName: "Warp",
|
||||||
Description: "Search engine",
|
Description: "Warp search engine",
|
||||||
Tags: "search, engine",
|
Tags: "search, engine, warp",
|
||||||
URLs: []URL{
|
URLs: []URL{
|
||||||
{
|
{
|
||||||
Type: "text/html",
|
Type: "text/html",
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
@ -32,15 +31,15 @@ func handleSuggestions(w http.ResponseWriter, r *http.Request) {
|
||||||
for _, fetchFunc := range suggestionSources {
|
for _, fetchFunc := range suggestionSources {
|
||||||
suggestions = fetchFunc(query)
|
suggestions = fetchFunc(query)
|
||||||
if len(suggestions) > 0 {
|
if len(suggestions) > 0 {
|
||||||
log.Printf("Suggestions found using %T\n", fetchFunc)
|
printDebug("Suggestions found using %T", fetchFunc)
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
log.Printf("%T did not return any suggestions or failed.\n", fetchFunc)
|
printWarn("%T did not return any suggestions or failed.", fetchFunc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(suggestions) == 0 {
|
if len(suggestions) == 0 {
|
||||||
log.Println("All suggestion services failed. Returning empty response.")
|
printErr("All suggestion services failed. Returning empty response.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the final suggestions as JSON
|
// Return the final suggestions as JSON
|
||||||
|
@ -51,87 +50,87 @@ func handleSuggestions(w http.ResponseWriter, r *http.Request) {
|
||||||
func fetchGoogleSuggestions(query string) []string {
|
func fetchGoogleSuggestions(query string) []string {
|
||||||
encodedQuery := url.QueryEscape(query)
|
encodedQuery := url.QueryEscape(query)
|
||||||
url := fmt.Sprintf("http://suggestqueries.google.com/complete/search?client=firefox&q=%s", encodedQuery)
|
url := fmt.Sprintf("http://suggestqueries.google.com/complete/search?client=firefox&q=%s", encodedQuery)
|
||||||
log.Println("Fetching suggestions from Google:", url)
|
printDebug("Fetching suggestions from Google: %s", url)
|
||||||
return fetchSuggestionsFromURL(url)
|
return fetchSuggestionsFromURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchDuckDuckGoSuggestions(query string) []string {
|
func fetchDuckDuckGoSuggestions(query string) []string {
|
||||||
encodedQuery := url.QueryEscape(query)
|
encodedQuery := url.QueryEscape(query)
|
||||||
url := fmt.Sprintf("https://duckduckgo.com/ac/?q=%s&type=list", encodedQuery)
|
url := fmt.Sprintf("https://duckduckgo.com/ac/?q=%s&type=list", encodedQuery)
|
||||||
log.Println("Fetching suggestions from DuckDuckGo:", url)
|
printDebug("Fetching suggestions from DuckDuckGo: %s", url)
|
||||||
return fetchSuggestionsFromURL(url)
|
return fetchSuggestionsFromURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchEdgeSuggestions(query string) []string {
|
func fetchEdgeSuggestions(query string) []string {
|
||||||
encodedQuery := url.QueryEscape(query)
|
encodedQuery := url.QueryEscape(query)
|
||||||
url := fmt.Sprintf("https://api.bing.com/osjson.aspx?query=%s", encodedQuery)
|
url := fmt.Sprintf("https://api.bing.com/osjson.aspx?query=%s", encodedQuery)
|
||||||
log.Println("Fetching suggestions from Edge (Bing):", url)
|
printDebug("Fetching suggestions from Edge (Bing): %s", url)
|
||||||
return fetchSuggestionsFromURL(url)
|
return fetchSuggestionsFromURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchBraveSuggestions(query string) []string {
|
func fetchBraveSuggestions(query string) []string {
|
||||||
encodedQuery := url.QueryEscape(query)
|
encodedQuery := url.QueryEscape(query)
|
||||||
url := fmt.Sprintf("https://search.brave.com/api/suggest?q=%s", encodedQuery)
|
url := fmt.Sprintf("https://search.brave.com/api/suggest?q=%s", encodedQuery)
|
||||||
log.Println("Fetching suggestions from Brave:", url)
|
printDebug("Fetching suggestions from Brave: %s", url)
|
||||||
return fetchSuggestionsFromURL(url)
|
return fetchSuggestionsFromURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchEcosiaSuggestions(query string) []string {
|
func fetchEcosiaSuggestions(query string) []string {
|
||||||
encodedQuery := url.QueryEscape(query)
|
encodedQuery := url.QueryEscape(query)
|
||||||
url := fmt.Sprintf("https://ac.ecosia.org/?q=%s&type=list", encodedQuery)
|
url := fmt.Sprintf("https://ac.ecosia.org/?q=%s&type=list", encodedQuery)
|
||||||
log.Println("Fetching suggestions from Ecosia:", url)
|
printDebug("Fetching suggestions from Ecosia: %s", url)
|
||||||
return fetchSuggestionsFromURL(url)
|
return fetchSuggestionsFromURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchQwantSuggestions(query string) []string {
|
func fetchQwantSuggestions(query string) []string {
|
||||||
encodedQuery := url.QueryEscape(query)
|
encodedQuery := url.QueryEscape(query)
|
||||||
url := fmt.Sprintf("https://api.qwant.com/v3/suggest?q=%s", encodedQuery)
|
url := fmt.Sprintf("https://api.qwant.com/v3/suggest?q=%s", encodedQuery)
|
||||||
log.Println("Fetching suggestions from Qwant:", url)
|
printDebug("Fetching suggestions from Qwant: %s", url)
|
||||||
return fetchSuggestionsFromURL(url)
|
return fetchSuggestionsFromURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchStartpageSuggestions(query string) []string {
|
func fetchStartpageSuggestions(query string) []string {
|
||||||
encodedQuery := url.QueryEscape(query)
|
encodedQuery := url.QueryEscape(query)
|
||||||
url := fmt.Sprintf("https://startpage.com/suggestions?q=%s", encodedQuery)
|
url := fmt.Sprintf("https://startpage.com/suggestions?q=%s", encodedQuery)
|
||||||
log.Println("Fetching suggestions from Startpage:", url)
|
printDebug("Fetching suggestions from Startpage: %s", url)
|
||||||
return fetchSuggestionsFromURL(url)
|
return fetchSuggestionsFromURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchSuggestionsFromURL(url string) []string {
|
func fetchSuggestionsFromURL(url string) []string {
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error fetching suggestions from", url, ":", err)
|
printWarn("Error fetching suggestions from %s: %v", url, err)
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error reading response body from", url, ":", err)
|
printWarn("Error reading response body from %s: %v", url, err)
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the Content-Type for debugging
|
// Log the Content-Type for debugging
|
||||||
contentType := resp.Header.Get("Content-Type")
|
contentType := resp.Header.Get("Content-Type")
|
||||||
log.Println("Response Content-Type from", url, ":", contentType)
|
printDebug("Response Content-Type from %s: %s", url, contentType)
|
||||||
|
|
||||||
// Check if the body is non-empty
|
// Check if the body is non-empty
|
||||||
if len(body) == 0 {
|
if len(body) == 0 {
|
||||||
log.Println("Received empty response body from", url)
|
printWarn("Received empty response body from %s", url)
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to parse the response as JSON regardless of Content-Type
|
// Attempt to parse the response as JSON regardless of Content-Type
|
||||||
var parsedResponse []interface{}
|
var parsedResponse []interface{}
|
||||||
if err := json.Unmarshal(body, &parsedResponse); err != nil {
|
if err := json.Unmarshal(body, &parsedResponse); err != nil {
|
||||||
log.Println("Error parsing JSON from", url, ":", err)
|
printErr("Error parsing JSON from %s: %v", url, err)
|
||||||
log.Println("Response body:", string(body)) // Log the body for debugging
|
printDebug("Response body: %s", string(body))
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the response structure is as expected
|
// Ensure the response structure is as expected
|
||||||
if len(parsedResponse) < 2 {
|
if len(parsedResponse) < 2 {
|
||||||
log.Println("Unexpected response format from", url, ":", string(body))
|
printWarn("Unexpected response format from %v: %v", url, string(body))
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +142,7 @@ func fetchSuggestionsFromURL(url string) []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("Unexpected suggestions format in response from", url)
|
printErr("Unexpected suggestions format in response from: %v", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
return suggestions
|
return suggestions
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="file">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="file">search</button>
|
||||||
|
<div class="autocomplete">
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<input type="submit" class="hide" name="t" value="file" />
|
<input type="submit" class="hide" name="t" value="file" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
|
@ -105,6 +109,7 @@
|
||||||
Try rephrasing your search term and/or recorrect any spelling mistakes.
|
Try rephrasing your search term and/or recorrect any spelling mistakes.
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
<script defer src="/static/js/autocomplete.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="forum">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="forum">search</button>
|
||||||
|
<div class="autocomplete">
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<input type="submit" class="hide" name="t" value="forum" />
|
<input type="submit" class="hide" name="t" value="forum" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
|
@ -84,6 +88,7 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/js/autocomplete.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="image">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="image">search</button>
|
||||||
|
<div class="autocomplete">
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<input type="submit" class="hide" name="t" value="image" />
|
<input type="submit" class="hide" name="t" value="image" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
|
@ -101,6 +105,7 @@
|
||||||
<div class="message-bottom-left" id="message-bottom-left">
|
<div class="message-bottom-left" id="message-bottom-left">
|
||||||
<span>Searching for new results...</span>
|
<span>Searching for new results...</span>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/js/autocomplete.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="map">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="map">search</button>
|
||||||
|
<div class="autocomplete">
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<input type="submit" class="hide" name="t" value="map" />
|
<input type="submit" class="hide" name="t" value="map" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="text">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="text">search</button>
|
||||||
|
<div class="autocomplete">
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<input type="submit" class="hide" name="t" value="text" />
|
<input type="submit" class="hide" name="t" value="text" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
|
@ -89,6 +93,7 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/js/autocomplete.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="video">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="video">search</button>
|
||||||
|
<div class="autocomplete">
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<input type="submit" class="hide" name="t" value="video" />
|
<input type="submit" class="hide" name="t" value="video" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
|
@ -82,6 +86,7 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/js/autocomplete.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
|
|
Loading…
Add table
Reference in a new issue