UHDMovies: Fix video extraction and some regex (#1455)

and lazy load current url
This commit is contained in:
Samfun75
2023-03-30 18:57:27 +03:00
committed by GitHub
parent a82204f80b
commit 042fffe5c4
2 changed files with 24 additions and 68 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'UHD Movies'
pkgNameSuffix = 'en.uhdmovies'
extClass = '.UHDMovies'
extVersionCode = 11
extVersionCode = 12
libVersion = '13'
}

View File

@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
@ -24,11 +23,8 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
@ -55,12 +51,10 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
private var currentBaseUrl: String
init {
private val currentBaseUrl by lazy {
runBlocking {
withContext(Dispatchers.Default) {
currentBaseUrl = client.newBuilder()
client.newBuilder()
.followRedirects(false)
.build()
.newCall(GET("$baseUrl/")).execute().let { resp ->
@ -135,7 +129,7 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override fun fetchEpisodeList(anime: SAnime): Observable<List<SEpisode>> {
val resp = client.newCall(GET(currentBaseUrl + anime.url)).execute().asJsoup()
val episodeList = mutableListOf<SEpisode>()
val episodeElements = resp.select("p:has(a[href*=?id]):has(a[class*=maxbutton])[style*=center],p:has(a[href*=?id]):has(span.maxbutton-1-center)")
val episodeElements = resp.select("p:has(a[href*=r?key=]):has(a[class*=maxbutton])[style*=center]")
val qualityRegex = "\\d{3,4}p".toRegex(RegexOption.IGNORE_CASE)
val firstText = episodeElements.first()!!.text()
if (firstText.contains("Episode", true) ||
@ -144,17 +138,26 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
) {
episodeElements.map { row ->
val prevP = row.previousElementSibling()!!
val seasonRegex = "[ .]S(?:eason)?[ .]?(\\d{1,2})[ .]".toRegex(RegexOption.IGNORE_CASE)
val seasonRegex = "[ .]?S(?:eason)?[ .]?(\\d{1,2})[ .]?".toRegex(RegexOption.IGNORE_CASE)
val partRegex = "Part ?(\\d{1,2})".toRegex(RegexOption.IGNORE_CASE)
val result = seasonRegex.find(prevP.text())
var part = ""
val season = (
result?.groups?.get(1)?.value ?: let {
result?.groups?.get(1)?.value?.also {
part = partRegex.find(prevP.text())?.groups?.get(1)?.value ?: ""
} ?: let {
val prevPre = row.previousElementSiblings().prev("pre,div.mks_separator")
val preResult = seasonRegex.find(prevPre.first()!!.text())
preResult?.groups?.get(1)?.value ?: let {
preResult?.groups?.get(1)?.value?.also {
part = partRegex.find(prevPre.first()!!.text())?.groups?.get(1)?.value ?: ""
} ?: let {
val title = resp.select("h1.entry-title")
val titleResult = "[ .\\[(]S(?:eason)?[ .]?(\\d{1,2})[ .\\])]".toRegex(RegexOption.IGNORE_CASE).find(title.text())
titleResult?.groups?.get(1)?.value ?: "-1"
val titleResult = "[ .\\[(]?S(?:eason)?[ .]?(\\d{1,2})[ .\\])]?"
.toRegex(RegexOption.IGNORE_CASE)
.find(title.text())
titleResult?.groups?.get(1)?.value?.also {
part = partRegex.find(title.text())?.groups?.get(1)?.value ?: ""
} ?: "-1"
}
}
).replaceFirst("^0+(?!$)".toRegex(), "")
@ -174,13 +177,14 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
?.replace("Episode", "", true)
?.trim()?.toIntOrNull() ?: (index + 1)
Triple(
season + "_$episode",
season + "_$episode" + "_$part",
linkElement.attr("href") ?: return@mapIndexed null,
quality,
)
}.filterNotNull()
}.flatten().groupBy { it.first }.map { group ->
val (season, episode) = group.key.split("_")
val (season, episode, part) = group.key.split("_")
val partText = if (part.isBlank()) "" else " Pt $part"
episodeList.add(
SEpisode.create().apply {
url = EpLinks(
@ -188,7 +192,7 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
EpUrl(url = it.second, quality = it.third)
},
).toJson()
name = "Season $season Ep $episode"
name = "Season $season$partText Ep $episode"
episode_number = episode.toFloat()
},
)
@ -284,31 +288,7 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
// ============================= Utilities ==============================
private fun extractVideo(epUrl: EpUrl): Pair<List<Video>, String> {
val postLink = epUrl.url.substringBefore("?id=").substringAfter("/?")
val formData = FormBody.Builder().add("_wp_http_c", epUrl.url.substringAfter("?id=")).build()
val response = client.newCall(POST(postLink, body = formData)).execute().body.string()
val (longC, catC, _) = getCookiesDetail(response)
val cookieHeader = Headers.headersOf("Cookie", "$longC; $catC")
val parsedSoup = Jsoup.parse(response)
val link = parsedSoup.selectFirst("center > a")!!.attr("href")
val response2 = client.newCall(GET(link, cookieHeader)).execute().body.string()
val (longC2, _, postC) = getCookiesDetail(response2)
val cookieHeader2 = Headers.headersOf("Cookie", "$catC; $longC2; $postC")
val parsedSoup2 = Jsoup.parse(response2)
val link2 = parsedSoup2.selectFirst("center > a")!!.attr("href")
val tokenResp = client.newCall(GET(link2, cookieHeader2)).execute().body.string()
val goToken = tokenResp.substringAfter("?go=").substringBefore("\"")
val tokenUrl = "$postLink?go=$goToken"
val newLongC = "$goToken=" + longC2.substringAfter("=")
val tokenCookie = Headers.headersOf("Cookie", "$catC; rdst_post=; $newLongC")
val noRedirectClient = client.newBuilder().followRedirects(false).build()
val tokenResponse = noRedirectClient.newCall(GET(tokenUrl, tokenCookie)).execute().asJsoup()
val redirectUrl = tokenResponse.select("meta[http-equiv=refresh]").attr("content")
.substringAfter("url=").substringBefore("\"")
val mediaResponse = noRedirectClient.newCall(GET(redirectUrl)).execute()
val mediaResponse = client.newCall(GET(epUrl.url)).execute()
val path = mediaResponse.body.string().substringAfter("replace(\"").substringBefore("\"")
if (path == "/404") return Pair(emptyList(), "")
val mediaUrl = "https://" + mediaResponse.request.url.host + path
@ -322,30 +302,6 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
return Pair(videoList, mediaUrl)
}
private fun getCookiesDetail(page: String): Triple<String, String, String> {
val cat = "rdst_cat"
val post = "rdst_post"
val longC = page.substringAfter(".setTime")
.substringAfter("document.cookie = \"")
.substringBefore("\"")
.substringBefore(";")
val catC = if (page.contains("$cat=")) {
page.substringAfterLast("$cat=")
.substringBefore(";").let {
"$cat=$it"
}
} else { "" }
val postC = if (page.contains("$post=")) {
page.substringAfterLast("$post=")
.substringBefore(";").let {
"$post=$it"
}
} else { "" }
return Triple(longC, catC, postC)
}
private val sizeRegex = "\\[((?:.(?!\\[))+)] *\$".toRegex(RegexOption.IGNORE_CASE)
private fun extractWorkerLinks(mediaUrl: String, quality: String, type: Int): List<Video> {