fix(tr/hdfilmcehennemi): Update baseUrl + add a new extractor (#2884)
This commit is contained in:
parent
6486f5c9b8
commit
5d62c958cf
@ -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
|
||||
|
@ -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>
|
||||
|
@ -1,7 +1,7 @@
|
||||
ext {
|
||||
extName = 'HDFilmCehennemi'
|
||||
extClass = '.HDFilmCehennemi'
|
||||
extVersionCode = 9
|
||||
extVersionCode = 10
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
|
@ -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)!!
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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('"')
|
||||
}
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
@ -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('"', "")
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user