diff --git a/README.md b/README.md index 5019b4f..f6f0038 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ - [x] Text results - [x] Image results +- [X] Video results - [x] HTML+CSS site (no JS version) ## Pending Tasks -- [ ] Video results - [ ] Forums results - [ ] Map results - [ ] Torrent results @@ -21,16 +21,14 @@ # Go Search Engine -A self-hosted aggregate search engine that respects privacy, contains no ads, and serves as a proxy to Google website. +A self-hosted aggregate search engine that respects privacy, contains no ads, and serves as a proxy/alternative to Google website. ## Features -- Image search using the Qwant API. - Text search using Google search results. -- Responsive web interface for displaying search results with previews. +- Image search using the Qwant API. +- Video search using Piped API. - Image viewing using proxy and direct links to image source pages for image searches. -- Display of text search results with links to source content. - ## Getting Started @@ -43,8 +41,9 @@ A self-hosted aggregate search engine that respects privacy, contains no ads, an ```bash git clone https://weforgecode.xyz/Spitfire/Search.git -cd search -go run main.go text.go images.go imageproxy.go +cd Search +chmod +x ./run.sh +./run.sh ``` ## Project Structure @@ -55,7 +54,9 @@ go run main.go text.go images.go imageproxy.go - `imageproxy.go`: Part of images.go srach logic, handles image reuslts and displays them using proxy. - `/templates`: Directory containing HTML templates for rendering the search interface and results. - `search.html`: The main search page template. + - `text.html`: Template for displaying text search results. - `images.html`: Template for displaying image search results. - - `text.html`: (If applicable) Template for displaying text search results. + - `videos.html`: Template for displaying video search results. - `/static/css`: Directory for CSS stylesheets. - - `style.css`: The main stylesheet for the search interface and results. \ No newline at end of file + - `style.css`: The main stylesheet for the search interface and results. +- `/static/css`: Directory for fonts and icons (as font). \ No newline at end of file diff --git a/main.go b/main.go index 46e2d4d..9550f84 100644 --- a/main.go +++ b/main.go @@ -63,18 +63,14 @@ var languageOptions = []LanguageOption{ {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 }, -// } - -// var templates = template.Must(template.New("").Funcs(funcs).ParseFiles("templates/results.html")) - func main() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) http.HandleFunc("/", handleSearch) http.HandleFunc("/search", handleSearch) http.HandleFunc("/img_proxy", handleImageProxy) + http.HandleFunc("/settings", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "templates/settings.html") + }) fmt.Println("Server is listening on http://localhost:5000") log.Fatal(http.ListenAndServe(":5000", nil)) } @@ -102,7 +98,7 @@ func handleSearch(w http.ResponseWriter, r *http.Request) { } if query == "" { - http.ServeFile(w, r, "static/search.html") + http.ServeFile(w, r, "templates/search.html") return } @@ -114,6 +110,6 @@ func handleSearch(w http.ResponseWriter, r *http.Request) { case "video": videoSearchEndpointHandler(w, r) default: - http.ServeFile(w, r, "static/search.html") + http.ServeFile(w, r, "templates/search.html") } } diff --git a/run.sh b/run.sh index 469dfac..b422cea 100755 --- a/run.sh +++ b/run.sh @@ -1,3 +1,3 @@ #!/bin/bash -go run main.go text.go images.go imageproxy.go video.go \ No newline at end of file +$ go run main.go text-google.go images.go imageproxy.go video.go \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css index 7ac347c..b8171d2 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1150,7 +1150,7 @@ p { background-color: inherit; font-size: 14px; font-family: 'Inter'; - margin-right: 14px; + margin-right: 10px; color: var(--search-button); margin-top: 72px; padding-bottom: 11px; diff --git a/static/searchicon.png b/static/searchicon.png deleted file mode 100644 index c751913..0000000 Binary files a/static/searchicon.png and /dev/null differ diff --git a/templates/A.html b/templates/A.html deleted file mode 100644 index 9bc0178..0000000 --- a/templates/A.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "results_layout.html" %} - -{% block body %} -

{{ lang_data.results.results }} {{ fetched }} {{ lang_data.results.seconds }}

- {% if results %} - {% for result in results %} -
- -
-

{{ result[1] }}

-

{{ result[3] }} • {{ result[2] }}

-

