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 0000000..b72872a Binary files /dev/null and b/static/images/dark.webp differ diff --git a/static/images/light.webp b/static/images/light.webp new file mode 100644 index 0000000..4c7146d Binary files /dev/null and b/static/images/light.webp differ 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)