files update, added torretbay
This commit is contained in:
parent
b17baba0a5
commit
4e8ca3192f
5 changed files with 226 additions and 101 deletions
119
files-thepiratebay.go
Normal file
119
files-thepiratebay.go
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
const PIRATEBAY_DOMAIN = "apibay.org"
|
||||||
|
|
||||||
|
type ThePirateBay struct{}
|
||||||
|
|
||||||
|
func NewThePirateBay() *ThePirateBay {
|
||||||
|
return &ThePirateBay{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ThePirateBay) Name() string {
|
||||||
|
return "tpb"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ThePirateBay) getCategoryCode(cat string) string {
|
||||||
|
switch cat {
|
||||||
|
case "all":
|
||||||
|
return ""
|
||||||
|
case "audiobook":
|
||||||
|
return "102"
|
||||||
|
case "movie":
|
||||||
|
return "201"
|
||||||
|
case "tv":
|
||||||
|
return "205"
|
||||||
|
case "games":
|
||||||
|
return "400"
|
||||||
|
case "software":
|
||||||
|
return "300"
|
||||||
|
case "anime":
|
||||||
|
// TPB has no anime category.
|
||||||
|
return "ignore"
|
||||||
|
case "music":
|
||||||
|
return "100"
|
||||||
|
case "xxx":
|
||||||
|
// Assuming safesearch can be determined from some context (cookies, settings, etc.)
|
||||||
|
safeSearch := true // Replace with actual condition check
|
||||||
|
if safeSearch {
|
||||||
|
return "ignore"
|
||||||
|
}
|
||||||
|
return "500"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ThePirateBay) Search(query string, category string) ([]TorrentResult, error) {
|
||||||
|
categoryCode := t.getCategoryCode(category)
|
||||||
|
if categoryCode == "ignore" {
|
||||||
|
return []TorrentResult{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("https://%s/q.php?q=%s&cat=%s", PIRATEBAY_DOMAIN, url.QueryEscape(query), categoryCode)
|
||||||
|
response, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
var torrentData []map[string]interface{}
|
||||||
|
if err := json.NewDecoder(response.Body).Decode(&torrentData); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []TorrentResult
|
||||||
|
for _, torrent := range torrentData {
|
||||||
|
byteSize, _ := strconv.Atoi(torrent["size"].(string)) // assuming size is string and can be converted to int
|
||||||
|
results = append(results, TorrentResult{
|
||||||
|
URL: "https://thepiratebay.org/",
|
||||||
|
Seeders: parseInt(torrent["seeders"].(string)),
|
||||||
|
Leechers: parseInt(torrent["leechers"].(string)),
|
||||||
|
Magnet: t.createMagnetLink(torrent["info_hash"].(string), torrent["name"].(string)),
|
||||||
|
Views: 0,
|
||||||
|
Size: t.bytesToString(byteSize),
|
||||||
|
Title: torrent["name"].(string),
|
||||||
|
Error: "",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ThePirateBay) createMagnetLink(infoHash string, name string) string {
|
||||||
|
// Replace spaces and problematic characters with dashes
|
||||||
|
sanitizedName := sanitizeFileName(name)
|
||||||
|
baseMagnet := fmt.Sprintf("magnet:?xt=urn:btih:%s&dn=%s", infoHash, sanitizedName)
|
||||||
|
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 {
|
||||||
|
baseMagnet += "&tr=" + url.QueryEscape(tracker)
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseMagnet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ThePirateBay) bytesToString(bytes int) string {
|
||||||
|
const unit = 1024
|
||||||
|
if bytes < unit {
|
||||||
|
return fmt.Sprintf("%d B", bytes)
|
||||||
|
}
|
||||||
|
div, exp := unit, 0
|
||||||
|
for n := bytes / unit; n >= unit; n /= unit {
|
||||||
|
div *= unit
|
||||||
|
exp++
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
||||||
|
}
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
|
@ -108,83 +106,3 @@ func (tg *TorrentGalaxy) Search(query string, category string) ([]TorrentResult,
|
||||||
|
|
||||||
return results, nil
|
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))
|
|
||||||
}
|
|
||||||
|
|
||||||
//apparently this is needed so it can announce that magnet link is being used and people start seeding it, but I dont like the fact that I add trackers purusefully
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
94
files.go
94
files.go
|
@ -6,7 +6,9 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -31,7 +33,7 @@ var (
|
||||||
func initializeTorrentSites() {
|
func initializeTorrentSites() {
|
||||||
torrentGalaxy = NewTorrentGalaxy()
|
torrentGalaxy = NewTorrentGalaxy()
|
||||||
// nyaa = NewNyaa()
|
// nyaa = NewNyaa()
|
||||||
// thePirateBay = NewThePirateBay()
|
thePirateBay = NewThePirateBay()
|
||||||
// rutor = NewRutor()
|
// rutor = NewRutor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +138,7 @@ func fetchAndCacheFileResults(query, safe, lang string, page int) []TorrentResul
|
||||||
allErrors = false
|
allErrors = false
|
||||||
}
|
}
|
||||||
for _, r := range res {
|
for _, r := range res {
|
||||||
r.Magnet = url.QueryEscape(removeMagnetLink(r.Magnet)) // Remove "magnet:" and encode url
|
r.Magnet = removeMagnetLink(r.Magnet) // Remove "magnet:", prehaps usless now?
|
||||||
results = append(results, r)
|
results = append(results, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +158,7 @@ func fetchAndCacheFileResults(query, safe, lang string, page int) []TorrentResul
|
||||||
|
|
||||||
func removeMagnetLink(magnet string) string {
|
func removeMagnetLink(magnet string) string {
|
||||||
// Remove the magnet: prefix unconditionally
|
// Remove the magnet: prefix unconditionally
|
||||||
return strings.TrimPrefix(magnet, "magnet:?")
|
return strings.TrimPrefix(magnet, "magnet:")
|
||||||
}
|
}
|
||||||
|
|
||||||
func subtract(a, b int) int {
|
func subtract(a, b int) int {
|
||||||
|
@ -166,3 +168,89 @@ func subtract(a, b int) int {
|
||||||
func add(a, b int) int {
|
func add(a, b int) int {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseInt(s string) int {
|
||||||
|
i, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
// apparently this is needed so it can announce that magnet link is being used and people start seeding it, but I dont like the fact that I add trackers purposefully
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitizeFileName(name string) string {
|
||||||
|
// Replace spaces with dashes
|
||||||
|
sanitized := regexp.MustCompile(`\s+`).ReplaceAllString(name, "-")
|
||||||
|
// Remove any characters that are not alphanumeric, dashes, or parentheses
|
||||||
|
sanitized = regexp.MustCompile(`[^a-zA-Z0-9\-\(\)]`).ReplaceAllString(sanitized, "")
|
||||||
|
return sanitized
|
||||||
|
}
|
||||||
|
|
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 files.go files-torrentgalaxy.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 files-thepiratebay.go --debug
|
|
@ -44,7 +44,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- <p class="fetched fetched_dif fetched_tor">{{ .Fetched }} seconds</p> -->
|
<p class="fetched fetched_dif fetched_tor">Fetched in {{ .Fetched }} seconds</p>
|
||||||
|
|
||||||
{{ if .Results }}
|
{{ if .Results }}
|
||||||
<form action="/search" class="torrent-sort" method="GET">
|
<form action="/search" class="torrent-sort" method="GET">
|
||||||
|
@ -65,26 +65,26 @@
|
||||||
<option value="software" {{ if eq .Category "software" }} selected {{ end }}>Software</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="anime" {{ if eq .Category "anime" }} selected {{ end }}>Anime</option>
|
||||||
<option value="music" {{ if eq .Category "music" }} selected {{ end }}>Music</option>
|
<option value="music" {{ if eq .Category "music" }} selected {{ end }}>Music</option>
|
||||||
<!-- {{ if eq .Settings.Safe "inactive" }} -->
|
{{ if eq .Settings.Safe "inactive" }}
|
||||||
<option value="xxx" {{ if eq .Category "xxx" }} selected {{ end }}>XXX (18+)</option>
|
<option value="xxx" {{ if eq .Category "xxx" }} selected {{ end }}>XXX (18+)</option>
|
||||||
<!-- {{ end }} -->
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
<button type="submit" class="torrent-sort-save">Submit</button>
|
<button type="submit" class="torrent-sort-save">Apply settings</button>
|
||||||
</form>
|
</form>
|
||||||
{{ range .Results }}
|
|
||||||
<div class="clean">
|
<div class="clean">
|
||||||
<div class="results">
|
{{ range .Results }}
|
||||||
{{ if .Error }}
|
<div class="results">
|
||||||
<div class="error">{{ .Error }}</div>
|
{{ if .Error }}
|
||||||
{{ else }}
|
<div class="error">{{ .Error }}</div>
|
||||||
<a id="link" href="{{ .URL }}">{{ .URL }}</a>
|
{{ else }}
|
||||||
<a class="torrent" href="magnet:{{ .Magnet }}"><h3>{{ .Title }}</h3></a>
|
<a id="link" href="{{ .URL }}">{{ .URL }}</a>
|
||||||
<p class="stats">{{ if .Views }}{{ .Views }} views • {{ end }}{{ .Size }}</p>
|
<a class="torrent" href="magnet:{{ .Magnet }}"><h3>{{ .Title }}</h3></a>
|
||||||
<p class="publish__info"> Seeders: <span class="seeders">{{ .Seeders }}</span> | Leechers: <span class="leechers">{{ .Leechers }}</span></p>
|
<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 }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
<div class="prev-next prev-img">
|
<div class="prev-next prev-img">
|
||||||
<form action="/search" method="get">
|
<form action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
|
|
Loading…
Add table
Reference in a new issue