forked from recloudstream/cloudstream
fixed gogo and added extractor
This commit is contained in:
parent
250d307df7
commit
f90b582b96
5 changed files with 151 additions and 60 deletions
|
@ -18,6 +18,7 @@ class GogoanimeProvider : MainAPI() {
|
|||
else if (t.contains("Movie")) TvType.AnimeMovie
|
||||
else TvType.Anime
|
||||
}
|
||||
|
||||
fun getStatus(t: String): ShowStatus {
|
||||
return when (t) {
|
||||
"Completed" -> ShowStatus.Completed
|
||||
|
@ -25,6 +26,7 @@ class GogoanimeProvider : MainAPI() {
|
|||
else -> ShowStatus.Completed
|
||||
}
|
||||
}
|
||||
|
||||
val qualityRegex = Regex("(\\d+)P")
|
||||
}
|
||||
|
||||
|
@ -58,7 +60,8 @@ class GogoanimeProvider : MainAPI() {
|
|||
"sec-fetch-dest" to "empty",
|
||||
"referer" to "$mainUrl/"
|
||||
)
|
||||
val parseRegex = Regex("""<li>\s*\n.*\n.*<a\s*href=["'](.*?-episode-(\d+))["']\s*title=["'](.*?)["']>\n.*?img src="(.*?)"""")
|
||||
val parseRegex =
|
||||
Regex("""<li>\s*\n.*\n.*<a\s*href=["'](.*?-episode-(\d+))["']\s*title=["'](.*?)["']>\n.*?img src="(.*?)"""")
|
||||
|
||||
val urls = listOf(
|
||||
Pair("1", "Recent Release - Sub"),
|
||||
|
@ -70,7 +73,11 @@ class GogoanimeProvider : MainAPI() {
|
|||
for (i in urls) {
|
||||
try {
|
||||
val params = mapOf("page" to "1", "type" to i.first)
|
||||
val html = get("https://ajax.gogo-load.com/ajax/page-recent-release.html", headers=headers, params=params).text
|
||||
val html = get(
|
||||
"https://ajax.gogo-load.com/ajax/page-recent-release.html",
|
||||
headers = headers,
|
||||
params = params
|
||||
).text
|
||||
items.add(HomePageList(i.second, (parseRegex.findAll(html).map {
|
||||
val (link, epNum, title, poster) = it.destructured
|
||||
AnimeSearchResponse(
|
||||
|
@ -81,7 +88,9 @@ class GogoanimeProvider : MainAPI() {
|
|||
poster,
|
||||
null,
|
||||
null,
|
||||
if (listOf(1, 3).contains(i.first.toInt())) EnumSet.of(DubStatus.Subbed) else EnumSet.of(DubStatus.Dubbed),
|
||||
if (listOf(1, 3).contains(i.first.toInt())) EnumSet.of(DubStatus.Subbed) else EnumSet.of(
|
||||
DubStatus.Dubbed
|
||||
),
|
||||
null,
|
||||
epNum.toIntOrNull()
|
||||
)
|
||||
|
@ -90,7 +99,7 @@ class GogoanimeProvider : MainAPI() {
|
|||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
if(items.size <= 0) throw ErrorLoadingException()
|
||||
if (items.size <= 0) throw ErrorLoadingException()
|
||||
return HomePageResponse(items)
|
||||
}
|
||||
|
||||
|
@ -108,7 +117,9 @@ class GogoanimeProvider : MainAPI() {
|
|||
it.selectFirst("img").attr("src"),
|
||||
it.selectFirst(".released")?.text()?.split(":")?.getOrNull(1)?.trim()?.toIntOrNull(),
|
||||
null,
|
||||
if (it.selectFirst(".name").text().contains("Dub")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed),
|
||||
if (it.selectFirst(".name").text().contains("Dub")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(
|
||||
DubStatus.Subbed
|
||||
),
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
@ -120,7 +131,7 @@ class GogoanimeProvider : MainAPI() {
|
|||
private fun getProperAnimeLink(uri: String): String {
|
||||
if (uri.contains("-episode")) {
|
||||
val split = uri.split("/")
|
||||
val slug = split[split.size-1].split("-episode")[0]
|
||||
val slug = split[split.size - 1].split("-episode")[0]
|
||||
return "$mainUrl/category/$slug"
|
||||
}
|
||||
return uri
|
||||
|
@ -169,7 +180,7 @@ class GogoanimeProvider : MainAPI() {
|
|||
|
||||
val animeId = doc.selectFirst("#movie_id").attr("value")
|
||||
val params = mapOf("ep_start" to "0", "ep_end" to "2000", "id" to animeId)
|
||||
val responseHTML = get(episodeloadApi, params=params).text
|
||||
val responseHTML = get(episodeloadApi, params = params).text
|
||||
val epiDoc = Jsoup.parse(responseHTML)
|
||||
val episodes = epiDoc.select("a").map {
|
||||
AnimeEpisode(
|
||||
|
@ -207,24 +218,27 @@ class GogoanimeProvider : MainAPI() {
|
|||
val page = get(link, headers = mapOf("Referer" to iframe))
|
||||
val pageDoc = Jsoup.parse(page.text)
|
||||
|
||||
return pageDoc.select(".dowload > a").map {
|
||||
return pageDoc.select(".dowload > a").pmap {
|
||||
if (it.hasAttr("download")) {
|
||||
val qual = if (it.text()
|
||||
.contains("HDP")
|
||||
) "1080" else qualityRegex.find(it.text())?.destructured?.component1().toString()
|
||||
listOf(ExtractorLink(
|
||||
"Gogoanime",
|
||||
if(qual == "null") "Gogoanime" else "Gogoanime - " + qual + "p",
|
||||
it.attr("href"),
|
||||
page.url,
|
||||
getQualityFromName(qual),
|
||||
it.attr("href").contains(".m3u8")
|
||||
))
|
||||
listOf(
|
||||
ExtractorLink(
|
||||
"Gogoanime",
|
||||
if (qual == "null") "Gogoanime" else "Gogoanime - " + qual + "p",
|
||||
it.attr("href"),
|
||||
page.url,
|
||||
getQualityFromName(qual),
|
||||
it.attr("href").contains(".m3u8")
|
||||
)
|
||||
)
|
||||
} else {
|
||||
val url = it.attr("href")
|
||||
val extractorLinks = ArrayList<ExtractorLink>()
|
||||
for (api in extractorApis) {
|
||||
if (api.name.equals(it.text().replace("Download", "").trim(), ignoreCase = true)) {
|
||||
extractorLinks.addAll(api.getSafeUrl(it.attr("href")) ?: listOf())
|
||||
if (url.startsWith(api.mainUrl) ) {
|
||||
extractorLinks.addAll(api.getSafeUrl(url) ?: listOf())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.network.get
|
||||
import com.lagradost.cloudstream3.network.post
|
||||
import com.lagradost.cloudstream3.network.text
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.getPostForm
|
||||
import org.jsoup.Jsoup
|
||||
|
||||
class SBPlay : ExtractorApi() {
|
||||
override val mainUrl: String
|
||||
get() = "https://sbplay.one"
|
||||
override val name: String
|
||||
get() = "SBPlay"
|
||||
override val requiresReferer: Boolean
|
||||
get() = false
|
||||
|
||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||
val response = get(url, referer = referer).text
|
||||
val document = Jsoup.parse(response)
|
||||
|
||||
val links = ArrayList<ExtractorLink>();
|
||||
|
||||
val tree = document.select("table > tbody > tr > td > a")
|
||||
for (item in tree) {
|
||||
val onDownload = item.attr("onclick")
|
||||
val name = "${this.name} - ${item.text()}"
|
||||
try {
|
||||
Regex("download_video\\('(.*?)','(.*?)','(.*?)'\\)").matchEntire(onDownload)?.let {
|
||||
val id = it.groupValues[1]
|
||||
val mode = it.groupValues[2]
|
||||
val hash = it.groupValues[3]
|
||||
val href = "https://sbplay.one/dl?op=download_orig&id=$id&mode=$mode&hash=$hash"
|
||||
val hrefResponse = get(href).text
|
||||
post("https://sbplay.one/?op=notifications&open=&_=$unixTimeMS", referer = href)
|
||||
val hrefDocument = Jsoup.parse(hrefResponse)
|
||||
val hrefSpan = hrefDocument.selectFirst("span > a")
|
||||
if (hrefSpan == null) {
|
||||
getPostForm(href, hrefResponse)?.let { form ->
|
||||
val postDocument = Jsoup.parse(form)
|
||||
val downloadBtn = postDocument.selectFirst("a.downloadbtn")?.attr("href")
|
||||
if(downloadBtn.isNullOrEmpty()) {
|
||||
val hrefSpan2 = postDocument.selectFirst("span > a")?.attr("href")
|
||||
if(hrefSpan2?.startsWith("https://") == true) {
|
||||
links.add(ExtractorLink(this.name, name,
|
||||
hrefSpan2, "", Qualities.Unknown.value, false))
|
||||
} else {
|
||||
// no link found!!!
|
||||
}
|
||||
} else {
|
||||
links.add(ExtractorLink(this.name, name, downloadBtn, "", Qualities.Unknown.value, false))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val link = hrefSpan.attr("href")
|
||||
links.add(ExtractorLink(this.name, name, link, "", Qualities.Unknown.value, false))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logError(e)
|
||||
}
|
||||
}
|
||||
|
||||
return links
|
||||
}
|
||||
}
|
|
@ -3,16 +3,15 @@ package com.lagradost.cloudstream3.movieproviders
|
|||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.network.get
|
||||
import com.lagradost.cloudstream3.network.post
|
||||
import com.lagradost.cloudstream3.network.text
|
||||
import com.lagradost.cloudstream3.network.url
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.getPostForm
|
||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||
import okio.Buffer
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import java.lang.Thread.sleep
|
||||
import java.net.URLDecoder
|
||||
|
||||
class AllMoviesForYouProvider : MainAPI() {
|
||||
|
@ -192,46 +191,13 @@ class AllMoviesForYouProvider : MainAPI() {
|
|||
tries += 1
|
||||
html += buffer.readUtf8()
|
||||
}
|
||||
getPostForm(request.url,html)?.let { form ->
|
||||
val postDocument = Jsoup.parse(form)
|
||||
|
||||
val document = Jsoup.parse(html)
|
||||
val inputs = document.select("Form > input")
|
||||
if (inputs.size < 4) return false
|
||||
var op: String? = null
|
||||
var id: String? = null
|
||||
var mode: String? = null
|
||||
var hash: String? = null
|
||||
|
||||
for (input in inputs) {
|
||||
val value = input.attr("value") ?: continue
|
||||
when (input.attr("name")) {
|
||||
"op" -> op = value
|
||||
"id" -> id = value
|
||||
"mode" -> mode = value
|
||||
"hash" -> hash = value
|
||||
else -> {
|
||||
}
|
||||
postDocument.selectFirst("a.downloadbtn")?.attr("href")?.let { url ->
|
||||
callback(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value))
|
||||
}
|
||||
}
|
||||
if (op == null || id == null || mode == null || hash == null) {
|
||||
return false
|
||||
}
|
||||
sleep(5000) // ye this is needed, wont work with 0 delay
|
||||
|
||||
val postResponse = post(
|
||||
request.url,
|
||||
headers = mapOf(
|
||||
"content-type" to "application/x-www-form-urlencoded",
|
||||
"referer" to request.url,
|
||||
"user-agent" to USER_AGENT,
|
||||
"accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
),
|
||||
data = mapOf("op" to op, "id" to id, "mode" to mode, "hash" to hash)
|
||||
).text
|
||||
val postDocument = Jsoup.parse(postResponse)
|
||||
|
||||
val url = postDocument.selectFirst("a.downloadbtn").attr("href")
|
||||
if (url.isNullOrEmpty()) return false
|
||||
callback(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value))
|
||||
} else {
|
||||
callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.lagradost.cloudstream3.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.net.Uri
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
|
@ -97,10 +96,8 @@ object CastHelper {
|
|||
startIndex: Int? = null,
|
||||
startTime: Long? = null,
|
||||
) : Boolean {
|
||||
println("HELLO:" + episodes.isNullOrEmpty())
|
||||
if(this == null) return false
|
||||
if (episodes.isEmpty()) return false
|
||||
println("LINKS SIE:" + currentLinks.size)
|
||||
if (currentLinks.size <= currentEpisodeIndex) return false
|
||||
|
||||
val epData = episodes[currentEpisodeIndex]
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package com.lagradost.cloudstream3.utils
|
||||
|
||||
import com.lagradost.cloudstream3.USER_AGENT
|
||||
import com.lagradost.cloudstream3.extractors.*
|
||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||
import com.lagradost.cloudstream3.network.post
|
||||
import com.lagradost.cloudstream3.network.text
|
||||
import org.jsoup.Jsoup
|
||||
|
||||
data class ExtractorLink(
|
||||
val source: String,
|
||||
|
@ -72,6 +76,7 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
|
|||
XStreamCdn(),
|
||||
StreamSB(),
|
||||
Streamhub(),
|
||||
SBPlay(),
|
||||
|
||||
// dood extractors
|
||||
DoodToExtractor(),
|
||||
|
@ -94,6 +99,45 @@ fun httpsify(url: String): String {
|
|||
return if (url.startsWith("//")) "https:$url" else url
|
||||
}
|
||||
|
||||
fun getPostForm(requestUrl : String, html : String) : String? {
|
||||
val document = Jsoup.parse(html)
|
||||
val inputs = document.select("Form > input")
|
||||
if (inputs.size < 4) return null
|
||||
var op: String? = null
|
||||
var id: String? = null
|
||||
var mode: String? = null
|
||||
var hash: String? = null
|
||||
|
||||
for (input in inputs) {
|
||||
val value = input.attr("value") ?: continue
|
||||
when (input.attr("name")) {
|
||||
"op" -> op = value
|
||||
"id" -> id = value
|
||||
"mode" -> mode = value
|
||||
"hash" -> hash = value
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (op == null || id == null || mode == null || hash == null) {
|
||||
return null
|
||||
}
|
||||
Thread.sleep(5000) // ye this is needed, wont work with 0 delay
|
||||
|
||||
val postResponse = post(
|
||||
requestUrl,
|
||||
headers = mapOf(
|
||||
"content-type" to "application/x-www-form-urlencoded",
|
||||
"referer" to requestUrl,
|
||||
"user-agent" to USER_AGENT,
|
||||
"accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
),
|
||||
data = mapOf("op" to op, "id" to id, "mode" to mode, "hash" to hash)
|
||||
).text
|
||||
|
||||
return postResponse
|
||||
}
|
||||
|
||||
abstract class ExtractorApi {
|
||||
abstract val name: String
|
||||
abstract val mainUrl: String
|
||||
|
|
Loading…
Reference in a new issue