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 if (t.contains("Movie")) TvType.AnimeMovie
|
||||||
else TvType.Anime
|
else TvType.Anime
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStatus(t: String): ShowStatus {
|
fun getStatus(t: String): ShowStatus {
|
||||||
return when (t) {
|
return when (t) {
|
||||||
"Completed" -> ShowStatus.Completed
|
"Completed" -> ShowStatus.Completed
|
||||||
|
@ -25,6 +26,7 @@ class GogoanimeProvider : MainAPI() {
|
||||||
else -> ShowStatus.Completed
|
else -> ShowStatus.Completed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val qualityRegex = Regex("(\\d+)P")
|
val qualityRegex = Regex("(\\d+)P")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +60,8 @@ class GogoanimeProvider : MainAPI() {
|
||||||
"sec-fetch-dest" to "empty",
|
"sec-fetch-dest" to "empty",
|
||||||
"referer" to "$mainUrl/"
|
"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(
|
val urls = listOf(
|
||||||
Pair("1", "Recent Release - Sub"),
|
Pair("1", "Recent Release - Sub"),
|
||||||
|
@ -70,7 +73,11 @@ class GogoanimeProvider : MainAPI() {
|
||||||
for (i in urls) {
|
for (i in urls) {
|
||||||
try {
|
try {
|
||||||
val params = mapOf("page" to "1", "type" to i.first)
|
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 {
|
items.add(HomePageList(i.second, (parseRegex.findAll(html).map {
|
||||||
val (link, epNum, title, poster) = it.destructured
|
val (link, epNum, title, poster) = it.destructured
|
||||||
AnimeSearchResponse(
|
AnimeSearchResponse(
|
||||||
|
@ -81,7 +88,9 @@ class GogoanimeProvider : MainAPI() {
|
||||||
poster,
|
poster,
|
||||||
null,
|
null,
|
||||||
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,
|
null,
|
||||||
epNum.toIntOrNull()
|
epNum.toIntOrNull()
|
||||||
)
|
)
|
||||||
|
@ -108,7 +117,9 @@ class GogoanimeProvider : MainAPI() {
|
||||||
it.selectFirst("img").attr("src"),
|
it.selectFirst("img").attr("src"),
|
||||||
it.selectFirst(".released")?.text()?.split(":")?.getOrNull(1)?.trim()?.toIntOrNull(),
|
it.selectFirst(".released")?.text()?.split(":")?.getOrNull(1)?.trim()?.toIntOrNull(),
|
||||||
null,
|
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,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
@ -207,24 +218,27 @@ class GogoanimeProvider : MainAPI() {
|
||||||
val page = get(link, headers = mapOf("Referer" to iframe))
|
val page = get(link, headers = mapOf("Referer" to iframe))
|
||||||
val pageDoc = Jsoup.parse(page.text)
|
val pageDoc = Jsoup.parse(page.text)
|
||||||
|
|
||||||
return pageDoc.select(".dowload > a").map {
|
return pageDoc.select(".dowload > a").pmap {
|
||||||
if (it.hasAttr("download")) {
|
if (it.hasAttr("download")) {
|
||||||
val qual = if (it.text()
|
val qual = if (it.text()
|
||||||
.contains("HDP")
|
.contains("HDP")
|
||||||
) "1080" else qualityRegex.find(it.text())?.destructured?.component1().toString()
|
) "1080" else qualityRegex.find(it.text())?.destructured?.component1().toString()
|
||||||
listOf(ExtractorLink(
|
listOf(
|
||||||
|
ExtractorLink(
|
||||||
"Gogoanime",
|
"Gogoanime",
|
||||||
if (qual == "null") "Gogoanime" else "Gogoanime - " + qual + "p",
|
if (qual == "null") "Gogoanime" else "Gogoanime - " + qual + "p",
|
||||||
it.attr("href"),
|
it.attr("href"),
|
||||||
page.url,
|
page.url,
|
||||||
getQualityFromName(qual),
|
getQualityFromName(qual),
|
||||||
it.attr("href").contains(".m3u8")
|
it.attr("href").contains(".m3u8")
|
||||||
))
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
|
val url = it.attr("href")
|
||||||
val extractorLinks = ArrayList<ExtractorLink>()
|
val extractorLinks = ArrayList<ExtractorLink>()
|
||||||
for (api in extractorApis) {
|
for (api in extractorApis) {
|
||||||
if (api.name.equals(it.text().replace("Download", "").trim(), ignoreCase = true)) {
|
if (url.startsWith(api.mainUrl) ) {
|
||||||
extractorLinks.addAll(api.getSafeUrl(it.attr("href")) ?: listOf())
|
extractorLinks.addAll(api.getSafeUrl(url) ?: listOf())
|
||||||
break
|
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.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.network.get
|
import com.lagradost.cloudstream3.network.get
|
||||||
import com.lagradost.cloudstream3.network.post
|
|
||||||
import com.lagradost.cloudstream3.network.text
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.network.url
|
import com.lagradost.cloudstream3.network.url
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
import com.lagradost.cloudstream3.utils.getPostForm
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import java.lang.Thread.sleep
|
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
|
|
||||||
class AllMoviesForYouProvider : MainAPI() {
|
class AllMoviesForYouProvider : MainAPI() {
|
||||||
|
@ -192,46 +191,13 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
tries += 1
|
tries += 1
|
||||||
html += buffer.readUtf8()
|
html += buffer.readUtf8()
|
||||||
}
|
}
|
||||||
|
getPostForm(request.url,html)?.let { form ->
|
||||||
|
val postDocument = Jsoup.parse(form)
|
||||||
|
|
||||||
val document = Jsoup.parse(html)
|
postDocument.selectFirst("a.downloadbtn")?.attr("href")?.let { url ->
|
||||||
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 -> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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))
|
callback(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value))
|
callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.lagradost.cloudstream3.utils
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
|
@ -97,10 +96,8 @@ object CastHelper {
|
||||||
startIndex: Int? = null,
|
startIndex: Int? = null,
|
||||||
startTime: Long? = null,
|
startTime: Long? = null,
|
||||||
) : Boolean {
|
) : Boolean {
|
||||||
println("HELLO:" + episodes.isNullOrEmpty())
|
|
||||||
if(this == null) return false
|
if(this == null) return false
|
||||||
if (episodes.isEmpty()) return false
|
if (episodes.isEmpty()) return false
|
||||||
println("LINKS SIE:" + currentLinks.size)
|
|
||||||
if (currentLinks.size <= currentEpisodeIndex) return false
|
if (currentLinks.size <= currentEpisodeIndex) return false
|
||||||
|
|
||||||
val epData = episodes[currentEpisodeIndex]
|
val epData = episodes[currentEpisodeIndex]
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package com.lagradost.cloudstream3.utils
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.USER_AGENT
|
||||||
import com.lagradost.cloudstream3.extractors.*
|
import com.lagradost.cloudstream3.extractors.*
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
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(
|
data class ExtractorLink(
|
||||||
val source: String,
|
val source: String,
|
||||||
|
@ -72,6 +76,7 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
|
||||||
XStreamCdn(),
|
XStreamCdn(),
|
||||||
StreamSB(),
|
StreamSB(),
|
||||||
Streamhub(),
|
Streamhub(),
|
||||||
|
SBPlay(),
|
||||||
|
|
||||||
// dood extractors
|
// dood extractors
|
||||||
DoodToExtractor(),
|
DoodToExtractor(),
|
||||||
|
@ -94,6 +99,45 @@ fun httpsify(url: String): String {
|
||||||
return if (url.startsWith("//")) "https:$url" else url
|
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 class ExtractorApi {
|
||||||
abstract val name: String
|
abstract val name: String
|
||||||
abstract val mainUrl: String
|
abstract val mainUrl: String
|
||||||
|
|
Loading…
Reference in a new issue