mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
parent
1948a2c2d9
commit
3a78f41aad
36 changed files with 547 additions and 246 deletions
|
@ -132,4 +132,7 @@ dependencies {
|
||||||
// Downloading
|
// Downloading
|
||||||
implementation "androidx.work:work-runtime:2.7.0-beta01"
|
implementation "androidx.work:work-runtime:2.7.0-beta01"
|
||||||
implementation "androidx.work:work-runtime-ktx:2.7.0-beta01"
|
implementation "androidx.work:work-runtime-ktx:2.7.0-beta01"
|
||||||
|
|
||||||
|
// Networking
|
||||||
|
implementation "com.squareup.okhttp3:okhttp:4.9.0"
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ import android.content.Context
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.google.auto.service.AutoService
|
import com.google.auto.service.AutoService
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
|
import com.lagradost.cloudstream3.network.post
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.runOnMainThread
|
import com.lagradost.cloudstream3.utils.Coroutines.runOnMainThread
|
||||||
import org.acra.ReportField
|
import org.acra.ReportField
|
||||||
import org.acra.config.CoreConfiguration
|
import org.acra.config.CoreConfiguration
|
||||||
|
@ -27,7 +28,7 @@ class CustomReportSender : ReportSender {
|
||||||
|
|
||||||
thread { // to not run it on main thread
|
thread { // to not run it on main thread
|
||||||
normalSafeApiCall {
|
normalSafeApiCall {
|
||||||
val post = khttp.post(url, data = data)
|
val post = post(url, data = data)
|
||||||
println("Report response: $post")
|
println("Report response: $post")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.animeproviders
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
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.extractorApis
|
import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
|
@ -36,7 +38,7 @@ class AnimeFlickProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): ArrayList<SearchResponse> {
|
override fun search(query: String): ArrayList<SearchResponse> {
|
||||||
val link = "https://animeflick.net/search.php?search=$query"
|
val link = "https://animeflick.net/search.php?search=$query"
|
||||||
val html = khttp.get(link).text
|
val html = get(link).text
|
||||||
val doc = Jsoup.parse(html)
|
val doc = Jsoup.parse(html)
|
||||||
|
|
||||||
return ArrayList(doc.select(".row.mt-2").map {
|
return ArrayList(doc.select(".row.mt-2").map {
|
||||||
|
@ -59,7 +61,7 @@ class AnimeFlickProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val html = khttp.get(url).text
|
val html = get(url).text
|
||||||
val doc = Jsoup.parse(html)
|
val doc = Jsoup.parse(html)
|
||||||
|
|
||||||
val poster = mainUrl + doc.selectFirst("img.rounded").attr("src")
|
val poster = mainUrl + doc.selectFirst("img.rounded").attr("src")
|
||||||
|
@ -101,7 +103,7 @@ class AnimeFlickProvider : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val html = khttp.get(data).text
|
val html = get(data).text
|
||||||
|
|
||||||
val episodeRegex = Regex("""(https://.*?\.mp4)""")
|
val episodeRegex = Regex("""(https://.*?\.mp4)""")
|
||||||
val links = episodeRegex.findAll(html).map {
|
val links = episodeRegex.findAll(html).map {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package com.lagradost.cloudstream3.animeproviders
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import khttp.structures.cookie.CookieJar
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
|
import com.lagradost.cloudstream3.network.*
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
import okhttp3.Response
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
@ -15,7 +16,7 @@ class AnimePaheProvider : MainAPI() {
|
||||||
companion object {
|
companion object {
|
||||||
const val MAIN_URL = "https://animepahe.com"
|
const val MAIN_URL = "https://animepahe.com"
|
||||||
|
|
||||||
var cookies = CookieJar()
|
var cookies: Map<String, String> = mapOf()
|
||||||
private fun getType(t: String): TvType {
|
private fun getType(t: String): TvType {
|
||||||
return if (t.contains("OVA") || t.contains("Special")) TvType.ONA
|
return if (t.contains("OVA") || t.contains("Special")) TvType.ONA
|
||||||
else if (t.contains("Movie")) TvType.AnimeMovie
|
else if (t.contains("Movie")) TvType.AnimeMovie
|
||||||
|
@ -23,9 +24,9 @@ class AnimePaheProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateSession(): Boolean {
|
fun generateSession(): Boolean {
|
||||||
if (cookies.entries.size != 0) return true
|
if (cookies.isNotEmpty()) return true
|
||||||
return try {
|
return try {
|
||||||
val response = khttp.get("$MAIN_URL/")
|
val response = get("$MAIN_URL/")
|
||||||
cookies = response.cookies
|
cookies = response.cookies
|
||||||
true
|
true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -82,8 +83,8 @@ class AnimePaheProvider : MainAPI() {
|
||||||
val items = ArrayList<HomePageList>()
|
val items = ArrayList<HomePageList>()
|
||||||
for (i in urls) {
|
for (i in urls) {
|
||||||
try {
|
try {
|
||||||
val response = khttp.get(i.first)
|
val response = get(i.first).text
|
||||||
val episodes = mapper.readValue<AnimePaheLatestReleases>(response.text).data.map {
|
val episodes = mapper.readValue<AnimePaheLatestReleases>(response).data.map {
|
||||||
|
|
||||||
AnimeSearchResponse(
|
AnimeSearchResponse(
|
||||||
it.animeTitle,
|
it.animeTitle,
|
||||||
|
@ -132,8 +133,8 @@ class AnimePaheProvider : MainAPI() {
|
||||||
val url = "$mainUrl/api?m=search&l=8&q=$title"
|
val url = "$mainUrl/api?m=search&l=8&q=$title"
|
||||||
val headers = mapOf("referer" to "$mainUrl/")
|
val headers = mapOf("referer" to "$mainUrl/")
|
||||||
|
|
||||||
val req = khttp.get(url, headers = headers)
|
val req = get(url, headers = headers).text
|
||||||
val data = req.let { mapper.readValue<AnimePaheSearch>(it.text) }
|
val data = req.let { mapper.readValue<AnimePaheSearch>(it) }
|
||||||
for (anime in data.data) {
|
for (anime in data.data) {
|
||||||
if (anime.id == animeId) {
|
if (anime.id == animeId) {
|
||||||
return "https://animepahe.com/anime/${anime.session}"
|
return "https://animepahe.com/anime/${anime.session}"
|
||||||
|
@ -147,8 +148,8 @@ class AnimePaheProvider : MainAPI() {
|
||||||
val url = "$mainUrl/api?m=search&l=8&q=$query"
|
val url = "$mainUrl/api?m=search&l=8&q=$query"
|
||||||
val headers = mapOf("referer" to "$mainUrl/")
|
val headers = mapOf("referer" to "$mainUrl/")
|
||||||
|
|
||||||
val req = khttp.get(url, headers = headers)
|
val req = get(url, headers = headers).text
|
||||||
val data = req.let { mapper.readValue<AnimePaheSearch>(it.text) }
|
val data = req.let { mapper.readValue<AnimePaheSearch>(it) }
|
||||||
|
|
||||||
return ArrayList(data.data.map {
|
return ArrayList(data.data.map {
|
||||||
AnimeSearchResponse(
|
AnimeSearchResponse(
|
||||||
|
@ -198,8 +199,8 @@ class AnimePaheProvider : MainAPI() {
|
||||||
val uri = "$mainUrl/api?m=release&id=$id&sort=episode_asc&page=1"
|
val uri = "$mainUrl/api?m=release&id=$id&sort=episode_asc&page=1"
|
||||||
val headers = mapOf("referer" to "$mainUrl/")
|
val headers = mapOf("referer" to "$mainUrl/")
|
||||||
|
|
||||||
val req = khttp.get(uri, headers = headers)
|
val req = get(uri, headers = headers).text
|
||||||
val data = req.let { mapper.readValue<AnimePaheAnimeData>(it.text) }
|
val data = req.let { mapper.readValue<AnimePaheAnimeData>(it) }
|
||||||
|
|
||||||
val lastPage = data.lastPage
|
val lastPage = data.lastPage
|
||||||
val perPage = data.perPage
|
val perPage = data.perPage
|
||||||
|
@ -257,7 +258,7 @@ class AnimePaheProvider : MainAPI() {
|
||||||
val (animeId, animeTitle) = regex.find(url)!!.destructured
|
val (animeId, animeTitle) = regex.find(url)!!.destructured
|
||||||
val link = getAnimeByIdAndTitle(animeTitle, animeId.toInt())!!
|
val link = getAnimeByIdAndTitle(animeTitle, animeId.toInt())!!
|
||||||
|
|
||||||
val html = khttp.get(link).text
|
val html = get(link).text
|
||||||
val doc = Jsoup.parse(html)
|
val doc = Jsoup.parse(html)
|
||||||
|
|
||||||
val japTitle = doc.selectFirst("h2.japanese")?.text()
|
val japTitle = doc.selectFirst("h2.japanese")?.text()
|
||||||
|
@ -454,17 +455,17 @@ class AnimePaheProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var responseCode = 302
|
var responseCode = 302
|
||||||
var adflyContent: khttp.responses.Response? = null
|
var adflyContent: Response? = null
|
||||||
var tries = 0
|
var tries = 0
|
||||||
|
|
||||||
while (responseCode != 200 && tries < 20) {
|
while (responseCode != 200 && tries < 20) {
|
||||||
adflyContent = khttp.get(
|
adflyContent = get(
|
||||||
khttp.get(adflyUri, cookies = cookies, allowRedirects = false).headers.getValue("location"),
|
get(adflyUri, cookies = cookies, allowRedirects = false).url,
|
||||||
cookies = cookies,
|
cookies = cookies,
|
||||||
allowRedirects = false
|
allowRedirects = false
|
||||||
)
|
)
|
||||||
cookies.putAll(adflyContent.cookies.toMap())
|
cookies = cookies + adflyContent.cookies
|
||||||
responseCode = adflyContent.statusCode
|
responseCode = adflyContent.code
|
||||||
++tries
|
++tries
|
||||||
}
|
}
|
||||||
if (tries > 19) {
|
if (tries > 19) {
|
||||||
|
@ -475,33 +476,33 @@ class AnimePaheProvider : MainAPI() {
|
||||||
|
|
||||||
private fun getStreamUrlFromKwik(adflyUri: String): String {
|
private fun getStreamUrlFromKwik(adflyUri: String): String {
|
||||||
val fContent =
|
val fContent =
|
||||||
khttp.get(bypassAdfly(adflyUri), headers = mapOf("referer" to "https://kwik.cx/"), cookies = cookies)
|
get(bypassAdfly(adflyUri), headers = mapOf("referer" to "https://kwik.cx/"), cookies = cookies)
|
||||||
cookies.putAll(fContent.cookies.toMap())
|
cookies = cookies + fContent.cookies
|
||||||
|
|
||||||
val (fullString, key, v1, v2) = KWIK_PARAMS_RE.find(fContent.text)!!.destructured
|
val (fullString, key, v1, v2) = KWIK_PARAMS_RE.find(fContent.text)!!.destructured
|
||||||
val decrypted = decrypt(fullString, key, v1.toInt(), v2.toInt())
|
val decrypted = decrypt(fullString, key, v1.toInt(), v2.toInt())
|
||||||
val uri = KWIK_D_URL.find(decrypted)!!.destructured.component1()
|
val uri = KWIK_D_URL.find(decrypted)!!.destructured.component1()
|
||||||
val tok = KWIK_D_TOKEN.find(decrypted)!!.destructured.component1()
|
val tok = KWIK_D_TOKEN.find(decrypted)!!.destructured.component1()
|
||||||
var content: khttp.responses.Response? = null
|
var content: Response? = null
|
||||||
|
|
||||||
var code = 419
|
var code = 419
|
||||||
var tries = 0
|
var tries = 0
|
||||||
|
|
||||||
while (code != 302 && tries < 20) {
|
while (code != 302 && tries < 20) {
|
||||||
content = khttp.post(
|
content = post(
|
||||||
uri,
|
uri,
|
||||||
allowRedirects = false,
|
allowRedirects = false,
|
||||||
data = mapOf("_token" to tok),
|
data = mapOf("_token" to tok),
|
||||||
headers = mapOf("referer" to fContent.url),
|
headers = mapOf("referer" to fContent.url),
|
||||||
cookies = cookieStrToMap(fContent.headers.getValue("set-cookie").replace("path=/,", ""))
|
cookies = fContent.cookies
|
||||||
)
|
)
|
||||||
code = content.statusCode
|
code = content.code
|
||||||
++tries
|
++tries
|
||||||
}
|
}
|
||||||
if (tries > 19) {
|
if (tries > 19) {
|
||||||
throw Exception("Failed to extract the stream uri from kwik.")
|
throw Exception("Failed to extract the stream uri from kwik.")
|
||||||
}
|
}
|
||||||
return content?.headers?.getValue("location").toString()
|
return content?.headers?.values("location").toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractVideoLinks(episodeLink: String): List<ExtractorLink> {
|
private fun extractVideoLinks(episodeLink: String): List<ExtractorLink> {
|
||||||
|
@ -516,8 +517,8 @@ class AnimePaheProvider : MainAPI() {
|
||||||
link = link.replace(regex, "")
|
link = link.replace(regex, "")
|
||||||
|
|
||||||
|
|
||||||
val req = khttp.get(link, headers = headers)
|
val req = get(link, headers = headers).text
|
||||||
val jsonResponse = req.let { mapper.readValue<AnimePaheAnimeData>(it.text) }
|
val jsonResponse = req.let { mapper.readValue<AnimePaheAnimeData>(it) }
|
||||||
val ep = ((jsonResponse.data.map {
|
val ep = ((jsonResponse.data.map {
|
||||||
if (it.episode == episodeNum) {
|
if (it.episode == episodeNum) {
|
||||||
it
|
it
|
||||||
|
@ -527,8 +528,8 @@ class AnimePaheProvider : MainAPI() {
|
||||||
}).filterNotNull())[0]
|
}).filterNotNull())[0]
|
||||||
link = "$mainUrl/api?m=links&id=${ep.animeId}&session=${ep.session}&p=kwik"
|
link = "$mainUrl/api?m=links&id=${ep.animeId}&session=${ep.session}&p=kwik"
|
||||||
}
|
}
|
||||||
val req = khttp.get(link, headers = headers)
|
val req = get(link, headers = headers).text
|
||||||
val data = mapper.readValue<AnimePaheEpisodeLoadLinks>(req.text)
|
val data = mapper.readValue<AnimePaheEpisodeLoadLinks>(req)
|
||||||
|
|
||||||
val qualities = ArrayList<ExtractorLink>()
|
val qualities = ArrayList<ExtractorLink>()
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.APIHolder.unixTime
|
import com.lagradost.cloudstream3.APIHolder.unixTime
|
||||||
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -61,8 +63,8 @@ class DubbedAnimeProvider : MainAPI() {
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun parseDocumentTrending(url: String): List<SearchResponse> {
|
private fun parseDocumentTrending(url: String): List<SearchResponse> {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
return document.select("li > a").map {
|
return document.select("li > a").map {
|
||||||
val href = fixUrl(it.attr("href"))
|
val href = fixUrl(it.attr("href"))
|
||||||
val title = it.selectFirst("> div > div.cittx").text()
|
val title = it.selectFirst("> div > div.cittx").text()
|
||||||
|
@ -83,8 +85,8 @@ class DubbedAnimeProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseDocument(url: String, trimEpisode: Boolean = false): List<SearchResponse> {
|
private fun parseDocument(url: String, trimEpisode: Boolean = false): List<SearchResponse> {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
return document.select("a.grid__link").map {
|
return document.select("a.grid__link").map {
|
||||||
val href = fixUrl(it.attr("href"))
|
val href = fixUrl(it.attr("href"))
|
||||||
val title = it.selectFirst("> div.gridtitlek").text()
|
val title = it.selectFirst("> div.gridtitlek").text()
|
||||||
|
@ -124,10 +126,8 @@ class DubbedAnimeProvider : MainAPI() {
|
||||||
private fun getAnimeEpisode(slug: String, isMovie: Boolean): EpisodeInfo {
|
private fun getAnimeEpisode(slug: String, isMovie: Boolean): EpisodeInfo {
|
||||||
val url =
|
val url =
|
||||||
mainUrl + (if (isMovie) "/movies/jsonMovie" else "/xz/v3/jsonEpi") + ".php?slug=$slug&_=$unixTime"
|
mainUrl + (if (isMovie) "/movies/jsonMovie" else "/xz/v3/jsonEpi") + ".php?slug=$slug&_=$unixTime"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
println(response.text)
|
val mapped = mapper.readValue<QueryEpisodeResultRoot>(response)
|
||||||
val mapped = mapper.readValue<QueryEpisodeResultRoot>(response.text)
|
|
||||||
|
|
||||||
return mapped.result.anime.first()
|
return mapped.result.anime.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,8 +142,8 @@ class DubbedAnimeProvider : MainAPI() {
|
||||||
|
|
||||||
override fun quickSearch(query: String): List<SearchResponse> {
|
override fun quickSearch(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/xz/searchgrid.php?p=1&limit=12&s=$query&_=$unixTime"
|
val url = "$mainUrl/xz/searchgrid.php?p=1&limit=12&s=$query&_=$unixTime"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val items = document.select("div.grid__item > a")
|
val items = document.select("div.grid__item > a")
|
||||||
if (items.isEmpty()) return ArrayList()
|
if (items.isEmpty()) return ArrayList()
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
@ -177,8 +177,8 @@ class DubbedAnimeProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/search/$query"
|
val url = "$mainUrl/search/$query"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val items = document.select("div.resultinner > a.resulta")
|
val items = document.select("div.resultinner > a.resulta")
|
||||||
if (items.isEmpty()) return ArrayList()
|
if (items.isEmpty()) return ArrayList()
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
@ -229,9 +229,8 @@ class DubbedAnimeProvider : MainAPI() {
|
||||||
}.toList())
|
}.toList())
|
||||||
for (hl in hls) {
|
for (hl in hls) {
|
||||||
try {
|
try {
|
||||||
val sources = khttp.get("$mainUrl/xz/api/playeri.php?url=$hl&_=$unixTime")
|
val sources = get("$mainUrl/xz/api/playeri.php?url=$hl&_=$unixTime").text
|
||||||
val txt = sources.text
|
val find = "src=\"(.*?)\".*?label=\"(.*?)\"".toRegex().find(sources)
|
||||||
val find = "src=\"(.*?)\".*?label=\"(.*?)\"".toRegex().find(txt)
|
|
||||||
if (find != null) {
|
if (find != null) {
|
||||||
val quality = find.groupValues[2]
|
val quality = find.groupValues[2]
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
|
@ -268,8 +267,8 @@ class DubbedAnimeProvider : MainAPI() {
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val title = document.selectFirst("h4").text()
|
val title = document.selectFirst("h4").text()
|
||||||
val descriptHeader = document.selectFirst("div.animeDescript")
|
val descriptHeader = document.selectFirst("div.animeDescript")
|
||||||
val descript = descriptHeader.selectFirst("> p").text()
|
val descript = descriptHeader.selectFirst("> p").text()
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package com.lagradost.cloudstream3.animeproviders
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
import com.lagradost.cloudstream3.network.url
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.extractorApis
|
import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
@ -67,7 +70,7 @@ 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 = khttp.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(
|
||||||
|
@ -93,7 +96,7 @@ class GogoanimeProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): ArrayList<SearchResponse> {
|
override fun search(query: String): ArrayList<SearchResponse> {
|
||||||
val link = "$mainUrl/search.html?keyword=$query"
|
val link = "$mainUrl/search.html?keyword=$query"
|
||||||
val html = khttp.get(link).text
|
val html = get(link).text
|
||||||
val doc = Jsoup.parse(html)
|
val doc = Jsoup.parse(html)
|
||||||
|
|
||||||
val episodes = doc.select(""".last_episodes li""").map {
|
val episodes = doc.select(""".last_episodes li""").map {
|
||||||
|
@ -126,7 +129,7 @@ class GogoanimeProvider : MainAPI() {
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val link = getProperAnimeLink(url)
|
val link = getProperAnimeLink(url)
|
||||||
val episodeloadApi = "https://ajax.gogo-load.com/ajax/load-list-episode"
|
val episodeloadApi = "https://ajax.gogo-load.com/ajax/load-list-episode"
|
||||||
val html = khttp.get(link).text
|
val html = get(link).text
|
||||||
val doc = Jsoup.parse(html)
|
val doc = Jsoup.parse(html)
|
||||||
|
|
||||||
val animeBody = doc.selectFirst(".anime_info_body_bg")
|
val animeBody = doc.selectFirst(".anime_info_body_bg")
|
||||||
|
@ -166,7 +169,7 @@ class GogoanimeProvider : MainAPI() {
|
||||||
|
|
||||||
val animeId = doc.selectFirst("#movie_id").attr("value")
|
val animeId = doc.selectFirst("#movie_id").attr("value")
|
||||||
val params = mapOf("ep_start" to "0", "ep_end" to "2000", "id" to animeId)
|
val params = mapOf("ep_start" to "0", "ep_end" to "2000", "id" to animeId)
|
||||||
val responseHTML = khttp.get(episodeloadApi, params=params).text
|
val responseHTML = get(episodeloadApi, params=params).text
|
||||||
val epiDoc = Jsoup.parse(responseHTML)
|
val epiDoc = Jsoup.parse(responseHTML)
|
||||||
val episodes = epiDoc.select("a").map {
|
val episodes = epiDoc.select("a").map {
|
||||||
AnimeEpisode(
|
AnimeEpisode(
|
||||||
|
@ -195,13 +198,13 @@ class GogoanimeProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractVideos(uri: String): List<ExtractorLink> {
|
private fun extractVideos(uri: String): List<ExtractorLink> {
|
||||||
val html = khttp.get(uri).text
|
val html = get(uri).text
|
||||||
val doc = Jsoup.parse(html)
|
val doc = Jsoup.parse(html)
|
||||||
|
|
||||||
val iframe = "https:" + doc.selectFirst("div.play-video > iframe").attr("src")
|
val iframe = "https:" + doc.selectFirst("div.play-video > iframe").attr("src")
|
||||||
val link = iframe.replace("streaming.php", "download")
|
val link = iframe.replace("streaming.php", "download")
|
||||||
|
|
||||||
val page = khttp.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").map {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.animeproviders
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -23,7 +25,9 @@ class KawaiifuProvider : MainAPI() {
|
||||||
|
|
||||||
override fun getMainPage(): HomePageResponse {
|
override fun getMainPage(): HomePageResponse {
|
||||||
val items = ArrayList<HomePageList>()
|
val items = ArrayList<HomePageList>()
|
||||||
val soup = Jsoup.parse(khttp.get(mainUrl).text)
|
val resp = get(mainUrl).text
|
||||||
|
println("RESP $resp")
|
||||||
|
val soup = Jsoup.parse(resp)
|
||||||
|
|
||||||
items.add(HomePageList("Latest Updates", soup.select(".today-update .item").map {
|
items.add(HomePageList("Latest Updates", soup.select(".today-update .item").map {
|
||||||
val title = it.selectFirst("img").attr("alt")
|
val title = it.selectFirst("img").attr("alt")
|
||||||
|
@ -71,7 +75,7 @@ class KawaiifuProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): ArrayList<SearchResponse> {
|
override fun search(query: String): ArrayList<SearchResponse> {
|
||||||
val link = "$mainUrl/search-movie?keyword=${query}"
|
val link = "$mainUrl/search-movie?keyword=${query}"
|
||||||
val html = khttp.get(link).text
|
val html = get(link).text
|
||||||
val soup = Jsoup.parse(html)
|
val soup = Jsoup.parse(html)
|
||||||
|
|
||||||
return ArrayList(soup.select(".item").map {
|
return ArrayList(soup.select(".item").map {
|
||||||
|
@ -95,7 +99,7 @@ class KawaiifuProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val html = khttp.get(url).text
|
val html = get(url).text
|
||||||
val soup = Jsoup.parse(html)
|
val soup = Jsoup.parse(html)
|
||||||
|
|
||||||
val title = soup.selectFirst(".title").text()
|
val title = soup.selectFirst(".title").text()
|
||||||
|
@ -104,7 +108,7 @@ class KawaiifuProvider : MainAPI() {
|
||||||
.filter { it.select("strong").isEmpty() && it.select("iframe").isEmpty() }.joinToString("\n") { it.text() }
|
.filter { it.select("strong").isEmpty() && it.select("iframe").isEmpty() }.joinToString("\n") { it.text() }
|
||||||
val year = url.split("/").filter { it.contains("-") }[0].split("-")[1].toIntOrNull()
|
val year = url.split("/").filter { it.contains("-") }[0].split("-")[1].toIntOrNull()
|
||||||
val episodes = Jsoup.parse(
|
val episodes = Jsoup.parse(
|
||||||
khttp.get(
|
get(
|
||||||
soup.selectFirst("a[href*=\".html-episode\"]").attr("href")
|
soup.selectFirst("a[href*=\".html-episode\"]").attr("href")
|
||||||
).text
|
).text
|
||||||
).selectFirst(".list-ep").select("li").map {
|
).selectFirst(".list-ep").select("li").map {
|
||||||
|
@ -140,7 +144,7 @@ class KawaiifuProvider : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val htmlSource = khttp.get(data).text
|
val htmlSource = get(data).text
|
||||||
val soupa = Jsoup.parse(htmlSource)
|
val soupa = Jsoup.parse(htmlSource)
|
||||||
|
|
||||||
val episodeNum = if (data.contains("ep=")) data.split("ep=")[1].split("&")[0].toIntOrNull() else null
|
val episodeNum = if (data.contains("ep=")) data.split("ep=")[1].split("&")[0].toIntOrNull() else null
|
||||||
|
@ -159,7 +163,7 @@ class KawaiifuProvider : MainAPI() {
|
||||||
val sources = soupa.select("video > source").map { source -> Pair(source.attr("src"), source.attr("data-quality")) }
|
val sources = soupa.select("video > source").map { source -> Pair(source.attr("src"), source.attr("data-quality")) }
|
||||||
Triple(it.first, sources, it.second.second)
|
Triple(it.first, sources, it.second.second)
|
||||||
} else {
|
} else {
|
||||||
val html = khttp.get(it.second.first).text
|
val html = get(it.second.first).text
|
||||||
val soup = Jsoup.parse(html)
|
val soup = Jsoup.parse(html)
|
||||||
|
|
||||||
val sources = soup.select("video > source").map { source -> Pair(source.attr("src"), source.attr("data-quality")) }
|
val sources = soup.select("video > source").map { source -> Pair(source.attr("src"), source.attr("data-quality")) }
|
||||||
|
|
|
@ -4,9 +4,11 @@ import android.annotation.SuppressLint
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
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.cookies
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import khttp.structures.cookie.CookieJar
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -15,7 +17,7 @@ import java.util.*
|
||||||
class TenshiProvider : MainAPI() {
|
class TenshiProvider : MainAPI() {
|
||||||
companion object {
|
companion object {
|
||||||
var token: String? = null
|
var token: String? = null
|
||||||
var cookie: CookieJar? = null
|
var cookie: Map<String, String> = mapOf()
|
||||||
|
|
||||||
fun getType(t: String): TvType {
|
fun getType(t: String): TvType {
|
||||||
return if (t.contains("OVA") || t.contains("Special")) TvType.ONA
|
return if (t.contains("OVA") || t.contains("Special")) TvType.ONA
|
||||||
|
@ -39,7 +41,7 @@ class TenshiProvider : MainAPI() {
|
||||||
|
|
||||||
private fun loadToken(): Boolean {
|
private fun loadToken(): Boolean {
|
||||||
return try {
|
return try {
|
||||||
val response = khttp.get(mainUrl)
|
val response = get(mainUrl)
|
||||||
cookie = response.cookies
|
cookie = response.cookies
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response.text)
|
||||||
token = document.selectFirst("""meta[name="csrf-token"]""").attr("content")
|
token = document.selectFirst("""meta[name="csrf-token"]""").attr("content")
|
||||||
|
@ -51,7 +53,7 @@ class TenshiProvider : MainAPI() {
|
||||||
|
|
||||||
override fun getMainPage(): HomePageResponse {
|
override fun getMainPage(): HomePageResponse {
|
||||||
val items = ArrayList<HomePageList>()
|
val items = ArrayList<HomePageList>()
|
||||||
val soup = Jsoup.parse(khttp.get(mainUrl).text)
|
val soup = Jsoup.parse(get(mainUrl).text)
|
||||||
for (section in soup.select("#content > section")) {
|
for (section in soup.select("#content > section")) {
|
||||||
try {
|
try {
|
||||||
if (section.attr("id") == "toplist-tabs") {
|
if (section.attr("id") == "toplist-tabs") {
|
||||||
|
@ -95,7 +97,7 @@ class TenshiProvider : MainAPI() {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(items.size <= 0) throw ErrorLoadingException()
|
if (items.size <= 0) throw ErrorLoadingException()
|
||||||
return HomePageResponse(items)
|
return HomePageResponse(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +151,7 @@ class TenshiProvider : MainAPI() {
|
||||||
dateString.replace("th ", " ").replace("st ", " ").replace("nd ", " ").replace("rd ", " ")
|
dateString.replace("th ", " ").replace("st ", " ").replace("nd ", " ").replace("rd ", " ")
|
||||||
) ?: return null
|
) ?: return null
|
||||||
return newFormat.format(data)
|
return newFormat.format(data)
|
||||||
} catch (e : Exception) {
|
} catch (e: Exception) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,15 +209,15 @@ class TenshiProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): ArrayList<SearchResponse> {
|
override fun search(query: String): ArrayList<SearchResponse> {
|
||||||
val url = "$mainUrl/anime"
|
val url = "$mainUrl/anime"
|
||||||
var response = khttp.get(url, params = mapOf("q" to query), cookies = mapOf("loop-view" to "thumb"))
|
var response = get(url, params = mapOf("q" to query), cookies = mapOf("loop-view" to "thumb")).text
|
||||||
var document = Jsoup.parse(response.text)
|
var document = Jsoup.parse(response)
|
||||||
val returnValue = parseSearchPage(document)
|
val returnValue = parseSearchPage(document)
|
||||||
|
|
||||||
while (!document.select("""a.page-link[rel="next"]""").isEmpty()) {
|
while (!document.select("""a.page-link[rel="next"]""").isEmpty()) {
|
||||||
val link = document.select("""a.page-link[rel="next"]""")
|
val link = document.select("""a.page-link[rel="next"]""")
|
||||||
if (link != null && !link.isEmpty()) {
|
if (link != null && !link.isEmpty()) {
|
||||||
response = khttp.get(link[0].attr("href"), cookies = mapOf("loop-view" to "thumb"))
|
response = get(link[0].attr("href"), cookies = mapOf("loop-view" to "thumb")).text
|
||||||
document = Jsoup.parse(response.text)
|
document = Jsoup.parse(response)
|
||||||
returnValue.addAll(parseSearchPage(document))
|
returnValue.addAll(parseSearchPage(document))
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
|
@ -226,8 +228,8 @@ class TenshiProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val response = khttp.get(url, timeout = 120.0, cookies = mapOf("loop-view" to "thumb"))
|
val response = get(url, cookies = mapOf("loop-view" to "thumb")).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val englishTitle = document.selectFirst("span.value > span[title=\"English\"]")?.parent()?.text()?.trim()
|
val englishTitle = document.selectFirst("span.value > span[title=\"English\"]")?.parent()?.text()?.trim()
|
||||||
val japaneseTitle = document.selectFirst("span.value > span[title=\"Japanese\"]")?.parent()?.text()?.trim()
|
val japaneseTitle = document.selectFirst("span.value > span[title=\"Japanese\"]")?.parent()?.text()?.trim()
|
||||||
|
@ -291,8 +293,8 @@ class TenshiProvider : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val response = khttp.get(data)
|
val response = get(data).text
|
||||||
val soup = Jsoup.parse(response.text)
|
val soup = Jsoup.parse(response)
|
||||||
|
|
||||||
data class Quality(
|
data class Quality(
|
||||||
@JsonProperty("src") val src: String,
|
@JsonProperty("src") val src: String,
|
||||||
|
@ -302,9 +304,9 @@ class TenshiProvider : MainAPI() {
|
||||||
val sources = ArrayList<ExtractorLink>()
|
val sources = ArrayList<ExtractorLink>()
|
||||||
for (source in soup.select("""[aria-labelledby="mirror-dropdown"] > li > a.dropdown-item""")) {
|
for (source in soup.select("""[aria-labelledby="mirror-dropdown"] > li > a.dropdown-item""")) {
|
||||||
val release = source.text().replace("/", "").trim()
|
val release = source.text().replace("/", "").trim()
|
||||||
val sourceHTML = khttp.get(
|
val sourceHTML = get(
|
||||||
"https://tenshi.moe/embed?v=${source.attr("href").split("v=")[1].split("&")[0]}",
|
"https://tenshi.moe/embed?v=${source.attr("href").split("v=")[1].split("&")[0]}",
|
||||||
headers=mapOf("Referer" to data)
|
headers = mapOf("Referer" to data)
|
||||||
).text
|
).text
|
||||||
|
|
||||||
val match = Regex("""sources: (\[(?:.|\s)+?type: ['\"]video\/.*?['\"](?:.|\s)+?\])""").find(sourceHTML)
|
val match = Regex("""sources: (\[(?:.|\s)+?type: ['\"]video\/.*?['\"](?:.|\s)+?\])""").find(sourceHTML)
|
||||||
|
|
|
@ -3,6 +3,9 @@ package com.lagradost.cloudstream3.animeproviders
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
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.post
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
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 org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -27,13 +30,14 @@ class WatchCartoonOnlineProvider : MainAPI() {
|
||||||
val url = "https://www.wcostream.com/search"
|
val url = "https://www.wcostream.com/search"
|
||||||
|
|
||||||
var response =
|
var response =
|
||||||
khttp.post(
|
post(
|
||||||
url,
|
url,
|
||||||
headers = mapOf("Referer" to url),
|
headers = mapOf("Referer" to url),
|
||||||
data = mapOf("catara" to query, "konuara" to "series")
|
data = mapOf("catara" to query, "konuara" to "series")
|
||||||
)
|
).text
|
||||||
var document = Jsoup.parse(response.text)
|
var document = Jsoup.parse(response)
|
||||||
var items = document.select("div#blog > div.cerceve").toList()
|
var items = document.select("div#blog > div.cerceve").toList()
|
||||||
|
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
|
@ -68,12 +72,12 @@ class WatchCartoonOnlineProvider : MainAPI() {
|
||||||
|
|
||||||
// "episodes-search", is used for finding movies, anime episodes should be filtered out
|
// "episodes-search", is used for finding movies, anime episodes should be filtered out
|
||||||
response =
|
response =
|
||||||
khttp.post(
|
post(
|
||||||
url,
|
url,
|
||||||
headers = mapOf("Referer" to url),
|
headers = mapOf("Referer" to url),
|
||||||
data = mapOf("catara" to query, "konuara" to "episodes")
|
data = mapOf("catara" to query, "konuara" to "episodes")
|
||||||
)
|
).text
|
||||||
document = Jsoup.parse(response.text)
|
document = Jsoup.parse(response)
|
||||||
items = document.select("#catlist-listview2 > ul > li").filter { it?.text() != null && !it?.text().toString().contains("Episode") }
|
items = document.select("#catlist-listview2 > ul > li").filter { it?.text() != null && !it?.text().toString().contains("Episode") }
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,9 +106,8 @@ class WatchCartoonOnlineProvider : MainAPI() {
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val isMovie = !url.contains("/anime/")
|
val isMovie = !url.contains("/anime/")
|
||||||
|
val response = get(url).text
|
||||||
val response = khttp.get(url)
|
val document = Jsoup.parse(response)
|
||||||
val document = Jsoup.parse(response.text)
|
|
||||||
|
|
||||||
|
|
||||||
return if (!isMovie) {
|
return if (!isMovie) {
|
||||||
|
@ -194,13 +197,12 @@ class WatchCartoonOnlineProvider : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val response = khttp.get(data)
|
val response = get(data).text
|
||||||
/*val embedUrl = fixUrl(
|
/*val embedUrl = fixUrl(
|
||||||
Regex("itemprop=\"embedURL\" content=\"(.*?)\"").find(response.text)?.groupValues?.get(1) ?: return false
|
Regex("itemprop=\"embedURL\" content=\"(.*?)\"").find(response.text)?.groupValues?.get(1) ?: return false
|
||||||
)*/
|
)*/
|
||||||
val text = response.text
|
val start = response.indexOf("itemprop=\"embedURL")
|
||||||
val start = text.indexOf("itemprop=\"embedURL")
|
val foundJS = Regex("<script>(.*?)</script>").find(response, start)?.groupValues?.get(1)
|
||||||
val foundJS = Regex("<script>(.*?)</script>").find(text, start)?.groupValues?.get(1)
|
|
||||||
?.replace("document.write", "var returnValue = ")
|
?.replace("document.write", "var returnValue = ")
|
||||||
|
|
||||||
val rhino = Context.enter()
|
val rhino = Context.enter()
|
||||||
|
@ -223,7 +225,7 @@ class WatchCartoonOnlineProvider : MainAPI() {
|
||||||
val jsEval = scope.get("returnValue", scope) ?: return false
|
val jsEval = scope.get("returnValue", scope) ?: return false
|
||||||
val src = fixUrl(Regex("src=\"(.*?)\"").find(jsEval as String)?.groupValues?.get(1) ?: return false)
|
val src = fixUrl(Regex("src=\"(.*?)\"").find(jsEval as String)?.groupValues?.get(1) ?: return false)
|
||||||
|
|
||||||
val embedResponse = khttp.get(
|
val embedResponse = get(
|
||||||
(src),
|
(src),
|
||||||
headers = mapOf("Referer" to data)
|
headers = mapOf("Referer" to data)
|
||||||
)
|
)
|
||||||
|
@ -231,7 +233,7 @@ class WatchCartoonOnlineProvider : MainAPI() {
|
||||||
val getVidLink = fixUrl(
|
val getVidLink = fixUrl(
|
||||||
Regex("get\\(\"(.*?)\"").find(embedResponse.text)?.groupValues?.get(1) ?: return false
|
Regex("get\\(\"(.*?)\"").find(embedResponse.text)?.groupValues?.get(1) ?: return false
|
||||||
)
|
)
|
||||||
val linkResponse = khttp.get(
|
val linkResponse = get(
|
||||||
getVidLink, headers = mapOf(
|
getVidLink, headers = mapOf(
|
||||||
"sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"",
|
"sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"",
|
||||||
"sec-ch-ua-mobile" to "?0",
|
"sec-ch-ua-mobile" to "?0",
|
||||||
|
|
|
@ -3,6 +3,10 @@ package com.lagradost.cloudstream3.animeproviders
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.extractors.WcoStream
|
import com.lagradost.cloudstream3.extractors.WcoStream
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.post
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
import org.json.JSONObject
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -45,9 +49,9 @@ class WcoProvider : MainAPI() {
|
||||||
val items = ArrayList<HomePageList>()
|
val items = ArrayList<HomePageList>()
|
||||||
for (i in urls) {
|
for (i in urls) {
|
||||||
try {
|
try {
|
||||||
val response = khttp.get(
|
val response = JSONObject(get(
|
||||||
i.first,
|
i.first,
|
||||||
).jsonObject.getString("html") // I won't make a dataclass for this shit
|
).text).getString("html") // I won't make a dataclass for this shit
|
||||||
val document = Jsoup.parse(response)
|
val document = Jsoup.parse(response)
|
||||||
val results = document.select("div.flw-item").map {
|
val results = document.select("div.flw-item").map {
|
||||||
val filmPoster = it.selectFirst("> div.film-poster")
|
val filmPoster = it.selectFirst("> div.film-poster")
|
||||||
|
@ -116,15 +120,16 @@ class WcoProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/search"
|
val url = "$mainUrl/search"
|
||||||
val response = khttp.get(url, params = mapOf("keyword" to query))
|
val response =
|
||||||
|
get(url, params = mapOf("keyword" to query))
|
||||||
var document = Jsoup.parse(response.text)
|
var document = Jsoup.parse(response.text)
|
||||||
val returnValue = parseSearchPage(document)
|
val returnValue = parseSearchPage(document)
|
||||||
|
|
||||||
while (!document.select(".pagination").isEmpty()) {
|
while (!document.select(".pagination").isEmpty()) {
|
||||||
val link = document.select("a.page-link[rel=\"next\"]")
|
val link = document.select("a.page-link[rel=\"next\"]")
|
||||||
if (!link.isEmpty()) {
|
if (!link.isEmpty()) {
|
||||||
val extraResponse = khttp.get(fixUrl(link[0].attr("href")))
|
val extraResponse = get(fixUrl(link[0].attr("href"))).text
|
||||||
document = Jsoup.parse(extraResponse.text)
|
document = Jsoup.parse(extraResponse)
|
||||||
returnValue.addAll(parseSearchPage(document))
|
returnValue.addAll(parseSearchPage(document))
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
|
@ -136,10 +141,10 @@ class WcoProvider : MainAPI() {
|
||||||
override fun quickSearch(query: String): List<SearchResponse> {
|
override fun quickSearch(query: String): List<SearchResponse> {
|
||||||
val returnValue: ArrayList<SearchResponse> = ArrayList()
|
val returnValue: ArrayList<SearchResponse> = ArrayList()
|
||||||
|
|
||||||
val response = khttp.post(
|
val response = JSONObject(post(
|
||||||
"https://wcostream.cc/ajax/search",
|
"https://wcostream.cc/ajax/search",
|
||||||
data = mapOf("keyword" to query)
|
data = mapOf("keyword" to query)
|
||||||
).jsonObject.getString("html") // I won't make a dataclass for this shit
|
).text).getString("html") // I won't make a dataclass for this shit
|
||||||
val document = Jsoup.parse(response)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
document.select("a.nav-item").forEach {
|
document.select("a.nav-item").forEach {
|
||||||
|
@ -177,8 +182,8 @@ class WcoProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val response = khttp.get(url, timeout = 120.0)
|
val response = get(url, timeout = 120).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val japaneseTitle = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(1)")
|
val japaneseTitle = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(1)")
|
||||||
?.text()?.trim()?.replace("Other names:", "")?.trim()
|
?.text()?.trim()?.replace("Other names:", "")?.trim()
|
||||||
|
@ -234,8 +239,8 @@ class WcoProvider : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val response = khttp.get(data)
|
val response = get(data).text
|
||||||
val servers = Jsoup.parse(response.text).select("#servers-list > ul > li").map {
|
val servers = Jsoup.parse(response).select("#servers-list > ul > li").map {
|
||||||
mapOf(
|
mapOf(
|
||||||
"link" to it?.selectFirst("a")?.attr("data-embed"),
|
"link" to it?.selectFirst("a")?.attr("data-embed"),
|
||||||
"title" to it?.selectFirst("span")?.text()?.trim()
|
"title" to it?.selectFirst("span")?.text()?.trim()
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
@ -30,13 +32,13 @@ open class DoodLaExtractor : ExtractorApi() {
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
val id = url.removePrefix("$mainUrl/e/").removePrefix("$mainUrl/d/")
|
val id = url.removePrefix("$mainUrl/e/").removePrefix("$mainUrl/d/")
|
||||||
val trueUrl = getExtractorUrl(id)
|
val trueUrl = getExtractorUrl(id)
|
||||||
val response = khttp.get(trueUrl)
|
val response = get(trueUrl).text
|
||||||
Regex("href=\".*/download/(.*?)\"").find(response.text)?.groupValues?.get(1)?.let { link ->
|
Regex("href=\".*/download/(.*?)\"").find(response)?.groupValues?.get(1)?.let { link ->
|
||||||
if (link.isEmpty()) return null
|
if (link.isEmpty()) return null
|
||||||
sleep(5000) // might need this to not trigger anti bot
|
sleep(5000) // might need this to not trigger anti bot
|
||||||
val downloadLink = "$mainUrl/download/$link"
|
val downloadLink = "$mainUrl/download/$link"
|
||||||
val downloadResponse = khttp.get(downloadLink)
|
val downloadResponse = get(downloadLink).text
|
||||||
Regex("onclick=\"window\\.open\\((['\"])(.*?)(['\"])").find(downloadResponse.text)?.groupValues?.get(2)
|
Regex("onclick=\"window\\.open\\((['\"])(.*?)(['\"])").find(downloadResponse)?.groupValues?.get(2)
|
||||||
?.let { trueLink ->
|
?.let { trueLink ->
|
||||||
return listOf(
|
return listOf(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
|
||||||
class MixDrop : ExtractorApi() {
|
class MixDrop : ExtractorApi() {
|
||||||
|
@ -13,7 +15,7 @@ class MixDrop : ExtractorApi() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
with(khttp.get(url)) {
|
with(get(url)) {
|
||||||
getAndUnpack(this.text)?.let { unpackedText ->
|
getAndUnpack(this.text)?.let { unpackedText ->
|
||||||
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
|
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
|
||||||
return listOf(
|
return listOf(
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
|
||||||
class Mp4Upload : ExtractorApi() {
|
class Mp4Upload : ExtractorApi() {
|
||||||
|
@ -9,7 +11,7 @@ class Mp4Upload : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
with(khttp.get(url)) {
|
with(get(url)) {
|
||||||
getAndUnpack(this.text)?.let { unpackedText ->
|
getAndUnpack(this.text)?.let { unpackedText ->
|
||||||
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
|
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
|
||||||
return listOf(
|
return listOf(
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
import com.lagradost.cloudstream3.network.url
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
@ -28,12 +31,12 @@ class MultiQuality : ExtractorApi() {
|
||||||
|
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
||||||
with(khttp.get(url)) {
|
with(get(url)) {
|
||||||
sourceRegex.findAll(this.text).forEach { sourceMatch ->
|
sourceRegex.findAll(this.text).forEach { sourceMatch ->
|
||||||
val extractedUrl = sourceMatch.groupValues[1]
|
val extractedUrl = sourceMatch.groupValues[1]
|
||||||
// Trusting this isn't mp4, may fuck up stuff
|
// Trusting this isn't mp4, may fuck up stuff
|
||||||
if (extractedUrl.endsWith(".m3u8")) {
|
if (extractedUrl.endsWith(".m3u8")) {
|
||||||
with(khttp.get(extractedUrl)) {
|
with(get(extractedUrl)) {
|
||||||
m3u8Regex.findAll(this.text).forEach { match ->
|
m3u8Regex.findAll(this.text).forEach { match ->
|
||||||
extractedLinksList.add(
|
extractedLinksList.add(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getAndUnpack
|
import com.lagradost.cloudstream3.utils.getAndUnpack
|
||||||
|
@ -21,12 +23,12 @@ class StreamSB : ExtractorApi() {
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
||||||
val newUrl = url.replace("sbplay.org/embed-", "sbplay.org/play/").removeSuffix(".html")
|
val newUrl = url.replace("sbplay.org/embed-", "sbplay.org/play/").removeSuffix(".html")
|
||||||
with(khttp.get(newUrl, timeout = 10.0)) {
|
with(get(newUrl, timeout = 10)) {
|
||||||
getAndUnpack(this.text)?.let {
|
getAndUnpack(this.text)?.let {
|
||||||
sourceRegex.findAll(it).forEach { sourceMatch ->
|
sourceRegex.findAll(it).forEach { sourceMatch ->
|
||||||
val extractedUrl = sourceMatch.groupValues[1]
|
val extractedUrl = sourceMatch.groupValues[1]
|
||||||
if (extractedUrl.contains(".m3u8")) {
|
if (extractedUrl.contains(".m3u8")) {
|
||||||
with(khttp.get(extractedUrl)) {
|
with(get(extractedUrl)) {
|
||||||
m3u8UrlRegex.findAll(this.text).forEach { match ->
|
m3u8UrlRegex.findAll(this.text).forEach { match ->
|
||||||
val extractedUrlM3u8 = match.groupValues[2]
|
val extractedUrlM3u8 = match.groupValues[2]
|
||||||
val extractedRes = match.groupValues[1]
|
val extractedRes = match.groupValues[1]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
@ -14,7 +16,7 @@ class StreamTape : ExtractorApi() {
|
||||||
Regex("""(i(|" \+ ')d(|" \+ ')=.*?&(|" \+ ')e(|" \+ ')x(|" \+ ')p(|" \+ ')i(|" \+ ')r(|" \+ ')e(|" \+ ')s(|" \+ ')=.*?&(|" \+ ')i(|" \+ ')p(|" \+ ')=.*?&(|" \+ ')t(|" \+ ')o(|" \+ ')k(|" \+ ')e(|" \+ ')n(|" \+ ')=.*)'""")
|
Regex("""(i(|" \+ ')d(|" \+ ')=.*?&(|" \+ ')e(|" \+ ')x(|" \+ ')p(|" \+ ')i(|" \+ ')r(|" \+ ')e(|" \+ ')s(|" \+ ')=.*?&(|" \+ ')i(|" \+ ')p(|" \+ ')=.*?&(|" \+ ')t(|" \+ ')o(|" \+ ')k(|" \+ ')e(|" \+ ')n(|" \+ ')=.*)'""")
|
||||||
|
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
with(khttp.get(url)) {
|
with(get(url)) {
|
||||||
linkRegex.find(this.text)?.let {
|
linkRegex.find(this.text)?.let {
|
||||||
val extractedUrl = "https://streamtape.com/get_video?${it.groupValues[1]}".replace("""" + '""", "")
|
val extractedUrl = "https://streamtape.com/get_video?${it.groupValues[1]}".replace("""" + '""", "")
|
||||||
return listOf(
|
return listOf(
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.JsUnpacker
|
import com.lagradost.cloudstream3.utils.JsUnpacker
|
||||||
|
@ -18,8 +20,8 @@ class Streamhub : ExtractorApi() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
Regex("eval((.|\\n)*?)</script>").find(response.text)?.groupValues?.get(1)?.let { jsEval ->
|
Regex("eval((.|\\n)*?)</script>").find(response)?.groupValues?.get(1)?.let { jsEval ->
|
||||||
JsUnpacker("eval$jsEval" ).unpack()?.let { unPacked ->
|
JsUnpacker("eval$jsEval" ).unpack()?.let { unPacked ->
|
||||||
Regex("sources:\\[\\{src:\"(.*?)\"").find(unPacked)?.groupValues?.get(1)?.let { link ->
|
Regex("sources:\\[\\{src:\"(.*?)\"").find(unPacked)?.groupValues?.get(1)?.let { link ->
|
||||||
return listOf(
|
return listOf(
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
import com.lagradost.cloudstream3.network.url
|
||||||
import com.lagradost.cloudstream3.pmap
|
import com.lagradost.cloudstream3.pmap
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.extractorApis
|
import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
|
@ -38,7 +41,7 @@ class Vidstream(overrideMainUrl: String? = null) {
|
||||||
/** Stolen from GogoanimeProvider.kt extractor */
|
/** Stolen from GogoanimeProvider.kt extractor */
|
||||||
normalSafeApiCall {
|
normalSafeApiCall {
|
||||||
val link = getDownloadUrl(id)
|
val link = getDownloadUrl(id)
|
||||||
val page = khttp.get(link, headers = mapOf("Referer" to extractorUrl))
|
val page = get(link, headers = mapOf("Referer" to extractorUrl))
|
||||||
val pageDoc = Jsoup.parse(page.text)
|
val pageDoc = Jsoup.parse(page.text)
|
||||||
val qualityRegex = Regex("(\\d+)P")
|
val qualityRegex = Regex("(\\d+)P")
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ class Vidstream(overrideMainUrl: String? = null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
with(khttp.get(extractorUrl)) {
|
with(get(extractorUrl)) {
|
||||||
val document = Jsoup.parse(this.text)
|
val document = Jsoup.parse(this.text)
|
||||||
val primaryLinks = document.select("ul.list-server-items > li.linkserver")
|
val primaryLinks = document.select("ul.list-server-items > li.linkserver")
|
||||||
//val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
//val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
||||||
|
|
|
@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.mapper
|
import com.lagradost.cloudstream3.mapper
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
|
||||||
class WcoStream : ExtractorApi() {
|
class WcoStream : ExtractorApi() {
|
||||||
override val name: String = "WcoStream"
|
override val name: String = "WcoStream"
|
||||||
|
@ -14,14 +16,14 @@ class WcoStream : ExtractorApi() {
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
val baseUrl = url.split("/e/")[0]
|
val baseUrl = url.split("/e/")[0]
|
||||||
|
|
||||||
val html = khttp.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text
|
val html = get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text
|
||||||
val (Id) = "/e/(.*?)?domain".toRegex().find(url)!!.destructured
|
val (Id) = "/e/(.*?)?domain".toRegex().find(url)!!.destructured
|
||||||
val (skey) = """skey\s=\s['"](.*?)['"];""".toRegex().find(html)!!.destructured
|
val (skey) = """skey\s=\s['"](.*?)['"];""".toRegex().find(html)!!.destructured
|
||||||
|
|
||||||
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
|
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
|
||||||
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
|
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
|
||||||
|
|
||||||
val response = khttp.get(apiLink, headers = mapOf("Referer" to referrer)).text
|
val response = get(apiLink, headers = mapOf("Referer" to referrer)).text
|
||||||
|
|
||||||
data class Sources(
|
data class Sources(
|
||||||
@JsonProperty("file") val file: String,
|
@JsonProperty("file") val file: String,
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.extractors
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.mapper
|
import com.lagradost.cloudstream3.mapper
|
||||||
|
import com.lagradost.cloudstream3.network.post
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
@ -44,9 +46,10 @@ class XStreamCdn : ExtractorApi() {
|
||||||
)
|
)
|
||||||
val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/")
|
val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/")
|
||||||
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
||||||
with(khttp.post(newUrl, headers = headers)) {
|
with(post(newUrl, headers = headers)) {
|
||||||
if (this.text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf()
|
val text = this.text
|
||||||
mapper.readValue<ResponseJson?>(this.text)?.let {
|
if (text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf()
|
||||||
|
mapper.readValue<ResponseJson?>(text)?.let {
|
||||||
if (it.success && it.data != null) {
|
if (it.success && it.data != null) {
|
||||||
it.data.forEach { data ->
|
it.data.forEach { data ->
|
||||||
extractedLinksList.add(
|
extractedLinksList.add(
|
||||||
|
|
|
@ -2,9 +2,14 @@ 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.post
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
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.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
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.lang.Thread.sleep
|
||||||
|
@ -33,8 +38,8 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/?s=$query"
|
val url = "$mainUrl/?s=$query"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val items = document.select("ul.MovieList > li > article > a")
|
val items = document.select("ul.MovieList > li > article > a")
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
@ -72,8 +77,8 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val type = getType(url)
|
val type = getType(url)
|
||||||
|
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val title = document.selectFirst("h1.Title").text()
|
val title = document.selectFirst("h1.Title").text()
|
||||||
val descipt = document.selectFirst("div.Description > p").text()
|
val descipt = document.selectFirst("div.Description > p").text()
|
||||||
|
@ -98,8 +103,8 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
val episodeList = ArrayList<TvSeriesEpisode>()
|
val episodeList = ArrayList<TvSeriesEpisode>()
|
||||||
|
|
||||||
for (season in list) {
|
for (season in list) {
|
||||||
val seasonResponse = khttp.get(season.second)
|
val seasonResponse = get(season.second).text
|
||||||
val seasonDocument = Jsoup.parse(seasonResponse.text)
|
val seasonDocument = Jsoup.parse(seasonResponse)
|
||||||
val episodes = seasonDocument.select("table > tbody > tr")
|
val episodes = seasonDocument.select("table > tbody > tr")
|
||||||
if (episodes.isNotEmpty()) {
|
if (episodes.isNotEmpty()) {
|
||||||
episodes.forEach { episode ->
|
episodes.forEach { episode ->
|
||||||
|
@ -162,8 +167,8 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (data.startsWith("$mainUrl/episode/")) {
|
if (data.startsWith("$mainUrl/episode/")) {
|
||||||
val response = khttp.get(data)
|
val response = get(data).text
|
||||||
getLink(Jsoup.parse(response.text))?.let { links ->
|
getLink(Jsoup.parse(response))?.let { links ->
|
||||||
for (link in links) {
|
for (link in links) {
|
||||||
if (link == data) continue
|
if (link == data) continue
|
||||||
loadLinks(link, isCasting, subtitleCallback, callback)
|
loadLinks(link, isCasting, subtitleCallback, callback)
|
||||||
|
@ -174,9 +179,21 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
} else if (data.startsWith(mainUrl) && data != mainUrl) {
|
} else if (data.startsWith(mainUrl) && data != mainUrl) {
|
||||||
val realDataUrl = URLDecoder.decode(data, "application/x-www-form-urlencoded")
|
val realDataUrl = URLDecoder.decode(data, "application/x-www-form-urlencoded")
|
||||||
if (data.contains("trdownload")) {
|
if (data.contains("trdownload")) {
|
||||||
val request = khttp.get(data, stream = true)
|
val request = get(data)
|
||||||
if (request.url.startsWith("https://streamhub.to/d/")) {
|
if (request.url.startsWith("https://streamhub.to/d/")) {
|
||||||
val document = Jsoup.parse(request.text)
|
val buffer = Buffer()
|
||||||
|
val source = request.body?.source()
|
||||||
|
var html = ""
|
||||||
|
var tries = 0 // 20 tries = 163840 bytes = 0.16mb
|
||||||
|
|
||||||
|
while (source?.exhausted() == false && tries < 20) {
|
||||||
|
// 8192 = max size
|
||||||
|
source.read(buffer, 8192)
|
||||||
|
tries += 1
|
||||||
|
html += buffer.readUtf8()
|
||||||
|
}
|
||||||
|
|
||||||
|
val document = Jsoup.parse(html)
|
||||||
val inputs = document.select("Form > input")
|
val inputs = document.select("Form > input")
|
||||||
if (inputs.size < 4) return false
|
if (inputs.size < 4) return false
|
||||||
var op: String? = null
|
var op: String? = null
|
||||||
|
@ -195,24 +212,33 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(op == null || id == null || mode == null || hash == null) {
|
if (op == null || id == null || mode == null || hash == null) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
sleep(5000) // ye this is needed, wont work with 0 delay
|
sleep(5000) // ye this is needed, wont work with 0 delay
|
||||||
|
|
||||||
val postResponse = khttp.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))
|
val postResponse = post(
|
||||||
val postDocument = Jsoup.parse(postResponse.text)
|
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")
|
val url = postDocument.selectFirst("a.downloadbtn").attr("href")
|
||||||
if(url.isNullOrEmpty()) return false
|
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))
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val response = khttp.get(realDataUrl)
|
val response = get(realDataUrl).text
|
||||||
Regex("<iframe.*?src=\"(.*?)\"").find(response.text)?.groupValues?.get(1)?.let { url ->
|
Regex("<iframe.*?src=\"(.*?)\"").find(response)?.groupValues?.get(1)?.let { url ->
|
||||||
loadExtractor(url.trimStart(), realDataUrl, callback)
|
loadExtractor(url.trimStart(), realDataUrl, callback)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -5,10 +5,11 @@ import com.fasterxml.jackson.core.JsonParser
|
||||||
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.animeproviders.GogoanimeProvider.Companion.getStatus
|
import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.getStatus
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
|
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import khttp.get
|
|
||||||
|
|
||||||
class AsiaFlixProvider : MainAPI() {
|
class AsiaFlixProvider : MainAPI() {
|
||||||
override val mainUrl: String
|
override val mainUrl: String
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.movieproviders
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
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 org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -18,8 +20,8 @@ class HDMProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/search/$query"
|
val url = "$mainUrl/search/$query"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val items = document.select("div.col-md-2 > article > a")
|
val items = document.select("div.col-md-2 > article > a")
|
||||||
if (items.isEmpty()) return ArrayList()
|
if (items.isEmpty()) return ArrayList()
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
@ -42,8 +44,8 @@ class HDMProvider : MainAPI() {
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (data == "") return false
|
if (data == "") return false
|
||||||
val slug = ".*/(.*?)\\.mp4".toRegex().find(data)?.groupValues?.get(1) ?: return false
|
val slug = ".*/(.*?)\\.mp4".toRegex().find(data)?.groupValues?.get(1) ?: return false
|
||||||
val response = khttp.get(data)
|
val response = get(data).text
|
||||||
val key = "playlist\\.m3u8(.*?)\"".toRegex().find(response.text)?.groupValues?.get(1) ?: return false
|
val key = "playlist\\.m3u8(.*?)\"".toRegex().find(response)?.groupValues?.get(1) ?: return false
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
this.name,
|
this.name,
|
||||||
|
@ -58,14 +60,14 @@ class HDMProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse? {
|
override fun load(url: String): LoadResponse? {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val title = document.selectFirst("h2.movieTitle")?.text() ?: throw ErrorLoadingException("No Data Found")
|
val title = document.selectFirst("h2.movieTitle")?.text() ?: throw ErrorLoadingException("No Data Found")
|
||||||
val poster = document.selectFirst("div.post-thumbnail > img").attr("src")
|
val poster = document.selectFirst("div.post-thumbnail > img").attr("src")
|
||||||
val descript = document.selectFirst("div.synopsis > p").text()
|
val descript = document.selectFirst("div.synopsis > p").text()
|
||||||
val year = document.select("div.movieInfoAll > div.row > div.col-md-6")?.get(1)?.selectFirst("> p > a")?.text()
|
val year = document.select("div.movieInfoAll > div.row > div.col-md-6")?.get(1)?.selectFirst("> p > a")?.text()
|
||||||
?.toIntOrNull()
|
?.toIntOrNull()
|
||||||
val data = "src/player/\\?v=(.*?)\"".toRegex().find(response.text)?.groupValues?.get(1) ?: return null
|
val data = "src/player/\\?v=(.*?)\"".toRegex().find(response)?.groupValues?.get(1) ?: return null
|
||||||
|
|
||||||
return MovieLoadResponse(
|
return MovieLoadResponse(
|
||||||
title, url, this.name, TvType.Movie,
|
title, url, this.name, TvType.Movie,
|
||||||
|
|
|
@ -6,6 +6,8 @@ import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.APIHolder.unixTime
|
import com.lagradost.cloudstream3.APIHolder.unixTime
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.extractors.M3u8Manifest
|
import com.lagradost.cloudstream3.extractors.M3u8Manifest
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
|
@ -71,12 +73,12 @@ class LookMovieProvider : MainAPI() {
|
||||||
|
|
||||||
override fun quickSearch(query: String): List<SearchResponse> {
|
override fun quickSearch(query: String): List<SearchResponse> {
|
||||||
val movieUrl = "$mainUrl/api/v1/movies/search/?q=$query"
|
val movieUrl = "$mainUrl/api/v1/movies/search/?q=$query"
|
||||||
val movieResponse = khttp.get(movieUrl)
|
val movieResponse = get(movieUrl).text
|
||||||
val movies = mapper.readValue<LookMovieSearchResultRoot>(movieResponse.text).result
|
val movies = mapper.readValue<LookMovieSearchResultRoot>(movieResponse).result
|
||||||
|
|
||||||
val showsUrl = "$mainUrl/api/v1/shows/search/?q=$query"
|
val showsUrl = "$mainUrl/api/v1/shows/search/?q=$query"
|
||||||
val showsResponse = khttp.get(showsUrl)
|
val showsResponse = get(showsUrl).text
|
||||||
val shows = mapper.readValue<LookMovieSearchResultRoot>(showsResponse.text).result
|
val shows = mapper.readValue<LookMovieSearchResultRoot>(showsResponse).result
|
||||||
|
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
if (!movies.isNullOrEmpty()) {
|
if (!movies.isNullOrEmpty()) {
|
||||||
|
@ -117,8 +119,8 @@ class LookMovieProvider : MainAPI() {
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
fun search(query: String, isMovie: Boolean): ArrayList<SearchResponse> {
|
fun search(query: String, isMovie: Boolean): ArrayList<SearchResponse> {
|
||||||
val url = "$mainUrl/${if (isMovie) "movies" else "shows"}/search/?q=$query"
|
val url = "$mainUrl/${if (isMovie) "movies" else "shows"}/search/?q=$query"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val items = document.select("div.flex-wrap-movielist > div.movie-item-style-1")
|
val items = document.select("div.flex-wrap-movielist > div.movie-item-style-1")
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
@ -161,8 +163,8 @@ class LookMovieProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadCurrentLinks(url: String, callback: (ExtractorLink) -> Unit) {
|
private fun loadCurrentLinks(url: String, callback: (ExtractorLink) -> Unit) {
|
||||||
val response = khttp.get(url.replace("\$unixtime", unixTime.toString()))
|
val response = get(url.replace("\$unixtime", unixTime.toString())).text
|
||||||
M3u8Manifest.extractLinks(response.text).forEach {
|
M3u8Manifest.extractLinks(response).forEach {
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
this.name,
|
this.name,
|
||||||
|
@ -185,24 +187,24 @@ class LookMovieProvider : MainAPI() {
|
||||||
val localData: LookMovieLinkLoad = mapper.readValue(data)
|
val localData: LookMovieLinkLoad = mapper.readValue(data)
|
||||||
|
|
||||||
if (localData.isMovie) {
|
if (localData.isMovie) {
|
||||||
val tokenResponse = khttp.get(localData.url)
|
val tokenResponse = get(localData.url).text
|
||||||
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse.text)
|
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse)
|
||||||
val accessToken = root.data?.accessToken ?: return false
|
val accessToken = root.data?.accessToken ?: return false
|
||||||
addSubtitles(root.data.subtitles, subtitleCallback)
|
addSubtitles(root.data.subtitles, subtitleCallback)
|
||||||
loadCurrentLinks(localData.extraUrl.replace("\$accessToken", accessToken), callback)
|
loadCurrentLinks(localData.extraUrl.replace("\$accessToken", accessToken), callback)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
loadCurrentLinks(localData.url, callback)
|
loadCurrentLinks(localData.url, callback)
|
||||||
val subResponse = khttp.get(localData.extraUrl)
|
val subResponse = get(localData.extraUrl).text
|
||||||
val subs = mapper.readValue<List<LookMovieTokenSubtitle>>(subResponse.text)
|
val subs = mapper.readValue<List<LookMovieTokenSubtitle>>(subResponse)
|
||||||
addSubtitles(subs, subtitleCallback)
|
addSubtitles(subs, subtitleCallback)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse? {
|
override fun load(url: String): LoadResponse? {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val isMovie = url.contains("/movies/")
|
val isMovie = url.contains("/movies/")
|
||||||
|
|
||||||
val watchHeader = document.selectFirst("div.watch-heading")
|
val watchHeader = document.selectFirst("div.watch-heading")
|
||||||
|
@ -215,7 +217,7 @@ class LookMovieProvider : MainAPI() {
|
||||||
var poster = if (img.isNullOrEmpty()) null else "url\\((.*?)\\)".toRegex().find(img)?.groupValues?.get(1)
|
var poster = if (img.isNullOrEmpty()) null else "url\\((.*?)\\)".toRegex().find(img)?.groupValues?.get(1)
|
||||||
if (poster.isNullOrEmpty()) poster = imgElement?.attr("data-background-image")
|
if (poster.isNullOrEmpty()) poster = imgElement?.attr("data-background-image")
|
||||||
val descript = document.selectFirst("p.description-short").text()
|
val descript = document.selectFirst("p.description-short").text()
|
||||||
val id = "${if (isMovie) "id_movie" else "id_show"}:(.*?),".toRegex().find(response.text)?.groupValues?.get(1)
|
val id = "${if (isMovie) "id_movie" else "id_show"}:(.*?),".toRegex().find(response)?.groupValues?.get(1)
|
||||||
?.replace(" ", "")
|
?.replace(" ", "")
|
||||||
?: return null
|
?: return null
|
||||||
val realSlug = url.replace("$mainUrl/${if (isMovie) "movies" else "shows"}/view/", "")
|
val realSlug = url.replace("$mainUrl/${if (isMovie) "movies" else "shows"}/view/", "")
|
||||||
|
@ -243,12 +245,12 @@ class LookMovieProvider : MainAPI() {
|
||||||
rating
|
rating
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val tokenResponse = khttp.get(realUrl)
|
val tokenResponse = get(realUrl).text
|
||||||
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse.text)
|
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse)
|
||||||
val accessToken = root.data?.accessToken ?: return null
|
val accessToken = root.data?.accessToken ?: return null
|
||||||
|
|
||||||
val window =
|
val window =
|
||||||
"window\\['show_storage'] =((.|\\n)*?<)".toRegex().find(response.text)?.groupValues?.get(1)
|
"window\\['show_storage'] =((.|\\n)*?<)".toRegex().find(response)?.groupValues?.get(1)
|
||||||
?: return null
|
?: return null
|
||||||
// val id = "id_show:(.*?),".toRegex().find(response.text)?.groupValues?.get(1) ?: return null
|
// val id = "id_show:(.*?),".toRegex().find(response.text)?.groupValues?.get(1) ?: return null
|
||||||
val season = "seasons:.*\\[((.|\\n)*?)]".toRegex().find(window)?.groupValues?.get(1) ?: return null
|
val season = "seasons:.*\\[((.|\\n)*?)]".toRegex().find(window)?.groupValues?.get(1) ?: return null
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.movieproviders
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
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.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -38,8 +40,8 @@ class MeloMovieProvider : MainAPI() {
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/movie/search/?name=$query"
|
val url = "$mainUrl/movie/search/?name=$query"
|
||||||
val returnValue: ArrayList<SearchResponse> = ArrayList()
|
val returnValue: ArrayList<SearchResponse> = ArrayList()
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val mapped = response.let { mapper.readValue<List<MeloMovieSearchResult>>(it.text) }
|
val mapped = response.let { mapper.readValue<List<MeloMovieSearchResult>>(it) }
|
||||||
if (mapped.isEmpty()) return returnValue
|
if (mapped.isEmpty()) return returnValue
|
||||||
|
|
||||||
for (i in mapped) {
|
for (i in mapped) {
|
||||||
|
@ -115,7 +117,7 @@ class MeloMovieProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse? {
|
override fun load(url: String): LoadResponse? {
|
||||||
val response = khttp.get(url).text
|
val response = get(url).text
|
||||||
|
|
||||||
//backdrop = imgurl
|
//backdrop = imgurl
|
||||||
fun findUsingRegex(src: String): String? {
|
fun findUsingRegex(src: String): String? {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.movieproviders
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
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.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
@ -41,8 +43,8 @@ class ThenosProvider : MainAPI() {
|
||||||
val list = ArrayList<HomePageList>()
|
val list = ArrayList<HomePageList>()
|
||||||
map.entries.forEach {
|
map.entries.forEach {
|
||||||
val url = "$apiUrl/library/${it.value}"
|
val url = "$apiUrl/library/${it.value}"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val mapped = mapper.readValue<ThenosLoadResponse>(response.text)
|
val mapped = mapper.readValue<ThenosLoadResponse>(response)
|
||||||
|
|
||||||
mapped.Metadata?.mapNotNull { meta ->
|
mapped.Metadata?.mapNotNull { meta ->
|
||||||
meta?.toSearchResponse()
|
meta?.toSearchResponse()
|
||||||
|
@ -209,8 +211,8 @@ class ThenosProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchFromUrl(url: String): List<SearchResponse> {
|
private fun searchFromUrl(url: String): List<SearchResponse> {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val test = mapper.readValue<ThenosSearchResponse>(response.text)
|
val test = mapper.readValue<ThenosSearchResponse>(response)
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
|
||||||
test.Hub?.forEach {
|
test.Hub?.forEach {
|
||||||
|
@ -255,12 +257,12 @@ class ThenosProvider : MainAPI() {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val url = "$apiUrl/library/watch/$data"
|
val url = "$apiUrl/library/watch/$data"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val mapped = mapper.readValue<ThenosSource>(response.text)
|
val mapped = mapper.readValue<ThenosSource>(response)
|
||||||
|
|
||||||
mapped.sources?.forEach { source ->
|
mapped.sources?.forEach { source ->
|
||||||
val isM3u8 = source.type != "video/mp4"
|
val isM3u8 = source.type != "video/mp4"
|
||||||
val token = khttp.get("https://token.noss.workers.dev/").text
|
val token = get("https://token.noss.workers.dev/").text
|
||||||
val authorization =
|
val authorization =
|
||||||
String(android.util.Base64.decode(token, android.util.Base64.DEFAULT), Charsets.ISO_8859_1)
|
String(android.util.Base64.decode(token, android.util.Base64.DEFAULT), Charsets.ISO_8859_1)
|
||||||
|
|
||||||
|
@ -423,12 +425,12 @@ class ThenosProvider : MainAPI() {
|
||||||
private fun getAllEpisodes(id: String): List<TvSeriesEpisode> {
|
private fun getAllEpisodes(id: String): List<TvSeriesEpisode> {
|
||||||
val episodes = ArrayList<TvSeriesEpisode>()
|
val episodes = ArrayList<TvSeriesEpisode>()
|
||||||
val url = "$apiUrl/library/metadata/$id/children"
|
val url = "$apiUrl/library/metadata/$id/children"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val mapped = mapper.readValue<ThenosSeriesResponse>(response.text)
|
val mapped = mapper.readValue<ThenosSeriesResponse>(response)
|
||||||
mapped.Metadata?.forEach { series_meta ->
|
mapped.Metadata?.forEach { series_meta ->
|
||||||
val fixedUrl = apiUrl + series_meta.key
|
val fixedUrl = apiUrl + series_meta.key
|
||||||
val child = khttp.get(fixedUrl)
|
val child = get(fixedUrl).text
|
||||||
val mappedSeason = mapper.readValue<SeasonResponse>(child.text)
|
val mappedSeason = mapper.readValue<SeasonResponse>(child)
|
||||||
mappedSeason.Metadata?.forEach mappedSeason@{ meta ->
|
mappedSeason.Metadata?.forEach mappedSeason@{ meta ->
|
||||||
episodes.add(
|
episodes.add(
|
||||||
TvSeriesEpisode(
|
TvSeriesEpisode(
|
||||||
|
@ -450,8 +452,8 @@ class ThenosProvider : MainAPI() {
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse? {
|
override fun load(url: String): LoadResponse? {
|
||||||
val fixedUrl = "$apiUrl/library/metadata/${url.split("/").last()}"
|
val fixedUrl = "$apiUrl/library/metadata/${url.split("/").last()}"
|
||||||
val response = khttp.get(fixedUrl)
|
val response = get(fixedUrl).text
|
||||||
val mapped = mapper.readValue<ThenosLoadResponse>(response.text)
|
val mapped = mapper.readValue<ThenosLoadResponse>(response)
|
||||||
|
|
||||||
val isShow = mapped.Metadata?.any { it?.type == "show" } == true
|
val isShow = mapped.Metadata?.any { it?.type == "show" } == true
|
||||||
val metadata = mapped.Metadata?.getOrNull(0) ?: return null
|
val metadata = mapped.Metadata?.getOrNull(0) ?: return null
|
||||||
|
|
|
@ -2,6 +2,8 @@ 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.text
|
||||||
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.SubtitleHelper
|
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
||||||
|
@ -33,8 +35,8 @@ class TrailersToProvider : MainAPI() {
|
||||||
get() = VPNStatus.MightBeNeeded
|
get() = VPNStatus.MightBeNeeded
|
||||||
|
|
||||||
override fun getMainPage(): HomePageResponse? {
|
override fun getMainPage(): HomePageResponse? {
|
||||||
val response = khttp.get(mainUrl)
|
val response = get(mainUrl).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val returnList = ArrayList<HomePageList>()
|
val returnList = ArrayList<HomePageList>()
|
||||||
val docs = document.select("section.section > div.container")
|
val docs = document.select("section.section > div.container")
|
||||||
for (doc in docs) {
|
for (doc in docs) {
|
||||||
|
@ -76,8 +78,8 @@ class TrailersToProvider : MainAPI() {
|
||||||
|
|
||||||
override fun quickSearch(query: String): List<SearchResponse> {
|
override fun quickSearch(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/en/quick-search?q=$query"
|
val url = "$mainUrl/en/quick-search?q=$query"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val items = document.select("div.group-post-minimal > a.post-minimal")
|
val items = document.select("div.group-post-minimal > a.post-minimal")
|
||||||
if (items.isNullOrEmpty()) return ArrayList()
|
if (items.isNullOrEmpty()) return ArrayList()
|
||||||
|
|
||||||
|
@ -104,8 +106,8 @@ class TrailersToProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/en/popular/movies-tvshows-collections?q=$query"
|
val url = "$mainUrl/en/popular/movies-tvshows-collections?q=$query"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val items = document.select("div.col-lg-8 > article.list-item")
|
val items = document.select("div.col-lg-8 > article.list-item")
|
||||||
if (items.isNullOrEmpty()) return ArrayList()
|
if (items.isNullOrEmpty()) return ArrayList()
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
@ -133,8 +135,8 @@ class TrailersToProvider : MainAPI() {
|
||||||
data: String,
|
data: String,
|
||||||
callback: (ExtractorLink) -> Unit,
|
callback: (ExtractorLink) -> Unit,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val response = khttp.get(data)
|
val response = get(data).text
|
||||||
val url = "<source src='(.*?)'".toRegex().find(response.text)?.groupValues?.get(1)
|
val url = "<source src='(.*?)'".toRegex().find(response)?.groupValues?.get(1)
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
callback.invoke(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value, false))
|
callback.invoke(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value, false))
|
||||||
}
|
}
|
||||||
|
@ -144,8 +146,8 @@ class TrailersToProvider : MainAPI() {
|
||||||
private fun loadSubs(url: String, subtitleCallback: (SubtitleFile) -> Unit) {
|
private fun loadSubs(url: String, subtitleCallback: (SubtitleFile) -> Unit) {
|
||||||
if (url.isEmpty()) return
|
if (url.isEmpty()) return
|
||||||
|
|
||||||
val response = khttp.get(fixUrl(url))
|
val response = get(fixUrl(url)).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val items = document.select("div.list-group > a.list-group-item")
|
val items = document.select("div.list-group > a.list-group-item")
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
|
@ -181,8 +183,8 @@ class TrailersToProvider : MainAPI() {
|
||||||
|
|
||||||
return isSucc
|
return isSucc
|
||||||
} else if (url.contains("/episode/")) {
|
} else if (url.contains("/episode/")) {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
// val qSub = document.select("subtitle-content")
|
// val qSub = document.select("subtitle-content")
|
||||||
val subUrl = document.select("subtitle-content")?.attr("data-url") ?: ""
|
val subUrl = document.select("subtitle-content")?.attr("data-url") ?: ""
|
||||||
|
|
||||||
|
@ -198,8 +200,8 @@ class TrailersToProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
var title = document?.selectFirst("h2.breadcrumbs-custom-title > a")?.text() ?: throw ErrorLoadingException("Service might be unavailable")
|
var title = document?.selectFirst("h2.breadcrumbs-custom-title > a")?.text() ?: throw ErrorLoadingException("Service might be unavailable")
|
||||||
|
|
||||||
val metaInfo = document.select("div.post-info-meta > ul.post-info-meta-list > li")
|
val metaInfo = document.select("div.post-info-meta > ul.post-info-meta-list > li")
|
||||||
|
|
|
@ -3,6 +3,10 @@ package com.lagradost.cloudstream3.movieproviders
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
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.post
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
import com.lagradost.cloudstream3.network.url
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -21,8 +25,8 @@ class VMoveeProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/?s=$query"
|
val url = "$mainUrl/?s=$query"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val searchItems = document.select("div.search-page > div.result-item > article")
|
val searchItems = document.select("div.search-page > div.result-item > article")
|
||||||
if (searchItems.size == 0) return ArrayList()
|
if (searchItems.size == 0) return ArrayList()
|
||||||
val returnValue = ArrayList<SearchResponse>()
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
@ -75,24 +79,24 @@ class VMoveeProvider : MainAPI() {
|
||||||
|
|
||||||
val url = "$mainUrl/dashboard/admin-ajax.php"
|
val url = "$mainUrl/dashboard/admin-ajax.php"
|
||||||
val post =
|
val post =
|
||||||
khttp.post(
|
post(
|
||||||
url,
|
url,
|
||||||
headers = mapOf("referer" to url),
|
headers = mapOf("referer" to url),
|
||||||
data = mapOf("action" to "doo_player_ajax", "post" to data, "nume" to "2", "type" to "movie")
|
data = mapOf("action" to "doo_player_ajax", "post" to data, "nume" to "2", "type" to "movie")
|
||||||
)
|
).text
|
||||||
|
|
||||||
val ajax = mapper.readValue<LoadLinksAjax>(post.text)
|
val ajax = mapper.readValue<LoadLinksAjax>(post)
|
||||||
var realUrl = ajax.embedUrl
|
var realUrl = ajax.embedUrl
|
||||||
if (realUrl.startsWith("//")) {
|
if (realUrl.startsWith("//")) {
|
||||||
realUrl = "https:$realUrl"
|
realUrl = "https:$realUrl"
|
||||||
}
|
}
|
||||||
|
|
||||||
val request = khttp.get(realUrl)
|
val request = get(realUrl)
|
||||||
val prefix = "https://reeoov.tube/v/"
|
val prefix = "https://reeoov.tube/v/"
|
||||||
if (request.url.startsWith(prefix)) {
|
if (request.url.startsWith(prefix)) {
|
||||||
val apiUrl = "https://reeoov.tube/api/source/${request.url.removePrefix(prefix)}"
|
val apiUrl = "https://reeoov.tube/api/source/${request.url.removePrefix(prefix)}"
|
||||||
val apiResponse = khttp.post(apiUrl,headers = mapOf("Referer" to request.url),data = mapOf("r" to "https://www.vmovee.watch/", "d" to "reeoov.tube"))
|
val apiResponse = post(apiUrl,headers = mapOf("Referer" to request.url),data = mapOf("r" to "https://www.vmovee.watch/", "d" to "reeoov.tube")).text
|
||||||
val apiData = mapper.readValue<ReeoovAPI>(apiResponse.text)
|
val apiData = mapper.readValue<ReeoovAPI>(apiResponse)
|
||||||
for (d in apiData.data) {
|
for (d in apiData.data) {
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
@ -111,8 +115,8 @@ class VMoveeProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val sheader = document.selectFirst("div.sheader")
|
val sheader = document.selectFirst("div.sheader")
|
||||||
|
|
||||||
|
|
|
@ -3,22 +3,37 @@ package com.lagradost.cloudstream3.movieproviders
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.extractors.Vidstream
|
import com.lagradost.cloudstream3.extractors.Vidstream
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
/** Needs to inherit from MainAPI() to
|
||||||
|
* make the app know what functions to call
|
||||||
|
*/
|
||||||
class VidEmbedProvider : MainAPI() {
|
class VidEmbedProvider : MainAPI() {
|
||||||
|
// mainUrl is good to have as a holder for the url to make future changes easier.
|
||||||
override val mainUrl: String
|
override val mainUrl: String
|
||||||
get() = "https://vidembed.cc"
|
get() = "https://vidembed.cc"
|
||||||
|
|
||||||
|
// name is for how the provider will be named which is visible in the UI, no real rules for this.
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = "VidEmbed"
|
get() = "VidEmbed"
|
||||||
|
|
||||||
|
// hasQuickSearch defines if quickSearch() should be called, this is only when typing the searchbar
|
||||||
|
// gives results on the site instead of bringing you to another page.
|
||||||
|
// if hasQuickSearch is true and quickSearch() hasn't been overridden you will get errors.
|
||||||
|
// VidEmbed actually has quick search on their site, but the function wasn't implemented.
|
||||||
override val hasQuickSearch: Boolean
|
override val hasQuickSearch: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
|
// If getMainPage() is functional, used to display the homepage in app, an optional, but highly encouraged endevour.
|
||||||
override val hasMainPage: Boolean
|
override val hasMainPage: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
|
|
||||||
|
// Sometimes on sites the urls can be something like "/movie.html" which translates to "*full site url*/movie.html" in the browser
|
||||||
private fun fixUrl(url: String): String {
|
private fun fixUrl(url: String): String {
|
||||||
return if (url.startsWith("//")) {
|
return if (url.startsWith("//")) {
|
||||||
"https:$url"
|
"https:$url"
|
||||||
|
@ -29,33 +44,49 @@ class VidEmbedProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is just extra metadata about what type of movies the provider has.
|
||||||
|
// Needed for search functionality.
|
||||||
override val supportedTypes: Set<TvType>
|
override val supportedTypes: Set<TvType>
|
||||||
get() = setOf(TvType.Anime, TvType.AnimeMovie, TvType.TvSeries, TvType.Movie)
|
get() = setOf(TvType.Anime, TvType.AnimeMovie, TvType.TvSeries, TvType.Movie)
|
||||||
|
|
||||||
|
// Searching returns a SearchResponse, which can be one of the following: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse
|
||||||
|
// Each of the classes requires some different data, but always has some critical things like name, poster and url.
|
||||||
override fun search(query: String): ArrayList<SearchResponse> {
|
override fun search(query: String): ArrayList<SearchResponse> {
|
||||||
|
// Simply looking at devtools network is enough to spot a request like:
|
||||||
|
// https://vidembed.cc/search.html?keyword=neverland where neverland is the query, can be written as below.
|
||||||
val link = "$mainUrl/search.html?keyword=$query"
|
val link = "$mainUrl/search.html?keyword=$query"
|
||||||
val html = khttp.get(link).text
|
val html = get(link).text
|
||||||
val soup = Jsoup.parse(html)
|
val soup = Jsoup.parse(html)
|
||||||
|
|
||||||
return ArrayList(soup.select(".listing.items > .video-block").map { li ->
|
return ArrayList(soup.select(".listing.items > .video-block").map { li ->
|
||||||
|
// Selects the href in <a href="...">
|
||||||
val href = fixUrl(li.selectFirst("a").attr("href"))
|
val href = fixUrl(li.selectFirst("a").attr("href"))
|
||||||
val poster = li.selectFirst("img")?.attr("src")
|
val poster = li.selectFirst("img")?.attr("src")
|
||||||
|
|
||||||
|
// .text() selects all the text in the element, be careful about doing this while too high up in the html hierarchy
|
||||||
val title = li.selectFirst(".name").text()
|
val title = li.selectFirst(".name").text()
|
||||||
|
// Use get(0) and toIntOrNull() to prevent any possible crashes, [0] or toInt() will error the search on unexpected values.
|
||||||
val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull()
|
val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull()
|
||||||
|
|
||||||
TvSeriesSearchResponse(
|
TvSeriesSearchResponse(
|
||||||
|
// .trim() removes unwanted spaces in the start and end.
|
||||||
if (!title.contains("Episode")) title else title.split("Episode")[0].trim(),
|
if (!title.contains("Episode")) title else title.split("Episode")[0].trim(),
|
||||||
href,
|
href,
|
||||||
this.name,
|
this.name,
|
||||||
TvType.TvSeries,
|
TvType.TvSeries,
|
||||||
poster, year,
|
poster, year,
|
||||||
|
// You can't get the episodes from the search bar.
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Load, like the name suggests loads the info page, where all the episodes and data usually is.
|
||||||
|
// Like search you should return either of: AnimeLoadResponse, MovieLoadResponse, TorrentLoadResponse, TvSeriesLoadResponse.
|
||||||
override fun load(url: String): LoadResponse? {
|
override fun load(url: String): LoadResponse? {
|
||||||
val html = khttp.get(url).text
|
// Gets the url returned from searching.
|
||||||
|
val html = get(url).text
|
||||||
val soup = Jsoup.parse(html)
|
val soup = Jsoup.parse(html)
|
||||||
|
|
||||||
var title = soup.selectFirst("h1,h2,h3").text()
|
var title = soup.selectFirst("h1,h2,h3").text()
|
||||||
|
@ -89,8 +120,10 @@ class VidEmbedProvider : MainAPI() {
|
||||||
epDate
|
epDate
|
||||||
)
|
)
|
||||||
}.reversed()
|
}.reversed()
|
||||||
val year = if (episodes.isNotEmpty()) episodes.first().date?.split("-")?.get(0)?.toIntOrNull() else null
|
|
||||||
|
|
||||||
|
val year = episodes.first().date?.split("-")?.get(0)?.toIntOrNull()
|
||||||
|
|
||||||
|
// Make sure to get the type right to display the correct UI.
|
||||||
val tvType = if (episodes.size == 1 && episodes[0].name == title) TvType.Movie else TvType.TvSeries
|
val tvType = if (episodes.size == 1 && episodes[0].name == title) TvType.Movie else TvType.TvSeries
|
||||||
|
|
||||||
return when (tvType) {
|
return when (tvType) {
|
||||||
|
@ -127,6 +160,8 @@ class VidEmbedProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This loads the homepage, which is basically a collection of search results with labels.
|
||||||
|
// Optional function, but make sure to enable hasMainPage if you program this.
|
||||||
override fun getMainPage(): HomePageResponse? {
|
override fun getMainPage(): HomePageResponse? {
|
||||||
val urls = listOf(
|
val urls = listOf(
|
||||||
mainUrl,
|
mainUrl,
|
||||||
|
@ -136,10 +171,12 @@ class VidEmbedProvider : MainAPI() {
|
||||||
"$mainUrl/cinema-movies"
|
"$mainUrl/cinema-movies"
|
||||||
)
|
)
|
||||||
val homePageList = ArrayList<HomePageList>()
|
val homePageList = ArrayList<HomePageList>()
|
||||||
|
// .pmap {} is used to fetch the different pages in parallel
|
||||||
urls.pmap { url ->
|
urls.pmap { url ->
|
||||||
val response = khttp.get(url, timeout = 20.0)
|
val response = get(url, timeout = 20).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
document.select("div.main-inner")?.forEach {
|
document.select("div.main-inner")?.forEach {
|
||||||
|
// Always trim your text unless you want the risk of spaces at the start or end.
|
||||||
val title = it.select(".widget-title").text().trim()
|
val title = it.select(".widget-title").text().trim()
|
||||||
val elements = it.select(".video-block").map {
|
val elements = it.select(".video-block").map {
|
||||||
val link = fixUrl(it.select("a").attr("href"))
|
val link = fixUrl(it.select("a").attr("href"))
|
||||||
|
@ -182,13 +219,21 @@ class VidEmbedProvider : MainAPI() {
|
||||||
return HomePageResponse(homePageList)
|
return HomePageResponse(homePageList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadLinks gets the raw .mp4 or .m3u8 urls from the data parameter in the episodes class generated in load()
|
||||||
|
// See TvSeriesEpisode(...) in this provider.
|
||||||
|
// The data are usually links, but can be any other string to help aid loading the links.
|
||||||
override fun loadLinks(
|
override fun loadLinks(
|
||||||
data: String,
|
data: String,
|
||||||
isCasting: Boolean,
|
isCasting: Boolean,
|
||||||
|
// These callbacks are functions you should call when you get a link to a subtitle file or media file.
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val iframeLink = Jsoup.parse(khttp.get(data).text).selectFirst("iframe")?.attr("src") ?: return false
|
// "?: return" is a very useful statement which returns if the iframe link isn't found.
|
||||||
|
val iframeLink = Jsoup.parse(get(data).text).selectFirst("iframe")?.attr("src") ?: return false
|
||||||
|
|
||||||
|
// In this case the video player is a vidstream clone and can be handled by the vidstream extractor.
|
||||||
|
// This case is a both unorthodox and you normally do not call extractors as they detect the url returned and does the rest.
|
||||||
val vidstreamObject = Vidstream("https://vidembed.cc")
|
val vidstreamObject = Vidstream("https://vidembed.cc")
|
||||||
// https://vidembed.cc/streaming.php?id=MzUwNTY2&... -> MzUwNTY2
|
// https://vidembed.cc/streaming.php?id=MzUwNTY2&... -> MzUwNTY2
|
||||||
val id = Regex("""id=([^&]*)""").find(iframeLink)?.groupValues?.get(1)
|
val id = Regex("""id=([^&]*)""").find(iframeLink)?.groupValues?.get(1)
|
||||||
|
@ -197,7 +242,7 @@ class VidEmbedProvider : MainAPI() {
|
||||||
vidstreamObject.getUrl(id, isCasting, callback)
|
vidstreamObject.getUrl(id, isCasting, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
val html = khttp.get(fixUrl(iframeLink)).text
|
val html = get(fixUrl(iframeLink)).text
|
||||||
val soup = Jsoup.parse(html)
|
val soup = Jsoup.parse(html)
|
||||||
|
|
||||||
val servers = soup.select(".list-server-items > .linkserver").mapNotNull { li ->
|
val servers = soup.select(".list-server-items > .linkserver").mapNotNull { li ->
|
||||||
|
@ -208,12 +253,16 @@ class VidEmbedProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
servers.forEach {
|
servers.forEach {
|
||||||
|
// When checking strings make sure to make them lowercase and trimmed because edgecases like "beta server " wouldn't work otherwise.
|
||||||
if (it.first.toLowerCase(Locale.ROOT).trim() == "beta server") {
|
if (it.first.toLowerCase(Locale.ROOT).trim() == "beta server") {
|
||||||
// Group 1: link, Group 2: Label
|
// Group 1: link, Group 2: Label
|
||||||
|
// Regex can be used to effectively parse small amounts of json without bothering with writing a json class.
|
||||||
val sourceRegex = Regex("""sources:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""")
|
val sourceRegex = Regex("""sources:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""")
|
||||||
val trackRegex = Regex("""tracks:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""")
|
val trackRegex = Regex("""tracks:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""")
|
||||||
|
|
||||||
val html = khttp.get(it.second, headers = mapOf("referer" to iframeLink)).text
|
// Having a referer is often required. It's a basic security check most providers have.
|
||||||
|
// Try to replicate what your browser does.
|
||||||
|
val html = get(it.second, headers = mapOf("referer" to iframeLink)).text
|
||||||
sourceRegex.findAll(html).forEach { match ->
|
sourceRegex.findAll(html).forEach { match ->
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
@ -221,8 +270,11 @@ class VidEmbedProvider : MainAPI() {
|
||||||
match.groupValues.getOrNull(2)?.let { "${this.name} $it" } ?: this.name,
|
match.groupValues.getOrNull(2)?.let { "${this.name} $it" } ?: this.name,
|
||||||
match.groupValues[1],
|
match.groupValues[1],
|
||||||
it.second,
|
it.second,
|
||||||
|
// Useful function to turn something like "1080p" to an app quality.
|
||||||
getQualityFromName(match.groupValues.getOrNull(2) ?: ""),
|
getQualityFromName(match.groupValues.getOrNull(2) ?: ""),
|
||||||
// Kinda risky
|
// Kinda risky
|
||||||
|
// isM3u8 makes the player pick the correct extractor for the source.
|
||||||
|
// If isM3u8 is wrong the player will error on that source.
|
||||||
match.groupValues[1].endsWith(".m3u8"),
|
match.groupValues[1].endsWith(".m3u8"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
154
app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt
Normal file
154
app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
package com.lagradost.cloudstream3.network
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.USER_AGENT
|
||||||
|
import okhttp3.*
|
||||||
|
import okhttp3.Headers.Companion.toHeaders
|
||||||
|
import okio.Buffer
|
||||||
|
import java.net.URI
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
private const val DEFAULT_TIME = 10
|
||||||
|
private val DEFAULT_TIME_UNIT = TimeUnit.MINUTES
|
||||||
|
private const val DEFAULT_USER_AGENT = USER_AGENT
|
||||||
|
private val DEFAULT_HEADERS = mapOf("User-Agent" to DEFAULT_USER_AGENT)
|
||||||
|
private val DEFAULT_DATA: Map<String, String> = mapOf()
|
||||||
|
private val DEFAULT_COOKIES: Map<String, String> = mapOf()
|
||||||
|
private val DEFAULT_REFERER: String? = null
|
||||||
|
|
||||||
|
|
||||||
|
/** WARNING! CAN ONLY BE READ ONCE */
|
||||||
|
val Response.text: String
|
||||||
|
get() {
|
||||||
|
return this.body?.string() ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
val Response.url: String
|
||||||
|
get() {
|
||||||
|
return this.request.url.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
val Response.cookies: Map<String, String>
|
||||||
|
get() {
|
||||||
|
val cookieList =
|
||||||
|
this.headers.filter { it.first.toLowerCase(Locale.ROOT) == "set-cookie" }.getOrNull(0)?.second?.split(";")
|
||||||
|
return cookieList?.associate {
|
||||||
|
val split = it.split("=")
|
||||||
|
(split.getOrNull(0)?.trim() ?: "") to (split.getOrNull(1)?.trim() ?: "")
|
||||||
|
}?.filter { it.key.isNotBlank() && it.value.isNotBlank() } ?: mapOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getData(data: Map<String, String>): RequestBody {
|
||||||
|
val builder = FormBody.Builder()
|
||||||
|
data.forEach {
|
||||||
|
builder.add(it.key, it.value)
|
||||||
|
}
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com, id=test -> https://github.com?id=test
|
||||||
|
fun appendUri(uri: String, appendQuery: String): String {
|
||||||
|
val oldUri = URI(uri)
|
||||||
|
return URI(
|
||||||
|
oldUri.scheme, oldUri.authority, oldUri.path,
|
||||||
|
if (oldUri.query == null) appendQuery else oldUri.query + "&" + appendQuery, oldUri.fragment
|
||||||
|
).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can probably be done recursively
|
||||||
|
fun addParamsToUrl(url: String, params: Map<String, String>): String {
|
||||||
|
var appendedUrl = url
|
||||||
|
params.forEach {
|
||||||
|
appendedUrl = appendUri(appendedUrl, "${it.key}=${it.value}")
|
||||||
|
}
|
||||||
|
return appendedUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCache(cacheTime: Int, cacheUnit: TimeUnit): CacheControl {
|
||||||
|
return CacheControl.Builder().maxAge(cacheTime, cacheUnit).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Referer > Set headers > Set cookies > Default headers > Default Cookies
|
||||||
|
*/
|
||||||
|
fun getHeaders(headers: Map<String, String>, referer: String?, cookie: Map<String, String>): Headers {
|
||||||
|
val refererMap = (referer ?: DEFAULT_REFERER)?.let { mapOf("referer" to it) } ?: mapOf()
|
||||||
|
return (DEFAULT_COOKIES + DEFAULT_HEADERS + cookie + headers + refererMap).toHeaders()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun get(
|
||||||
|
url: String,
|
||||||
|
headers: Map<String, String> = mapOf(),
|
||||||
|
referer: String? = null,
|
||||||
|
params: Map<String, String> = mapOf(),
|
||||||
|
cookies: Map<String, String> = mapOf(),
|
||||||
|
allowRedirects: Boolean = true,
|
||||||
|
cacheTime: Int = DEFAULT_TIME,
|
||||||
|
cacheUnit: TimeUnit = DEFAULT_TIME_UNIT,
|
||||||
|
timeout: Long = 0L
|
||||||
|
): Response {
|
||||||
|
val client = OkHttpClient().newBuilder()
|
||||||
|
.followRedirects(allowRedirects)
|
||||||
|
.followSslRedirects(allowRedirects)
|
||||||
|
.callTimeout(timeout, TimeUnit.SECONDS)
|
||||||
|
.build()
|
||||||
|
val request = getRequestCreator(url, headers, referer, params, cookies, cacheTime, cacheUnit)
|
||||||
|
return client.newCall(request).execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun post(
|
||||||
|
url: String,
|
||||||
|
headers: Map<String, String> = mapOf(),
|
||||||
|
referer: String? = null,
|
||||||
|
params: Map<String, String> = mapOf(),
|
||||||
|
cookies: Map<String, String> = mapOf(),
|
||||||
|
data: Map<String, String> = DEFAULT_DATA,
|
||||||
|
allowRedirects: Boolean = true,
|
||||||
|
cacheTime: Int = DEFAULT_TIME,
|
||||||
|
cacheUnit: TimeUnit = DEFAULT_TIME_UNIT,
|
||||||
|
timeout: Long = 0L
|
||||||
|
): Response {
|
||||||
|
val client = OkHttpClient().newBuilder()
|
||||||
|
.followRedirects(allowRedirects)
|
||||||
|
.followSslRedirects(allowRedirects)
|
||||||
|
.callTimeout(timeout, TimeUnit.SECONDS)
|
||||||
|
.build()
|
||||||
|
val request = postRequestCreator(url, headers, referer, params, cookies, data, cacheTime, cacheUnit)
|
||||||
|
return client.newCall(request).execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getRequestCreator(
|
||||||
|
url: String,
|
||||||
|
headers: Map<String, String>,
|
||||||
|
referer: String?,
|
||||||
|
params: Map<String, String>,
|
||||||
|
cookies: Map<String, String>,
|
||||||
|
cacheTime: Int,
|
||||||
|
cacheUnit: TimeUnit
|
||||||
|
): Request {
|
||||||
|
return Request.Builder()
|
||||||
|
.url(addParamsToUrl(url, params))
|
||||||
|
.cacheControl(getCache(cacheTime, cacheUnit))
|
||||||
|
.headers(getHeaders(headers, referer, cookies))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun postRequestCreator(
|
||||||
|
url: String,
|
||||||
|
headers: Map<String, String>,
|
||||||
|
referer: String?,
|
||||||
|
params: Map<String, String>,
|
||||||
|
cookies: Map<String, String>,
|
||||||
|
data: Map<String, String>,
|
||||||
|
cacheTime: Int,
|
||||||
|
cacheUnit: TimeUnit
|
||||||
|
): Request {
|
||||||
|
return Request.Builder()
|
||||||
|
.url(addParamsToUrl(url, params))
|
||||||
|
.cacheControl(getCache(cacheTime, cacheUnit))
|
||||||
|
.headers(getHeaders(headers, referer, cookies))
|
||||||
|
.post(getData(data))
|
||||||
|
.build()
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.torrentproviders
|
package com.lagradost.cloudstream3.torrentproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
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 org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -23,8 +25,8 @@ class NyaaProvider : MainAPI() {
|
||||||
|
|
||||||
override fun search(query: String): List<SearchResponse> {
|
override fun search(query: String): List<SearchResponse> {
|
||||||
val url = "$mainUrl/?f=0&c=0_0&q=$query&s=seeders&o=desc"
|
val url = "$mainUrl/?f=0&c=0_0&q=$query&s=seeders&o=desc"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
val returnValues = ArrayList<SearchResponse>()
|
val returnValues = ArrayList<SearchResponse>()
|
||||||
val elements = document.select("table > tbody > tr")
|
val elements = document.select("table > tbody > tr")
|
||||||
|
@ -43,8 +45,8 @@ class NyaaProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(url: String): LoadResponse {
|
override fun load(url: String): LoadResponse {
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val title = document.selectFirst("h3.panel-title").text()
|
val title = document.selectFirst("h3.panel-title").text()
|
||||||
val description = document.selectFirst("div#torrent-description").text()
|
val description = document.selectFirst("div#torrent-description").text()
|
||||||
val downloadLinks = document.select("div.panel-footer > a")
|
val downloadLinks = document.select("div.panel-footer > a")
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.utils
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
@ -16,8 +18,8 @@ object FillerEpisodeCheck {
|
||||||
private fun getFillerList(): Boolean {
|
private fun getFillerList(): Boolean {
|
||||||
if (list != null) return true
|
if (list != null) return true
|
||||||
try {
|
try {
|
||||||
val result = khttp.get("$MAIN_URL/shows")
|
val result = get("$MAIN_URL/shows").text
|
||||||
val documented = Jsoup.parse(result.text)
|
val documented = Jsoup.parse(result)
|
||||||
val localHTMLList = documented.select("div#ShowList > div.Group > ul > li > a")
|
val localHTMLList = documented.select("div#ShowList > div.Group > ul > li > a")
|
||||||
val localList = HashMap<String, String>()
|
val localList = HashMap<String, String>()
|
||||||
for (i in localHTMLList) {
|
for (i in localHTMLList) {
|
||||||
|
@ -71,8 +73,8 @@ object FillerEpisodeCheck {
|
||||||
val realQuery = fixName(query.replace(blackListRegex, "")).replace("shippuuden", "shippuden")
|
val realQuery = fixName(query.replace(blackListRegex, "")).replace("shippuuden", "shippuden")
|
||||||
if (!localList.containsKey(realQuery)) return null
|
if (!localList.containsKey(realQuery)) return null
|
||||||
val href = localList[realQuery]?.replace(MAIN_URL, "") ?: return null // JUST IN CASE
|
val href = localList[realQuery]?.replace(MAIN_URL, "") ?: return null // JUST IN CASE
|
||||||
val result = khttp.get("$MAIN_URL$href")
|
val result = get("$MAIN_URL$href").text
|
||||||
val documented = Jsoup.parse(result.text) ?: return null
|
val documented = Jsoup.parse(result) ?: return null
|
||||||
val hashMap = HashMap<Int, Boolean>()
|
val hashMap = HashMap<Int, Boolean>()
|
||||||
documented.select("table.EpisodeList > tbody > tr").forEach {
|
documented.select("table.EpisodeList > tbody > tr").forEach {
|
||||||
val type = it.selectFirst("td.Type > span").text() == "Filler"
|
val type = it.selectFirst("td.Type > span").text() == "Filler"
|
||||||
|
|
|
@ -40,7 +40,7 @@ class HttpSession {
|
||||||
allowRedirects: Boolean? = null,
|
allowRedirects: Boolean? = null,
|
||||||
stream: Boolean = false, files: List<FileLike> = listOf(),
|
stream: Boolean = false, files: List<FileLike> = listOf(),
|
||||||
): Response {
|
): Response {
|
||||||
val res = khttp.get(
|
val res = get(
|
||||||
url, headers, params,
|
url, headers, params,
|
||||||
data, json, auth,
|
data, json, auth,
|
||||||
mergeCookies(sessionCookies, cookies), timeout,
|
mergeCookies(sessionCookies, cookies), timeout,
|
||||||
|
@ -62,7 +62,7 @@ class HttpSession {
|
||||||
allowRedirects: Boolean? = null,
|
allowRedirects: Boolean? = null,
|
||||||
stream: Boolean = false, files: List<FileLike> = listOf()
|
stream: Boolean = false, files: List<FileLike> = listOf()
|
||||||
): Response {
|
): Response {
|
||||||
val res = khttp.post(
|
val res = post(
|
||||||
url, headers, params,
|
url, headers, params,
|
||||||
data, json, auth,
|
data, json, auth,
|
||||||
mergeCookies(sessionCookies, cookies), timeout,
|
mergeCookies(sessionCookies, cookies), timeout,
|
||||||
|
|
|
@ -23,6 +23,8 @@ import com.lagradost.cloudstream3.MainActivity.Companion.showToast
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
@ -82,7 +84,7 @@ class InAppUpdater {
|
||||||
val url = "https://api.github.com/repos/LagradOst/CloudStream-3/releases"
|
val url = "https://api.github.com/repos/LagradOst/CloudStream-3/releases"
|
||||||
val headers = mapOf("Accept" to "application/vnd.github.v3+json")
|
val headers = mapOf("Accept" to "application/vnd.github.v3+json")
|
||||||
val response =
|
val response =
|
||||||
mapper.readValue<List<GithubRelease>>(khttp.get(url, headers = headers).text)
|
mapper.readValue<List<GithubRelease>>(get(url, headers = headers).text)
|
||||||
|
|
||||||
val versionRegex = Regex("""(.*?((\d+)\.(\d+)\.(\d+))\.apk)""")
|
val versionRegex = Regex("""(.*?((\d+)\.(\d+)\.(\d+))\.apk)""")
|
||||||
val versionRegexLocal = Regex("""(.*?((\d+)\.(\d+)\.(\d+)).*)""")
|
val versionRegexLocal = Regex("""(.*?((\d+)\.(\d+)\.(\d+)).*)""")
|
||||||
|
@ -138,7 +140,7 @@ class InAppUpdater {
|
||||||
val releaseUrl = "https://api.github.com/repos/LagradOst/CloudStream-3/releases"
|
val releaseUrl = "https://api.github.com/repos/LagradOst/CloudStream-3/releases"
|
||||||
val headers = mapOf("Accept" to "application/vnd.github.v3+json")
|
val headers = mapOf("Accept" to "application/vnd.github.v3+json")
|
||||||
val response =
|
val response =
|
||||||
mapper.readValue<List<GithubRelease>>(khttp.get(releaseUrl, headers = headers).text)
|
mapper.readValue<List<GithubRelease>>(get(releaseUrl, headers = headers).text)
|
||||||
|
|
||||||
val found =
|
val found =
|
||||||
response.lastOrNull { rel ->
|
response.lastOrNull { rel ->
|
||||||
|
@ -147,7 +149,7 @@ class InAppUpdater {
|
||||||
val foundAsset = found?.assets?.getOrNull(0)
|
val foundAsset = found?.assets?.getOrNull(0)
|
||||||
|
|
||||||
val tagResponse =
|
val tagResponse =
|
||||||
mapper.readValue<GithubTag>(khttp.get(tagUrl, headers = headers).text)
|
mapper.readValue<GithubTag>(get(tagUrl, headers = headers).text)
|
||||||
|
|
||||||
val shouldUpdate = (getString(R.string.prerelease_commit_hash) != tagResponse.github_object.sha)
|
val shouldUpdate = (getString(R.string.prerelease_commit_hash) != tagResponse.github_object.sha)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.utils
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
import javax.crypto.spec.IvParameterSpec
|
import javax.crypto.spec.IvParameterSpec
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
@ -79,9 +81,9 @@ class M3u8Helper {
|
||||||
fun m3u8Generation(m3u8: M3u8Stream): List<M3u8Stream> {
|
fun m3u8Generation(m3u8: M3u8Stream): List<M3u8Stream> {
|
||||||
val generate = sequence {
|
val generate = sequence {
|
||||||
val m3u8Parent = getParentLink(m3u8.streamUrl)
|
val m3u8Parent = getParentLink(m3u8.streamUrl)
|
||||||
val response = khttp.get(m3u8.streamUrl, headers = m3u8.headers)
|
val response = get(m3u8.streamUrl, headers = m3u8.headers).text
|
||||||
|
|
||||||
for (match in QUALITY_REGEX.findAll(response.text)) {
|
for (match in QUALITY_REGEX.findAll(response)) {
|
||||||
var (quality, m3u8Link, m3u8Link2) = match.destructured
|
var (quality, m3u8Link, m3u8Link2) = match.destructured
|
||||||
if (m3u8Link.isNullOrEmpty()) m3u8Link = m3u8Link2
|
if (m3u8Link.isNullOrEmpty()) m3u8Link = m3u8Link2
|
||||||
if (absoluteExtensionDetermination(m3u8Link) == "m3u8") {
|
if (absoluteExtensionDetermination(m3u8Link) == "m3u8") {
|
||||||
|
@ -134,18 +136,17 @@ class M3u8Helper {
|
||||||
|
|
||||||
val secondSelection = selectBest(streams.ifEmpty { listOf(selected) })
|
val secondSelection = selectBest(streams.ifEmpty { listOf(selected) })
|
||||||
if (secondSelection != null) {
|
if (secondSelection != null) {
|
||||||
val m3u8Response = khttp.get(secondSelection.streamUrl, headers = headers)
|
val m3u8Response = get(secondSelection.streamUrl, headers = headers).text
|
||||||
val m3u8Data = m3u8Response.text
|
|
||||||
|
|
||||||
var encryptionUri: String? = null
|
var encryptionUri: String? = null
|
||||||
var encryptionIv = byteArrayOf()
|
var encryptionIv = byteArrayOf()
|
||||||
var encryptionData = byteArrayOf()
|
var encryptionData = byteArrayOf()
|
||||||
|
|
||||||
val encryptionState = isEncrypted(m3u8Data)
|
val encryptionState = isEncrypted(m3u8Response)
|
||||||
|
|
||||||
if (encryptionState) {
|
if (encryptionState) {
|
||||||
val match =
|
val match =
|
||||||
ENCRYPTION_URL_IV_REGEX.find(m3u8Data)!!.destructured // its safe to assume that its not going to be null
|
ENCRYPTION_URL_IV_REGEX.find(m3u8Response)!!.destructured // its safe to assume that its not going to be null
|
||||||
encryptionUri = match.component2()
|
encryptionUri = match.component2()
|
||||||
|
|
||||||
if (isNotCompleteUrl(encryptionUri)) {
|
if (isNotCompleteUrl(encryptionUri)) {
|
||||||
|
@ -153,11 +154,11 @@ class M3u8Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptionIv = match.component3().toByteArray()
|
encryptionIv = match.component3().toByteArray()
|
||||||
val encryptionKeyResponse = khttp.get(encryptionUri, headers = headers)
|
val encryptionKeyResponse = get(encryptionUri, headers = headers)
|
||||||
encryptionData = encryptionKeyResponse.content
|
encryptionData = encryptionKeyResponse.body?.bytes() ?: byteArrayOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
val allTs = TS_EXTENSION_REGEX.findAll(m3u8Data)
|
val allTs = TS_EXTENSION_REGEX.findAll(m3u8Response)
|
||||||
val allTsList = allTs.toList()
|
val allTsList = allTs.toList()
|
||||||
val totalTs = allTsList.size
|
val totalTs = allTsList.size
|
||||||
if (totalTs == 0) {
|
if (totalTs == 0) {
|
||||||
|
@ -176,8 +177,8 @@ class M3u8Helper {
|
||||||
|
|
||||||
while (lastYield != c) {
|
while (lastYield != c) {
|
||||||
try {
|
try {
|
||||||
val tsResponse = khttp.get(url, headers = headers)
|
val tsResponse = get(url, headers = headers)
|
||||||
var tsData = tsResponse.content
|
var tsData = tsResponse.body?.bytes() ?: byteArrayOf()
|
||||||
|
|
||||||
if (encryptionState) {
|
if (encryptionState) {
|
||||||
tsData = getDecrypter(encryptionData, tsData, encryptionIv)
|
tsData = getDecrypter(encryptionData, tsData, encryptionIv)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.utils
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -16,8 +18,8 @@ object SubtitleHelper {
|
||||||
|
|
||||||
fun createISO() {
|
fun createISO() {
|
||||||
val url = "https://infogalactic.com/info/List_of_ISO_639-1_codes"
|
val url = "https://infogalactic.com/info/List_of_ISO_639-1_codes"
|
||||||
val response = khttp.get(url)
|
val response = get(url).text
|
||||||
val document = Jsoup.parse(response.text)
|
val document = Jsoup.parse(response)
|
||||||
val headers = document.select("table.wikitable > tbody > tr")
|
val headers = document.select("table.wikitable > tbody > tr")
|
||||||
|
|
||||||
var text = "listOf(\n"
|
var text = "listOf(\n"
|
||||||
|
|
Loading…
Reference in a new issue