Skip to content

Commit

Permalink
torrent galaxy (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpozinen committed Oct 23, 2023
1 parent 647e716 commit 7e171c1
Show file tree
Hide file tree
Showing 13 changed files with 3,030 additions and 14 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
}

group = 'dpozinen'
version = '2.7'
version = '2.8'

repositories {
mavenCentral()
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/dpozinen/tracker/Tracker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,19 @@ class Tracker(
fun from(tracker: Trackers) =
when (tracker) {
Trackers.OneThreeThree -> oneThreeThreeSevenXTo()
Trackers.TorrentGalaxy -> torrentGalaxy()
}

private fun oneThreeThreeSevenXTo() = Tracker(
TrackerParser.OneThreeThree(),
TrackerOps.OneThreeThree()
)

private fun torrentGalaxy() = Tracker(
TrackerParser.TorrentGalaxy(),
TrackerOps.TorrentGalaxy()
)

}

}
19 changes: 17 additions & 2 deletions src/main/kotlin/dpozinen/tracker/TrackerOps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,27 @@ interface TrackerOps {

override fun expandUrl(url: String): String = "$baseUrl/$url"

private fun keywordsSegment(keywords: List<String>) = keywords.joinToString("+")
}

class TorrentGalaxy : TrackerOps {
private val baseUrl: String = "https://torrentgalaxy.to"

override fun open(torrent: Torrent) = "" // noop

override fun search(keywords: List<String>): String =
session.newRequest()
.url("$baseUrl/torrents.php?search=${keywordsSegment(keywords)}")
.execute()
.body()

override fun expandUrl(url: String): String = "$baseUrl/$url"

}

companion object {
val session: Connection = Jsoup.newSession()
}

}
}

fun keywordsSegment(keywords: List<String>) = keywords.joinToString("+")
45 changes: 45 additions & 0 deletions src/main/kotlin/dpozinen/tracker/TrackerParser.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dpozinen.tracker

import mu.KotlinLogging.logger
import org.jsoup.Jsoup
import org.jsoup.nodes.Element

Expand Down Expand Up @@ -55,4 +56,48 @@ interface TrackerParser {

}

class TorrentGalaxy : TrackerParser {

private val log = logger {}

override fun parseSearch(body: String): Torrents {
val document = Jsoup.parse(body)

if (document.select("p").any { e -> e.text().contains("No results were returned") })
return Torrents.empty()

return Torrents(
document.select(".tgxtablerow")
.map { toTorrent(it) }
.toList()
)
}

private fun toTorrent(element: Element): Torrent {
val link = element.select("a[href^=magnet:]").attr("href")
val name = element.select("div[data-href^=/torrent/] b").text()

val details: Element = element.select(".tgxtablecell tbody tr")
.firstOrNull { it.select("td").text().contains("Size") }
?: run {
log.warn { "Torrent named $name doesn't have any details" }
Element("")
}

val size = details.select("td").first { it.text().contains("Size") }.select("span").text()
val contributor = details.select(".username").first()?.text() ?: ""

val seedLeech = details.select("span[title=Seeders/Leechers]")
val seeds = seedLeech.select("b").first()?.text()?.toInt() ?: 0
val leeches = seedLeech.select("b").last()?.text()?.toInt() ?: 0
val date = details.select("td").first { it.text().contains("Added") }
?.select("small")?.text() ?: ""

return Torrent(link, name, size, seeds, leeches, date, contributor)
}

override fun parseTorrentPage(body: String) = Torrent("", "") // noop, all info from search

}

}
11 changes: 5 additions & 6 deletions src/main/kotlin/dpozinen/tracker/Trackers.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package dpozinen.tracker

