From 123e9ce477321e448d703f7650b00931447aaace Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 2 Apr 2024 20:56:45 +0200 Subject: [PATCH] filesplit --- main.go | 301 ++++++++++++++--------------------------- static/css/style.css | 2 +- templates/results.html | 2 + text.go | 72 ++++++++++ 4 files changed, 180 insertions(+), 197 deletions(-) create mode 100644 text.go diff --git a/main.go b/main.go index 02f6195..2968749 100644 --- a/main.go +++ b/main.go @@ -1,223 +1,132 @@ package main import ( - "fmt" - "log" - "math/rand" - "net/http" - "net/url" - "strconv" + "fmt" + "html/template" + "log" + "net/http" + "strconv" "strings" - "time" - "html/template" - "github.com/PuerkitoBio/goquery" + "time" ) -// Define a struct to represent search result -type SearchResult struct { - URL string - Header string - Description string -} - +// LanguageOption represents a language option for search type LanguageOption struct { - Code string - Name string + Code string + Name string } var languageOptions = []LanguageOption{ - {Code: "", Name: "Any Language"}, - {Code: "lang_en", Name: "English"}, - {Code: "lang_af", Name: "Afrikaans"}, - {Code: "lang_ar", Name: "العربية (Arabic)"}, - {Code: "lang_hy", Name: "Հայերեն (Armenian)"}, - {Code: "lang_be", Name: "Беларуская (Belarusian)"}, - {Code: "lang_bg", Name: "български (Bulgarian)"}, - {Code: "lang_ca", Name: "Català (Catalan)"}, - {Code: "lang_zh-CN", Name: "中文 (简体) (Chinese Simplified)"}, - {Code: "lang_zh-TW", Name: "中文 (繁體) (Chinese Traditional)"}, - {Code: "lang_hr", Name: "Hrvatski (Croatian)"}, - {Code: "lang_cs", Name: "Čeština (Czech)"}, - {Code: "lang_da", Name: "Dansk (Danish)"}, - {Code: "lang_nl", Name: "Nederlands (Dutch)"}, - {Code: "lang_eo", Name: "Esperanto"}, - {Code: "lang_et", Name: "Eesti (Estonian)"}, - {Code: "lang_tl", Name: "Filipino (Tagalog)"}, - {Code: "lang_fi", Name: "Suomi (Finnish)"}, - {Code: "lang_fr", Name: "Français (French)"}, - {Code: "lang_de", Name: "Deutsch (German)"}, - {Code: "lang_el", Name: "Ελληνικά (Greek)"}, - {Code: "lang_iw", Name: "עברית (Hebrew)"}, - {Code: "lang_hi", Name: "हिन्दी (Hindi)"}, - {Code: "lang_hu", Name: "magyar (Hungarian)"}, - {Code: "lang_is", Name: "íslenska (Icelandic)"}, - {Code: "lang_id", Name: "Bahasa Indonesia (Indonesian)"}, - {Code: "lang_it", Name: "italiano (Italian)"}, - {Code: "lang_ja", Name: "日本語 (Japanese)"}, - {Code: "lang_ko", Name: "한국어 (Korean)"}, - {Code: "lang_lv", Name: "latviešu (Latvian)"}, - {Code: "lang_lt", Name: "lietuvių (Lithuanian)"}, - {Code: "lang_no", Name: "norsk (Norwegian)"}, - {Code: "lang_fa", Name: "فارسی (Persian)"}, - {Code: "lang_pl", Name: "polski (Polish)"}, - {Code: "lang_pt", Name: "português (Portuguese)"}, - {Code: "lang_ro", Name: "română (Romanian)"}, - {Code: "lang_ru", Name: "русский (Russian)"}, - {Code: "lang_sr", Name: "српски (Serbian)"}, - {Code: "lang_sk", Name: "slovenčina (Slovak)"}, - {Code: "lang_sl", Name: "slovenščina (Slovenian)"}, - {Code: "lang_es", Name: "español (Spanish)"}, - {Code: "lang_sw", Name: "Kiswahili (Swahili)"}, - {Code: "lang_sv", Name: "svenska (Swedish)"}, - {Code: "lang_th", Name: "ไทย (Thai)"}, - {Code: "lang_tr", Name: "Türkçe (Turkish)"}, - {Code: "lang_uk", Name: "українська (Ukrainian)"}, - {Code: "lang_vi", Name: "Tiếng Việt (Vietnamese)"}, + {Code: "", Name: "Any Language"}, + {Code: "lang_en", Name: "English"}, + {Code: "lang_af", Name: "Afrikaans"}, + {Code: "lang_ar", Name: "العربية (Arabic)"}, + {Code: "lang_hy", Name: "Հայերեն (Armenian)"}, + {Code: "lang_be", Name: "Беларуская (Belarusian)"}, + {Code: "lang_bg", Name: "български (Bulgarian)"}, + {Code: "lang_ca", Name: "Català (Catalan)"}, + {Code: "lang_zh-CN", Name: "中文 (简体) (Chinese Simplified)"}, + {Code: "lang_zh-TW", Name: "中文 (繁體) (Chinese Traditional)"}, + {Code: "lang_hr", Name: "Hrvatski (Croatian)"}, + {Code: "lang_cs", Name: "Čeština (Czech)"}, + {Code: "lang_da", Name: "Dansk (Danish)"}, + {Code: "lang_nl", Name: "Nederlands (Dutch)"}, + {Code: "lang_eo", Name: "Esperanto"}, + {Code: "lang_et", Name: "Eesti (Estonian)"}, + {Code: "lang_tl", Name: "Filipino (Tagalog)"}, + {Code: "lang_fi", Name: "Suomi (Finnish)"}, + {Code: "lang_fr", Name: "Français (French)"}, + {Code: "lang_de", Name: "Deutsch (German)"}, + {Code: "lang_el", Name: "Ελληνικά (Greek)"}, + {Code: "lang_iw", Name: "עברית (Hebrew)"}, + {Code: "lang_hi", Name: "हिन्दी (Hindi)"}, + {Code: "lang_hu", Name: "magyar (Hungarian)"}, + {Code: "lang_is", Name: "íslenska (Icelandic)"}, + {Code: "lang_id", Name: "Bahasa Indonesia (Indonesian)"}, + {Code: "lang_it", Name: "italiano (Italian)"}, + {Code: "lang_ja", Name: "日本語 (Japanese)"}, + {Code: "lang_ko", Name: "한국어 (Korean)"}, + {Code: "lang_lv", Name: "latviešu (Latvian)"}, + {Code: "lang_lt", Name: "lietuvių (Lithuanian)"}, + {Code: "lang_no", Name: "norsk (Norwegian)"}, + {Code: "lang_fa", Name: "فارسی (Persian)"}, + {Code: "lang_pl", Name: "polski (Polish)"}, + {Code: "lang_pt", Name: "português (Portuguese)"}, + {Code: "lang_ro", Name: "română (Romanian)"}, + {Code: "lang_ru", Name: "русский (Russian)"}, + {Code: "lang_sr", Name: "српски (Serbian)"}, + {Code: "lang_sk", Name: "slovenčina (Slovak)"}, + {Code: "lang_sl", Name: "slovenščina (Slovenian)"}, + {Code: "lang_es", Name: "español (Spanish)"}, + {Code: "lang_sw", Name: "Kiswahili (Swahili)"}, + {Code: "lang_sv", Name: "svenska (Swedish)"}, + {Code: "lang_th", Name: "ไทย (Thai)"}, + {Code: "lang_tr", Name: "Türkçe (Turkish)"}, + {Code: "lang_uk", Name: "українська (Ukrainian)"}, + {Code: "lang_vi", Name: "Tiếng Việt (Vietnamese)"}, } var funcs = template.FuncMap{ - "title": func(s string) string { - return strings.Title(s) - }, - "url_for": func(filename string) string { - return "/" + filename - }, + "title": func(s string) string { return strings.Title(s) }, + "url_for": func(filename string) string { return "/" + filename }, } var templates = template.Must(template.New("").Funcs(funcs).ParseFiles("templates/results.html")) func main() { - // Serve static files from the 'static' directory - http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) - - http.HandleFunc("/", handleSearch) - http.HandleFunc("/search", handleSearch) - fmt.Println("Server is listening on http://localhost:5000") - log.Fatal(http.ListenAndServe(":5000", nil)) + http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) + http.HandleFunc("/", handleSearch) + http.HandleFunc("/search", handleSearch) + fmt.Println("Server is listening on http://localhost:5000") + log.Fatal(http.ListenAndServe(":5000", nil)) } func handleSearch(w http.ResponseWriter, r *http.Request) { - var query, safe, lang string + var query, safe, lang string - // Differentiate between GET and POST requests to correctly extract query, safe, and lang. - if r.Method == "GET" { - // Serve the search page if no query is provided for a GET request - // Or extract the query parameters directly from the URL if present - query = r.URL.Query().Get("q") - if query == "" { - http.ServeFile(w, r, "static/search.html") - return - } - safe = r.URL.Query().Get("safe") - lang = r.URL.Query().Get("lang") - } else if r.Method == "POST" { - // For a POST request, extract form values - query = r.FormValue("q") - safe = r.FormValue("safe") - lang = r.FormValue("lang") - } + if r.Method == "GET" { + query = r.URL.Query().Get("q") + safe = r.URL.Query().Get("safe") + lang = r.URL.Query().Get("lang") + } else if r.Method == "POST" { + query = r.FormValue("q") + safe = r.FormValue("safe") + lang = r.FormValue("lang") + } - // Early return if query is empty - if query == "" { - http.ServeFile(w, r, "static/search.html") - return - } + if query == "" { + http.ServeFile(w, r, "static/search.html") + return + } - // Time - start := time.Now() + start := time.Now() // This line is correctly placed + results, err := PerformTextSearch(query, safe, lang) + if err != nil { + http.Error(w, "Failed to fetch search results", http.StatusInternalServerError) + return + } + elapsed := time.Since(start) // Correctly captures the elapsed time after search + fetched := fmt.Sprintf("Fetched the results in %.2f seconds", elapsed.Seconds()) - // Adjust the search URL based on safe search and language settings - var safeParam string - if safe == "active" { - safeParam = "&safe=active" - } else { - safeParam = "&safe=off" - } + data := struct { + Results []SearchResult + Query string + Fetched string + ElapsedTime string + LanguageOptions []LanguageOption + CurrentLang string + }{ + Results: results, + Query: query, + Fetched: fetched, + ElapsedTime: strconv.FormatFloat(time.Since(start).Seconds(), 'f', 2, 64), + LanguageOptions: languageOptions, + CurrentLang: lang, + } - var langParam string - if lang != "" { - langParam = "&lr=" + lang - } - - searchURL := "https://www.google.com/search?q=" + url.QueryEscape(query) + safeParam + langParam - print(searchURL+"\n") - req, err := http.NewRequest("GET", searchURL, nil) - if err != nil { - http.Error(w, "Failed to create request", http.StatusInternalServerError) - return - } - - // Random user agent - userAgents := []string{ - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15", - } - randIndex := rand.Intn(len(userAgents)) - userAgent := userAgents[randIndex] - - req.Header.Set("User-Agent", userAgent) - resp, err := http.DefaultClient.Do(req) - if err != nil { - http.Error(w, "Failed to fetch search results", http.StatusInternalServerError) - return - } - defer resp.Body.Close() - - // Parse HTML - doc, err := goquery.NewDocumentFromReader(resp.Body) - if err != nil { - http.Error(w, "Failed to parse HTML", http.StatusInternalServerError) - return - } - - // Retrieve links, headers, and descriptions - var results []SearchResult - doc.Find(".yuRUbf").Each(func(i int, s *goquery.Selection) { - link := s.Find("a") - href, _ := link.Attr("href") - header := link.Find("h3").Text() - header = strings.TrimSpace(strings.TrimSuffix(header, "›")) - - descSelection := doc.Find(".VwiC3b").Eq(i) - description := "" - if descSelection.Length() > 0 { - description = descSelection.Text() - } - - results = append(results, SearchResult{ - URL: href, - Header: header, - Description: description, - }) - }) - - elapsed := time.Since(start) - - // Prepare data for rendering template - data := struct { - Results []SearchResult - Query string - Fetched string - ElapsedTime string - LanguageOptions []LanguageOption - CurrentLang string - }{ - Results: results, - Query: query, - Fetched: fmt.Sprintf("Fetched the results in %.2f seconds", elapsed.Seconds()), - ElapsedTime: strconv.FormatFloat(elapsed.Seconds(), 'f', 2, 64), - LanguageOptions: languageOptions, - CurrentLang: lang, - } - - // Render template - err = templates.ExecuteTemplate(w, "results.html", data) - if err != nil { - http.Error(w, "Failed to render template", http.StatusInternalServerError) - return - } + err = templates.ExecuteTemplate(w, "results.html", data) + if err != nil { + http.Error(w, "Failed to render template", http.StatusInternalServerError) + return + } } diff --git a/static/css/style.css b/static/css/style.css index bdd1722..ee261a3 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1388,7 +1388,7 @@ p { --footer-bg: #303134; --footer-font: #e8eaed; --border: #5f6368; - --link-visited: #c79ff; + --link-visited: #c79fff; --publish-info: #e8eaed; --green: #8ab4f8; } diff --git a/templates/results.html b/templates/results.html index 329a982..e6bbb12 100644 --- a/templates/results.html +++ b/templates/results.html @@ -33,9 +33,11 @@ {{range .Results}}
+ {{.URL}}

