diff --git a/common.go b/common.go index 3915f24..b128041 100755 --- a/common.go +++ b/common.go @@ -3,7 +3,9 @@ package main import ( "crypto/rand" "encoding/base64" + "encoding/json" "html/template" + "net/http" "strings" ) @@ -15,9 +17,35 @@ var ( "add": func(a, b int) int { return a + b }, + "translate": Translate, + "toJSON": func(v interface{}) (string, error) { + jsonBytes, err := json.Marshal(v) + if err != nil { + return "", err + } + return string(jsonBytes), nil + }, } ) +// Helper function to render templates without elapsed time measurement +func renderTemplate(w http.ResponseWriter, tmplName string, data map[string]interface{}) { + // Parse the template with common functions (including translate) + tmpl, err := template.New(tmplName).Funcs(funcs).ParseFiles("templates/" + tmplName) + if err != nil { + printErr("Error parsing template: %v", err) + http.Error(w, Translate("internal_server_error"), http.StatusInternalServerError) + return + } + + // Execute the template + err = tmpl.Execute(w, data) + if err != nil { + printErr("Error executing template: %v", err) + http.Error(w, Translate("internal_server_error"), http.StatusInternalServerError) + } +} + func generateStrongRandomString(length int) string { bytes := make([]byte, length) _, err := rand.Read(bytes) diff --git a/files.go b/files.go index fb849cd..3f7847b 100755 --- a/files.go +++ b/files.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "html/template" "net/http" "net/url" "regexp" @@ -44,59 +43,30 @@ func handleFileSearch(w http.ResponseWriter, settings UserSettings, query string 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 the results by the number of seeders sort.Slice(combinedResults, func(i, j int) bool { return combinedResults[i].Seeders > combinedResults[j].Seeders }) elapsedTime := time.Since(startTime) - funcMap := template.FuncMap{ - "sub": func(a, b int) int { return a - b }, - "add": func(a, b int) int { return a + b }, - } - tmpl, err := template.New("files.html").Funcs(funcMap).ParseFiles("templates/files.html") - if err != nil { - printErr("Failed to load template: %v", err) - http.Error(w, "Failed to load template", http.StatusInternalServerError) - return + + // Prepare the data to pass to the template + data := map[string]interface{}{ + "Results": combinedResults, + "Query": query, + "Fetched": fmt.Sprintf("%.2f %s", elapsedTime.Seconds(), Translate("seconds")), // Time for fetching results + "Category": "all", + "Sort": "seed", + "Page": page, + "HasPrevPage": page > 1, + "HasNextPage": len(combinedResults) > 0, + "LanguageOptions": languageOptions, + "CurrentLang": settings.SearchLanguage, + "Theme": settings.Theme, + "Safe": settings.SafeSearch, + "IsThemeDark": settings.IsThemeDark, } - data := struct { - Results []TorrentResult - Query string - Fetched string - Category string - Sort string - Page int - HasPrevPage bool - HasNextPage bool - LanguageOptions []LanguageOption - CurrentLang string - Theme string - Safe string - IsThemeDark bool - }{ - Results: combinedResults, - Query: query, - Fetched: fmt.Sprintf("%.2f seconds", elapsedTime.Seconds()), - Category: "all", - Sort: "seed", - Page: page, - HasPrevPage: page > 1, - HasNextPage: len(combinedResults) > 0, - LanguageOptions: languageOptions, - CurrentLang: settings.SearchLanguage, - Theme: settings.Theme, - Safe: settings.SafeSearch, - IsThemeDark: settings.IsThemeDark, - } - - // // Debugging: Print results before rendering template - // for _, result := range combinedResults { - // fmt.Printf("Title: %s, Magnet: %s\n", result.Title, result.Magnet) - // } - - if err := tmpl.Execute(w, data); err != nil { - printErr("Failed to render template: %v", err) - http.Error(w, "Failed to render template", http.StatusInternalServerError) - } + // Render the template without measuring the time + renderTemplate(w, "files.html", data) } func getFileResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string, page int) []TorrentResult { diff --git a/forums.go b/forums.go index e9fa982..ea1a2f6 100755 --- a/forums.go +++ b/forums.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "fmt" - "html/template" "log" "math" "net/http" @@ -99,48 +98,34 @@ func PerformRedditSearch(query string, safe string, page int) ([]ForumSearchResu } func handleForumsSearch(w http.ResponseWriter, settings UserSettings, query string, page int) { + // Start measuring the time for fetching results + startTime := time.Now() + + // Perform the forum search 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 { log.Printf("No results from primary search, trying other nodes") results = tryOtherNodesForForumSearch(query, settings.SafeSearch, settings.SearchLanguage, page) } - data := struct { - Query string - Results []ForumSearchResult - Page int - HasPrevPage bool - HasNextPage bool - LanguageOptions []LanguageOption - CurrentLang string - Theme string - Safe string - IsThemeDark bool - }{ - Query: query, - Results: results, - Page: page, - HasPrevPage: page > 1, - HasNextPage: len(results) == 25, - LanguageOptions: languageOptions, - CurrentLang: settings.SearchLanguage, - Theme: settings.Theme, - Safe: settings.SafeSearch, - IsThemeDark: settings.IsThemeDark, + // Measure the elapsed time for fetching results + elapsedTime := time.Since(startTime) + + // Prepare the data to pass to the template + data := map[string]interface{}{ + "Query": query, + "Results": results, + "Page": page, + "Fetched": fmt.Sprintf("%.2f %s", elapsedTime.Seconds(), Translate("seconds")), // Time for fetching results + "HasPrevPage": page > 1, + "HasNextPage": len(results) == 25, // Assuming 25 results per page + "LanguageOptions": languageOptions, + "CurrentLang": settings.SearchLanguage, + "Theme": settings.Theme, + "Safe": settings.SafeSearch, + "IsThemeDark": settings.IsThemeDark, } - funcMap := template.FuncMap{ - "sub": func(a, b int) int { return a - b }, - "add": func(a, b int) int { return a + b }, - } - - tmpl, err := template.New("forums.html").Funcs(funcMap).ParseFiles("templates/forums.html") - if err != nil { - http.Error(w, fmt.Sprintf("Error loading template: %v", err), http.StatusInternalServerError) - return - } - - if err := tmpl.Execute(w, data); err != nil { - http.Error(w, fmt.Sprintf("Error rendering template: %v", err), http.StatusInternalServerError) - } + // Render the template without measuring the time + renderTemplate(w, "forums.html", data) } diff --git a/images.go b/images.go index 7bd55a4..f67ca3d 100755 --- a/images.go +++ b/images.go @@ -2,8 +2,6 @@ package main import ( "fmt" - "html/template" - "log" "net/http" "time" ) @@ -26,46 +24,25 @@ func handleImageSearch(w http.ResponseWriter, settings UserSettings, query strin 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") - if err != nil { - log.Printf("Error parsing template: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return + + // Prepare the data to pass to the template + data := map[string]interface{}{ + "Results": combinedResults, + "Query": query, + "Fetched": fmt.Sprintf("%.2f %s", elapsedTime.Seconds(), Translate("seconds")), // Time for fetching + "Page": page, + "HasPrevPage": page > 1, + "HasNextPage": len(combinedResults) >= 50, + "NoResults": len(combinedResults) == 0, + "LanguageOptions": languageOptions, + "CurrentLang": settings.SearchLanguage, + "Theme": settings.Theme, + "Safe": settings.SafeSearch, + "IsThemeDark": settings.IsThemeDark, } - data := struct { - Results []ImageSearchResult - Query string - Page int - Fetched string - HasPrevPage bool - HasNextPage bool - NoResults bool - LanguageOptions []LanguageOption - CurrentLang string - Theme string - Safe string - IsThemeDark bool - }{ - Results: combinedResults, - Query: query, - Page: page, - Fetched: fmt.Sprintf("%.2f seconds", elapsedTime.Seconds()), - HasPrevPage: page > 1, - HasNextPage: len(combinedResults) >= 50, - NoResults: len(combinedResults) == 0, - LanguageOptions: languageOptions, - CurrentLang: settings.SearchLanguage, - Theme: settings.Theme, - Safe: settings.SafeSearch, - IsThemeDark: settings.IsThemeDark, - } - - err = tmpl.Execute(w, data) - if err != nil { - printErr("Error executing template: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - } + // Render the template without measuring the time + renderTemplate(w, "images.html", data) } func getImageResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string, page int) []ImageSearchResult { diff --git a/lang/en/LC_MESSAGES/default.po b/lang/en/LC_MESSAGES/default.po index d37eb73..99311b4 100644 --- a/lang/en/LC_MESSAGES/default.po +++ b/lang/en/LC_MESSAGES/default.po @@ -1,4 +1,3 @@ - msgid "settings_title" msgstr "Settings" @@ -29,10 +28,10 @@ msgstr "Latte" msgid "safe_search" msgstr "Safe Search" -msgid "safe_search_off" +msgid "off" msgstr "Off" -msgid "safe_search_on" +msgid "on" msgstr "On" msgid "site_language" @@ -41,5 +40,152 @@ msgstr "Site Language" msgid "search_language" msgstr "Search Language" +msgid "no_results" +msgstr "No results found for '%s'. Try different keywords." + +msgid "no_more_results" +msgstr "Looks like this is the end of results." + +msgid "safe_search_off" +msgstr "Safe Search Off" + +msgid "safe_search_on" +msgstr "Safe Search On" + msgid "save_settings" -msgstr "Save Settings" +msgstr "Save settings" + +msgid "page_title" +msgstr "Search results for '%s'" + +msgid "site_name" +msgstr "Ocásek" + +msgid "search" +msgstr "Search" + +msgid "web" +msgstr "Web" + +msgid "image" +msgstr "Image" + +msgid "images" +msgstr "Images" + +msgid "video" +msgstr "Video" + +msgid "videos" +msgstr "Videos" + +msgid "forum" +msgstr "Forum" + +msgid "forums" +msgstr "Forums" + +msgid "map" +msgstr "Map" + +msgid "maps" +msgstr "Maps" + +msgid "file" +msgstr "File" + +msgid "torrents" +msgstr "Torrents" + +msgid "searching_for_new_results" +msgstr "Searching for new results..." + +msgid "previous" +msgstr "Previous" + +msgid "next" +msgstr "Next" + +msgid "fetched_in" +msgstr "Fetched in %s seconds" + +msgid "sort_seeders" +msgstr "Number of Seeders" + +msgid "sort_leechers" +msgstr "Number of Leechers" + +msgid "sort_lth" +msgstr "Size (Low to High)" + +msgid "sort_htl" +msgstr "Size (High to Low)" + +msgid "category_all" +msgstr "All Categories" + +msgid "category_movie" +msgstr "Movies" + +msgid "category_audiobook" +msgstr "Audiobooks" + +msgid "category_tv" +msgstr "TV Shows" + +msgid "category_games" +msgstr "Games" + +msgid "category_software" +msgstr "Software" + +msgid "category_anime" +msgstr "Anime" + +msgid "category_music" +msgstr "Music" + +msgid "category_xxx" +msgstr "XXX (18+)" + +msgid "apply_settings" +msgstr "Apply settings" + +msgid "error" +msgstr "Error" + +msgid "views" +msgstr "views" + +msgid "seeders" +msgstr "Seeders" + +msgid "leechers" +msgstr "Leechers" + +msgid "no_results_found" +msgstr "Your search '%s' came back with no results." + +msgid "suggest_rephrase" +msgstr "Try rephrasing your search term and/or correct any spelling mistakes." + +msgid "streets" +msgstr "Streets" + +msgid "satellite" +msgstr "Satellite" + +msgid "esri_satellite" +msgstr "Esri Satellite" + +msgid "topographic" +msgstr "Topographic" + +msgid "locate_me" +msgstr "Locate Me" + +msgid "you_are_within" +msgstr "You are within " + +msgid "meters_from_point" +msgstr "meters from this point" diff --git a/lang/pl/LC_MESSAGES/default.po b/lang/pl/LC_MESSAGES/default.po index 4acac06..f60783a 100644 --- a/lang/pl/LC_MESSAGES/default.po +++ b/lang/pl/LC_MESSAGES/default.po @@ -1,4 +1,3 @@ - msgid "settings_title" msgstr "Ustawienia" @@ -29,17 +28,164 @@ msgstr "Latte" msgid "safe_search" msgstr "Bezpieczne wyszukiwanie" -msgid "safe_search_off" +msgid "off" msgstr "Wyłączone" -msgid "safe_search_on" +msgid "on" msgstr "Włączone" msgid "site_language" -msgstr "Język witryny" +msgstr "Język strony" msgid "search_language" msgstr "Język wyszukiwania" +msgid "no_results" +msgstr "Nie znaleziono wyników dla '%s'. Spróbuj innych słów kluczowych." + +msgid "no_more_results" +msgstr "Wygląda na to, że to koniec wyników." + +msgid "safe_search_off" +msgstr "Wyłączony filtr" + +msgid "safe_search_on" +msgstr "Włączony filtr" + msgid "save_settings" -msgstr "Zapisz ustawienia" \ No newline at end of file +msgstr "Zapisz ustawienia" + +msgid "page_title" +msgstr "Wyniki wyszukiwania dla '%s'" + +msgid "site_name" +msgstr "Ocásek" + +msgid "search" +msgstr "Szukaj" + +msgid "web" +msgstr "Strona" + +msgid "image" +msgstr "Obraz" + +msgid "images" +msgstr "Obrazy" + +msgid "video" +msgstr "Wideo" + +msgid "videos" +msgstr "Wideo" + +msgid "forum" +msgstr "Forum" + +msgid "forums" +msgstr "Fora" + +msgid "map" +msgstr "Mapa" + +msgid "maps" +msgstr "Mapy" + +msgid "file" +msgstr "Plik" + +msgid "torrents" +msgstr "Torrenty" + +msgid "searching_for_new_results" +msgstr "Wyszukiwanie nowych wyników..." + +msgid "previous" +msgstr "Poprzednie" + +msgid "next" +msgstr "Następne" + +msgid "fetched_in" +msgstr "Pobrano w %s sekund" + +msgid "sort_seeders" +msgstr "Liczba seedów" + +msgid "sort_leechers" +msgstr "Liczba leechów" + +msgid "sort_lth" +msgstr "Rozmiar (od najmniejszego)" + +msgid "sort_htl" +msgstr "Rozmiar (od największego)" + +msgid "category_all" +msgstr "Wszystkie kategorie" + +msgid "category_movie" +msgstr "Filmy" + +msgid "category_audiobook" +msgstr "Audiobooki" + +msgid "category_tv" +msgstr "Seriale TV" + +msgid "category_games" +msgstr "Gry" + +msgid "category_software" +msgstr "Oprogramowanie" + +msgid "category_anime" +msgstr "Anime" + +msgid "category_music" +msgstr "Muzyka" + +msgid "category_xxx" +msgstr "XXX (18+)" + +msgid "apply_settings" +msgstr "Zastosuj ustawienia" + +msgid "error" +msgstr "Błąd" + +msgid "views" +msgstr "Wyświetlenia" + +msgid "seeders" +msgstr "Seedy" + +msgid "leechers" +msgstr "Leechy" + +msgid "no_results_found" +msgstr "Twoje wyszukiwanie '%s' nie zwróciło żadnych wyników." + +msgid "suggest_rephrase" +msgstr "Spróbuj zmienić zapytanie lub poprawić błędy ortograficzne." + +msgid "streets" +msgstr "Ulice" + +msgid "satellite" +msgstr "Satelita" + +msgid "esri_satellite" +msgstr "Esri Satelita" + +msgid "topographic" +msgstr "Topograficzna" + +msgid "locate_me" +msgstr "Zlokalizuj mnie" + +msgid "you_are_within" +msgstr "Znajdujesz się w odległości " + +msgid "meters_from_point" +msgstr "metrów od tego punktu" diff --git a/main.go b/main.go index 91bc3f9..2541c58 100755 --- a/main.go +++ b/main.go @@ -126,11 +126,25 @@ func handleSearch(w http.ResponseWriter, r *http.Request) { IsThemeDark: settings.IsThemeDark, } - tmpl := template.Must(template.ParseFiles("templates/search.html")) - tmpl.Execute(w, data) + // Add Translate to the template functions + tmpl, err := template.New("search.html").Funcs(template.FuncMap{ + "translate": Translate, + }).ParseFiles("templates/search.html") + if err != nil { + printErr("Error parsing template: %v", err) + http.Error(w, Translate("internal_server_error"), http.StatusInternalServerError) + return + } + + err = tmpl.Execute(w, data) + if err != nil { + printErr("Error executing template: %v", err) + http.Error(w, Translate("internal_server_error"), http.StatusInternalServerError) + } return } + // Handle different search types switch searchType { case "image": handleImageSearch(w, settings, query, page) diff --git a/map.go b/map.go index 1008353..9bc3e32 100755 --- a/map.go +++ b/map.go @@ -3,9 +3,9 @@ package main import ( "encoding/json" "fmt" - "html/template" "net/http" "net/url" + "time" ) type NominatimResponse struct { @@ -44,31 +44,32 @@ func geocodeQuery(query string) (latitude, longitude string, found bool, err err } func handleMapSearch(w http.ResponseWriter, settings UserSettings, query string) { + // Start measuring the time for geocoding the query + startTime := time.Now() + // Geocode the query to get coordinates latitude, longitude, found, err := geocodeQuery(query) if err != nil { printDebug("Error geocoding query: %s, error: %v", query, err) - http.Error(w, "Failed to find location", http.StatusInternalServerError) + http.Error(w, Translate("internal_server_error"), http.StatusInternalServerError) return } - // Use a template to serve the map page + // Measure the elapsed time for geocoding + elapsedTime := time.Since(startTime) + + // Prepare the data to pass to the template data := map[string]interface{}{ "Query": query, "Latitude": latitude, "Longitude": longitude, "Found": found, + "Fetched": fmt.Sprintf("%.2f %s", elapsedTime.Seconds(), Translate("seconds")), "Theme": settings.Theme, "Safe": settings.SafeSearch, "IsThemeDark": settings.IsThemeDark, } - tmpl, err := template.ParseFiles("templates/map.html") - if err != nil { - printErr("Error loading map template: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - - tmpl.Execute(w, data) + // Render the template + renderTemplate(w, "map.html", data) } diff --git a/templates/files.html b/templates/files.html index 4b1b246..24d91c8 100755 --- a/templates/files.html +++ b/templates/files.html @@ -6,14 +6,14 @@ {{ if .IsThemeDark }} {{ end }} - {{.Query}} - Ocásek + {{ translate "page_title" .Query }} - +
-

