v0.3.0 #12

Merged
partisan merged 13 commits from work into main 2024-09-29 18:36:46 +00:00
8 changed files with 110 additions and 86 deletions
Showing only changes of commit 9f71666df3 - Show all commits

View file

@ -41,8 +41,8 @@ func initializeTorrentSites() {
func handleFileSearch(w http.ResponseWriter, settings UserSettings, query string, page int) { func handleFileSearch(w http.ResponseWriter, settings UserSettings, query string, page int) {
startTime := time.Now() startTime := time.Now()
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.Language, Type: "file"} cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.SearchLanguage, Type: "file"}
combinedResults := getFileResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.Language, page) combinedResults := getFileResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page)
sort.Slice(combinedResults, func(i, j int) bool { return combinedResults[i].Seeders > combinedResults[j].Seeders }) sort.Slice(combinedResults, func(i, j int) bool { return combinedResults[i].Seeders > combinedResults[j].Seeders })
@ -82,7 +82,7 @@ func handleFileSearch(w http.ResponseWriter, settings UserSettings, query string
HasPrevPage: page > 1, HasPrevPage: page > 1,
HasNextPage: len(combinedResults) > 0, HasNextPage: len(combinedResults) > 0,
LanguageOptions: languageOptions, LanguageOptions: languageOptions,
CurrentLang: settings.Language, CurrentLang: settings.SearchLanguage,
Theme: settings.Theme, Theme: settings.Theme,
Safe: settings.SafeSearch, Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark, IsThemeDark: settings.IsThemeDark,

View file

@ -102,7 +102,7 @@ func handleForumsSearch(w http.ResponseWriter, settings UserSettings, query stri
results, err := PerformRedditSearch(query, settings.SafeSearch, page) results, err := PerformRedditSearch(query, settings.SafeSearch, page)
if err != nil || len(results) == 0 { // 0 == 0 to force search by other node if err != nil || len(results) == 0 { // 0 == 0 to force search by other node
log.Printf("No results from primary search, trying other nodes") log.Printf("No results from primary search, trying other nodes")
results = tryOtherNodesForForumSearch(query, settings.SafeSearch, settings.Language, page) results = tryOtherNodesForForumSearch(query, settings.SafeSearch, settings.SearchLanguage, page)
} }
data := struct { data := struct {
@ -123,7 +123,7 @@ func handleForumsSearch(w http.ResponseWriter, settings UserSettings, query stri
HasPrevPage: page > 1, HasPrevPage: page > 1,
HasNextPage: len(results) == 25, HasNextPage: len(results) == 25,
LanguageOptions: languageOptions, LanguageOptions: languageOptions,
CurrentLang: settings.Language, CurrentLang: settings.SearchLanguage,
Theme: settings.Theme, Theme: settings.Theme,
Safe: settings.SafeSearch, Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark, IsThemeDark: settings.IsThemeDark,

View file

@ -22,8 +22,8 @@ func init() {
func handleImageSearch(w http.ResponseWriter, settings UserSettings, query string, page int) { func handleImageSearch(w http.ResponseWriter, settings UserSettings, query string, page int) {
startTime := time.Now() startTime := time.Now()
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.Language, Type: "image"} cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.SearchLanguage, Type: "image"}
combinedResults := getImageResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.Language, page) combinedResults := getImageResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page)
elapsedTime := time.Since(startTime) elapsedTime := time.Since(startTime)
tmpl, err := template.New("images.html").Funcs(funcs).ParseFiles("templates/images.html") tmpl, err := template.New("images.html").Funcs(funcs).ParseFiles("templates/images.html")
@ -55,7 +55,7 @@ func handleImageSearch(w http.ResponseWriter, settings UserSettings, query strin
HasNextPage: len(combinedResults) >= 50, HasNextPage: len(combinedResults) >= 50,
NoResults: len(combinedResults) == 0, NoResults: len(combinedResults) == 0,
LanguageOptions: languageOptions, LanguageOptions: languageOptions,
CurrentLang: settings.Language, CurrentLang: settings.SearchLanguage,
Theme: settings.Theme, Theme: settings.Theme,
Safe: settings.SafeSearch, Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark, IsThemeDark: settings.IsThemeDark,

41
main.go
View file

@ -17,7 +17,7 @@ type LanguageOption struct {
var settings UserSettings var settings UserSettings
var languageOptions = []LanguageOption{ var languageOptions = []LanguageOption{
{Code: "", Name: "Auto-detect"}, {Code: "", Name: "Any"},
{Code: "en", Name: "English"}, {Code: "en", Name: "English"},
{Code: "af", Name: "Afrikaans"}, {Code: "af", Name: "Afrikaans"},
{Code: "ar", Name: "العربية (Arabic)"}, {Code: "ar", Name: "العربية (Arabic)"},
@ -69,35 +69,37 @@ var languageOptions = []LanguageOption{
func handleSearch(w http.ResponseWriter, r *http.Request) { func handleSearch(w http.ResponseWriter, r *http.Request) {
query, safe, lang, searchType, page := parseSearchParams(r) query, safe, lang, searchType, page := parseSearchParams(r)
// Load user settings
settings = loadUserSettings(w, r) settings = loadUserSettings(w, r)
// Update theme if provided, or use existing settings
theme := r.URL.Query().Get("theme") theme := r.URL.Query().Get("theme")
if theme != "" { if theme != "" {
settings.Theme = theme settings.Theme = theme
saveUserSettings(w, settings) // Save if theme is updated saveUserSettings(w, settings)
} else if settings.Theme == "" { } else if settings.Theme == "" {
settings.Theme = "dark" // Default theme settings.Theme = "dark"
} }
// Update safe search if provided, or use existing settings
if safe != "" && safe != settings.SafeSearch { if safe != "" && safe != settings.SafeSearch {
settings.SafeSearch = safe settings.SafeSearch = safe
saveUserSettings(w, settings) // Save if safe search is updated saveUserSettings(w, settings)
} }
// Update language if provided, or use existing settings // Update site language if provided, or use existing settings
if lang != "" && lang != settings.Language { if lang != "" && lang != settings.SiteLanguage {
settings.Language = lang settings.SiteLanguage = lang
saveUserSettings(w, settings) // Save if language is updated saveUserSettings(w, settings)
} else if settings.Language == "" { } else if settings.SiteLanguage == "" {
// If no language set, auto-detect from browser or default to "en" settings.SiteLanguage = normalizeLangCode(r.Header.Get("Accept-Language"))
settings.Language = normalizeLangCode(r.Header.Get("Accept-Language")) saveUserSettings(w, settings)
saveUserSettings(w, settings) // Save if language is auto-detected }
// Update search language (can be empty)
searchLang := r.URL.Query().Get("search_lang")
if searchLang != settings.SearchLanguage {
settings.SearchLanguage = searchLang
saveUserSettings(w, settings)
} }
// This will do for now (to handle Dark Reader addon)
switch settings.Theme { switch settings.Theme {
case "dark", "black", "night", "latte": case "dark", "black", "night", "latte":
settings.IsThemeDark = true settings.IsThemeDark = true
@ -105,18 +107,18 @@ func handleSearch(w http.ResponseWriter, r *http.Request) {
settings.IsThemeDark = false settings.IsThemeDark = false
} }
// Check if there is a search query
if query == "" { if query == "" {
// If no query is provided, render the search page template
data := struct { data := struct {
LanguageOptions []LanguageOption LanguageOptions []LanguageOption
CurrentLang string CurrentLang string
CurrentSearchLang string
Theme string Theme string
Safe string Safe string
IsThemeDark bool IsThemeDark bool
}{ }{
LanguageOptions: languageOptions, LanguageOptions: languageOptions,
CurrentLang: settings.Language, CurrentLang: settings.SiteLanguage,
CurrentSearchLang: settings.SearchLanguage,
Theme: settings.Theme, Theme: settings.Theme,
Safe: settings.SafeSearch, Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark, IsThemeDark: settings.IsThemeDark,
@ -127,7 +129,6 @@ func handleSearch(w http.ResponseWriter, r *http.Request) {
return return
} }
// Handle search based on the type
switch searchType { switch searchType {
case "image": case "image":
handleImageSearch(w, settings, query, page) handleImageSearch(w, settings, query, page)

View file

@ -79,6 +79,10 @@ func buildSearchURL(query, safe, lang string, page, resultsPerPage int) string {
} }
startIndex := (page - 1) * resultsPerPage startIndex := (page - 1) * resultsPerPage
printDebug(fmt.Sprintf("https://www.google.com/search?q=%s%s%s%s%s&start=%d",
url.QueryEscape(query), safeParam, langParam, glParam, uuleParam, startIndex))
return fmt.Sprintf("https://www.google.com/search?q=%s%s%s%s%s&start=%d", return fmt.Sprintf("https://www.google.com/search?q=%s%s%s%s%s&start=%d",
url.QueryEscape(query), safeParam, langParam, glParam, uuleParam, startIndex) url.QueryEscape(query), safeParam, langParam, glParam, uuleParam, startIndex)
} }

10
text.go
View file

@ -22,17 +22,17 @@ func init() {
func HandleTextSearch(w http.ResponseWriter, settings UserSettings, query string, page int) { func HandleTextSearch(w http.ResponseWriter, settings UserSettings, query string, page int) {
startTime := time.Now() startTime := time.Now()
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.Language, Type: "text"} cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.SearchLanguage, Type: "text"}
combinedResults := getTextResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.Language, page) combinedResults := getTextResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page)
hasPrevPage := page > 1 // dupe hasPrevPage := page > 1 // dupe
//displayResults(w, combinedResults, query, lang, time.Since(startTime).Seconds(), page, hasPrevPage, hasNextPage) //displayResults(w, combinedResults, query, lang, time.Since(startTime).Seconds(), page, hasPrevPage, hasNextPage)
// Prefetch next and previous pages // Prefetch next and previous pages
go prefetchPage(query, settings.SafeSearch, settings.Language, page+1) go prefetchPage(query, settings.SafeSearch, settings.SearchLanguage, page+1)
if hasPrevPage { if hasPrevPage {
go prefetchPage(query, settings.SafeSearch, settings.Language, page-1) go prefetchPage(query, settings.SafeSearch, settings.SearchLanguage, page-1)
} }
elapsedTime := time.Since(startTime) elapsedTime := time.Since(startTime)
@ -65,7 +65,7 @@ func HandleTextSearch(w http.ResponseWriter, settings UserSettings, query string
HasNextPage: len(combinedResults) >= 50, HasNextPage: len(combinedResults) >= 50,
NoResults: len(combinedResults) == 0, NoResults: len(combinedResults) == 0,
LanguageOptions: languageOptions, LanguageOptions: languageOptions,
CurrentLang: settings.Language, CurrentLang: settings.SearchLanguage,
Theme: settings.Theme, Theme: settings.Theme,
Safe: settings.SafeSearch, Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark, IsThemeDark: settings.IsThemeDark,

View file

@ -9,51 +9,51 @@ import (
type UserSettings struct { type UserSettings struct {
Theme string Theme string
Language string SiteLanguage string
SearchLanguage string
SafeSearch string SafeSearch string
IsThemeDark bool IsThemeDark bool
} }
func loadUserSettings(w http.ResponseWriter, r *http.Request) UserSettings { func loadUserSettings(w http.ResponseWriter, r *http.Request) UserSettings {
var settings UserSettings var settings UserSettings
saveRequired := false // Track if we need to save settings back saveRequired := false
// Load theme // Load theme
if cookie, err := r.Cookie("theme"); err == nil { if cookie, err := r.Cookie("theme"); err == nil {
settings.Theme = cookie.Value settings.Theme = cookie.Value
} else { } else {
settings.Theme = "dark" // Default theme settings.Theme = "dark"
saveRequired = true // No cookie found, need to save this later saveRequired = true
} }
// Load language // Load site language
if cookie, err := r.Cookie("language"); err == nil { if cookie, err := r.Cookie("site_language"); err == nil {
settings.Language = cookie.Value settings.SiteLanguage = cookie.Value
} else { } else {
settings.Language = "" // Set language to empty, handled later // If no site language is set, use Accept-Language or default to "en"
}
// If language is empty, get it from the Accept-Language header
if settings.Language == "" {
acceptLang := r.Header.Get("Accept-Language") acceptLang := r.Header.Get("Accept-Language")
if acceptLang != "" { if acceptLang != "" {
// Get the first language from Accept-Language header and normalize settings.SiteLanguage = normalizeLangCode(strings.Split(acceptLang, ",")[0])
settings.Language = normalizeLangCode(strings.Split(acceptLang, ",")[0])
} else { } else {
settings.Language = "en" // Default language if Accept-Language is not present settings.SiteLanguage = "en" // Default language
} }
saveRequired = true // No language cookie found, need to save saveRequired = true
}
// Load search language (can be empty)
if cookie, err := r.Cookie("search_language"); err == nil {
settings.SearchLanguage = cookie.Value
} }
// Load safe search // Load safe search
if cookie, err := r.Cookie("safe"); err == nil { if cookie, err := r.Cookie("safe"); err == nil {
settings.SafeSearch = cookie.Value settings.SafeSearch = cookie.Value
} else { } else {
settings.SafeSearch = "" // Default safe search off settings.SafeSearch = ""
saveRequired = true // No safe search cookie found, need to save saveRequired = true
} }
// Save settings if required (no cookie found for any of the settings)
if saveRequired { if saveRequired {
saveUserSettings(w, settings) saveUserSettings(w, settings)
} }
@ -62,19 +62,27 @@ func loadUserSettings(w http.ResponseWriter, r *http.Request) UserSettings {
} }
func saveUserSettings(w http.ResponseWriter, settings UserSettings) { func saveUserSettings(w http.ResponseWriter, settings UserSettings) {
expiration := time.Now().Add(90 * 24 * time.Hour) // 90 days from now expiration := time.Now().Add(90 * 24 * time.Hour)
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: "theme", Name: "theme",
Value: settings.Theme, Value: settings.Theme,
Path: "/", Path: "/",
Expires: expiration, // Expiration time needs to be set otherwise it will expire immediately Expires: expiration,
Secure: true, // Ensure cookie is sent over HTTPS only Secure: true,
SameSite: http.SameSiteStrictMode, SameSite: http.SameSiteStrictMode,
}) })
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: "language", Name: "site_language",
Value: settings.Language, Value: settings.SiteLanguage,
Path: "/",
Expires: expiration,
Secure: true,
SameSite: http.SameSiteStrictMode,
})
http.SetCookie(w, &http.Cookie{
Name: "search_language",
Value: settings.SearchLanguage,
Path: "/", Path: "/",
Expires: expiration, Expires: expiration,
Secure: true, Secure: true,
@ -101,15 +109,24 @@ func handleSaveSettings(w http.ResponseWriter, r *http.Request) {
if theme := r.FormValue("theme"); theme != "" { if theme := r.FormValue("theme"); theme != "" {
settings.Theme = theme settings.Theme = theme
} }
if lang := r.FormValue("lang"); lang != "" {
settings.Language = lang // Update site language if provided
if siteLang := r.FormValue("site_lang"); siteLang != "" {
settings.SiteLanguage = siteLang
} else { } else {
// If lang is empty, try to get from Accept-Language header // If site_lang is empty, try to get from Accept-Language header
acceptLang := r.Header.Get("Accept-Language") acceptLang := r.Header.Get("Accept-Language")
if acceptLang != "" { if acceptLang != "" {
settings.Language = strings.Split(acceptLang, ",")[0] settings.SiteLanguage = strings.Split(acceptLang, ",")[0]
} }
} }
// Update search language if provided
if searchLang := r.FormValue("search_lang"); searchLang != "" {
settings.SearchLanguage = searchLang
}
// Update safe search if provided
if safe := r.FormValue("safe"); safe != "" { if safe := r.FormValue("safe"); safe != "" {
settings.SafeSearch = safe settings.SafeSearch = safe
} }
@ -128,13 +145,15 @@ func handleSettings(w http.ResponseWriter, r *http.Request) {
data := struct { data := struct {
LanguageOptions []LanguageOption LanguageOptions []LanguageOption
CurrentLang string CurrentSiteLang string
CurrentSearchLang string
Theme string Theme string
Safe string Safe string
IsThemeDark bool IsThemeDark bool
}{ }{
LanguageOptions: languageOptions, LanguageOptions: languageOptions,
CurrentLang: settings.Language, CurrentSiteLang: settings.SiteLanguage,
CurrentSearchLang: settings.SearchLanguage,
Theme: settings.Theme, Theme: settings.Theme,
Safe: settings.SafeSearch, Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark, IsThemeDark: settings.IsThemeDark,

View file

@ -151,10 +151,10 @@ func makeHTMLRequest(query, safe, lang string, page int) (*VideoAPIResponse, err
func handleVideoSearch(w http.ResponseWriter, settings UserSettings, query string, page int) { func handleVideoSearch(w http.ResponseWriter, settings UserSettings, query string, page int) {
start := time.Now() start := time.Now()
results := fetchVideoResults(query, settings.SafeSearch, settings.Language, page) results := fetchVideoResults(query, settings.SafeSearch, settings.SearchLanguage, page)
if len(results) == 0 { if len(results) == 0 {
printWarn("No results from primary search, trying other nodes") printWarn("No results from primary search, trying other nodes")
results = tryOtherNodesForVideoSearch(query, settings.SafeSearch, settings.Language, page, []string{hostID}) results = tryOtherNodesForVideoSearch(query, settings.SafeSearch, settings.SearchLanguage, page, []string{hostID})
} }
elapsed := time.Since(start) elapsed := time.Since(start)
@ -173,7 +173,7 @@ func handleVideoSearch(w http.ResponseWriter, settings UserSettings, query strin
"HasPrevPage": page > 1, "HasPrevPage": page > 1,
"HasNextPage": len(results) > 0, "HasNextPage": len(results) > 0,
"LanguageOptions": languageOptions, "LanguageOptions": languageOptions,
"CurrentLang": settings.Language, "CurrentLang": settings.SearchLanguage,
"Theme": settings.Theme, "Theme": settings.Theme,
"Safe": settings.SafeSearch, "Safe": settings.SafeSearch,
"IsThemeDark": settings.IsThemeDark, "IsThemeDark": settings.IsThemeDark,