Merge branch 'almightyhak:main' into ext-improvements

This commit is contained in:
imper1aldev 2024-08-13 02:53:58 -06:00 committed by GitHub
commit 645361ef42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 46 additions and 57 deletions

View file

@ -23,7 +23,6 @@ import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -130,7 +129,7 @@ class Pelisplusph(override val name: String, override val baseUrl: String) : Pel
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup() val document = response.asJsoup()
return document.select("[class*=server-item-]").parallelCatchingFlatMapBlocking { serverItem -> return document.select("[class*=server-item-]").flatMap { serverItem ->
val langIdx = getNumberFromString(serverItem.attr("class").substringAfter("server-item-")) val langIdx = getNumberFromString(serverItem.attr("class").substringAfter("server-item-"))
val langItem = document.select("li[data-id=\"$langIdx\"] a").text() val langItem = document.select("li[data-id=\"$langIdx\"] a").text()
val lang = if (langItem.contains("Subtitulado")) "[SUB]" else if (langItem.contains("Latino")) "[LAT]" else "[CAST]" val lang = if (langItem.contains("Subtitulado")) "[SUB]" else if (langItem.contains("Latino")) "[LAT]" else "[CAST]"
@ -166,7 +165,7 @@ class Pelisplusph(override val name: String, override val baseUrl: String) : Pel
} }
embedUrl.contains("doodstream") || embedUrl.contains("dood.") || embedUrl.contains("ds2play") || embedUrl.contains("doods.") -> { embedUrl.contains("doodstream") || embedUrl.contains("dood.") || embedUrl.contains("ds2play") || embedUrl.contains("doods.") -> {
val url2 = url.replace("https://doodstream.com/e/", "https://dood.to/e/") val url2 = url.replace("https://doodstream.com/e/", "https://dood.to/e/")
listOf(DoodExtractor(client).videoFromUrl(url2, "$prefix DoodStream", false)!!) listOf(DoodExtractor(client).videoFromUrl(url2, "$prefix DoodStream")!!)
} }
embedUrl.contains("streamlare") -> StreamlareExtractor(client).videosFromUrl(url, prefix = prefix) embedUrl.contains("streamlare") -> StreamlareExtractor(client).videosFromUrl(url, prefix = prefix)
embedUrl.contains("yourupload") || embedUrl.contains("upload") -> YourUploadExtractor(client).videoFromUrl(url, headers = headers, prefix = prefix) embedUrl.contains("yourupload") || embedUrl.contains("upload") -> YourUploadExtractor(client).videoFromUrl(url, headers = headers, prefix = prefix)

View file