Ocásek

+

{{ translate "site_name" }}

@@ -26,70 +26,70 @@
- +
- +
- +
- +
- +
- +
-

Fetched in {{ .Fetched }} seconds

+

{{ translate "fetched_in" .Fetched }}

{{ if .Results }}
- +
{{ range .Results }}
{{ if .Error }} -
{{ .Error }}
+
{{ translate "error" }}: {{ .Error }}
{{ else }} {{ .URL }}

{{ .Title }}

-

{{ if .Views }}{{ .Views }} views • {{ end }}{{ .Size }}

-

Seeders: {{ .Seeders }} | Leechers: {{ .Leechers }}

+

{{ if .Views }}{{ .Views }} {{ translate "views" }} • {{ end }}{{ .Size }}

+

{{ translate "seeders" }}: {{ .Seeders }} | {{ translate "leechers" }}: {{ .Leechers }}

{{ end }}
{{ end }} @@ -99,17 +99,17 @@ {{ if .HasPrevPage }} - + {{ end }} {{ if .HasNextPage }} - + {{ end }}
{{ else }}
- Your search '{{ .Query }}' came back with no results.
- Try rephrasing your search term and/or recorrect any spelling mistakes. + {{ translate "no_results_found" .Query }}
+ {{ translate "suggest_rephrase" }}
{{ end }} diff --git a/templates/forums.html b/templates/forums.html index 3fbdea7..67168d5 100755 --- a/templates/forums.html +++ b/templates/forums.html @@ -6,14 +6,14 @@ {{ if .IsThemeDark }} {{ end }} - {{.Query}} - Ocásek + {{ translate "page_title" .Query }} - +
-

