From 5e84d68b175986a039a73ff7484fcf8973e0af99 Mon Sep 17 00:00:00 2001 From: partisan Date: Sun, 11 Aug 2024 21:45:52 +0200 Subject: [PATCH] updated logging, added theming, added settings button --- cache.go | 5 ++- files.go | 6 ++-- forums.go | 4 ++- imageproxy.go | 5 ++- images.go | 4 ++- main.go | 47 ++++++++++++++++++++----- map.go | 8 ++--- node.go | 5 ++- printing.go | 4 +-- static/css/dark.css | 74 +++++++++++++++++++++++++++++++++++++++ static/css/light.css | 72 +++++++++++++++++++++++++++++++++++++ static/css/style.css | 54 ++++++++++++++++++++++------ static/images/dark.webp | Bin 0 -> 9050 bytes static/images/light.webp | Bin 0 -> 10008 bytes templates/files.html | 5 +-- templates/forums.html | 5 +-- templates/images.html | 3 +- templates/map.html | 1 + templates/search.html | 47 ++++++++++++++++++++++++- templates/settings.html | 3 +- templates/text.html | 5 +-- templates/videos.html | 1 + text.go | 25 ++++++------- user-settings.go | 54 ++++++++++++++++++++++++++++ video.go | 9 ++--- 25 files changed, 384 insertions(+), 62 deletions(-) create mode 100644 static/css/dark.css create mode 100644 static/css/light.css create mode 100644 static/images/dark.webp create mode 100644 static/images/light.webp create mode 100644 user-settings.go diff --git a/cache.go b/cache.go index db982a8..b0b7a18 100644 --- a/cache.go +++ b/cache.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "log" "sync" "time" @@ -143,7 +142,7 @@ func (rc *ResultsCache) checkAndCleanCache() { func (rc *ResultsCache) memoryUsage() float64 { v, err := mem.VirtualMemory() if err != nil { - log.Printf("Failed to get memory info: %v", err) + printErr("Failed to get memory info: %v", err) return 0 } @@ -167,7 +166,7 @@ func (rc *ResultsCache) cleanOldestItems() { if oldestKey != "" { delete(rc.results, oldestKey) - log.Printf("Removed oldest cache item: %s", oldestKey) + printDebug("Removed oldest cache item: %s", oldestKey) } else { break } diff --git a/files.go b/files.go index 0308b56..65dee0a 100644 --- a/files.go +++ b/files.go @@ -39,7 +39,7 @@ func initializeTorrentSites() { // rutor = NewRutor() } -func handleFileSearch(w http.ResponseWriter, query, safe, lang string, page int) { +func handleFileSearch(w http.ResponseWriter, settings UserSettings, query, safe, lang string, page int) { startTime := time.Now() cacheKey := CacheKey{Query: query, Page: page, Safe: safe == "true", Lang: lang, Type: "file"} @@ -69,6 +69,7 @@ func handleFileSearch(w http.ResponseWriter, query, safe, lang string, page int) HasNextPage bool Page int Settings Settings + Theme string }{ Results: combinedResults, Query: query, @@ -78,7 +79,8 @@ func handleFileSearch(w http.ResponseWriter, query, safe, lang string, page int) HasPrevPage: page > 1, HasNextPage: len(combinedResults) > 0, Page: page, - Settings: Settings{UxLang: lang, Safe: safe}, + Settings: Settings{UxLang: lang, Safe: safe}, // Now this is painful, are there two Settings variables?? + Theme: settings.Theme, } // // Debugging: Print results before rendering template diff --git a/forums.go b/forums.go index b358acd..e3fbed5 100644 --- a/forums.go +++ b/forums.go @@ -98,7 +98,7 @@ func PerformRedditSearch(query string, safe string, page int) ([]ForumSearchResu return results, nil } -func handleForumsSearch(w http.ResponseWriter, query, safe, lang string, page int) { +func handleForumsSearch(w http.ResponseWriter, settings UserSettings, query, safe, lang string, page int) { results, err := PerformRedditSearch(query, safe, 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") @@ -113,6 +113,7 @@ func handleForumsSearch(w http.ResponseWriter, query, safe, lang string, page in Page int HasPrevPage bool HasNextPage bool + Theme string }{ Query: query, Results: results, @@ -121,6 +122,7 @@ func handleForumsSearch(w http.ResponseWriter, query, safe, lang string, page in Page: page, HasPrevPage: page > 1, HasNextPage: len(results) == 25, + Theme: settings.Theme, } funcMap := template.FuncMap{ diff --git a/imageproxy.go b/imageproxy.go index f828116..4dd7478 100644 --- a/imageproxy.go +++ b/imageproxy.go @@ -2,7 +2,6 @@ package main import ( "io" - "log" "net/http" ) @@ -17,7 +16,7 @@ func handleImageProxy(w http.ResponseWriter, r *http.Request) { // Fetch the image from the external URL resp, err := http.Get(imageURL) if err != nil { - log.Printf("Error fetching image: %v", err) + printWarn("Error fetching image: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } @@ -40,7 +39,7 @@ func handleImageProxy(w http.ResponseWriter, r *http.Request) { // Write the image content to the response if _, err := io.Copy(w, resp.Body); err != nil { - log.Printf("Error writing image to response: %v", err) + printWarn("Error writing image to response: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } diff --git a/images.go b/images.go index 38eed51..13873af 100644 --- a/images.go +++ b/images.go @@ -17,7 +17,7 @@ func init() { } } -func handleImageSearch(w http.ResponseWriter, query, safe, lang string, page int) { +func handleImageSearch(w http.ResponseWriter, settings UserSettings, query, safe, lang string, page int) { startTime := time.Now() cacheKey := CacheKey{Query: query, Page: page, Safe: safe == "true", Lang: lang, Type: "image"} @@ -41,6 +41,7 @@ func handleImageSearch(w http.ResponseWriter, query, safe, lang string, page int HasPrevPage bool HasNextPage bool NoResults bool + Theme string }{ Results: combinedResults, Query: query, @@ -51,6 +52,7 @@ func handleImageSearch(w http.ResponseWriter, query, safe, lang string, page int HasPrevPage: page > 1, HasNextPage: len(combinedResults) >= 50, NoResults: len(combinedResults) == 0, + Theme: settings.Theme, } err = tmpl.Execute(w, data) diff --git a/main.go b/main.go index f79eef2..fb12b70 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "html/template" "log" "net/http" "strconv" @@ -13,6 +14,8 @@ type LanguageOption struct { Name string } +var settings UserSettings + var languageOptions = []LanguageOption{ {Code: "", Name: "Any Language"}, {Code: "lang_en", Name: "English"}, @@ -66,27 +69,55 @@ var languageOptions = []LanguageOption{ func handleSearch(w http.ResponseWriter, r *http.Request) { query, safe, lang, searchType, page := parseSearchParams(r) + // Load user settings + settings = loadUserSettings(r) + + // Update the theme, safe search, and language based on query parameters or use existing settings + theme := r.URL.Query().Get("theme") + if theme != "" { + settings.Theme = theme + saveUserSettings(w, settings) + } else if settings.Theme == "" { + settings.Theme = "dark" // Default theme + } + + if safe != "" { + settings.SafeSearch = safe + saveUserSettings(w, settings) + } + + if lang != "" { + settings.Language = lang + saveUserSettings(w, settings) + } + + // Render the search page template if no query if query == "" { - http.ServeFile(w, r, "templates/search.html") + tmpl := template.Must(template.ParseFiles("templates/search.html")) + tmpl.Execute(w, settings) return } + settings := loadUserSettings(r) + + // Handle search based on the type switch searchType { case "image": - handleImageSearch(w, query, safe, lang, page) + handleImageSearch(w, settings, query, safe, lang, page) case "video": - handleVideoSearch(w, query, safe, lang, page) + handleVideoSearch(w, settings, query, safe, lang, page) case "map": - handleMapSearch(w, query, safe) + handleMapSearch(w, settings, query, safe) case "forum": - handleForumsSearch(w, query, safe, lang, page) + handleForumsSearch(w, settings, query, safe, lang, page) case "file": - handleFileSearch(w, query, safe, lang, page) + handleFileSearch(w, settings, query, safe, lang, page) case "text": fallthrough default: - HandleTextSearch(w, query, safe, lang, page) + HandleTextSearch(w, settings, query, safe, lang, page) } + // This is immeasurably stupid it passes safe and language then it passes settings with safe and lang again } func parseSearchParams(r *http.Request) (query, safe, lang, searchType string, page int) { @@ -139,7 +170,7 @@ func runServer() { config := loadConfig() generateOpenSearchXML(config) - fmt.Printf("Server is listening on http://localhost:%d\n", config.Port) + printMessage("Server is listening on http://localhost:%d", config.Port) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", config.Port), nil)) // Start automatic update checker diff --git a/map.go b/map.go index 7ad21ff..9ec879e 100644 --- a/map.go +++ b/map.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "html/template" - "log" "net/http" "net/url" ) @@ -44,11 +43,11 @@ func geocodeQuery(query string) (latitude, longitude string, found bool, err err return "", "", false, nil } -func handleMapSearch(w http.ResponseWriter, query string, lang string) { +func handleMapSearch(w http.ResponseWriter, settings UserSettings, query string, lang string) { // Geocode the query to get coordinates latitude, longitude, found, err := geocodeQuery(query) if err != nil { - log.Printf("Error geocoding query: %s, error: %v", query, err) + printDebug("Error geocoding query: %s, error: %v", query, err) http.Error(w, "Failed to find location", http.StatusInternalServerError) return } @@ -59,11 +58,12 @@ func handleMapSearch(w http.ResponseWriter, query string, lang string) { "Latitude": latitude, "Longitude": longitude, "Found": found, + "Theme": settings.Theme, } tmpl, err := template.ParseFiles("templates/map.html") if err != nil { - log.Printf("Error loading map template: %v", err) + printErr("Error loading map template: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } diff --git a/node.go b/node.go index e95ab08..43960a3 100644 --- a/node.go +++ b/node.go @@ -6,7 +6,6 @@ import ( "encoding/json" "fmt" "io/ioutil" - "log" "net/http" "time" ) @@ -111,9 +110,9 @@ func startNodeClient() { err := sendMessage(peerAddr, msg) if err != nil { - log.Printf("Error sending message to %s: %v", peerAddr, err) + printWarn("Error sending message to %s: %v", peerAddr, err) } else { - log.Println("Message sent successfully to", peerAddr) + printInfo("Message sent successfully to: %s", peerAddr) } } time.Sleep(10 * time.Second) diff --git a/printing.go b/printing.go index 88abfbd..2cfd951 100644 --- a/printing.go +++ b/printing.go @@ -40,10 +40,10 @@ func printMessage(format string, args ...interface{}) { // logMessage handles the actual logging logic without using the default logger's timestamp. func logMessage(level string, format string, args ...interface{}) { - timestamp := time.Now().Format("2006-01-02|15:04:05") + timestamp := time.Now().Format("2006-01-02 15:04:05") message := fmt.Sprintf(format, args...) if level != "" { - fmt.Printf("[%s|%s] %s\n", timestamp, level, message) + fmt.Printf("[%s %s] %s\n", timestamp, level, message) } else { fmt.Printf("[%s] %s\n", timestamp, message) } diff --git a/static/css/dark.css b/static/css/dark.css new file mode 100644 index 0000000..0555cd3 --- /dev/null +++ b/static/css/dark.css @@ -0,0 +1,74 @@ +:root { + --html-bg: #1c1c1c; + --font-fg: #f1f3f4; + --fg: #BABCBE; + + --search-bg: #161616; + --search-bg-input: #333333; + --search-bg-input-border: #3C4043; + --search-select: #282828; + + --border: #303134; + + --link: #8ab4f8; + --link-visited: #c58af9; + + --snip-border: #303134; + --snip-background: #282828; + --snip-text: #f1f3f4; + + --settings-border: #5f6368; + --button: #333333; + + --footer-bg: #161616; + --footer-font: #999da2; + + --highlight: #bcc0c3; + + --blue: #8ab4f8; + + --green: #31b06e; + + --search-button: #BABCBE; + + --image-view: #161616; + --image-view-titlebar: #161616; + --view-image-color: #000000; + --image-select: #303030; + --fff: #fff; + + --publish-info: #7f869e; + + color-scheme: dark; +} + +.calc-btn:hover { + box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); +} + +.calc-btn-2:hover { + box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); +} + +.calc-btn-2 { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + transition: all 0.3s cubic-bezier(.25, .8, .25, 1); +} + +.calc-btn { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + transition: all 0.3s cubic-bezier(.25, .8, .25, 1); +} + +.calc { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); +} + +.view-image-search { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + transition: all 0.3s cubic-bezier(.25, .8, .25, 1); +} + +.view-image-search:hover { + box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); +} diff --git a/static/css/light.css b/static/css/light.css new file mode 100644 index 0000000..656f89a --- /dev/null +++ b/static/css/light.css @@ -0,0 +1,72 @@ +:root { + --html-bg: #ffffff; + --font-fg: #000000; + --fg: #202124; + + --search-bg: #ffffff; + --search-bg-input: #f6f6f6; + --search-bg-input-border: #dadce0; + --search-select: #eeeeee; + + --border: #dadce0; + + --link: #1a0dab; + --link-visited: #681da8; + + --snip-border: #dadce0; + --snip-background: #ffffff; + --snip-text: #000000; + + --settings-border: #5f6368; + --button: #f6f6f6; + + --footer-bg: #f6f6f6; + --footer-font: #353535; + + --highlight: #202124; + + --blue: #4285f4; + + --green: #202124; + + --image-view: #ffffff; + --image-view-titlebar: #ffffff; + --view-image-color: #f1f3f4; + --image-select: #f6f6f6; + --fff: #fff; + + --publish-info: #202124; + + --search-button: #202124; +} + +.wrapper-results:hover, +.wrapper-results:focus-within, +.wrapper:hover, +.wrapper:focus-within { + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08) !important; + transition: all 0.3s cubic-bezier(.25, .8, .25, 1) !important; +} + +.check p { + color: var(--highlight) !important; +} + +.image_view { + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08) !important; + transition: all 0.3s cubic-bezier(.25, .8, .25, 1) !important; +} + +.search-menu { + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08) !important; +} + +.view-image-search { + box-shadow: none; + transition: all 0.3s cubic-bezier(.25, .8, .25, 1) !important; +} + +.view-image-search:hover { + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08) !important; + transition: all 0.3s cubic-bezier(.25, .8, .25, 1) !important; +} diff --git a/static/css/style.css b/static/css/style.css index 903ba80..48d9127 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -120,6 +120,7 @@ } .clean { + margin-top: 30px; max-width: 775px; } @@ -556,7 +557,7 @@ hr { left: 0; right: 0; z-index: 2; - border: 2px solid var(--search-bg-input-border); + border: 1px solid var(--search-bg-input-border); } .wrapper input { @@ -689,7 +690,8 @@ hr { } .kno_wiki_show { - display: initial !important; + display: initial !important; + border-radius: 6px; } .open-in-new-tab * { @@ -796,6 +798,7 @@ form.torrent-sort { transition: all 0.3s cubic-bezier(.25, .8, .25, 1); border: 1px solid var(--border); border-radius: 10px; + top: 24px; } .search-menu h2 { @@ -1164,7 +1167,7 @@ p { background-color: inherit; font-size: 14px; font-family: 'Inter'; - margin-right: 10px; + margin-right: 14px; color: var(--search-button); margin-top: 72px; padding-bottom: 11px; @@ -1218,6 +1221,10 @@ p { margin-top: -2px; } +.link { + color: var(--link); +} + .results a:visited h3, .result_sublink a:visited h3 { color: var(--link-visited); @@ -1236,6 +1243,7 @@ p { .results p, .result_sublink p { margin-top: 0px; + color: var(--font-fg); } .results a, @@ -1245,6 +1253,7 @@ p { .result_sublink a:hover, .result_sublink a:visited { text-decoration: none; + /* color: #ebecf7; */ font-size: 14px; } @@ -1287,6 +1296,12 @@ p { font-size: 22px; } +.wiki_known_for { + margin: 0px; + font-weight: normal; + margin-bottom: 10px; +} + .snip img { float: right; max-width: 30%; @@ -1295,8 +1310,7 @@ p { margin-left: 10px; } -.snip a { - display: block; +.snip .wiki_link { margin-top: 10px; text-decoration: none; color: var(--link); @@ -1310,6 +1324,28 @@ p { text-decoration: underline; } +.snip .about { + font-size: 18px; + margin-top: 10px; + margin-bottom: 5px; +} + +.factpoint { + color: var(--fg); + font-weight: bold; + vertical-align: text-top; + text-align: left; + padding-right: 14px; +} + +.fact a { + color: var(--link); + text-decoration: none; +} +.fact a:visited { + color: var(--link-visited); +} + .snipp { padding: 10px; border-bottom: 1px solid var(--border); @@ -1690,7 +1726,7 @@ body, h1, p, a, input, button { margin-top: 0px; top: 0px; left: 0px; - background-color: var(--search-bg); + /* background-color: var(--search-bg); */ } .mobile-none { @@ -1860,8 +1896,7 @@ body, h1, p, a, input, button { color: var(--link) !important; } } - -/* Variables for light theme */ +/* :root { --background-color: #ffffff; --text-color: #000000; @@ -1890,7 +1925,6 @@ body, h1, p, a, input, button { --box-shadow: #00000020; } -/* Styles for dark theme */ @media (prefers-color-scheme: dark) { :root { --background-color: #202124; @@ -1919,4 +1953,4 @@ body, h1, p, a, input, button { --green: #8ab4f8; --box-shadow: #ffffff20; } -} +} */ diff --git a/static/images/dark.webp b/static/images/dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..b72872a21849c5d20c739a881f75788fd20c7f24 GIT binary patch literal 9050 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 literal 0 HcmV?d00001 diff --git a/templates/files.html b/templates/files.html index 67ed60d..b1fc4cb 100644 --- a/templates/files.html +++ b/templates/files.html @@ -4,7 +4,8 @@ {{.Query}} - Ocásek - + + @@ -74,7 +75,7 @@
{{ range .Results }} -
+
{{ if .Error }}
{{ .Error }}
{{ else }} diff --git a/templates/forums.html b/templates/forums.html index c7752aa..6d04557 100644 --- a/templates/forums.html +++ b/templates/forums.html @@ -4,7 +4,8 @@ {{.Query}} - Ocásek - + + @@ -61,7 +62,7 @@ {{if .Results}} {{range .Results}}
- {{.URL}} + {{.URL}}

{{.Header}}

{{.Description}}

diff --git a/templates/images.html b/templates/images.html index 54e3687..7a7e07d 100644 --- a/templates/images.html +++ b/templates/images.html @@ -4,7 +4,8 @@ {{.Query}} - Ocásek - + + diff --git a/templates/map.html b/templates/map.html index f698229..dedcb37 100644 --- a/templates/map.html +++ b/templates/map.html @@ -5,6 +5,7 @@ {{ .Query }} - Ocásek + diff --git a/templates/search.html b/templates/search.html index 4cc6ab8..f82599a 100644 --- a/templates/search.html +++ b/templates/search.html @@ -5,11 +5,56 @@ Search with Ocásek + + +
+

Settings

+
+ +
+

Theme: Default Theme

+
+
Dark Theme
+
Light Theme
+
+
+ + + +

Ocásek

diff --git a/templates/settings.html b/templates/settings.html index b484e7e..d106af3 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -4,7 +4,8 @@ Settings - Ocásek - + + diff --git a/templates/text.html b/templates/text.html index f7607b7..6dccaa7 100644 --- a/templates/text.html +++ b/templates/text.html @@ -4,7 +4,8 @@ {{.Query}} - Ocásek - + + @@ -61,7 +62,7 @@ {{if .Results}} {{range .Results}}
- {{.URL}} + {{.URL}}

{{.Header}}

{{.Description}}

diff --git a/templates/videos.html b/templates/videos.html index 5b2cefc..d03b984 100644 --- a/templates/videos.html +++ b/templates/videos.html @@ -5,6 +5,7 @@ {{.Query}} - Ocásek + diff --git a/text.go b/text.go index 6b26f24..471d0ed 100644 --- a/text.go +++ b/text.go @@ -3,7 +3,6 @@ package main import ( "fmt" "html/template" - "log" "net/http" "time" ) @@ -20,7 +19,7 @@ func init() { } } -func HandleTextSearch(w http.ResponseWriter, query, safe, lang string, page int) { +func HandleTextSearch(w http.ResponseWriter, settings UserSettings, query, safe, lang string, page int) { startTime := time.Now() cacheKey := CacheKey{Query: query, Page: page, Safe: safe == "true", Lang: lang, Type: "text"} @@ -39,7 +38,7 @@ func HandleTextSearch(w http.ResponseWriter, query, safe, lang string, page int) elapsedTime := time.Since(startTime) tmpl, err := template.New("text.html").Funcs(funcs).ParseFiles("templates/text.html") if err != nil { - log.Printf("Error parsing template: %v", err) + printErr("Error parsing template: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } @@ -54,6 +53,7 @@ func HandleTextSearch(w http.ResponseWriter, query, safe, lang string, page int) HasPrevPage bool HasNextPage bool NoResults bool + Theme string }{ Results: combinedResults, Query: query, @@ -64,11 +64,12 @@ func HandleTextSearch(w http.ResponseWriter, query, safe, lang string, page int) HasPrevPage: page > 1, HasNextPage: len(combinedResults) >= 50, NoResults: len(combinedResults) == 0, + Theme: settings.Theme, } err = tmpl.Execute(w, data) if err != nil { - log.Printf("Error executing template: %v", err) + printErr("Error executing template: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } @@ -80,10 +81,10 @@ func getTextResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string, go func() { results, exists := resultsCache.Get(cacheKey) if exists { - log.Println("Cache hit") + printInfo("Cache hit") cacheChan <- results } else { - log.Println("Cache miss") + printInfo("Cache miss") cacheChan <- nil } }() @@ -100,7 +101,7 @@ func getTextResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string, combinedResults = textResults } case <-time.After(2 * time.Second): - log.Println("Cache check timeout") + printInfo("Cache check timeout") combinedResults = fetchTextResults(query, safe, lang, page) if len(combinedResults) > 0 { resultsCache.Set(cacheKey, convertToSearchResults(combinedResults)) @@ -113,13 +114,13 @@ func getTextResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string, func prefetchPage(query, safe, lang string, page int) { cacheKey := CacheKey{Query: query, Page: page, Safe: safe == "true", Lang: lang, Type: "text"} if _, exists := resultsCache.Get(cacheKey); !exists { - log.Printf("Page %d not cached, caching now...", page) + printInfo("Page %d not cached, caching now...", page) pageResults := fetchTextResults(query, safe, lang, page) if len(pageResults) > 0 { resultsCache.Set(cacheKey, convertToSearchResults(pageResults)) } } else { - log.Printf("Page %d already cached", page) + printInfo("Page %d already cached", page) } } @@ -127,12 +128,12 @@ func fetchTextResults(query, safe, lang string, page int) []TextSearchResult { var results []TextSearchResult for _, engine := range textSearchEngines { - log.Printf("Using search engine: %s", engine.Name) + printInfo("Using search engine: %s", engine.Name) searchResults, duration, err := engine.Func(query, safe, lang, page) updateEngineMetrics(&engine, duration, err == nil) if err != nil { - log.Printf("Error performing search with %s: %v", engine.Name, err) + printWarn("Error performing search with %s: %v", engine.Name, err) continue } @@ -146,7 +147,7 @@ func fetchTextResults(query, safe, lang string, page int) []TextSearchResult { // If no results found after trying all engines if len(results) == 0 { - log.Printf("No text results found for query: %s, trying other nodes", query) + printWarn("No text results found for query: %s, trying other nodes", query) results = tryOtherNodesForTextSearch(query, safe, lang, page, []string{hostID}) } diff --git a/user-settings.go b/user-settings.go new file mode 100644 index 0000000..41960a7 --- /dev/null +++ b/user-settings.go @@ -0,0 +1,54 @@ +package main + +import "net/http" + +type UserSettings struct { + Theme string + Language string + SafeSearch string +} + +func loadUserSettings(r *http.Request) UserSettings { + var settings UserSettings + + // Load theme + if cookie, err := r.Cookie("theme"); err == nil { + settings.Theme = cookie.Value + } else { + settings.Theme = "dark" // Default theme + } + + // Load language + if cookie, err := r.Cookie("language"); err == nil { + settings.Language = cookie.Value + } else { + settings.Language = "en" // Default language + } + + // Load safe search + if cookie, err := r.Cookie("safe"); err == nil { + settings.SafeSearch = cookie.Value + } else { + settings.SafeSearch = "" // Default safe search off + } + + return settings +} + +func saveUserSettings(w http.ResponseWriter, settings UserSettings) { + http.SetCookie(w, &http.Cookie{ + Name: "theme", + Value: settings.Theme, + Path: "/", + }) + http.SetCookie(w, &http.Cookie{ + Name: "language", + Value: settings.Language, + Path: "/", + }) + http.SetCookie(w, &http.Cookie{ + Name: "safe", + Value: settings.SafeSearch, + Path: "/", + }) +} diff --git a/video.go b/video.go index 0e2da9d..5b09276 100644 --- a/video.go +++ b/video.go @@ -149,13 +149,13 @@ func makeHTMLRequest(query, safe, lang string, page int) (*VideoAPIResponse, err } // handleVideoSearch adapted from the Python `videoResults`, handles video search requests -func handleVideoSearch(w http.ResponseWriter, query, safe, lang string, page int) { +func handleVideoSearch(w http.ResponseWriter, settings UserSettings, query, safe, lang string, page int) { start := time.Now() - results := fetchVideoResults(query, safe, lang, page) + results := fetchVideoResults(query, settings.SafeSearch, settings.Language, page) if len(results) == 0 { log.Printf("No results from primary search, trying other nodes") - results = tryOtherNodesForVideoSearch(query, safe, lang, page, []string{hostID}) + results = tryOtherNodesForVideoSearch(query, settings.SafeSearch, settings.Language, page, []string{hostID}) } elapsed := time.Since(start) @@ -172,7 +172,8 @@ func handleVideoSearch(w http.ResponseWriter, query, safe, lang string, page int "Fetched": fmt.Sprintf("%.2f seconds", elapsed.Seconds()), "Page": page, "HasPrevPage": page > 1, - "HasNextPage": len(results) > 0, // assuming you have a way to determine if there are more pages + "HasNextPage": len(results) > 0, // no + "Theme": settings.Theme, }) if err != nil { log.Printf("Error executing template: %v", err)