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) {
startTime := time.Now()
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.Language, Type: "file"}
combinedResults := getFileResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.Language, page)
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.SearchLanguage, Type: "file"}
combinedResults := getFileResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page)
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,
HasNextPage: len(combinedResults) > 0,
LanguageOptions: languageOptions,
CurrentLang: settings.Language,
CurrentLang: settings.SearchLanguage,
Theme: settings.Theme,
Safe: settings.SafeSearch,
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)
if err != nil || len(results) == 0 { // 0 == 0 to force search by other node
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 {
@ -123,7 +123,7 @@ func handleForumsSearch(w http.ResponseWriter, settings UserSettings, query stri
HasPrevPage: page > 1,
HasNextPage: len(results) == 25,
LanguageOptions: languageOptions,
CurrentLang: settings.Language,
CurrentLang: settings.SearchLanguage,
Theme: settings.Theme,
Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark,

View file

@ -22,8 +22,8 @@ func init() {
func handleImageSearch(w http.ResponseWriter, settings UserSettings, query string, page int) {
startTime := time.Now()
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.Language, Type: "image"}
combinedResults := getImageResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.Language, page)
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.SearchLanguage, Type: "image"}
combinedResults := getImageResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page)
elapsedTime := time.Since(startTime)
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,
NoResults: len(combinedResults) == 0,
LanguageOptions: languageOptions,
CurrentLang: settings.Language,
CurrentLang: settings.SearchLanguage,
Theme: settings.Theme,
Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark,

59
main.go
View file

@ -17,7 +17,7 @@ type LanguageOption struct {
var settings UserSettings
var languageOptions = []LanguageOption{
{Code: "", Name: "Auto-detect"},
{Code: "", Name: "Any"},
{Code: "en", Name: "English"},
{Code: "af", Name: "Afrikaans"},
{Code: "ar", Name: "العربية (Arabic)"},
@ -69,35 +69,37 @@ var languageOptions = []LanguageOption{
func handleSearch(w http.ResponseWriter, r *http.Request) {
query, safe, lang, searchType, page := parseSearchParams(r)
// Load user settings
settings = loadUserSettings(w, r)
// Update theme if provided, or use existing settings
theme := r.URL.Query().Get("theme")
if theme != "" {
settings.Theme = theme
saveUserSettings(w, settings) // Save if theme is updated
saveUserSettings(w, settings)
} 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 {
settings.SafeSearch = safe
saveUserSettings(w, settings) // Save if safe search is updated
saveUserSettings(w, settings)
}
// Update language if provided, or use existing settings
if lang != "" && lang != settings.Language {
settings.Language = lang
saveUserSettings(w, settings) // Save if language is updated
} else if settings.Language == "" {
// If no language set, auto-detect from browser or default to "en"
settings.Language = normalizeLangCode(r.Header.Get("Accept-Language"))
saveUserSettings(w, settings) // Save if language is auto-detected
// Update site language if provided, or use existing settings
if lang != "" && lang != settings.SiteLanguage {
settings.SiteLanguage = lang
saveUserSettings(w, settings)
} else if settings.SiteLanguage == "" {
settings.SiteLanguage = normalizeLangCode(r.Header.Get("Accept-Language"))
saveUserSettings(w, settings)
}
// 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 {
case "dark", "black", "night", "latte":
settings.IsThemeDark = true
@ -105,21 +107,21 @@ func handleSearch(w http.ResponseWriter, r *http.Request) {
settings.IsThemeDark = false
}
// Check if there is a search query
if query == "" {
// If no query is provided, render the search page template
data := struct {
LanguageOptions []LanguageOption
CurrentLang string
Theme string
Safe string
IsThemeDark bool
LanguageOptions []LanguageOption
CurrentLang string
CurrentSearchLang string
Theme string
Safe string
IsThemeDark bool
}{
LanguageOptions: languageOptions,
CurrentLang: settings.Language,
Theme: settings.Theme,
Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark,
LanguageOptions: languageOptions,
CurrentLang: settings.SiteLanguage,
CurrentSearchLang: settings.SearchLanguage,
Theme: settings.Theme,
Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark,
}
tmpl := template.Must(template.ParseFiles("templates/search.html"))
@ -127,7 +129,6 @@ func handleSearch(w http.ResponseWriter, r *http.Request) {
return
}
// Handle search based on the type
switch searchType {
case "image":
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
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",
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) {
startTime := time.Now()
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.Language, Type: "text"}
combinedResults := getTextResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.Language, page)
cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.SearchLanguage, Type: "text"}
combinedResults := getTextResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page)
hasPrevPage := page > 1 // dupe
//displayResults(w, combinedResults, query, lang, time.Since(startTime).Seconds(), page, hasPrevPage, hasNextPage)
// 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 {
go prefetchPage(query, settings.SafeSearch, settings.Language, page-1)
go prefetchPage(query, settings.SafeSearch, settings.SearchLanguage, page-1)
}
elapsedTime := time.Since(startTime)
@ -65,7 +65,7 @@ func HandleTextSearch(w http.ResponseWriter, settings UserSettings, query string
HasNextPage: len(combinedResults) >= 50,
NoResults: len(combinedResults) == 0,
LanguageOptions: languageOptions,
CurrentLang: settings.Language,
CurrentLang: settings.SearchLanguage,
Theme: settings.Theme,
Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark,

View file

@ -8,52 +8,52 @@ import (
)
type UserSettings struct {
Theme string
Language string
SafeSearch string
IsThemeDark bool
Theme string
SiteLanguage string
SearchLanguage string
SafeSearch string
IsThemeDark bool
}
func loadUserSettings(w http.ResponseWriter, r *http.Request) UserSettings {
var settings UserSettings
saveRequired := false // Track if we need to save settings back
saveRequired := false
// Load theme
if cookie, err := r.Cookie("theme"); err == nil {
settings.Theme = cookie.Value
} else {
settings.Theme = "dark" // Default theme
saveRequired = true // No cookie found, need to save this later
settings.Theme = "dark"
saveRequired = true
}
// Load language
if cookie, err := r.Cookie("language"); err == nil {
settings.Language = cookie.Value
// Load site language
if cookie, err := r.Cookie("site_language"); err == nil {
settings.SiteLanguage = cookie.Value
} else {
settings.Language = "" // Set language to empty, handled later
}
// If language is empty, get it from the Accept-Language header
if settings.Language == "" {
// If no site language is set, use Accept-Language or default to "en"
acceptLang := r.Header.Get("Accept-Language")
if acceptLang != "" {
// Get the first language from Accept-Language header and normalize
settings.Language = normalizeLangCode(strings.Split(acceptLang, ",")[0])
settings.SiteLanguage = normalizeLangCode(strings.Split(acceptLang, ",")[0])
} 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
if cookie, err := r.Cookie("safe"); err == nil {
settings.SafeSearch = cookie.Value
} else {
settings.SafeSearch = "" // Default safe search off
saveRequired = true // No safe search cookie found, need to save
settings.SafeSearch = ""
saveRequired = true
}
// Save settings if required (no cookie found for any of the settings)
if saveRequired {
saveUserSettings(w, settings)
}
@ -62,19 +62,27 @@ func loadUserSettings(w http.ResponseWriter, r *http.Request) 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{
Name: "theme",
Value: settings.Theme,
Path: "/",
Expires: expiration, // Expiration time needs to be set otherwise it will expire immediately
Secure: true, // Ensure cookie is sent over HTTPS only
Expires: expiration,
Secure: true,
SameSite: http.SameSiteStrictMode,
})
http.SetCookie(w, &http.Cookie{
Name: "language",
Value: settings.Language,
Name: "site_language",
Value: settings.SiteLanguage,
Path: "/",
Expires: expiration,
Secure: true,
SameSite: http.SameSiteStrictMode,
})
http.SetCookie(w, &http.Cookie{
Name: "search_language",
Value: settings.SearchLanguage,
Path: "/",
Expires: expiration,
Secure: true,
@ -101,15 +109,24 @@ func handleSaveSettings(w http.ResponseWriter, r *http.Request) {
if theme := r.FormValue("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 {
// 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")
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 != "" {
settings.SafeSearch = safe
}
@ -127,17 +144,19 @@ func handleSettings(w http.ResponseWriter, r *http.Request) {
settings = loadUserSettings(w, r)
data := struct {
LanguageOptions []LanguageOption
CurrentLang string
Theme string
Safe string
IsThemeDark bool
LanguageOptions []LanguageOption
CurrentSiteLang string
CurrentSearchLang string
Theme string
Safe string
IsThemeDark bool
}{
LanguageOptions: languageOptions,
CurrentLang: settings.Language,
Theme: settings.Theme,
Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark,
LanguageOptions: languageOptions,
CurrentSiteLang: settings.SiteLanguage,
CurrentSearchLang: settings.SearchLanguage,
Theme: settings.Theme,
Safe: settings.SafeSearch,
IsThemeDark: settings.IsThemeDark,
}
printDebug("Rendering settings with data: %+v", data)

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) {
start := time.Now()
results := fetchVideoResults(query, settings.SafeSearch, settings.Language, page)
results := fetchVideoResults(query, settings.SafeSearch, settings.SearchLanguage, page)
if len(results) == 0 {
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)
@ -173,7 +173,7 @@ func handleVideoSearch(w http.ResponseWriter, settings UserSettings, query strin
"HasPrevPage": page > 1,
"HasNextPage": len(results) > 0,
"LanguageOptions": languageOptions,
"CurrentLang": settings.Language,
"CurrentLang": settings.SearchLanguage,
"Theme": settings.Theme,
"Safe": settings.SafeSearch,
"IsThemeDark": settings.IsThemeDark,