@ -24,7 +24,6 @@ import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
@ -135,7 +134,7 @@ class Pelisplusto(override val name: String, override val baseUrl: String) : Pel
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup() val document = response.asJsoup()
val regIsUrl = "https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)".toRegex() val regIsUrl = "https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)".toRegex()
return document.select(".bg-tabs ul li").parallelCatchingFlatMapBlocking { return document.select(".bg-tabs ul li").flatMap {
val decode = String(Base64.decode(it.attr("data-server"), Base64.DEFAULT)) val decode = String(Base64.decode(it.attr("data-server"), Base64.DEFAULT))
val url = if (!regIsUrl.containsMatchIn(decode)) { val url = if (!regIsUrl.containsMatchIn(decode)) {
@ -207,7 +206,7 @@ class Pelisplusto(override val name: String, override val baseUrl: String) : Pel
} }
embedUrl.contains("doodstream") || embedUrl.contains("dood.") || embedUrl.contains("ds2play") || embedUrl.contains("doods.") -> { embedUrl.contains("doodstream") || embedUrl.contains("dood.") || embedUrl.contains("ds2play") || embedUrl.contains("doods.") -> {
val url2 = url.replace("https://doodstream.com/e/", "https://dood.to/e/") val url2 = url.replace("https://doodstream.com/e/", "https://dood.to/e/")
listOf(DoodExtractor(client).videoFromUrl(url2, "DoodStream", false)!!) listOf(DoodExtractor(client).videoFromUrl(url2, "DoodStream")!!)
} }
embedUrl.contains("streamlare") -> StreamlareExtractor(client).videosFromUrl(url) embedUrl.contains("streamlare") -> StreamlareExtractor(client).videosFromUrl(url)
embedUrl.contains("yourupload") || embedUrl.contains("upload") -> YourUploadExtractor(client).videoFromUrl(url, headers = headers) embedUrl.contains("yourupload") || embedUrl.contains("upload") -> YourUploadExtractor(client).videoFromUrl(url, headers = headers)

View file

@ -1,7 +1,7 @@
ext { ext {
extName = 'Oploverz' extName = 'Oploverz'
extClass = '.Oploverz' extClass = '.Oploverz'
extVersionCode = 26 extVersionCode = 27
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.animeextension.id.oploverz
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Base64
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
@ -12,14 +13,11 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
import eu.kanade.tachiyomi.util.parallelMapNotNullBlocking
import okhttp3.FormBody
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.json.JSONObject import org.json.JSONObject
import org.jsoup.Jsoup
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -39,28 +37,28 @@ class Oploverz : ConfigurableAnimeSource, AnimeHttpSource() {
// ============================== Popular =============================== // ============================== Popular ===============================
override fun popularAnimeRequest(page: Int): Request = override fun popularAnimeRequest(page: Int): Request =
GET("$baseUrl/anime-list/page/$page/?order=popular") GET("$baseUrl/anime/?page=$page&status=&type=&sub=&order=popular")
override fun popularAnimeParse(response: Response): AnimesPage = override fun popularAnimeParse(response: Response): AnimesPage =
getAnimeParse(response, "div.relat > article") getAnimeParse(response, "article[itemscope=itemscope]")
// =============================== Latest =============================== // =============================== Latest ===============================
override fun latestUpdatesRequest(page: Int): Request = override fun latestUpdatesRequest(page: Int): Request =
GET("$baseUrl/anime-list/page/$page/?order=latest") GET("$baseUrl/anime/?page=$page&status=&type=&sub=&order=latest")
override fun latestUpdatesParse(response: Response): AnimesPage = override fun latestUpdatesParse(response: Response): AnimesPage =
getAnimeParse(response, "div.relat > article") getAnimeParse(response, "article[itemscope=itemscope]")
// =============================== Search =============================== // =============================== Search ===============================
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
val params = OploverzFilters.getSearchParameters(filters) val params = OploverzFilters.getSearchParameters(filters)
return GET("$baseUrl/anime-list/page/$page/?title=$query${params.filter}", headers) return GET("$baseUrl/page/$page/?s=$query${params.filter}", headers)
} }
override fun searchAnimeParse(response: Response): AnimesPage = override fun searchAnimeParse(response: Response): AnimesPage =
getAnimeParse(response, "div.relat > article") getAnimeParse(response, "article[itemscope=itemscope]")
// ============================== Filters =============================== // ============================== Filters ===============================
@ -70,16 +68,16 @@ class Oploverz : ConfigurableAnimeSource, AnimeHttpSource() {
override fun animeDetailsParse(response: Response): SAnime { override fun animeDetailsParse(response: Response): SAnime {
val doc = response.asJsoup() val doc = response.asJsoup()
val detail = doc.selectFirst("div.infox > div.spe")!! val detail = doc.selectFirst("div.info-content > div.spe")!!
return SAnime.create().apply { return SAnime.create().apply {
author = detail.getInfo("Studio") author = detail.getInfo("Studio")
status = parseStatus(doc.selectFirst("div.alternati > span:nth-child(2)")!!.text()) status = parseStatus(detail.getInfo("Status"))
title = doc.selectFirst("div.title > h1.entry-title")!!.text() title = doc.selectFirst("h1.entry-title")!!.text()
thumbnail_url = thumbnail_url =
doc.selectFirst("div.infoanime.widget_senction > div.thumb > img")!! doc.selectFirst("div.thumb > img")!!
.attr("src") .attr("src")
description = description =
doc.select("div.entry-content.entry-content-single > p") doc.select("div.entry-content > p")
.joinToString("\n\n") { it.text() } .joinToString("\n\n") { it.text() }
} }
} }
@ -88,13 +86,13 @@ class Oploverz : ConfigurableAnimeSource, AnimeHttpSource() {
override fun episodeListParse(response: Response): List<SEpisode> { override fun episodeListParse(response: Response): List<SEpisode> {
val doc = response.asJsoup() val doc = response.asJsoup()
return doc.select("div.lstepsiode.listeps > ul.scrolling > li").map { return doc.select("div.eplister > ul > li").map {
val episode = it.selectFirst("span.eps > a")!! val episode = it.selectFirst("a")!!
SEpisode.create().apply { SEpisode.create().apply {
setUrlWithoutDomain(episode.attr("href")) setUrlWithoutDomain(episode.attr("href"))
episode_number = episode.text().trim().toFloatOrNull() ?: 1F episode_number = it.selectFirst("div.epl-num")!!.text().toFloatOrNull() ?: 1F
name = it.selectFirst("span.lchx > a")!!.text() name = it.selectFirst("div.epl-title")!!.text()
date_upload = it.selectFirst("span.date")!!.text().toDate() date_upload = it.selectFirst("div.epl-date")!!.text().toDate()
} }
} }
} }
@ -103,16 +101,26 @@ class Oploverz : ConfigurableAnimeSource, AnimeHttpSource() {
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
val doc = response.asJsoup() val doc = response.asJsoup()
val parseUrl = response.request.url.toUrl() val videoList = mutableListOf<Video>()
val url = "${parseUrl.protocol}://${parseUrl.host}"
return doc.select("#server > ul > li > div.east_player_option") doc.select("select.mirror > option[value]").forEach { opt ->
.parallelMapNotNullBlocking { val decoded = if (opt.attr("value").isEmpty()) {
runCatching { getEmbedLinks(url, it) }.getOrNull() doc.selectFirst("iframe")!!.attr("src")
} else {
Jsoup.parse(
String(Base64.decode(opt.attr("value"), Base64.DEFAULT)),
).select("iframe").attr("src")
} }
.parallelCatchingFlatMapBlocking {
getVideosFromEmbed(it.first) when {
decoded.contains("blogger.com") -> {
videoList.addAll(getVideosFromEmbed(decoded))
} }
} }
}
return videoList.sort()
}
// ============================= Utilities ============================== // ============================= Utilities ==============================
@ -140,19 +148,14 @@ class Oploverz : ConfigurableAnimeSource, AnimeHttpSource() {
val doc = response.asJsoup() val doc = response.asJsoup()
val animes = doc.select(query).map { val animes = doc.select(query).map {
SAnime.create().apply { SAnime.create().apply {
setUrlWithoutDomain(it.selectFirst("div.animposx > a")!!.attr("href")) setUrlWithoutDomain(it.selectFirst("a.tip")!!.attr("href"))
title = it.selectFirst("div.title > h2")!!.text() title = it.selectFirst("div.tt > h2")!!.text()
thumbnail_url = it.selectFirst("div.content-thumb > img")!!.attr("src") thumbnail_url = it.selectFirst("div.limit > img")!!.attr("src")
} }
} }
val hasNextPage = try {
val pagination = doc.selectFirst("div.pagination")!! val hasNextPage = doc.selectFirst("a.next.page-numbers") != null ?: doc.selectFirst("div.hpage > a.r")
val totalPage = pagination.selectFirst("span:nth-child(1)")!!.text().split(" ").last()
val currentPage = pagination.selectFirst("span.page-numbers.current")!!.text()
currentPage.toInt() < totalPage.toInt()
} catch (_: Exception) {
false
}
return AnimesPage(animes, hasNextPage) return AnimesPage(animes, hasNextPage)
} }
@ -164,18 +167,6 @@ class Oploverz : ConfigurableAnimeSource, AnimeHttpSource() {
} }
} }
private fun getEmbedLinks(url: String, element: Element): Pair<String, String> {
val form = FormBody.Builder().apply {
add("action", "player_ajax")
add("post", element.attr("data-post"))
add("nume", element.attr("data-nume"))
add("type", element.attr("data-type"))
}.build()
return client.newCall(POST("$url/wp-admin/admin-ajax.php", body = form))
.execute()
.let { Pair(it.asJsoup().selectFirst(".playeriframe")!!.attr("src"), "") }
}
private fun getVideosFromEmbed(link: String): List<Video> { private fun getVideosFromEmbed(link: String): List<Video> {
return when { return when {
"blogger" in link -> { "blogger" in link -> {