fix(tr/hdfilmcehennemi): Update baseUrl + add a new extractor (#2884)

This commit is contained in:
Claudemirovsky 2024-02-08 10:46:14 -03:00 committed by GitHub
parent 6486f5c9b8
commit 5d62c958cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 82 additions and 79 deletions

View File

@ -58,7 +58,7 @@ object Unpacker {
}
}
private val wordRegex by lazy { Regex("""\w+""") }
private val wordRegex by lazy { Regex("""[0-9A-Za-z]+""") }
private fun parseRadix62(str: String): Int {
var result = 0

View File

@ -13,7 +13,7 @@
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="www.hdfilmcehennemi.de"
android:host="www.hdfilmcehennemi.us"
android:pathPattern="/..*"
android:scheme="https" />
</intent-filter>

View File

@ -1,7 +1,7 @@
ext {
extName = 'HDFilmCehennemi'
extClass = '.HDFilmCehennemi'
extVersionCode = 9
extVersionCode = 10
isNsfw = true
}

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi
import android.app.Application
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi.extractors.RapidrameExtractor
import eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi.extractors.CloseloadExtractor
import eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi.extractors.VidmolyExtractor
import eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi.extractors.XBetExtractor
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
@ -22,7 +22,6 @@ import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
import eu.kanade.tachiyomi.util.parallelMapBlocking
import eu.kanade.tachiyomi.util.parseAs
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import okhttp3.FormBody
import okhttp3.MultipartBody
import okhttp3.Request
@ -31,7 +30,6 @@ import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.text.SimpleDateFormat
import java.util.Locale
@ -39,7 +37,7 @@ class HDFilmCehennemi : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override val name = "HDFilmCehennemi"
override val baseUrl = "https://www.hdfilmcehennemi.fun"
override val baseUrl = "https://www.hdfilmcehennemi.us"
override val lang = "tr"
@ -49,8 +47,6 @@ class HDFilmCehennemi : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.add("Referer", "$baseUrl/")
.add("Origin", baseUrl)
private val json: Json by injectLazy()
private val preferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
@ -225,8 +221,8 @@ class HDFilmCehennemi : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
// ============================ Video Links =============================
private val vidmolyExtractor by lazy { VidmolyExtractor(client, headers) }
private val rapidrameExtractor by lazy { RapidrameExtractor(client, headers, json) }
private val xbetExtractor by lazy { XBetExtractor(client, headers, json) }
private val closeloadExtractor by lazy { CloseloadExtractor(client, headers) }
private val xbetExtractor by lazy { XBetExtractor(client, headers) }
override fun videoListParse(response: Response): List<Video> {
val doc = response.asJsoup()
@ -235,12 +231,13 @@ class HDFilmCehennemi : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.drop(1)
.parallelMapBlocking { client.newCall(GET(it.absUrl("href") + "/")).await().asJsoup() }
.let { listOf(doc) + it }
.mapNotNull { it.selectFirst("div.card-video > iframe")?.attr("data-src") }
.mapNotNull { it.selectFirst("div.card-video > iframe") }
.map { it.attr("data-src").ifBlank { it.attr("src") } }
.filter(String::isNotBlank)
.parallelCatchingFlatMapBlocking { url ->
when {
url.contains("https://closeload") -> closeloadExtractor.videosFromUrl(url)
url.contains("vidmoly") -> vidmolyExtractor.videosFromUrl(url)
url.contains("$baseUrl/playerr") -> rapidrameExtractor.videosFromUrl(url)
url.contains("trstx.org") -> xbetExtractor.videosFromUrl(url)
else -> emptyList()
}
@ -279,7 +276,6 @@ class HDFilmCehennemi : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
}
// ============================= Utilities ==============================
override fun List<Video>.sort(): List<Video> {
val quality = preferences.getString(PREF_QUALITY_KEY, PREF_QUALITY_DEFAULT)!!

View File

@ -8,7 +8,7 @@ import android.util.Log
import kotlin.system.exitProcess
/**
* Springboard that accepts https://www.hdfilmcehennemi.de/<item> intents
* Springboard that accepts https://www.hdfilmcehennemi.us/<item> intents
* and redirects them to the main Aniyomi process.
*/
class HDFilmCehennemiUrlActivity : Activity() {

View File

@ -0,0 +1,62 @@
package eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi.extractors
import android.util.Base64
import eu.kanade.tachiyomi.animesource.model.Track
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.unpacker.Unpacker
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
class CloseloadExtractor(private val client: OkHttpClient, private val headers: Headers) {
suspend fun videosFromUrl(url: String): List<Video> {
val doc = client.newCall(GET(url, headers)).await().asJsoup()
val script = doc.selectFirst("script:containsData(eval):containsData(PlayerInit)")?.data()
?: return emptyList()
val unpackedScript = Unpacker.unpack(script).takeIf(String::isNotEmpty)
?: return emptyList()
val varName = unpackedScript.substringAfter("atob(").substringBefore(")")
val playlistUrl = unpackedScript.getProperty("$varName=")
.let { String(Base64.decode(it, Base64.DEFAULT)) }
val hostUrl = "https://" + url.toHttpUrl().host
val videoHeaders = headers.newBuilder()
.set("Referer", url)
.set("origin", hostUrl)
.build()
runCatching { tryAjaxPost(unpackedScript, hostUrl) }
val subtitles = doc.select("track[src]").map {
Track(it.absUrl("src"), it.attr("label").ifEmpty { it.attr("srclang") })
}
return listOf(Video(playlistUrl, "Closeload", playlistUrl, videoHeaders, subtitleTracks = subtitles))
}
private suspend fun tryAjaxPost(script: String, hostUrl: String) {
val hash = script.getProperty("hash:")
val url = script.getProperty("url:").let {
when {
it.startsWith("//") -> "https:$it"
it.startsWith("/") -> "https://" + hostUrl + it
!it.startsWith("https://") -> "https://$it"
else -> it
}
}
val body = FormBody.Builder().add("hash", hash).build()
client.newCall(POST(url, headers, body)).await().close()
}
private fun String.getProperty(before: String) =
substringAfter("$before\"").substringBefore('"')
}

View File

@ -1,54 +0,0 @@
package eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi.extractors
import android.util.Base64
import eu.kanade.tachiyomi.animesource.model.Track
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.lib.unpacker.Unpacker
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.Headers
import okhttp3.OkHttpClient
@Serializable
data class TrackDto(val label: String = "", val file: String, val kind: String)
class RapidrameExtractor(
private val client: OkHttpClient,
private val headers: Headers,
private val json: Json,
) {
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
fun videosFromUrl(url: String): List<Video> {
val doc = client.newCall(GET(url, headers)).execute().asJsoup()
val script = doc.selectFirst("script:containsData(eval):containsData(file_link)")?.data()
?: return emptyList()
val unpackedScript = Unpacker.unpack(script).takeIf(String::isNotEmpty)
?: return emptyList()
val subtitles = (script.substringAfter("tracks: ", "").substringBefore("],", "") + "]")
.let { list ->
runCatching {
val baseUrl = headers["Origin"]!!
json.decodeFromString<List<TrackDto>>(list)
.filter { it.kind.equals("captions") }
.map { Track(baseUrl + it.file, it.label.replace("Forced", "Türkçe")) }
}.getOrElse { emptyList() }
}
val playlistUrl = unpackedScript.substringAfter('"').substringBefore('"')
.let { String(Base64.decode(it, Base64.DEFAULT)) }
return playlistUtils.extractFromHls(
playlistUrl,
referer = url,
videoNameGen = { "Rapidrame - $it" },
subtitleList = subtitles,
)
}
}

View File

@ -3,14 +3,15 @@ package eu.kanade.tachiyomi.animeextension.tr.hdfilmcehennemi.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
import okhttp3.Headers
import okhttp3.OkHttpClient
class VidmolyExtractor(private val client: OkHttpClient, private val headers: Headers) {
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
fun videosFromUrl(url: String): List<Video> {
val body = client.newCall(GET(url, headers)).execute()
suspend fun videosFromUrl(url: String): List<Video> {
val body = client.newCall(GET(url, headers)).await()
.body.string()
val playlistUrl = body.substringAfter("file:\"", "").substringBefore('"', "")

View File

@ -4,10 +4,10 @@ import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.util.asJsoup
import eu.kanade.tachiyomi.util.parseAs
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
@ -15,13 +15,11 @@ import okhttp3.OkHttpClient
class XBetExtractor(
private val client: OkHttpClient,
private val headers: Headers,
private val json: Json,
) {
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
fun videosFromUrl(url: String): List<Video> {
val doc = client.newCall(GET(url, headers)).execute()
.asJsoup()
suspend fun videosFromUrl(url: String): List<Video> {
val doc = client.newCall(GET(url, headers)).await().asJsoup()
val script = doc.selectFirst("script:containsData(playerConfigs =)")?.data()
?: return emptyList()
@ -36,12 +34,12 @@ class XBetExtractor(
.set("Origin", host)
.build()
val postRes = client.newCall(POST(host + postPath, postHeaders)).execute()
val postRes = client.newCall(POST(host + postPath, postHeaders)).await()
.parseAs<List<VideoItemDto>> { it.replace("[],", "") }
return postRes.flatMap { video ->
runCatching {
val playlistUrl = client.newCall(POST(host + video.path, postHeaders)).execute()
val playlistUrl = client.newCall(POST(host + video.path, postHeaders)).await()
.body.string()
playlistUtils.extractFromHls(