enum class Trackers {
OneThreeThree;
OneThreeThree, TorrentGalaxy;

companion object {
fun from(name: String) : Trackers {
return when (name) {
"133" -> OneThreeThree
else -> throw IllegalArgumentException()
}
fun from(name: String) = when (name) {
"133" -> OneThreeThree
"torrent-galaxy" -> TorrentGalaxy
else -> throw IllegalArgumentException()
}
}
}
6 changes: 5 additions & 1 deletion src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ms-auto">
<li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#results">Results</a></li>
<li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="/deluge.html">Deluge</a></li>
<li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="/deluge.html?sort=UPLOAD_SPEED:DESC&filter=STATE:Downloading:IS">Deluge</a></li>
</ul>
</div>
</div>
Expand All @@ -43,6 +43,10 @@
<input type="radio" class="form-check-input btn-check" name="tracker" id="1337x" value="133" autocomplete="off" checked>
<label class="form-check-label btn btn-outline-secondary" for="1337x">1337x.to</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input btn-check" name="tracker" id="torrent-galaxy" value="torrent-galaxy" autocomplete="off">
<label class="form-check-label btn btn-outline-secondary" for="torrent-galaxy">torrentgalaxy.to</label>
</div>
<div class="mb-5"></div>
<div class="divider-custom divider-light">
<div class="divider-custom-line"></div>
Expand Down
19 changes: 17 additions & 2 deletions src/test/kotlin/Data.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class Data {

class OneThreeThree {
companion object {
const val SEARCH_PAGE_PATH = "src/test/resources/one337xto/search.html"
const val TORRENT_PAGE_PATH = "src/test/resources/one337xto/torrent-page.html"
const val SEARCH_PAGE_PATH = "src/test/resources/1337x/search.html"
const val TORRENT_PAGE_PATH = "src/test/resources/1337x/torrent-page.html"

val PAGE_EXPECTED_TORRENT = Torrent(
"magnet:?xt=urn:btih:7F7369A43153DEB61017E4E3076DD4DF6AED6F5F&dn=The+Birdcage+%281996%29+%281080p+BluRay+x265+HEVC+10bit+AAC+5.1+Panda%29+%5BQxR%5D&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.torrent.eu.org%3A451%2Fannounce&tr=+udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.zer0day.to%3A1337%2Fannounce&tr=udp%3A%2F%2Feddie4.nl%3A6969%2Fannounce+&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=http%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&tr=udp%3A%2F%2Fopentracker.i2p.rocks%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.internetwarriors.net%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969%2Fannounce&tr=udp%3A%2F%2Fcoppersurfer.tk%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.zer0day.to%3A1337%2Fannounce",
Expand Down Expand Up @@ -40,6 +40,21 @@ class Data {
}
}

class TorrentGalaxy {
companion object {
const val SEARCH_PAGE_PATH = "src/test/resources/torrentgalaxy/search.html"

val SEARCH_EXPECTED_TORRENT = Torrent(
"magnet:?xt=urn:btih:7bd21e8b9906b4a9c08697c1067e3f32ce86fdb5&dn=Capote.2005.1080p.BluRay.H264.AAC-RARBG&tr=udp%3A%2F%2Fopen.stealth.si%3A80%2Fannounce&tr=udp%3A%2F%2Fexodus.desync.com%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.cyberia.is%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.torrent.eu.org%3A451%2Fannounce&tr=udp%3A%2F%2Fexplodie.org%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.birkenwald.de%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.moeking.me%3A6969%2Fannounce&tr=udp%3A%2F%2Fipv4.tracker.harry.lu%3A80%2Fannounce&tr=udp%3A%2F%2Ftracker.tiny-vps.com%3A6969%2Fannounce",
"Capote.2005.1080p.BluRay.H264.AAC-RARBG",
"2.18 GB",
14,
6,
"10/10/23 23:56",
"indexFroggy",
)
}
}

companion object {
val info: DelugeTorrents.Info = DelugeTorrents.Info(
Expand Down
14 changes: 14 additions & 0 deletions src/test/kotlin/tracker/ParsingTest.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package tracker

import Data
import Data.OneThreeThree
import dpozinen.tracker.TrackerParser
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.data.Index.atIndex
import java.nio.file.Files
import java.nio.file.Path
import kotlin.test.Test
Expand All @@ -25,4 +27,16 @@ class ParsingTest {
assertThat(torrent).isEqualTo(OneThreeThree.PAGE_EXPECTED_TORRENT)
}

@Test
fun `should parse search page torrent galaxy`() {
val body = Files.readString(Path.of(Data.TorrentGalaxy.SEARCH_PAGE_PATH))
val torrents = TrackerParser.TorrentGalaxy().parseSearch(body)

assertThat(torrents.torrents)
.hasSize(15)
.satisfies(
{ assertThat(it).isEqualTo(Data.TorrentGalaxy.SEARCH_EXPECTED_TORRENT) },
atIndex(0))
}

}
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion src/test/resources/sensitive/plex

This file was deleted.

1 change: 0 additions & 1 deletion src/test/resources/sensitive/trueNas

This file was deleted.

Loading

0 comments on commit 7e171c1

Please sign in to comment.