diff --git a/app/build.gradle b/app/build.gradle index 2a35709d..f5a1fec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -132,4 +132,7 @@ dependencies { // Downloading implementation "androidx.work:work-runtime:2.7.0-beta01" implementation "androidx.work:work-runtime-ktx:2.7.0-beta01" + + // Networking + implementation "com.squareup.okhttp3:okhttp:4.9.0" } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/AcraApplication.kt b/app/src/main/java/com/lagradost/cloudstream3/AcraApplication.kt index 090760df..113e7291 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/AcraApplication.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/AcraApplication.kt @@ -5,6 +5,7 @@ import android.content.Context import android.widget.Toast import com.google.auto.service.AutoService import com.lagradost.cloudstream3.mvvm.normalSafeApiCall +import com.lagradost.cloudstream3.network.post import com.lagradost.cloudstream3.utils.Coroutines.runOnMainThread import org.acra.ReportField import org.acra.config.CoreConfiguration @@ -27,7 +28,7 @@ class CustomReportSender : ReportSender { thread { // to not run it on main thread normalSafeApiCall { - val post = khttp.post(url, data = data) + val post = post(url, data = data) println("Report response: $post") } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt index c71033b1..518b49dd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt @@ -1,6 +1,8 @@ package com.lagradost.cloudstream3.animeproviders 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.Qualities import com.lagradost.cloudstream3.utils.extractorApis @@ -36,7 +38,7 @@ class AnimeFlickProvider : MainAPI() { override fun search(query: String): ArrayList { 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) return ArrayList(doc.select(".row.mt-2").map { @@ -59,7 +61,7 @@ class AnimeFlickProvider : MainAPI() { } override fun load(url: String): LoadResponse { - val html = khttp.get(url).text + val html = get(url).text val doc = Jsoup.parse(html) val poster = mainUrl + doc.selectFirst("img.rounded").attr("src") @@ -101,7 +103,7 @@ class AnimeFlickProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - val html = khttp.get(data).text + val html = get(data).text val episodeRegex = Regex("""(https://.*?\.mp4)""") val links = episodeRegex.findAll(html).map { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt index dd9faf66..f598227f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt @@ -1,12 +1,13 @@ package com.lagradost.cloudstream3.animeproviders import com.lagradost.cloudstream3.* -import khttp.structures.cookie.CookieJar import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.mvvm.normalSafeApiCall +import com.lagradost.cloudstream3.network.* import com.lagradost.cloudstream3.utils.getQualityFromName +import okhttp3.Response import org.jsoup.Jsoup import java.util.* import kotlin.collections.ArrayList @@ -15,7 +16,7 @@ class AnimePaheProvider : MainAPI() { companion object { const val MAIN_URL = "https://animepahe.com" - var cookies = CookieJar() + var cookies: Map = mapOf() private fun getType(t: String): TvType { return if (t.contains("OVA") || t.contains("Special")) TvType.ONA else if (t.contains("Movie")) TvType.AnimeMovie @@ -23,9 +24,9 @@ class AnimePaheProvider : MainAPI() { } fun generateSession(): Boolean { - if (cookies.entries.size != 0) return true + if (cookies.isNotEmpty()) return true return try { - val response = khttp.get("$MAIN_URL/") + val response = get("$MAIN_URL/") cookies = response.cookies true } catch (e: Exception) { @@ -82,8 +83,8 @@ class AnimePaheProvider : MainAPI() { val items = ArrayList() for (i in urls) { try { - val response = khttp.get(i.first) - val episodes = mapper.readValue(response.text).data.map { + val response = get(i.first).text + val episodes = mapper.readValue(response).data.map { AnimeSearchResponse( it.animeTitle, @@ -132,8 +133,8 @@ class AnimePaheProvider : MainAPI() { val url = "$mainUrl/api?m=search&l=8&q=$title" val headers = mapOf("referer" to "$mainUrl/") - val req = khttp.get(url, headers = headers) - val data = req.let { mapper.readValue(it.text) } + val req = get(url, headers = headers).text + val data = req.let { mapper.readValue(it) } for (anime in data.data) { if (anime.id == animeId) { 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 headers = mapOf("referer" to "$mainUrl/") - val req = khttp.get(url, headers = headers) - val data = req.let { mapper.readValue(it.text) } + val req = get(url, headers = headers).text + val data = req.let { mapper.readValue(it) } return ArrayList(data.data.map { AnimeSearchResponse( @@ -198,8 +199,8 @@ class AnimePaheProvider : MainAPI() { val uri = "$mainUrl/api?m=release&id=$id&sort=episode_asc&page=1" val headers = mapOf("referer" to "$mainUrl/") - val req = khttp.get(uri, headers = headers) - val data = req.let { mapper.readValue(it.text) } + val req = get(uri, headers = headers).text + val data = req.let { mapper.readValue(it) } val lastPage = data.lastPage val perPage = data.perPage @@ -257,7 +258,7 @@ class AnimePaheProvider : MainAPI() { val (animeId, animeTitle) = regex.find(url)!!.destructured val link = getAnimeByIdAndTitle(animeTitle, animeId.toInt())!! - val html = khttp.get(link).text + val html = get(link).text val doc = Jsoup.parse(html) val japTitle = doc.selectFirst("h2.japanese")?.text() @@ -454,17 +455,17 @@ class AnimePaheProvider : MainAPI() { } var responseCode = 302 - var adflyContent: khttp.responses.Response? = null + var adflyContent: Response? = null var tries = 0 while (responseCode != 200 && tries < 20) { - adflyContent = khttp.get( - khttp.get(adflyUri, cookies = cookies, allowRedirects = false).headers.getValue("location"), + adflyContent = get( + get(adflyUri, cookies = cookies, allowRedirects = false).url, cookies = cookies, allowRedirects = false ) - cookies.putAll(adflyContent.cookies.toMap()) - responseCode = adflyContent.statusCode + cookies = cookies + adflyContent.cookies + responseCode = adflyContent.code ++tries } if (tries > 19) { @@ -475,33 +476,33 @@ class AnimePaheProvider : MainAPI() { private fun getStreamUrlFromKwik(adflyUri: String): String { val fContent = - khttp.get(bypassAdfly(adflyUri), headers = mapOf("referer" to "https://kwik.cx/"), cookies = cookies) - cookies.putAll(fContent.cookies.toMap()) + get(bypassAdfly(adflyUri), headers = mapOf("referer" to "https://kwik.cx/"), cookies = cookies) + cookies = cookies + fContent.cookies val (fullString, key, v1, v2) = KWIK_PARAMS_RE.find(fContent.text)!!.destructured val decrypted = decrypt(fullString, key, v1.toInt(), v2.toInt()) val uri = KWIK_D_URL.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 tries = 0 while (code != 302 && tries < 20) { - content = khttp.post( + content = post( uri, allowRedirects = false, data = mapOf("_token" to tok), 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 } if (tries > 19) { 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 { @@ -516,8 +517,8 @@ class AnimePaheProvider : MainAPI() { link = link.replace(regex, "") - val req = khttp.get(link, headers = headers) - val jsonResponse = req.let { mapper.readValue(it.text) } + val req = get(link, headers = headers).text + val jsonResponse = req.let { mapper.readValue(it) } val ep = ((jsonResponse.data.map { if (it.episode == episodeNum) { it @@ -527,8 +528,8 @@ class AnimePaheProvider : MainAPI() { }).filterNotNull())[0] link = "$mainUrl/api?m=links&id=${ep.animeId}&session=${ep.session}&p=kwik" } - val req = khttp.get(link, headers = headers) - val data = mapper.readValue(req.text) + val req = get(link, headers = headers).text + val data = mapper.readValue(req) val qualities = ArrayList() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt index e9318f84..51ba09c5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt @@ -5,6 +5,8 @@ import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.unixTime 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.getQualityFromName import org.jsoup.Jsoup @@ -61,8 +63,8 @@ class DubbedAnimeProvider : MainAPI() { ) private fun parseDocumentTrending(url: String): List { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) return document.select("li > a").map { val href = fixUrl(it.attr("href")) val title = it.selectFirst("> div > div.cittx").text() @@ -83,8 +85,8 @@ class DubbedAnimeProvider : MainAPI() { } private fun parseDocument(url: String, trimEpisode: Boolean = false): List { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) return document.select("a.grid__link").map { val href = fixUrl(it.attr("href")) val title = it.selectFirst("> div.gridtitlek").text() @@ -124,10 +126,8 @@ class DubbedAnimeProvider : MainAPI() { private fun getAnimeEpisode(slug: String, isMovie: Boolean): EpisodeInfo { val url = mainUrl + (if (isMovie) "/movies/jsonMovie" else "/xz/v3/jsonEpi") + ".php?slug=$slug&_=$unixTime" - val response = khttp.get(url) - println(response.text) - val mapped = mapper.readValue(response.text) - + val response = get(url).text + val mapped = mapper.readValue(response) return mapped.result.anime.first() } @@ -142,8 +142,8 @@ class DubbedAnimeProvider : MainAPI() { override fun quickSearch(query: String): List { val url = "$mainUrl/xz/searchgrid.php?p=1&limit=12&s=$query&_=$unixTime" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val items = document.select("div.grid__item > a") if (items.isEmpty()) return ArrayList() val returnValue = ArrayList() @@ -177,8 +177,8 @@ class DubbedAnimeProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/search/$query" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val items = document.select("div.resultinner > a.resulta") if (items.isEmpty()) return ArrayList() val returnValue = ArrayList() @@ -229,9 +229,8 @@ class DubbedAnimeProvider : MainAPI() { }.toList()) for (hl in hls) { try { - val sources = khttp.get("$mainUrl/xz/api/playeri.php?url=$hl&_=$unixTime") - val txt = sources.text - val find = "src=\"(.*?)\".*?label=\"(.*?)\"".toRegex().find(txt) + val sources = get("$mainUrl/xz/api/playeri.php?url=$hl&_=$unixTime").text + val find = "src=\"(.*?)\".*?label=\"(.*?)\"".toRegex().find(sources) if (find != null) { val quality = find.groupValues[2] callback.invoke( @@ -268,8 +267,8 @@ class DubbedAnimeProvider : MainAPI() { null ) } else { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val title = document.selectFirst("h4").text() val descriptHeader = document.selectFirst("div.animeDescript") val descript = descriptHeader.selectFirst("> p").text() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index 6a4f25ae..7704fc77 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -1,6 +1,9 @@ package com.lagradost.cloudstream3.animeproviders 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.extractorApis import com.lagradost.cloudstream3.utils.getQualityFromName @@ -67,7 +70,7 @@ class GogoanimeProvider : MainAPI() { for (i in urls) { try { 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 { val (link, epNum, title, poster) = it.destructured AnimeSearchResponse( @@ -93,7 +96,7 @@ class GogoanimeProvider : MainAPI() { override fun search(query: String): ArrayList { val link = "$mainUrl/search.html?keyword=$query" - val html = khttp.get(link).text + val html = get(link).text val doc = Jsoup.parse(html) val episodes = doc.select(""".last_episodes li""").map { @@ -126,7 +129,7 @@ class GogoanimeProvider : MainAPI() { override fun load(url: String): LoadResponse { val link = getProperAnimeLink(url) 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 animeBody = doc.selectFirst(".anime_info_body_bg") @@ -166,7 +169,7 @@ class GogoanimeProvider : MainAPI() { val animeId = doc.selectFirst("#movie_id").attr("value") val params = mapOf("ep_start" to "0", "ep_end" to "2000", "id" to animeId) - val responseHTML = khttp.get(episodeloadApi, params=params).text + val responseHTML = get(episodeloadApi, params=params).text val epiDoc = Jsoup.parse(responseHTML) val episodes = epiDoc.select("a").map { AnimeEpisode( @@ -195,13 +198,13 @@ class GogoanimeProvider : MainAPI() { } private fun extractVideos(uri: String): List { - val html = khttp.get(uri).text + val html = get(uri).text val doc = Jsoup.parse(html) val iframe = "https:" + doc.selectFirst("div.play-video > iframe").attr("src") 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) return pageDoc.select(".dowload > a").map { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt index 7ce600aa..465cb8d7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt @@ -1,6 +1,8 @@ package com.lagradost.cloudstream3.animeproviders 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.getQualityFromName import org.jsoup.Jsoup @@ -23,7 +25,9 @@ class KawaiifuProvider : MainAPI() { override fun getMainPage(): HomePageResponse { val items = ArrayList() - 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 { val title = it.selectFirst("img").attr("alt") @@ -71,7 +75,7 @@ class KawaiifuProvider : MainAPI() { override fun search(query: String): ArrayList { val link = "$mainUrl/search-movie?keyword=${query}" - val html = khttp.get(link).text + val html = get(link).text val soup = Jsoup.parse(html) return ArrayList(soup.select(".item").map { @@ -95,7 +99,7 @@ class KawaiifuProvider : MainAPI() { } override fun load(url: String): LoadResponse { - val html = khttp.get(url).text + val html = get(url).text val soup = Jsoup.parse(html) 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() } val year = url.split("/").filter { it.contains("-") }[0].split("-")[1].toIntOrNull() val episodes = Jsoup.parse( - khttp.get( + get( soup.selectFirst("a[href*=\".html-episode\"]").attr("href") ).text ).selectFirst(".list-ep").select("li").map { @@ -140,7 +144,7 @@ class KawaiifuProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - val htmlSource = khttp.get(data).text + val htmlSource = get(data).text val soupa = Jsoup.parse(htmlSource) 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")) } Triple(it.first, sources, it.second.second) } else { - val html = khttp.get(it.second.first).text + val html = get(it.second.first).text val soup = Jsoup.parse(html) val sources = soup.select("video > source").map { source -> Pair(source.attr("src"), source.attr("data-quality")) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt index 228198af..0cf1fd2d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt @@ -4,9 +4,11 @@ import android.annotation.SuppressLint import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue 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.getQualityFromName -import khttp.structures.cookie.CookieJar import org.jsoup.Jsoup import org.jsoup.nodes.Document import java.text.SimpleDateFormat @@ -15,7 +17,7 @@ import java.util.* class TenshiProvider : MainAPI() { companion object { var token: String? = null - var cookie: CookieJar? = null + var cookie: Map = mapOf() fun getType(t: String): TvType { return if (t.contains("OVA") || t.contains("Special")) TvType.ONA @@ -32,14 +34,14 @@ class TenshiProvider : MainAPI() { get() = false override val hasMainPage: Boolean get() = true - - + + override val supportedTypes: Set get() = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) private fun loadToken(): Boolean { return try { - val response = khttp.get(mainUrl) + val response = get(mainUrl) cookie = response.cookies val document = Jsoup.parse(response.text) token = document.selectFirst("""meta[name="csrf-token"]""").attr("content") @@ -48,10 +50,10 @@ class TenshiProvider : MainAPI() { false } } - + override fun getMainPage(): HomePageResponse { val items = ArrayList() - val soup = Jsoup.parse(khttp.get(mainUrl).text) + val soup = Jsoup.parse(get(mainUrl).text) for (section in soup.select("#content > section")) { try { if (section.attr("id") == "toplist-tabs") { @@ -95,7 +97,7 @@ class TenshiProvider : MainAPI() { e.printStackTrace() } } - if(items.size <= 0) throw ErrorLoadingException() + if (items.size <= 0) throw ErrorLoadingException() return HomePageResponse(items) } @@ -149,7 +151,7 @@ class TenshiProvider : MainAPI() { dateString.replace("th ", " ").replace("st ", " ").replace("nd ", " ").replace("rd ", " ") ) ?: return null return newFormat.format(data) - } catch (e : Exception) { + } catch (e: Exception) { return null } } @@ -207,15 +209,15 @@ class TenshiProvider : MainAPI() { override fun search(query: String): ArrayList { val url = "$mainUrl/anime" - var response = khttp.get(url, params = mapOf("q" to query), cookies = mapOf("loop-view" to "thumb")) - var document = Jsoup.parse(response.text) + var response = get(url, params = mapOf("q" to query), cookies = mapOf("loop-view" to "thumb")).text + var document = Jsoup.parse(response) val returnValue = parseSearchPage(document) while (!document.select("""a.page-link[rel="next"]""").isEmpty()) { val link = document.select("""a.page-link[rel="next"]""") if (link != null && !link.isEmpty()) { - response = khttp.get(link[0].attr("href"), cookies = mapOf("loop-view" to "thumb")) - document = Jsoup.parse(response.text) + response = get(link[0].attr("href"), cookies = mapOf("loop-view" to "thumb")).text + document = Jsoup.parse(response) returnValue.addAll(parseSearchPage(document)) } else { break @@ -226,8 +228,8 @@ class TenshiProvider : MainAPI() { } override fun load(url: String): LoadResponse { - val response = khttp.get(url, timeout = 120.0, cookies = mapOf("loop-view" to "thumb")) - val document = Jsoup.parse(response.text) + val response = get(url, cookies = mapOf("loop-view" to "thumb")).text + val document = Jsoup.parse(response) val englishTitle = document.selectFirst("span.value > span[title=\"English\"]")?.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, callback: (ExtractorLink) -> Unit ): Boolean { - val response = khttp.get(data) - val soup = Jsoup.parse(response.text) + val response = get(data).text + val soup = Jsoup.parse(response) data class Quality( @JsonProperty("src") val src: String, @@ -302,9 +304,9 @@ class TenshiProvider : MainAPI() { val sources = ArrayList() for (source in soup.select("""[aria-labelledby="mirror-dropdown"] > li > a.dropdown-item""")) { 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]}", - headers=mapOf("Referer" to data) + headers = mapOf("Referer" to data) ).text val match = Regex("""sources: (\[(?:.|\s)+?type: ['\"]video\/.*?['\"](?:.|\s)+?\])""").find(sourceHTML) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt index 18a13799..d465120e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt @@ -3,6 +3,9 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.post +import com.lagradost.cloudstream3.network.text import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import org.jsoup.Jsoup @@ -27,13 +30,14 @@ class WatchCartoonOnlineProvider : MainAPI() { val url = "https://www.wcostream.com/search" var response = - khttp.post( + post( url, headers = mapOf("Referer" to url), data = mapOf("catara" to query, "konuara" to "series") - ) - var document = Jsoup.parse(response.text) + ).text + var document = Jsoup.parse(response) var items = document.select("div#blog > div.cerceve").toList() + val returnValue = ArrayList() for (item in items) { @@ -68,12 +72,12 @@ class WatchCartoonOnlineProvider : MainAPI() { // "episodes-search", is used for finding movies, anime episodes should be filtered out response = - khttp.post( + post( url, headers = mapOf("Referer" to url), data = mapOf("catara" to query, "konuara" to "episodes") - ) - document = Jsoup.parse(response.text) + ).text + document = Jsoup.parse(response) 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 { val isMovie = !url.contains("/anime/") - - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) return if (!isMovie) { @@ -194,13 +197,12 @@ class WatchCartoonOnlineProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - val response = khttp.get(data) + val response = get(data).text /*val embedUrl = fixUrl( Regex("itemprop=\"embedURL\" content=\"(.*?)\"").find(response.text)?.groupValues?.get(1) ?: return false )*/ - val text = response.text - val start = text.indexOf("itemprop=\"embedURL") - val foundJS = Regex("").find(text, start)?.groupValues?.get(1) + val start = response.indexOf("itemprop=\"embedURL") + val foundJS = Regex("").find(response, start)?.groupValues?.get(1) ?.replace("document.write", "var returnValue = ") val rhino = Context.enter() @@ -223,7 +225,7 @@ class WatchCartoonOnlineProvider : MainAPI() { val jsEval = scope.get("returnValue", scope) ?: return false val src = fixUrl(Regex("src=\"(.*?)\"").find(jsEval as String)?.groupValues?.get(1) ?: return false) - val embedResponse = khttp.get( + val embedResponse = get( (src), headers = mapOf("Referer" to data) ) @@ -231,7 +233,7 @@ class WatchCartoonOnlineProvider : MainAPI() { val getVidLink = fixUrl( Regex("get\\(\"(.*?)\"").find(embedResponse.text)?.groupValues?.get(1) ?: return false ) - val linkResponse = khttp.get( + val linkResponse = get( getVidLink, headers = mapOf( "sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"", "sec-ch-ua-mobile" to "?0", @@ -275,4 +277,4 @@ class WatchCartoonOnlineProvider : MainAPI() { return true } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt index 4a8d73d6..046f2445 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -3,6 +3,10 @@ package com.lagradost.cloudstream3.animeproviders import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.ExtractorLink 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.nodes.Document import java.util.* @@ -45,9 +49,9 @@ class WcoProvider : MainAPI() { val items = ArrayList() for (i in urls) { try { - val response = khttp.get( + val response = JSONObject(get( 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 results = document.select("div.flw-item").map { val filmPoster = it.selectFirst("> div.film-poster") @@ -116,15 +120,16 @@ class WcoProvider : MainAPI() { override fun search(query: String): List { 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) val returnValue = parseSearchPage(document) while (!document.select(".pagination").isEmpty()) { val link = document.select("a.page-link[rel=\"next\"]") if (!link.isEmpty()) { - val extraResponse = khttp.get(fixUrl(link[0].attr("href"))) - document = Jsoup.parse(extraResponse.text) + val extraResponse = get(fixUrl(link[0].attr("href"))).text + document = Jsoup.parse(extraResponse) returnValue.addAll(parseSearchPage(document)) } else { break @@ -136,10 +141,10 @@ class WcoProvider : MainAPI() { override fun quickSearch(query: String): List { val returnValue: ArrayList = ArrayList() - val response = khttp.post( + val response = JSONObject(post( "https://wcostream.cc/ajax/search", 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) document.select("a.nav-item").forEach { @@ -177,8 +182,8 @@ class WcoProvider : MainAPI() { } override fun load(url: String): LoadResponse { - val response = khttp.get(url, timeout = 120.0) - val document = Jsoup.parse(response.text) + val response = get(url, timeout = 120).text + val document = Jsoup.parse(response) val japaneseTitle = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(1)") ?.text()?.trim()?.replace("Other names:", "")?.trim() @@ -234,8 +239,8 @@ class WcoProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - val response = khttp.get(data) - val servers = Jsoup.parse(response.text).select("#servers-list > ul > li").map { + val response = get(data).text + val servers = Jsoup.parse(response).select("#servers-list > ul > li").map { mapOf( "link" to it?.selectFirst("a")?.attr("data-embed"), "title" to it?.selectFirst("span")?.text()?.trim() diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt index 88e0ba80..b38807de 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt @@ -1,5 +1,7 @@ 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.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities @@ -30,13 +32,13 @@ open class DoodLaExtractor : ExtractorApi() { override fun getUrl(url: String, referer: String?): List? { val id = url.removePrefix("$mainUrl/e/").removePrefix("$mainUrl/d/") val trueUrl = getExtractorUrl(id) - val response = khttp.get(trueUrl) - Regex("href=\".*/download/(.*?)\"").find(response.text)?.groupValues?.get(1)?.let { link -> + val response = get(trueUrl).text + Regex("href=\".*/download/(.*?)\"").find(response)?.groupValues?.get(1)?.let { link -> if (link.isEmpty()) return null sleep(5000) // might need this to not trigger anti bot val downloadLink = "$mainUrl/download/$link" - val downloadResponse = khttp.get(downloadLink) - Regex("onclick=\"window\\.open\\((['\"])(.*?)(['\"])").find(downloadResponse.text)?.groupValues?.get(2) + val downloadResponse = get(downloadLink).text + Regex("onclick=\"window\\.open\\((['\"])(.*?)(['\"])").find(downloadResponse)?.groupValues?.get(2) ?.let { trueLink -> return listOf( ExtractorLink( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt index 9a8d7578..13452040 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt @@ -1,5 +1,7 @@ package com.lagradost.cloudstream3.extractors +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.text import com.lagradost.cloudstream3.utils.* class MixDrop : ExtractorApi() { @@ -13,7 +15,7 @@ class MixDrop : ExtractorApi() { } override fun getUrl(url: String, referer: String?): List? { - with(khttp.get(url)) { + with(get(url)) { getAndUnpack(this.text)?.let { unpackedText -> srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> return listOf( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt index 6ec2bec4..b9ca4a7c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt @@ -1,5 +1,7 @@ package com.lagradost.cloudstream3.extractors +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.text import com.lagradost.cloudstream3.utils.* class Mp4Upload : ExtractorApi() { @@ -9,7 +11,7 @@ class Mp4Upload : ExtractorApi() { override val requiresReferer = true override fun getUrl(url: String, referer: String?): List? { - with(khttp.get(url)) { + with(get(url)) { getAndUnpack(this.text)?.let { unpackedText -> srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> return listOf( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt index 19c14e93..0a5d13b2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt @@ -1,5 +1,8 @@ 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.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities @@ -28,12 +31,12 @@ class MultiQuality : ExtractorApi() { override fun getUrl(url: String, referer: String?): List? { val extractedLinksList: MutableList = mutableListOf() - with(khttp.get(url)) { + with(get(url)) { sourceRegex.findAll(this.text).forEach { sourceMatch -> val extractedUrl = sourceMatch.groupValues[1] // Trusting this isn't mp4, may fuck up stuff if (extractedUrl.endsWith(".m3u8")) { - with(khttp.get(extractedUrl)) { + with(get(extractedUrl)) { m3u8Regex.findAll(this.text).forEach { match -> extractedLinksList.add( ExtractorLink( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt index 37424d0f..4be15ae6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt @@ -1,5 +1,7 @@ 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.ExtractorLink import com.lagradost.cloudstream3.utils.getAndUnpack @@ -21,12 +23,12 @@ class StreamSB : ExtractorApi() { override fun getUrl(url: String, referer: String?): List { val extractedLinksList: MutableList = mutableListOf() 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 { sourceRegex.findAll(it).forEach { sourceMatch -> val extractedUrl = sourceMatch.groupValues[1] if (extractedUrl.contains(".m3u8")) { - with(khttp.get(extractedUrl)) { + with(get(extractedUrl)) { m3u8UrlRegex.findAll(this.text).forEach { match -> val extractedUrlM3u8 = match.groupValues[2] val extractedRes = match.groupValues[1] diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt index 49641cc4..b5581abb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt @@ -1,5 +1,7 @@ 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.ExtractorLink 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(|" \+ ')=.*)'""") override fun getUrl(url: String, referer: String?): List? { - with(khttp.get(url)) { + with(get(url)) { linkRegex.find(this.text)?.let { val extractedUrl = "https://streamtape.com/get_video?${it.groupValues[1]}".replace("""" + '""", "") return listOf( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Streamhub.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Streamhub.kt index 7d47278a..fba18ed3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Streamhub.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Streamhub.kt @@ -1,5 +1,7 @@ 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.ExtractorLink import com.lagradost.cloudstream3.utils.JsUnpacker @@ -18,8 +20,8 @@ class Streamhub : ExtractorApi() { } override fun getUrl(url: String, referer: String?): List? { - val response = khttp.get(url) - Regex("eval((.|\\n)*?)").find(response.text)?.groupValues?.get(1)?.let { jsEval -> + val response = get(url).text + Regex("eval((.|\\n)*?)").find(response)?.groupValues?.get(1)?.let { jsEval -> JsUnpacker("eval$jsEval" ).unpack()?.let { unPacked -> Regex("sources:\\[\\{src:\"(.*?)\"").find(unPacked)?.groupValues?.get(1)?.let { link -> return listOf( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt index b61705db..327b84e6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt @@ -1,6 +1,9 @@ package com.lagradost.cloudstream3.extractors 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.utils.ExtractorLink import com.lagradost.cloudstream3.utils.extractorApis @@ -38,7 +41,7 @@ class Vidstream(overrideMainUrl: String? = null) { /** Stolen from GogoanimeProvider.kt extractor */ normalSafeApiCall { 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 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 primaryLinks = document.select("ul.list-server-items > li.linkserver") //val extractedLinksList: MutableList = mutableListOf() diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt index 3c30fe65..587bb376 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.mapper +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.text class WcoStream : ExtractorApi() { override val name: String = "WcoStream" @@ -14,14 +16,14 @@ class WcoStream : ExtractorApi() { override fun getUrl(url: String, referer: String?): List { 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 (skey) = """skey\s=\s['"](.*?)['"];""".toRegex().find(html)!!.destructured val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey" 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( @JsonProperty("file") val file: String, diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/XStreamCdn.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/XStreamCdn.kt index a2545a1c..9a651811 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/XStreamCdn.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/XStreamCdn.kt @@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.extractors import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue 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.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities @@ -44,9 +46,10 @@ class XStreamCdn : ExtractorApi() { ) val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/") val extractedLinksList: MutableList = mutableListOf() - with(khttp.post(newUrl, headers = headers)) { - if (this.text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf() - mapper.readValue(this.text)?.let { + with(post(newUrl, headers = headers)) { + val text = this.text + if (text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf() + mapper.readValue(text)?.let { if (it.success && it.data != null) { it.data.forEach { data -> extractedLinksList.add( diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt index 7a1b7e6e..fcced01b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt @@ -2,9 +2,14 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.post +import com.lagradost.cloudstream3.network.text +import com.lagradost.cloudstream3.network.url import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.loadExtractor +import okio.Buffer import org.jsoup.Jsoup import org.jsoup.nodes.Document import java.lang.Thread.sleep @@ -33,8 +38,8 @@ class AllMoviesForYouProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/?s=$query" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val items = document.select("ul.MovieList > li > article > a") val returnValue = ArrayList() @@ -72,8 +77,8 @@ class AllMoviesForYouProvider : MainAPI() { override fun load(url: String): LoadResponse { val type = getType(url) - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val title = document.selectFirst("h1.Title").text() val descipt = document.selectFirst("div.Description > p").text() @@ -98,8 +103,8 @@ class AllMoviesForYouProvider : MainAPI() { val episodeList = ArrayList() for (season in list) { - val seasonResponse = khttp.get(season.second) - val seasonDocument = Jsoup.parse(seasonResponse.text) + val seasonResponse = get(season.second).text + val seasonDocument = Jsoup.parse(seasonResponse) val episodes = seasonDocument.select("table > tbody > tr") if (episodes.isNotEmpty()) { episodes.forEach { episode -> @@ -162,8 +167,8 @@ class AllMoviesForYouProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { if (data.startsWith("$mainUrl/episode/")) { - val response = khttp.get(data) - getLink(Jsoup.parse(response.text))?.let { links -> + val response = get(data).text + getLink(Jsoup.parse(response))?.let { links -> for (link in links) { if (link == data) continue loadLinks(link, isCasting, subtitleCallback, callback) @@ -174,9 +179,21 @@ class AllMoviesForYouProvider : MainAPI() { } else if (data.startsWith(mainUrl) && data != mainUrl) { val realDataUrl = URLDecoder.decode(data, "application/x-www-form-urlencoded") if (data.contains("trdownload")) { - val request = khttp.get(data, stream = true) + val request = get(data) 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") if (inputs.size < 4) return false 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 } 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 postDocument = Jsoup.parse(postResponse.text) + val postResponse = post( + request.url, + headers = mapOf( + "content-type" to "application/x-www-form-urlencoded", + "referer" to request.url, + "user-agent" to USER_AGENT, + "accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + ), + data = mapOf("op" to op, "id" to id, "mode" to mode, "hash" to hash) + ).text + val postDocument = Jsoup.parse(postResponse) val url = postDocument.selectFirst("a.downloadbtn").attr("href") - if(url.isNullOrEmpty()) return false + if (url.isNullOrEmpty()) return false callback(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value)) } else { callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value)) } return true } - val response = khttp.get(realDataUrl) - Regex(" + val response = get(realDataUrl).text + Regex(" loadExtractor(url.trimStart(), realDataUrl, callback) } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsiaFlixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsiaFlixProvider.kt index a36edec1..821f808d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsiaFlixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsiaFlixProvider.kt @@ -5,10 +5,11 @@ import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* 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.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName -import khttp.get class AsiaFlixProvider : MainAPI() { override val mainUrl: String diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt index fd9d8bd6..b0dff497 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt @@ -1,6 +1,8 @@ package com.lagradost.cloudstream3.movieproviders 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.Qualities import org.jsoup.Jsoup @@ -18,8 +20,8 @@ class HDMProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/search/$query" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val items = document.select("div.col-md-2 > article > a") if (items.isEmpty()) return ArrayList() val returnValue = ArrayList() @@ -42,8 +44,8 @@ class HDMProvider : MainAPI() { ): Boolean { if (data == "") return false val slug = ".*/(.*?)\\.mp4".toRegex().find(data)?.groupValues?.get(1) ?: return false - val response = khttp.get(data) - val key = "playlist\\.m3u8(.*?)\"".toRegex().find(response.text)?.groupValues?.get(1) ?: return false + val response = get(data).text + val key = "playlist\\.m3u8(.*?)\"".toRegex().find(response)?.groupValues?.get(1) ?: return false callback.invoke( ExtractorLink( this.name, @@ -58,14 +60,14 @@ class HDMProvider : MainAPI() { } override fun load(url: String): LoadResponse? { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val title = document.selectFirst("h2.movieTitle")?.text() ?: throw ErrorLoadingException("No Data Found") val poster = document.selectFirst("div.post-thumbnail > img").attr("src") 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() ?.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( title, url, this.name, TvType.Movie, diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt index fc7ae9b8..150d0e91 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt @@ -6,6 +6,8 @@ import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.unixTime import com.lagradost.cloudstream3.utils.ExtractorLink 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 org.jsoup.Jsoup @@ -71,12 +73,12 @@ class LookMovieProvider : MainAPI() { override fun quickSearch(query: String): List { val movieUrl = "$mainUrl/api/v1/movies/search/?q=$query" - val movieResponse = khttp.get(movieUrl) - val movies = mapper.readValue(movieResponse.text).result + val movieResponse = get(movieUrl).text + val movies = mapper.readValue(movieResponse).result val showsUrl = "$mainUrl/api/v1/shows/search/?q=$query" - val showsResponse = khttp.get(showsUrl) - val shows = mapper.readValue(showsResponse.text).result + val showsResponse = get(showsUrl).text + val shows = mapper.readValue(showsResponse).result val returnValue = ArrayList() if (!movies.isNullOrEmpty()) { @@ -117,8 +119,8 @@ class LookMovieProvider : MainAPI() { override fun search(query: String): List { fun search(query: String, isMovie: Boolean): ArrayList { val url = "$mainUrl/${if (isMovie) "movies" else "shows"}/search/?q=$query" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val items = document.select("div.flex-wrap-movielist > div.movie-item-style-1") val returnValue = ArrayList() @@ -161,8 +163,8 @@ class LookMovieProvider : MainAPI() { } private fun loadCurrentLinks(url: String, callback: (ExtractorLink) -> Unit) { - val response = khttp.get(url.replace("\$unixtime", unixTime.toString())) - M3u8Manifest.extractLinks(response.text).forEach { + val response = get(url.replace("\$unixtime", unixTime.toString())).text + M3u8Manifest.extractLinks(response).forEach { callback.invoke( ExtractorLink( this.name, @@ -185,24 +187,24 @@ class LookMovieProvider : MainAPI() { val localData: LookMovieLinkLoad = mapper.readValue(data) if (localData.isMovie) { - val tokenResponse = khttp.get(localData.url) - val root = mapper.readValue(tokenResponse.text) + val tokenResponse = get(localData.url).text + val root = mapper.readValue(tokenResponse) val accessToken = root.data?.accessToken ?: return false addSubtitles(root.data.subtitles, subtitleCallback) loadCurrentLinks(localData.extraUrl.replace("\$accessToken", accessToken), callback) return true } else { loadCurrentLinks(localData.url, callback) - val subResponse = khttp.get(localData.extraUrl) - val subs = mapper.readValue>(subResponse.text) + val subResponse = get(localData.extraUrl).text + val subs = mapper.readValue>(subResponse) addSubtitles(subs, subtitleCallback) } return true } override fun load(url: String): LoadResponse? { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val isMovie = url.contains("/movies/") 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) if (poster.isNullOrEmpty()) poster = imgElement?.attr("data-background-image") 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(" ", "") ?: return null val realSlug = url.replace("$mainUrl/${if (isMovie) "movies" else "shows"}/view/", "") @@ -243,12 +245,12 @@ class LookMovieProvider : MainAPI() { rating ) } else { - val tokenResponse = khttp.get(realUrl) - val root = mapper.readValue(tokenResponse.text) + val tokenResponse = get(realUrl).text + val root = mapper.readValue(tokenResponse) val accessToken = root.data?.accessToken ?: return null 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 // 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 diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt index ef7d3167..878830cb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt @@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue 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.getQualityFromName import org.jsoup.Jsoup @@ -38,8 +40,8 @@ class MeloMovieProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/movie/search/?name=$query" val returnValue: ArrayList = ArrayList() - val response = khttp.get(url) - val mapped = response.let { mapper.readValue>(it.text) } + val response = get(url).text + val mapped = response.let { mapper.readValue>(it) } if (mapped.isEmpty()) return returnValue for (i in mapped) { @@ -115,7 +117,7 @@ class MeloMovieProvider : MainAPI() { } override fun load(url: String): LoadResponse? { - val response = khttp.get(url).text + val response = get(url).text //backdrop = imgurl fun findUsingRegex(src: String): String? { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ThenosProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ThenosProvider.kt index d5c331aa..eb50654a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ThenosProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ThenosProvider.kt @@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue 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.getQualityFromName import java.util.concurrent.TimeUnit @@ -41,8 +43,8 @@ class ThenosProvider : MainAPI() { val list = ArrayList() map.entries.forEach { val url = "$apiUrl/library/${it.value}" - val response = khttp.get(url) - val mapped = mapper.readValue(response.text) + val response = get(url).text + val mapped = mapper.readValue(response) mapped.Metadata?.mapNotNull { meta -> meta?.toSearchResponse() @@ -209,8 +211,8 @@ class ThenosProvider : MainAPI() { } private fun searchFromUrl(url: String): List { - val response = khttp.get(url) - val test = mapper.readValue(response.text) + val response = get(url).text + val test = mapper.readValue(response) val returnValue = ArrayList() test.Hub?.forEach { @@ -255,12 +257,12 @@ class ThenosProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { val url = "$apiUrl/library/watch/$data" - val response = khttp.get(url) - val mapped = mapper.readValue(response.text) + val response = get(url).text + val mapped = mapper.readValue(response) mapped.sources?.forEach { source -> 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 = 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 { val episodes = ArrayList() val url = "$apiUrl/library/metadata/$id/children" - val response = khttp.get(url) - val mapped = mapper.readValue(response.text) + val response = get(url).text + val mapped = mapper.readValue(response) mapped.Metadata?.forEach { series_meta -> val fixedUrl = apiUrl + series_meta.key - val child = khttp.get(fixedUrl) - val mappedSeason = mapper.readValue(child.text) + val child = get(fixedUrl).text + val mappedSeason = mapper.readValue(child) mappedSeason.Metadata?.forEach mappedSeason@{ meta -> episodes.add( TvSeriesEpisode( @@ -450,8 +452,8 @@ class ThenosProvider : MainAPI() { override fun load(url: String): LoadResponse? { val fixedUrl = "$apiUrl/library/metadata/${url.split("/").last()}" - val response = khttp.get(fixedUrl) - val mapped = mapper.readValue(response.text) + val response = get(fixedUrl).text + val mapped = mapper.readValue(response) val isShow = mapped.Metadata?.any { it?.type == "show" } == true val metadata = mapped.Metadata?.getOrNull(0) ?: return null diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt index d90c5de9..3f10315c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt @@ -2,6 +2,8 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.text import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.SubtitleHelper @@ -33,8 +35,8 @@ class TrailersToProvider : MainAPI() { get() = VPNStatus.MightBeNeeded override fun getMainPage(): HomePageResponse? { - val response = khttp.get(mainUrl) - val document = Jsoup.parse(response.text) + val response = get(mainUrl).text + val document = Jsoup.parse(response) val returnList = ArrayList() val docs = document.select("section.section > div.container") for (doc in docs) { @@ -76,8 +78,8 @@ class TrailersToProvider : MainAPI() { override fun quickSearch(query: String): List { val url = "$mainUrl/en/quick-search?q=$query" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val items = document.select("div.group-post-minimal > a.post-minimal") if (items.isNullOrEmpty()) return ArrayList() @@ -104,8 +106,8 @@ class TrailersToProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/en/popular/movies-tvshows-collections?q=$query" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val items = document.select("div.col-lg-8 > article.list-item") if (items.isNullOrEmpty()) return ArrayList() val returnValue = ArrayList() @@ -133,8 +135,8 @@ class TrailersToProvider : MainAPI() { data: String, callback: (ExtractorLink) -> Unit, ): Boolean { - val response = khttp.get(data) - val url = " Unit) { if (url.isEmpty()) return - val response = khttp.get(fixUrl(url)) - val document = Jsoup.parse(response.text) + val response = get(fixUrl(url)).text + val document = Jsoup.parse(response) val items = document.select("div.list-group > a.list-group-item") for (item in items) { @@ -181,8 +183,8 @@ class TrailersToProvider : MainAPI() { return isSucc } else if (url.contains("/episode/")) { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) // val qSub = document.select("subtitle-content") val subUrl = document.select("subtitle-content")?.attr("data-url") ?: "" @@ -198,8 +200,8 @@ class TrailersToProvider : MainAPI() { } override fun load(url: String): LoadResponse { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) 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") diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt index 86222e1b..ce3a92e4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt @@ -3,6 +3,10 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.post +import com.lagradost.cloudstream3.network.text +import com.lagradost.cloudstream3.network.url import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import org.jsoup.Jsoup @@ -21,8 +25,8 @@ class VMoveeProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/?s=$query" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val searchItems = document.select("div.search-page > div.result-item > article") if (searchItems.size == 0) return ArrayList() val returnValue = ArrayList() @@ -75,24 +79,24 @@ class VMoveeProvider : MainAPI() { val url = "$mainUrl/dashboard/admin-ajax.php" val post = - khttp.post( + post( url, headers = mapOf("referer" to url), data = mapOf("action" to "doo_player_ajax", "post" to data, "nume" to "2", "type" to "movie") - ) + ).text - val ajax = mapper.readValue(post.text) + val ajax = mapper.readValue(post) var realUrl = ajax.embedUrl if (realUrl.startsWith("//")) { realUrl = "https:$realUrl" } - val request = khttp.get(realUrl) + val request = get(realUrl) val prefix = "https://reeoov.tube/v/" if (request.url.startsWith(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 apiData = mapper.readValue(apiResponse.text) + 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(apiResponse) for (d in apiData.data) { callback.invoke( ExtractorLink( @@ -111,8 +115,8 @@ class VMoveeProvider : MainAPI() { } override fun load(url: String): LoadResponse { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val sheader = document.selectFirst("div.sheader") diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt index 05f1c0d3..1034ad40 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt @@ -3,22 +3,37 @@ package com.lagradost.cloudstream3.movieproviders import org.jsoup.Jsoup import com.lagradost.cloudstream3.* 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.getQualityFromName import java.util.* import kotlin.collections.ArrayList - +/** Needs to inherit from MainAPI() to + * make the app know what functions to call + */ class VidEmbedProvider : MainAPI() { + // mainUrl is good to have as a holder for the url to make future changes easier. override val mainUrl: String 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 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 get() = false + + // If getMainPage() is functional, used to display the homepage in app, an optional, but highly encouraged endevour. override val hasMainPage: Boolean 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 { return if (url.startsWith("//")) { "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 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 { + // 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 html = khttp.get(link).text + val html = get(link).text val soup = Jsoup.parse(html) return ArrayList(soup.select(".listing.items > .video-block").map { li -> + // Selects the href in val href = fixUrl(li.selectFirst("a").attr("href")) 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() + // 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() TvSeriesSearchResponse( + // .trim() removes unwanted spaces in the start and end. if (!title.contains("Episode")) title else title.split("Episode")[0].trim(), href, this.name, TvType.TvSeries, poster, year, + // You can't get the episodes from the search bar. 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? { - val html = khttp.get(url).text + // Gets the url returned from searching. + val html = get(url).text val soup = Jsoup.parse(html) var title = soup.selectFirst("h1,h2,h3").text() @@ -89,8 +120,10 @@ class VidEmbedProvider : MainAPI() { epDate ) }.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 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? { val urls = listOf( mainUrl, @@ -136,10 +171,12 @@ class VidEmbedProvider : MainAPI() { "$mainUrl/cinema-movies" ) val homePageList = ArrayList() + // .pmap {} is used to fetch the different pages in parallel urls.pmap { url -> - val response = khttp.get(url, timeout = 20.0) - val document = Jsoup.parse(response.text) + val response = get(url, timeout = 20).text + val document = Jsoup.parse(response) 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 elements = it.select(".video-block").map { val link = fixUrl(it.select("a").attr("href")) @@ -182,13 +219,21 @@ class VidEmbedProvider : MainAPI() { 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( data: String, isCasting: Boolean, + // These callbacks are functions you should call when you get a link to a subtitle file or media file. subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): 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") // https://vidembed.cc/streaming.php?id=MzUwNTY2&... -> MzUwNTY2 val id = Regex("""id=([^&]*)""").find(iframeLink)?.groupValues?.get(1) @@ -197,7 +242,7 @@ class VidEmbedProvider : MainAPI() { vidstreamObject.getUrl(id, isCasting, callback) } - val html = khttp.get(fixUrl(iframeLink)).text + val html = get(fixUrl(iframeLink)).text val soup = Jsoup.parse(html) val servers = soup.select(".list-server-items > .linkserver").mapNotNull { li -> @@ -208,12 +253,16 @@ class VidEmbedProvider : MainAPI() { } } 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") { // 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 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 -> callback.invoke( ExtractorLink( @@ -221,8 +270,11 @@ class VidEmbedProvider : MainAPI() { match.groupValues.getOrNull(2)?.let { "${this.name} $it" } ?: this.name, match.groupValues[1], it.second, + // Useful function to turn something like "1080p" to an app quality. getQualityFromName(match.groupValues.getOrNull(2) ?: ""), // 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"), ) ) @@ -240,4 +292,4 @@ class VidEmbedProvider : MainAPI() { return true } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt b/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt new file mode 100644 index 00000000..bfc9496a --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt @@ -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 = mapOf() +private val DEFAULT_COOKIES: Map = 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 + 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): 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 { + 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, referer: String?, cookie: Map): 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 = mapOf(), + referer: String? = null, + params: Map = mapOf(), + cookies: Map = 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 = mapOf(), + referer: String? = null, + params: Map = mapOf(), + cookies: Map = mapOf(), + data: Map = 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, + referer: String?, + params: Map, + cookies: Map, + 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, + referer: String?, + params: Map, + cookies: Map, + data: Map, + 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() +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt index 03363f61..7057f964 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt @@ -1,6 +1,8 @@ package com.lagradost.cloudstream3.torrentproviders 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.Qualities import org.jsoup.Jsoup @@ -23,8 +25,8 @@ class NyaaProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/?f=0&c=0_0&q=$query&s=seeders&o=desc" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val returnValues = ArrayList() val elements = document.select("table > tbody > tr") @@ -43,8 +45,8 @@ class NyaaProvider : MainAPI() { } override fun load(url: String): LoadResponse { - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val title = document.selectFirst("h3.panel-title").text() val description = document.selectFirst("div#torrent-description").text() val downloadLinks = document.select("div.panel-footer > a") diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt index 880383e9..e2438dac 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt @@ -1,5 +1,7 @@ package com.lagradost.cloudstream3.utils +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.text import org.jsoup.Jsoup import java.util.* import kotlin.collections.HashMap @@ -16,8 +18,8 @@ object FillerEpisodeCheck { private fun getFillerList(): Boolean { if (list != null) return true try { - val result = khttp.get("$MAIN_URL/shows") - val documented = Jsoup.parse(result.text) + val result = get("$MAIN_URL/shows").text + val documented = Jsoup.parse(result) val localHTMLList = documented.select("div#ShowList > div.Group > ul > li > a") val localList = HashMap() for (i in localHTMLList) { @@ -71,8 +73,8 @@ object FillerEpisodeCheck { val realQuery = fixName(query.replace(blackListRegex, "")).replace("shippuuden", "shippuden") if (!localList.containsKey(realQuery)) return null val href = localList[realQuery]?.replace(MAIN_URL, "") ?: return null // JUST IN CASE - val result = khttp.get("$MAIN_URL$href") - val documented = Jsoup.parse(result.text) ?: return null + val result = get("$MAIN_URL$href").text + val documented = Jsoup.parse(result) ?: return null val hashMap = HashMap() documented.select("table.EpisodeList > tbody > tr").forEach { val type = it.selectFirst("td.Type > span").text() == "Filler" diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/HttpSession.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/HttpSession.kt index bb19a070..0836f3c5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/HttpSession.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/HttpSession.kt @@ -40,7 +40,7 @@ class HttpSession { allowRedirects: Boolean? = null, stream: Boolean = false, files: List = listOf(), ): Response { - val res = khttp.get( + val res = get( url, headers, params, data, json, auth, mergeCookies(sessionCookies, cookies), timeout, @@ -62,7 +62,7 @@ class HttpSession { allowRedirects: Boolean? = null, stream: Boolean = false, files: List = listOf() ): Response { - val res = khttp.post( + val res = post( url, headers, params, data, json, auth, mergeCookies(sessionCookies, cookies), timeout, diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt index 7261bf6e..6ab417a6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt @@ -23,6 +23,8 @@ import com.lagradost.cloudstream3.MainActivity.Companion.showToast import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.normalSafeApiCall +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.text import java.io.File import kotlin.concurrent.thread @@ -82,7 +84,7 @@ class InAppUpdater { val url = "https://api.github.com/repos/LagradOst/CloudStream-3/releases" val headers = mapOf("Accept" to "application/vnd.github.v3+json") val response = - mapper.readValue>(khttp.get(url, headers = headers).text) + mapper.readValue>(get(url, headers = headers).text) val versionRegex = Regex("""(.*?((\d+)\.(\d+)\.(\d+))\.apk)""") val versionRegexLocal = Regex("""(.*?((\d+)\.(\d+)\.(\d+)).*)""") @@ -138,7 +140,7 @@ class InAppUpdater { val releaseUrl = "https://api.github.com/repos/LagradOst/CloudStream-3/releases" val headers = mapOf("Accept" to "application/vnd.github.v3+json") val response = - mapper.readValue>(khttp.get(releaseUrl, headers = headers).text) + mapper.readValue>(get(releaseUrl, headers = headers).text) val found = response.lastOrNull { rel -> @@ -147,7 +149,7 @@ class InAppUpdater { val foundAsset = found?.assets?.getOrNull(0) val tagResponse = - mapper.readValue(khttp.get(tagUrl, headers = headers).text) + mapper.readValue(get(tagUrl, headers = headers).text) val shouldUpdate = (getString(R.string.prerelease_commit_hash) != tagResponse.github_object.sha) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt index 310ad54f..8d9ff2de 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt @@ -1,6 +1,8 @@ package com.lagradost.cloudstream3.utils 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.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec @@ -79,9 +81,9 @@ class M3u8Helper { fun m3u8Generation(m3u8: M3u8Stream): List { val generate = sequence { 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 if (m3u8Link.isNullOrEmpty()) m3u8Link = m3u8Link2 if (absoluteExtensionDetermination(m3u8Link) == "m3u8") { @@ -134,18 +136,17 @@ class M3u8Helper { val secondSelection = selectBest(streams.ifEmpty { listOf(selected) }) if (secondSelection != null) { - val m3u8Response = khttp.get(secondSelection.streamUrl, headers = headers) - val m3u8Data = m3u8Response.text + val m3u8Response = get(secondSelection.streamUrl, headers = headers).text var encryptionUri: String? = null var encryptionIv = byteArrayOf() var encryptionData = byteArrayOf() - val encryptionState = isEncrypted(m3u8Data) + val encryptionState = isEncrypted(m3u8Response) if (encryptionState) { 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() if (isNotCompleteUrl(encryptionUri)) { @@ -153,11 +154,11 @@ class M3u8Helper { } encryptionIv = match.component3().toByteArray() - val encryptionKeyResponse = khttp.get(encryptionUri, headers = headers) - encryptionData = encryptionKeyResponse.content + val encryptionKeyResponse = get(encryptionUri, headers = headers) + encryptionData = encryptionKeyResponse.body?.bytes() ?: byteArrayOf() } - val allTs = TS_EXTENSION_REGEX.findAll(m3u8Data) + val allTs = TS_EXTENSION_REGEX.findAll(m3u8Response) val allTsList = allTs.toList() val totalTs = allTsList.size if (totalTs == 0) { @@ -176,8 +177,8 @@ class M3u8Helper { while (lastYield != c) { try { - val tsResponse = khttp.get(url, headers = headers) - var tsData = tsResponse.content + val tsResponse = get(url, headers = headers) + var tsData = tsResponse.body?.bytes() ?: byteArrayOf() if (encryptionState) { tsData = getDecrypter(encryptionData, tsData, encryptionIv) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt index ad462b8b..c63761a9 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt @@ -1,5 +1,7 @@ package com.lagradost.cloudstream3.utils +import com.lagradost.cloudstream3.network.get +import com.lagradost.cloudstream3.network.text import org.jsoup.Jsoup import java.util.* @@ -16,8 +18,8 @@ object SubtitleHelper { fun createISO() { val url = "https://infogalactic.com/info/List_of_ISO_639-1_codes" - val response = khttp.get(url) - val document = Jsoup.parse(response.text) + val response = get(url).text + val document = Jsoup.parse(response) val headers = document.select("table.wikitable > tbody > tr") var text = "listOf(\n"