{{ result[5] }} | {{ result[4] }}

-
-
-
- {% endfor %} - - {% else %} -
- Your search '{{ q }}' came back with no results.
- Try rephrasing your search term and/or recorrect any spelling mistakes. -
- {% endif %} -{% endblock %} \ No newline at end of file diff --git a/static/search.html b/templates/search.html similarity index 86% rename from static/search.html rename to templates/search.html index fc381d4..710f381 100644 --- a/static/search.html +++ b/templates/search.html @@ -8,14 +8,14 @@

Ocásek

- close + close
diff --git a/templates/settings.html b/templates/settings.html new file mode 100644 index 0000000..c7540b2 --- /dev/null +++ b/templates/settings.html @@ -0,0 +1,70 @@ + + + + + + Settings + + + + +

Ocásek

+
+ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+

Settings

+

Theme

+ +
+ +

Language

+ +
+ + + +

Privacy

+ +
+ +

+ + +
+
+ + diff --git a/templates/results.html b/templates/text.html similarity index 100% rename from templates/results.html rename to templates/text.html diff --git a/text-google.go b/text-google.go new file mode 100644 index 0000000..0a49342 --- /dev/null +++ b/text-google.go @@ -0,0 +1,113 @@ +package main + +import ( + "fmt" + "html/template" + "log" + "net/http" + "net/url" + "strings" + "time" + + "github.com/PuerkitoBio/goquery" +) + +type TextSearchResult struct { + URL string + Header string + Description string +} + +func PerformTextSearch(query, safe, lang string) ([]TextSearchResult, error) { + var results []TextSearchResult + + 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, TextSearchResult{ + URL: href, + Header: header, + Description: description, + }) + }) + + return results, nil +} + +func handleTextSearch(w http.ResponseWriter, query, safe, lang string) { + // Perform the text search + results, err := PerformTextSearch(query, safe, lang) + if err != nil { + log.Printf("Error performing text search: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } + + // Assuming you have a separate template for text search results + tmpl, err := template.ParseFiles("templates/text.html") // Ensure this path matches your templates' location + if err != nil { + log.Printf("Error parsing template: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } + + data := struct { + Results []TextSearchResult // Ensure this type matches the structure expected by your template + Query string + Fetched string + LanguageOptions []LanguageOption + CurrentLang string + }{ + Results: results, + Query: query, + Fetched: fmt.Sprintf("%.2f seconds", time.Since(time.Now()).Seconds()), // Example fetched time, adjust as necessary + LanguageOptions: languageOptions, // Assuming this is defined globally or elsewhere + CurrentLang: lang, + } + + err = tmpl.Execute(w, data) + if err != nil { + log.Printf("Error executing template: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + } +} diff --git a/text.go b/text.go index 141c44c..e69de29 100644 --- a/text.go +++ b/text.go @@ -1,113 +0,0 @@ -package main - -import ( - "fmt" - "html/template" - "log" - "net/http" - "net/url" - "strings" - "time" - - "github.com/PuerkitoBio/goquery" -) - -type TextSearchResult struct { - URL string - Header string - Description string -} - -func PerformTextSearch(query, safe, lang string) ([]TextSearchResult, error) { - var results []TextSearchResult - - 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, TextSearchResult{ - URL: href, - Header: header, - Description: description, - }) - }) - - return results, nil -} - -func handleTextSearch(w http.ResponseWriter, query, safe, lang string) { - // Perform the text search - results, err := PerformTextSearch(query, safe, lang) - if err != nil { - log.Printf("Error performing text search: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - - // Assuming you have a separate template for text search results - tmpl, err := template.ParseFiles("templates/results.html") // Ensure this path matches your templates' location - if err != nil { - log.Printf("Error parsing template: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - - data := struct { - Results []TextSearchResult // Ensure this type matches the structure expected by your template - Query string - Fetched string - LanguageOptions []LanguageOption - CurrentLang string - }{ - Results: results, - Query: query, - Fetched: fmt.Sprintf("%.2f seconds", time.Since(time.Now()).Seconds()), // Example fetched time, adjust as necessary - LanguageOptions: languageOptions, // Assuming this is defined globally or elsewhere - CurrentLang: lang, - } - - err = tmpl.Execute(w, data) - if err != nil { - log.Printf("Error executing template: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - } -}