files search added (wip)
This commit is contained in:
parent
585684f15b
commit
31460ee6be
13 changed files with 431 additions and 44 deletions
185
files-torrentgalaxy.go
Normal file
185
files-torrentgalaxy.go
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/PuerkitoBio/goquery"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TORRENTGALAXY_DOMAIN = "torrentgalaxy.to"
|
||||||
|
|
||||||
|
type TorrentGalaxy struct{}
|
||||||
|
|
||||||
|
func NewTorrentGalaxy() *TorrentGalaxy {
|
||||||
|
return &TorrentGalaxy{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tg *TorrentGalaxy) Name() string {
|
||||||
|
return "torrentgalaxy"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tg *TorrentGalaxy) getCategoryCode(category string) string {
|
||||||
|
switch category {
|
||||||
|
case "all":
|
||||||
|
return ""
|
||||||
|
case "audiobook":
|
||||||
|
return "&c13=1"
|
||||||
|
case "movie":
|
||||||
|
return "&c3=1&c46=1&c45=1&c42=1&c4=1&c1=1"
|
||||||
|
case "tv":
|
||||||
|
return "&c41=1&c5=1&c11=1&c6=1&c7=1"
|
||||||
|
case "games":
|
||||||
|
return "&c43=1&c10=1"
|
||||||
|
case "software":
|
||||||
|
return "&c20=1&c21=1&c18=1"
|
||||||
|
case "anime":
|
||||||
|
return "&c28=1"
|
||||||
|
case "music":
|
||||||
|
return "&c28=1&c22=1&c26=1&c23=1&c25=1&c24=1"
|
||||||
|
case "xxx":
|
||||||
|
safeSearch := true // Replace with actual safe search status
|
||||||
|
if safeSearch {
|
||||||
|
return "ignore"
|
||||||
|
}
|
||||||
|
return "&c48=1&c35=1&c47=1&c34=1"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tg *TorrentGalaxy) Search(query string, category string) ([]TorrentResult, error) {
|
||||||
|
categoryCode := tg.getCategoryCode(category)
|
||||||
|
if categoryCode == "ignore" {
|
||||||
|
return []TorrentResult{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
searchURL := fmt.Sprintf("https://%s/torrents.php?search=%s%s#results", TORRENTGALAXY_DOMAIN, url.QueryEscape(query), categoryCode)
|
||||||
|
resp, err := http.Get(searchURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error making request to TorrentGalaxy: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc, err := goquery.NewDocumentFromReader(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing HTML: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []TorrentResult
|
||||||
|
doc.Find("div.tgxtablerow").Each(func(i int, s *goquery.Selection) {
|
||||||
|
titleDiv := s.Find("div#click")
|
||||||
|
title := strings.TrimSpace(titleDiv.Text())
|
||||||
|
magnetLink, exists := s.Find("a[href^='magnet']").Attr("href")
|
||||||
|
if !exists {
|
||||||
|
log.Printf("No magnet link found for title: %s", title)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
byteSize := parseSize(s.Find("span.badge-secondary").Text())
|
||||||
|
viewCount := parseInt(s.Find("font[color='orange']").Text())
|
||||||
|
seeder := parseInt(s.Find("font[color='green']").Text())
|
||||||
|
leecher := parseInt(s.Find("font[color='#ff0000']").Text())
|
||||||
|
|
||||||
|
result := TorrentResult{
|
||||||
|
URL: fmt.Sprintf("https://%s", TORRENTGALAXY_DOMAIN),
|
||||||
|
Seeders: seeder,
|
||||||
|
Leechers: leecher,
|
||||||
|
Magnet: applyTrackers(magnetLink),
|
||||||
|
Views: viewCount,
|
||||||
|
Size: formatSize(byteSize),
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
results = append(results, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseInt(s string) int {
|
||||||
|
s = strings.ReplaceAll(s, ",", "")
|
||||||
|
result, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error parsing integer: %v", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseSize(sizeStr string) int64 {
|
||||||
|
sizeStr = strings.TrimSpace(sizeStr)
|
||||||
|
if sizeStr == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use regex to extract numeric value and unit separately
|
||||||
|
re := regexp.MustCompile(`(?i)([\d.]+)\s*([KMGT]?B)`)
|
||||||
|
matches := re.FindStringSubmatch(sizeStr)
|
||||||
|
if len(matches) < 3 {
|
||||||
|
log.Printf("Error parsing size: invalid format %s", sizeStr)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
sizeStr = matches[1]
|
||||||
|
unit := strings.ToUpper(matches[2])
|
||||||
|
|
||||||
|
var multiplier int64 = 1
|
||||||
|
switch unit {
|
||||||
|
case "KB":
|
||||||
|
multiplier = 1024
|
||||||
|
case "MB":
|
||||||
|
multiplier = 1024 * 1024
|
||||||
|
case "GB":
|
||||||
|
multiplier = 1024 * 1024 * 1024
|
||||||
|
case "TB":
|
||||||
|
multiplier = 1024 * 1024 * 1024 * 1024
|
||||||
|
default:
|
||||||
|
log.Printf("Unknown unit: %s", unit)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
size, err := strconv.ParseFloat(sizeStr, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error parsing size: %v", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int64(size * float64(multiplier))
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyTrackers(magnetLink string) string {
|
||||||
|
if magnetLink == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
trackers := []string{
|
||||||
|
"udp://tracker.openbittorrent.com:80/announce",
|
||||||
|
"udp://tracker.opentrackr.org:1337/announce",
|
||||||
|
"udp://tracker.coppersurfer.tk:6969/announce",
|
||||||
|
"udp://tracker.leechers-paradise.org:6969/announce",
|
||||||
|
}
|
||||||
|
for _, tracker := range trackers {
|
||||||
|
magnetLink += "&tr=" + url.QueryEscape(tracker)
|
||||||
|
}
|
||||||
|
return magnetLink
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatSize(size int64) string {
|
||||||
|
if size >= 1024*1024*1024*1024 {
|
||||||
|
return fmt.Sprintf("%.2f TB", float64(size)/(1024*1024*1024*1024))
|
||||||
|
} else if size >= 1024*1024*1024 {
|
||||||
|
return fmt.Sprintf("%.2f GB", float64(size)/(1024*1024*1024))
|
||||||
|
} else if size >= 1024*1024 {
|
||||||
|
return fmt.Sprintf("%.2f MB", float64(size)/(1024*1024))
|
||||||
|
} else if size >= 1024 {
|
||||||
|
return fmt.Sprintf("%.2f KB", float64(size)/1024)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d B", size)
|
||||||
|
}
|
123
files.go
Normal file
123
files.go
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Settings struct {
|
||||||
|
UxLang string
|
||||||
|
Safe string
|
||||||
|
}
|
||||||
|
|
||||||
|
type TorrentSite interface {
|
||||||
|
Name() string
|
||||||
|
Search(query string, category string) ([]TorrentResult, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TorrentResult struct {
|
||||||
|
URL string
|
||||||
|
Seeders int
|
||||||
|
Leechers int
|
||||||
|
Magnet string
|
||||||
|
Views int
|
||||||
|
Size string
|
||||||
|
Title string
|
||||||
|
Error string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
torrentGalaxy TorrentSite
|
||||||
|
nyaa TorrentSite
|
||||||
|
thePirateBay TorrentSite
|
||||||
|
rutor TorrentSite
|
||||||
|
)
|
||||||
|
|
||||||
|
func initializeTorrentSites() {
|
||||||
|
torrentGalaxy = NewTorrentGalaxy()
|
||||||
|
// nyaa = NewNyaa()
|
||||||
|
// thePirateBay = NewThePirateBay()
|
||||||
|
// rutor = NewRutor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleFileSearch(w http.ResponseWriter, query, safe, lang string, page int) {
|
||||||
|
startTime := time.Now()
|
||||||
|
|
||||||
|
settings := Settings{UxLang: lang, Safe: safe}
|
||||||
|
sites := []TorrentSite{torrentGalaxy, nyaa, thePirateBay, rutor}
|
||||||
|
results := []TorrentResult{}
|
||||||
|
allErrors := true
|
||||||
|
|
||||||
|
for _, site := range sites {
|
||||||
|
if site == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
res, err := site.Search(query, "all")
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(res) > 0 {
|
||||||
|
allErrors = false
|
||||||
|
}
|
||||||
|
results = append(results, res...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if allErrors {
|
||||||
|
results = []TorrentResult{
|
||||||
|
{Error: "Results are currently unavailable, sorry. Please try again later."},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(results, func(i, j int) bool { return results[i].Seeders > results[j].Seeders })
|
||||||
|
|
||||||
|
elapsedTime := time.Since(startTime)
|
||||||
|
funcMap := template.FuncMap{
|
||||||
|
"sub": subtract,
|
||||||
|
"add": add,
|
||||||
|
}
|
||||||
|
tmpl, err := template.New("files.html").Funcs(funcMap).ParseFiles("templates/files.html")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to load template: %v", err)
|
||||||
|
http.Error(w, "Failed to load template", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := struct {
|
||||||
|
Results []TorrentResult
|
||||||
|
Query string
|
||||||
|
Fetched string
|
||||||
|
Category string
|
||||||
|
Sort string
|
||||||
|
HasPrevPage bool
|
||||||
|
HasNextPage bool
|
||||||
|
Page int
|
||||||
|
Settings Settings
|
||||||
|
}{
|
||||||
|
Results: results,
|
||||||
|
Query: query,
|
||||||
|
Fetched: fmt.Sprintf("%.2f", elapsedTime.Seconds()),
|
||||||
|
Category: "all",
|
||||||
|
Sort: "seed",
|
||||||
|
HasPrevPage: page > 1,
|
||||||
|
HasNextPage: len(results) > 0,
|
||||||
|
Page: page,
|
||||||
|
Settings: settings,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tmpl.Execute(w, data); err != nil {
|
||||||
|
log.Printf("Failed to render template: %v", err)
|
||||||
|
http.Error(w, "Failed to render template", http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func subtract(a, b int) int {
|
||||||
|
return a - b
|
||||||
|
}
|
||||||
|
|
||||||
|
func add(a, b int) int {
|
||||||
|
return a + b
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
// forums.go
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -23,13 +22,13 @@ type ForumSearchResult struct {
|
||||||
func PerformRedditSearch(query string, safe string, page int) ([]ForumSearchResult, error) {
|
func PerformRedditSearch(query string, safe string, page int) ([]ForumSearchResult, error) {
|
||||||
const (
|
const (
|
||||||
pageSize = 25
|
pageSize = 25
|
||||||
baseURL = "https://www.reddit.com/"
|
baseURL = "https://www.reddit.com"
|
||||||
maxRetries = 5
|
maxRetries = 5
|
||||||
initialBackoff = 2 * time.Second
|
initialBackoff = 2 * time.Second
|
||||||
)
|
)
|
||||||
var results []ForumSearchResult
|
var results []ForumSearchResult
|
||||||
|
|
||||||
searchURL := fmt.Sprintf("%ssearch.json?q=%s&limit=%d&start=%d", baseURL, url.QueryEscape(query), pageSize, page*pageSize)
|
searchURL := fmt.Sprintf("%s/search.json?q=%s&limit=%d&start=%d", baseURL, url.QueryEscape(query), pageSize, page*pageSize)
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -86,7 +85,7 @@ func PerformRedditSearch(query string, safe string, page int) ([]ForumSearchResu
|
||||||
}
|
}
|
||||||
publishedDate := time.Unix(int64(postData["created_utc"].(float64)), 0)
|
publishedDate := time.Unix(int64(postData["created_utc"].(float64)), 0)
|
||||||
permalink := postData["permalink"].(string)
|
permalink := postData["permalink"].(string)
|
||||||
resultURL := baseURL + permalink
|
resultURL := fmt.Sprintf("%s%s", baseURL, permalink)
|
||||||
|
|
||||||
result := ForumSearchResult{
|
result := ForumSearchResult{
|
||||||
URL: resultURL,
|
URL: resultURL,
|
||||||
|
|
|
@ -51,7 +51,7 @@ func fetchImageResults(query string, safe, lang string, page int) ([]ImageSearch
|
||||||
const resultsPerPage = 50
|
const resultsPerPage = 50
|
||||||
var offset int
|
var offset int
|
||||||
if page <= 1 {
|
if page <= 1 {
|
||||||
offset = 0 // Assuming the API expects offset to start from 0 for the first page
|
offset = 0
|
||||||
} else {
|
} else {
|
||||||
offset = (page - 1) * resultsPerPage
|
offset = (page - 1) * resultsPerPage
|
||||||
}
|
}
|
||||||
|
|
6
main.go
6
main.go
|
@ -1,4 +1,3 @@
|
||||||
// main.go
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -72,6 +71,7 @@ func main() {
|
||||||
http.HandleFunc("/settings", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||||
http.ServeFile(w, r, "templates/settings.html")
|
http.ServeFile(w, r, "templates/settings.html")
|
||||||
})
|
})
|
||||||
|
initializeTorrentSites()
|
||||||
fmt.Println("Server is listening on http://localhost:5000")
|
fmt.Println("Server is listening on http://localhost:5000")
|
||||||
log.Fatal(http.ListenAndServe(":5000", nil))
|
log.Fatal(http.ListenAndServe(":5000", nil))
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,13 @@ func handleSearch(w http.ResponseWriter, r *http.Request) {
|
||||||
case "image":
|
case "image":
|
||||||
handleImageSearch(w, query, safe, lang, page)
|
handleImageSearch(w, query, safe, lang, page)
|
||||||
case "video":
|
case "video":
|
||||||
videoSearchEndpointHandler(w, r)
|
handleVideoSearch(w, query, safe, lang, page)
|
||||||
case "map":
|
case "map":
|
||||||
handleMapSearch(w, query, safe)
|
handleMapSearch(w, query, safe)
|
||||||
case "forum":
|
case "forum":
|
||||||
handleForumsSearch(w, query, safe, lang, page)
|
handleForumsSearch(w, query, safe, lang, page)
|
||||||
|
case "file":
|
||||||
|
handleFileSearch(w, query, safe, lang, page)
|
||||||
case "text":
|
case "text":
|
||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
|
|
2
run.sh
2
run.sh
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
go run main.go text-google.go images.go imageproxy.go video.go map.go text.go text-quant.go text-duckduckgo.go cache.go forums.go --debug
|
go run main.go text-google.go images.go imageproxy.go video.go map.go text.go text-quant.go text-duckduckgo.go cache.go forums.go files.go files-torrentgalaxy.go --debug
|
112
templates/files.html
Normal file
112
templates/files.html
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{.Query}} - Ocásek</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
||||||
|
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
||||||
|
<div class="wrapper-results">
|
||||||
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="file">search</button>
|
||||||
|
<input type="submit" class="hide" name="t" value="file" />
|
||||||
|
</div>
|
||||||
|
<div class="sub-search-button-wrapper">
|
||||||
|
<div class="search-container-results-btn">
|
||||||
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
|
||||||
|
<button name="t" value="text" class="clickable">Web</button>
|
||||||
|
</div>
|
||||||
|
<div class="search-container-results-btn">
|
||||||
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
|
||||||
|
<button name="t" value="image" class="clickable">Images</button>
|
||||||
|
</div>
|
||||||
|
<div class="search-container-results-btn">
|
||||||
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
||||||
|
<button name="t" value="video" class="clickable">Videos</button>
|
||||||
|
</div>
|
||||||
|
<div class="search-container-results-btn">
|
||||||
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
|
||||||
|
<button name="t" value="forum" class="clickable">Forums</button>
|
||||||
|
</div>
|
||||||
|
<div id="content" class="js-enabled">
|
||||||
|
<div class="search-container-results-btn">
|
||||||
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
||||||
|
<button name="t" value="map" class="clickable">Maps</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="search-container-results-btn">
|
||||||
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="file">share</button>
|
||||||
|
<button name="t" value="file" class="clickable search-active">Torrents</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- <p class="fetched fetched_dif fetched_tor">{{ .Fetched }} seconds</p> -->
|
||||||
|
|
||||||
|
{{ if .Results }}
|
||||||
|
<form action="/search" class="torrent-sort" method="GET">
|
||||||
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
|
<input type="hidden" name="t" value="file">
|
||||||
|
<select class="torrent-settings" name="sort">
|
||||||
|
<option value="seed" {{ if eq .Sort "seed" }} selected {{ end }}>Number of Seeders</option>
|
||||||
|
<option value="leech" {{ if eq .Sort "leech" }} selected {{ end }}>Number of Leechers</option>
|
||||||
|
<option value="lth" {{ if eq .Sort "lth" }} selected {{ end }}>Size (Low to High)</option>
|
||||||
|
<option value="htl" {{ if eq .Sort "htl" }} selected {{ end }}>Size (High to Low)</option>
|
||||||
|
</select>
|
||||||
|
<select class="torrent-cat" name="cat">
|
||||||
|
<option value="all" {{ if eq .Category "all" }} selected {{ end }}>All Categories</option>
|
||||||
|
<option value="movie" {{ if eq .Category "movie" }} selected {{ end }}>Movies</option>
|
||||||
|
<option value="audiobook" {{ if eq .Category "audiobook" }} selected {{ end }}>Audiobooks</option>
|
||||||
|
<option value="tv" {{ if eq .Category "tv" }} selected {{ end }}>TV Shows</option>
|
||||||
|
<option value="games" {{ if eq .Category "games" }} selected {{ end }}>Games</option>
|
||||||
|
<option value="software" {{ if eq .Category "software" }} selected {{ end }}>Software</option>
|
||||||
|
<option value="anime" {{ if eq .Category "anime" }} selected {{ end }}>Anime</option>
|
||||||
|
<option value="music" {{ if eq .Category "music" }} selected {{ end }}>Music</option>
|
||||||
|
<!-- {{ if eq .Settings.Safe "inactive" }} -->
|
||||||
|
<option value="xxx" {{ if eq .Category "xxx" }} selected {{ end }}>XXX (18+)</option>
|
||||||
|
<!-- {{ end }} -->
|
||||||
|
</select>
|
||||||
|
<button type="submit" class="torrent-sort-save">Submit</button>
|
||||||
|
</form>
|
||||||
|
<div class="clean">
|
||||||
|
{{ range .Results }}
|
||||||
|
<div class="results">
|
||||||
|
{{ if .Error }}
|
||||||
|
<div class="error">{{ .Error }}</div>
|
||||||
|
{{ else }}
|
||||||
|
<a id="link" href="{{ .Magnet }}">{{ .URL }}</a>
|
||||||
|
<a class="torrent" href="{{ .Magnet }}"><h3>{{ .Title }}</h3></a>
|
||||||
|
<p class="stats">{{ if .Views }}{{ .Views }} views • {{ end }}{{ .Size }}</p>
|
||||||
|
<p class="publish__info"> Seeders: <span class="seeders">{{ .Seeders }}</span> | Leechers: <span class="leechers">{{ .Leechers }}</span></p>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="prev-next prev-img">
|
||||||
|
<form action="/search" method="get">
|
||||||
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
|
<input type="hidden" name="t" value="file">
|
||||||
|
{{ if .HasPrevPage }}
|
||||||
|
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
||||||
|
{{ end }}
|
||||||
|
{{ if .HasNextPage }}
|
||||||
|
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
||||||
|
{{ end }}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{ else }}
|
||||||
|
<div class="no-results-found">
|
||||||
|
Your search '{{ .Query }}' came back with no results.<br>
|
||||||
|
Try rephrasing your search term and/or recorrect any spelling mistakes.
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
<script>
|
||||||
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -38,8 +38,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="torrent">share</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="file">share</button>
|
||||||
<button name="t" value="torrent" class="clickable">Torrents</button>
|
<button name="t" value="file" class="clickable">Torrents</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// text-duckduckgo.go
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// text-google.go
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// text-qwant.go
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
16
text.go
16
text.go
|
@ -173,22 +173,6 @@ func fetchAndCacheResults(query, safe, lang string, page, resultsPerPage int) []
|
||||||
return combinedResults
|
return combinedResults
|
||||||
}
|
}
|
||||||
|
|
||||||
func paginateResults(results []TextSearchResult, page, resultsPerPage int) []TextSearchResult {
|
|
||||||
startIndex := (page - 1) * resultsPerPage
|
|
||||||
endIndex := startIndex + resultsPerPage
|
|
||||||
|
|
||||||
log.Printf("Paginating results: startIndex=%d, endIndex=%d, totalResults=%d", startIndex, endIndex, len(results))
|
|
||||||
|
|
||||||
if startIndex >= len(results) {
|
|
||||||
return []TextSearchResult{}
|
|
||||||
}
|
|
||||||
if endIndex > len(results) {
|
|
||||||
endIndex = len(results)
|
|
||||||
}
|
|
||||||
|
|
||||||
return results[startIndex:endIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
func sourceOrder(source string) int {
|
func sourceOrder(source string) int {
|
||||||
switch source {
|
switch source {
|
||||||
case "Google":
|
case "Google":
|
||||||
|
|
15
video.go
15
video.go
|
@ -7,7 +7,6 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -163,20 +162,6 @@ func makeHTMLRequest(query string) (*VideoAPIResponse, error) {
|
||||||
return nil, fmt.Errorf("all instances failed, last error: %v", lastError)
|
return nil, fmt.Errorf("all instances failed, last error: %v", lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func videoSearchEndpointHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
query := r.URL.Query().Get("q")
|
|
||||||
safe := r.URL.Query().Get("safe") // Assuming "safe" is a query parameter
|
|
||||||
lang := r.URL.Query().Get("lang") // Assuming "lang" is a query parameter
|
|
||||||
pageStr := r.URL.Query().Get("page")
|
|
||||||
page, err := strconv.Atoi(pageStr)
|
|
||||||
if err != nil {
|
|
||||||
// Handle error, perhaps set page to a default value if it's not critical
|
|
||||||
page = 1 // Default page
|
|
||||||
}
|
|
||||||
|
|
||||||
handleVideoSearch(w, query, safe, lang, page)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleVideoSearch adapted from the Python `videoResults`, handles video search requests
|
// 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, query, safe, lang string, page int) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
Loading…
Add table
Reference in a new issue