2024-05-23 10:56:26 +02:00
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 ) {
2024-05-24 08:32:32 +02:00
titleDiv := s . Find ( "div#click > div > a.txlight" )
2024-05-23 10:56:26 +02:00
title := strings . TrimSpace ( titleDiv . Text ( ) )
magnetLink , exists := s . Find ( "a[href^='magnet']" ) . Attr ( "href" )
2024-05-24 08:32:32 +02:00
fmt . Printf ( "Found title: %s\n" , title ) // Debugging statement
fmt . Printf ( "Found magnet link: %s\n" , magnetLink ) // Debugging statement
2024-05-23 10:56:26 +02:00
if ! exists {
log . Printf ( "No magnet link found for title: %s" , title )
return
}
byteSize := parseSize ( s . Find ( "span.badge-secondary" ) . Text ( ) )
2024-05-24 08:32:32 +02:00
viewCount := parseInt ( s . Find ( "span.badge-warning font[color='orange']" ) . Text ( ) )
seeder := parseInt ( s . Find ( "span[title='Seeders/Leechers'] font[color='green']" ) . Text ( ) )
leecher := parseInt ( s . Find ( "span[title='Seeders/Leechers'] font[color='#ff0000']" ) . Text ( ) )
2024-05-23 10:56:26 +02:00
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 ) )
}
2024-05-24 08:32:32 +02:00
//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
2024-05-23 10:56:26 +02:00
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 )
}