Ocásek

+

{{ translate "site_name" }}

@@ -25,44 +25,44 @@
- +
- +
- +
- +
- +
- +
- +
{{if .Results}} @@ -75,13 +75,13 @@
{{end}} {{else if .NoResults}} -
No results found for '{{ .Query }}'. Try different keywords.
+
{{ translate "no_results" .Query }}
{{else}} -
Looks like this is the end of results.
+
{{ translate "no_more_results" }}
{{end}}
- Searching for new results... + {{ translate "searching_for_new_results" }}
@@ -89,10 +89,10 @@
{{ if .HasPrevPage }} - + {{ end }} {{ if .HasNextPage }} - + {{ end }}
diff --git a/templates/images.html b/templates/images.html index 206315b..e5a0849 100755 --- a/templates/images.html +++ b/templates/images.html @@ -6,15 +6,15 @@ {{ if .IsThemeDark }} {{ end }} - {{.Query}} - Ocásek + {{ translate "page_title" .Query }} - +
-

Ocásek

+

{{ translate "site_name" }}

@@ -27,44 +27,44 @@
- +
- +
- +
- +
- +
- +
- +
@@ -78,7 +78,7 @@
{{ .Width }} × {{ .Height }}
{{ .Title }} - Source + {{ translate "source" }}
{{ end }} @@ -90,24 +90,22 @@ {{ if .HasPrevPage }} - - + {{ end }} {{ if .HasNextPage }} - - + {{ end }}
{{ else if .NoResults }} -
No results found for '{{ .Query }}'. Try different keywords.
+
{{ translate "no_results" .Query }}
{{ else }} -
Looks like this is the end of results.
+
{{ translate "no_more_results" }}
{{ end }}
- Searching for new results... + {{ translate "searching_for_new_results" }}
diff --git a/templates/map.html b/templates/map.html index d0d9fa3..1cb3bd4 100644 --- a/templates/map.html +++ b/templates/map.html @@ -6,10 +6,10 @@ {{ if .IsThemeDark }} {{ end }} - {{ .Query }} - Ocásek + {{ translate "page_title" .Query }} - +