{{.Header}}

{{.Description}}

+
{{end}} diff --git a/text.go b/text.go new file mode 100644 index 0000000..7e88b57 --- /dev/null +++ b/text.go @@ -0,0 +1,72 @@ +package main + +import ( + "log" + "net/http" + "net/url" + "strings" + + "github.com/PuerkitoBio/goquery" +) + +type SearchResult struct { + URL string + Header string + Description string +} + +func PerformTextSearch(query, safe, lang string) ([]SearchResult, error) { + var results []SearchResult + + client := &http.Client{} + safeParam := "&safe=off" + if safe == "active" { + safeParam = "&safe=active" + } + + langParam := "" + if lang != "" { + langParam = "&lr=" + lang + } + + searchURL := "https://www.google.com/search?q=" + url.QueryEscape(query) + safeParam + langParam + + req, err := http.NewRequest("GET", searchURL, nil) + if err != nil { + log.Fatalf("Failed to create request: %v", err) + } + + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36") + + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + doc, err := goquery.NewDocumentFromReader(resp.Body) + if err != nil { + return nil, err + } + + doc.Find(".yuRUbf").Each(func(i int, s *goquery.Selection) { + link := s.Find("a") + href, _ := link.Attr("href") + header := link.Find("h3").Text() + header = strings.TrimSpace(strings.TrimSuffix(header, "›")) + + descSelection := doc.Find(".VwiC3b").Eq(i) + description := "" + if descSelection.Length() > 0 { + description = descSelection.Text() + } + + results = append(results, SearchResult{ + URL: href, + Header: header, + Description: description, + }) + }) + + return results, nil +}