From 9c25b32470d822f91a5f39078ccd34e884b03eaa Mon Sep 17 00:00:00 2001 From: Arjix <53124886+ArjixWasTaken@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:58:31 +0300 Subject: [PATCH 1/8] Create WcoProvider.kt --- .../animeproviders/WcoProvider.kt | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt new file mode 100644 index 00000000..7ca0938b --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -0,0 +1,214 @@ +package com.lagradost.cloudstream3.animeproviders + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.extractors.Vidstream +import com.lagradost.cloudstream3.utils.extractors.WcoStream +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import java.util.* +import kotlin.collections.ArrayList + + +class WcoProvider : MainAPI() { + + companion object { + fun getType(t: String): TvType { + return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + else if (t.contains("Movie")) TvType.Movie + else TvType.Anime + } + } + + override val mainUrl: String + get() = "https://wcostream.cc" + override val name: String + get() = "WCO Stream" + override val hasQuickSearch: Boolean + get() = true + + + private fun getSlug(href: String): String { + return href.replace("$mainUrl/anime/", "").replace("/", "") + } + + private fun fixAnimeLink(url: String): String { + val regex = "watch/([a-zA-Z\\-0-9]*)-episode".toRegex() + val (aniId) = regex.find(url)!!.destructured + return "$mainUrl/anime/$aniId" + } + + private fun parseSearchPage(soup: Document): ArrayList { + val items = soup.select(".film_list-wrap > .flw-item") + if (items.isEmpty()) return ArrayList() + val returnValue = ArrayList() + for (i in items) { + val href = fixAnimeLink(i.selectFirst("a").attr("href")) + val img = fixUrl(i.selectFirst("img").attr("data-src")) + val title = i.selectFirst("img").attr("title") + val isDub = !i.select(".pick.film-poster-quality").isEmpty() + val year = i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(1)").text().toIntOrNull() + val type = i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text() + + returnValue.add( + if (getType(type) == TvType.Movie) { + MovieSearchResponse( + title, href, getSlug(href), this.name, TvType.Movie, img, year + ) + } else { + AnimeSearchResponse( + title, + href, + getSlug(href), + this.name, + TvType.Anime, + img, + year, + null, + EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed), + null, + null + ) + } + ) + } + return returnValue + } + + override fun search(query: String): ArrayList { + val url = "$mainUrl/search" + val response = khttp.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 != null && !link.isEmpty()) { + val extraResponse = khttp.get(fixUrl(link[0].attr("href"))) + document = Jsoup.parse(extraResponse.text) + returnValue.addAll(parseSearchPage(document)) + } else { + break + } + } + return returnValue + } + + override fun quickSearch(query: String): ArrayList { + val returnValue: ArrayList = ArrayList() + + val response = khttp.post( + "https://wcostream.cc/ajax/search", + data=mapOf("keyword" to query) + ).jsonObject.getString("html") // I won't make a dataclass for this shit + val document = Jsoup.parse(response) + + document.select("a.nav-item").forEach { + val title = it.selectFirst("img")?.attr("title").toString() + val img = it?.selectFirst("img")?.attr("src") + val href = it?.attr("href").toString() + val isDub = title.contains("(Dub)") + val filmInfo = it?.selectFirst(".film-infor") + val year = filmInfo?.select("span")?.get(0)?.text()?.toIntOrNull() + val type = filmInfo?.select("span")?.get(1)?.text().toString() + if (title != "null") { + returnValue.add( + if (getType(type) == TvType.Movie) { + MovieSearchResponse( + title, href, getSlug(href), this.name, TvType.Movie, img, year + ) + } else { + AnimeSearchResponse( + title, + href, + getSlug(href), + this.name, + TvType.Anime, + img, + year, + null, + EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed), + null, + null + ) + } + ) + } + } + return returnValue + } + + override fun load(slug: String): LoadResponse? { + val url = "$mainUrl/anime/${slug}" + + val response = khttp.get(url, timeout = 120.0) + val document = Jsoup.parse(response.text) + + val japaneseTitle = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(1)") + ?.text()?.trim()?.replace("Other names:", "")?.trim() + + val canonicalTitle = document.selectFirst("meta[name=\"title\"]") + ?.attr("content")?.split("| W")?.get(0).toString() + + val isDubbed = canonicalTitle.contains("Dub") + val episodeNodes = document.select(".tab-content .nav-item > a") + + val episodes = ArrayList(episodeNodes?.map { + AnimeEpisode(it.attr("href")) + } + ?: ArrayList()) + val statusElem = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(2)") + val status = when (statusElem?.text()?.replace("Status:", "")?.trim()) { + "Ongoing" -> ShowStatus.Ongoing + "Completed" -> ShowStatus.Completed + else -> null + } + val yearText = document.selectFirst("div.elements div.row > div:nth-child(2) > div.row-line:nth-child(4)")?.text() + val year = yearText?.replace("Date release:", "")?.trim()?.split("-")?.get(0)?.toIntOrNull() + + val poster = document.selectFirst(".film-poster-img")?.attr("src") + val type = document.selectFirst("span.item.mr-1 > a")?.text()?.trim() + + val synopsis = document.selectFirst(".description > p")?.text()?.trim() + val genre = document.select("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(5) > a").map { it?.text()?.trim().toString() } + + return AnimeLoadResponse( + canonicalTitle, + japaneseTitle, + canonicalTitle, + "$mainUrl/anime/${slug}", + this.name, + WcoProvider.getType(type ?: ""), + poster, + year, + null, + episodes, + status, + synopsis, + ArrayList(genre), + ArrayList(), + ) + } + + override fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val response = khttp.get(data) + val servers = Jsoup.parse(response.text).select("#servers-list > ul > li").map { + mapOf( + "link" to it?.selectFirst("a")?.attr("data-embed"), + "title" to it?.selectFirst("span")?.text()?.trim() + ) + } + + for (server in servers) { + WcoStream().getUrl(server["link"].toString(), "").forEach { + callback.invoke(it) + } + } + return true + } +} From 61f8068830a80ef2c1afbb286b1dffef5ceccf3d Mon Sep 17 00:00:00 2001 From: Arjix <53124886+ArjixWasTaken@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:58:53 +0300 Subject: [PATCH 2/8] Update MainAPI.kt --- app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 3adcdc02..5493c217 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -8,6 +8,7 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule import com.lagradost.cloudstream3.animeproviders.DubbedAnimeProvider import com.lagradost.cloudstream3.animeproviders.ShiroProvider import com.lagradost.cloudstream3.animeproviders.TenshiProvider +import com.lagradost.cloudstream3.animeproviders.WcoProvider import com.lagradost.cloudstream3.movieproviders.HDMProvider import com.lagradost.cloudstream3.movieproviders.LookMovieProvider import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider @@ -33,6 +34,7 @@ object APIHolder { val apis = arrayListOf( ShiroProvider(), TenshiProvider(), + WcoProvider(), MeloMovieProvider(), DubbedAnimeProvider(), HDMProvider(), From d3a0ef2c34c456cd5f7946c382dbda8ed6186939 Mon Sep 17 00:00:00 2001 From: Arjix <53124886+ArjixWasTaken@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:59:41 +0300 Subject: [PATCH 3/8] Update ExtractorApi.kt --- .../java/com/lagradost/cloudstream3/utils/ExtractorApi.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index e388c97e..7b83b964 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -3,6 +3,7 @@ package com.lagradost.cloudstream3.utils import com.lagradost.cloudstream3.utils.extractors.MixDrop import com.lagradost.cloudstream3.utils.extractors.Mp4Upload import com.lagradost.cloudstream3.utils.extractors.Shiro +import com.lagradost.cloudstream3.utils.extractors.WcoStream import com.lagradost.cloudstream3.utils.extractors.StreamTape import com.lagradost.cloudstream3.utils.extractors.XStreamCdn @@ -54,6 +55,7 @@ fun getAndUnpack(string: String): String? { val extractorApis: Array = arrayOf( //AllProvider(), Shiro(), + WcoStream(), Mp4Upload(), StreamTape(), MixDrop(), @@ -85,4 +87,4 @@ abstract class ExtractorApi { open fun getExtractorUrl(id: String): String { return id } -} \ No newline at end of file +} From 640637804bd6f45123e9ae9ea339ff4ab2cbf1d6 Mon Sep 17 00:00:00 2001 From: Arjix <53124886+ArjixWasTaken@users.noreply.github.com> Date: Fri, 23 Jul 2021 15:00:07 +0300 Subject: [PATCH 4/8] Create WcoStream.kt --- .../utils/extractors/WcoStream.kt | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt new file mode 100644 index 00000000..7a5fea9a --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt @@ -0,0 +1,62 @@ +package com.lagradost.cloudstream3.utils.extractors + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.module.kotlin.readValue +import com.lagradost.cloudstream3.utils.* +import com.lagradost.cloudstream3.mapper + +class WcoStream : ExtractorApi() { + override val name: String = "WcoStream" + override val mainUrl: String = "https://vidstreame.pro" + override val requiresReferer = false + + override fun getUrl(url: String, referer: String?): List { + try { + val baseUrl = url.split("/e/")[0] + + val html = khttp.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 + + data class Sources ( + @JsonProperty("file") val file : String, + @JsonProperty("label") val label : String + ) + + data class Media ( + @JsonProperty("sources") val sources : List + ) + + data class WcoResponse ( + @JsonProperty("success") val success : Boolean, + @JsonProperty("media") val media : Media + ) + + val mapped = response.let { mapper.readValue(it) } + val sources = mutableListOf() + + if (mapped.success) { + mapped.media.sources.forEach { + sources.add( + ExtractorLink( + "WcoStream", + "WcoStream" + "- ${it.label}", + it.file, + "", + Qualities.HD.value, + it.file.contains(".m3u8") + ) + ) + } + } + return sources + } catch (e: Exception) { + return listOf() + } + } +} From 7c1f46740b50302585e3a6a9f92310044665ddda Mon Sep 17 00:00:00 2001 From: Arjix <53124886+ArjixWasTaken@users.noreply.github.com> Date: Fri, 23 Jul 2021 15:10:50 +0300 Subject: [PATCH 5/8] Update WcoStream.kt --- .../com/lagradost/cloudstream3/utils/extractors/WcoStream.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt index 7a5fea9a..85321793 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt @@ -7,7 +7,7 @@ import com.lagradost.cloudstream3.mapper class WcoStream : ExtractorApi() { override val name: String = "WcoStream" - override val mainUrl: String = "https://vidstreame.pro" + override val mainUrl: String = "https://vidstream.pro" override val requiresReferer = false override fun getUrl(url: String, referer: String?): List { From 73adb9894d96e0c2dfaca368d2632fbc49091735 Mon Sep 17 00:00:00 2001 From: Arjix <53124886+ArjixWasTaken@users.noreply.github.com> Date: Fri, 23 Jul 2021 15:13:33 +0300 Subject: [PATCH 6/8] Update WcoProvider.kt --- .../com/lagradost/cloudstream3/animeproviders/WcoProvider.kt | 1 - 1 file changed, 1 deletion(-) 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 7ca0938b..ead475ba 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -2,7 +2,6 @@ package com.lagradost.cloudstream3.animeproviders import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.extractors.Vidstream import com.lagradost.cloudstream3.utils.extractors.WcoStream import org.jsoup.Jsoup import org.jsoup.nodes.Document From be714a9a26e6f975685e261814c2a5086380657e Mon Sep 17 00:00:00 2001 From: Arjix <53124886+ArjixWasTaken@users.noreply.github.com> Date: Fri, 23 Jul 2021 15:15:04 +0300 Subject: [PATCH 7/8] Update WcoProvider.kt --- .../com/lagradost/cloudstream3/animeproviders/WcoProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ead475ba..f8b886af 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -82,7 +82,7 @@ class WcoProvider : MainAPI() { while (!document.select(".pagination").isEmpty()) { val link = document.select("a.page-link[rel=\"next\"]") - if (link != null && !link.isEmpty()) { + if (!link.isEmpty()) { val extraResponse = khttp.get(fixUrl(link[0].attr("href"))) document = Jsoup.parse(extraResponse.text) returnValue.addAll(parseSearchPage(document)) From 3551cb1c67117a2bfb030fa48ea01cc9e351b036 Mon Sep 17 00:00:00 2001 From: LagradOst Date: Fri, 23 Jul 2021 18:41:37 +0200 Subject: [PATCH 8/8] fuck git --- .idea/.gitignore | 3 - .idea/gradle.xml | 2 +- .idea/jarRepositories.xml | 8 +- .idea/misc.xml | 8 +- .idea/uiDesigner.xml | 124 ------------------ .idea/vcs.xml | 2 +- .../animeproviders/TenshiProvider.kt | 28 ++-- .../animeproviders/WcoProvider.kt | 11 +- .../cloudstream3/utils/ExtractorApi.kt | 18 ++- .../cloudstream3/utils/extractors/MixDrop.kt | 28 ++-- .../utils/extractors/Mp4Upload.kt | 28 ++-- .../utils/extractors/MultiQuality.kt | 66 +++++----- .../cloudstream3/utils/extractors/StreamSB.kt | 51 +++++++ .../utils/extractors/StreamTape.kt | 25 ++-- .../utils/extractors/Vidstream.kt | 4 +- .../utils/extractors/WcoStream.kt | 68 +++++----- .../utils/extractors/XStreamCdn.kt | 43 +++--- 17 files changed, 203 insertions(+), 314 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/uiDesigner.xml create mode 100644 app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamSB.kt diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 33b144a8..1b86bb06 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,11 +1,11 @@ - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 6199cc2a..4bc4fc6e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,9 +1,5 @@ - - - - - + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml deleted file mode 100644 index e96534fb..00000000 --- a/.idea/uiDesigner.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7f..35eb1ddf 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file 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 6c5cfc6e..fac2ba92 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt @@ -1,31 +1,24 @@ package com.lagradost.cloudstream3.animeproviders 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.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.extractors.Vidstream import com.lagradost.cloudstream3.utils.getQualityFromName +import khttp.structures.cookie.CookieJar import org.jsoup.Jsoup import org.jsoup.nodes.Document -import java.util.* -import kotlin.collections.ArrayList -import khttp.structures.cookie.CookieJar import java.text.SimpleDateFormat - - +import java.util.* class TenshiProvider : MainAPI() { - companion object { var token: String? = null var cookie: CookieJar? = null fun getType(t: String): TvType { - if (t.contains("OVA") || t.contains("Special")) return TvType.ONA - else if (t.contains("Movie")) return TvType.Movie - else return TvType.Anime + return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + else if (t.contains("Movie")) TvType.Movie + else TvType.Anime } } @@ -43,9 +36,7 @@ class TenshiProvider : MainAPI() { private fun loadToken(): Boolean { return try { - val response = khttp.get( - "https://tenshi.moe/", - ) + val response = khttp.get(mainUrl) cookie = response.cookies val document = Jsoup.parse(response.text) token = document.selectFirst("""meta[name="csrf-token"]""").attr("content") @@ -179,7 +170,7 @@ class TenshiProvider : MainAPI() { return returnValue } - override fun load(slug: String): LoadResponse? { + override fun load(slug: String): LoadResponse { val url = "$mainUrl/anime/${slug}" val response = khttp.get(url, timeout = 120.0, cookies=mapOf("loop-view" to "thumb")) @@ -189,7 +180,6 @@ class TenshiProvider : MainAPI() { val japaneseTitle = document.selectFirst("span.value > span[title=\"Japanese\"]")?.parent()?.text()?.trim() val canonicalTitle = document.selectFirst("header.entry-header > h1.mb-3").text().trim() - val isDubbed = false val episodeNodes = document.select("li[class*=\"episode\"] > a") val episodes = ArrayList(episodeNodes?.map { @@ -212,7 +202,7 @@ class TenshiProvider : MainAPI() { val (year) = pattern.find(yearText)!!.destructured val poster = document.selectFirst("img.cover-image")?.attr("src") - val type = document.selectFirst("a[href*=\"https://tenshi.moe/type/\"]")?.text()?.trim() + val type = document.selectFirst("a[href*=\"$mainUrl/type/\"]")?.text()?.trim() val synopsis = document.selectFirst(".entry-description > .card-body")?.text()?.trim() val genre = document.select("li.genre.meta-data > span.value").map { it?.text()?.trim().toString() } @@ -232,7 +222,7 @@ class TenshiProvider : MainAPI() { episodes, status, synopsis, - ArrayList(genre) ?: ArrayList(), + ArrayList(genre), ArrayList(synonyms), null, null, 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 f8b886af..5fd1022c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -10,7 +10,6 @@ import kotlin.collections.ArrayList class WcoProvider : MainAPI() { - companion object { fun getType(t: String): TvType { return if (t.contains("OVA") || t.contains("Special")) TvType.ONA @@ -137,7 +136,7 @@ class WcoProvider : MainAPI() { return returnValue } - override fun load(slug: String): LoadResponse? { + override fun load(slug: String): LoadResponse { val url = "$mainUrl/anime/${slug}" val response = khttp.get(url, timeout = 120.0) @@ -177,11 +176,11 @@ class WcoProvider : MainAPI() { canonicalTitle, "$mainUrl/anime/${slug}", this.name, - WcoProvider.getType(type ?: ""), + getType(type ?: ""), poster, year, - null, - episodes, + if(isDubbed) episodes else null, + if(!isDubbed) episodes else null, status, synopsis, ArrayList(genre), @@ -204,7 +203,7 @@ class WcoProvider : MainAPI() { } for (server in servers) { - WcoStream().getUrl(server["link"].toString(), "").forEach { + WcoStream().getSafeUrl(server["link"].toString(), "")?.forEach { callback.invoke(it) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 7b83b964..f6a7955b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -1,11 +1,7 @@ package com.lagradost.cloudstream3.utils -import com.lagradost.cloudstream3.utils.extractors.MixDrop -import com.lagradost.cloudstream3.utils.extractors.Mp4Upload -import com.lagradost.cloudstream3.utils.extractors.Shiro -import com.lagradost.cloudstream3.utils.extractors.WcoStream -import com.lagradost.cloudstream3.utils.extractors.StreamTape -import com.lagradost.cloudstream3.utils.extractors.XStreamCdn +import com.lagradost.cloudstream3.mvvm.normalSafeApiCall +import com.lagradost.cloudstream3.utils.extractors.* data class ExtractorLink( val source: String, @@ -59,7 +55,8 @@ val extractorApis: Array = arrayOf( Mp4Upload(), StreamTape(), MixDrop(), - XStreamCdn() + XStreamCdn(), + StreamSB(), ) fun getExtractorApiFromName(name: String): ExtractorApi { @@ -82,6 +79,13 @@ abstract class ExtractorApi { abstract val mainUrl: String abstract val requiresReferer: Boolean + fun getSafeUrl(url: String, referer: String? = null): List? { + return normalSafeApiCall { getUrl(url, referer) } + } + + /** + * Will throw errors, use getSafeUrl if you don't want to handle the exception yourself + */ abstract fun getUrl(url: String, referer: String? = null): List? open fun getExtractorUrl(id: String): String { diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MixDrop.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MixDrop.kt index b3e2aa7d..f506645d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MixDrop.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MixDrop.kt @@ -13,25 +13,21 @@ class MixDrop : ExtractorApi() { } override fun getUrl(url: String, referer: String?): List? { - try { - with(khttp.get(url)) { - getAndUnpack(this.text)?.let { unpackedText -> - srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> - return listOf( - ExtractorLink( - name, - name, - httpsify(link), - url, - Qualities.Unknown.value, - ) + with(khttp.get(url)) { + getAndUnpack(this.text)?.let { unpackedText -> + srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> + return listOf( + ExtractorLink( + name, + name, + httpsify(link), + url, + Qualities.Unknown.value, ) - } + ) } } - return null - } catch (e: Exception) { - return null } + return null } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Mp4Upload.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Mp4Upload.kt index 188e9735..e8166583 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Mp4Upload.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Mp4Upload.kt @@ -9,25 +9,21 @@ class Mp4Upload : ExtractorApi() { override val requiresReferer = true override fun getUrl(url: String, referer: String?): List? { - try { - with(khttp.get(url)) { - getAndUnpack(this.text)?.let { unpackedText -> - srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> - return listOf( - ExtractorLink( - name, - name, - link, - url, - Qualities.Unknown.value, - ) + with(khttp.get(url)) { + getAndUnpack(this.text)?.let { unpackedText -> + srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> + return listOf( + ExtractorLink( + name, + name, + link, + url, + Qualities.Unknown.value, ) - } + ) } } - return null - } catch (e: Exception) { - return null } + return null } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MultiQuality.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MultiQuality.kt index df668356..2450c1e2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MultiQuality.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/MultiQuality.kt @@ -27,44 +27,40 @@ class MultiQuality : ExtractorApi() { } override fun getUrl(url: String, referer: String?): List? { - try { - val extractedLinksList: MutableList = mutableListOf() - with(khttp.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)) { - m3u8Regex.findAll(this.text).forEach { match -> - extractedLinksList.add( - ExtractorLink( - name, - "$name ${match.groupValues[1]}p", - urlRegex.find(this.url)!!.groupValues[1] + match.groupValues[0], - url, - getQuality(match.groupValues[1]), - isM3u8 = true - ) + val extractedLinksList: MutableList = mutableListOf() + with(khttp.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)) { + m3u8Regex.findAll(this.text).forEach { match -> + extractedLinksList.add( + ExtractorLink( + name, + "$name ${match.groupValues[1]}p", + urlRegex.find(this.url)!!.groupValues[1] + match.groupValues[0], + url, + getQuality(match.groupValues[1]), + isM3u8 = true ) - } - - } - } else if (extractedUrl.endsWith(".mp4")) { - extractedLinksList.add( - ExtractorLink( - name, - "$name ${sourceMatch.groupValues[2]}", - extractedUrl, - url.replace(" ", "%20"), - Qualities.Unknown.value, ) - ) - } - } - return extractedLinksList - } - } catch (e: Exception) { + } + } + } else if (extractedUrl.endsWith(".mp4")) { + extractedLinksList.add( + ExtractorLink( + name, + "$name ${sourceMatch.groupValues[2]}", + extractedUrl, + url.replace(" ", "%20"), + Qualities.Unknown.value, + ) + ) + } + } + return extractedLinksList } return null } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamSB.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamSB.kt new file mode 100644 index 00000000..388c04c4 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamSB.kt @@ -0,0 +1,51 @@ +package com.lagradost.cloudstream3.utils.extractors + +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.getAndUnpack +import com.lagradost.cloudstream3.utils.getQualityFromName + +class StreamSB : ExtractorApi() { + override val name: String = "StreamSB" + override val mainUrl: String = "https://sbplay.org" + private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*"(.*?)"""") + + //private val m3u8Regex = Regex(""".*?(\d*).m3u8""") + //private val urlRegex = Regex("""(.*?)([^/]+$)""") + + // 1: Resolution 2: url + private val m3u8UrlRegex = Regex("""RESOLUTION=\d*x(\d*).*\n(http.*.m3u8)""") + override val requiresReferer = false + + // https://sbembed.com/embed-ns50b0cukf9j.html -> https://sbvideo.net/play/ns50b0cukf9j + 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)) { + getAndUnpack(this.text)?.let { + sourceRegex.findAll(it).forEach { sourceMatch -> + val extractedUrl = sourceMatch.groupValues[1] + if (extractedUrl.contains(".m3u8")) { + with(khttp.get(extractedUrl)) { + m3u8UrlRegex.findAll(this.text).forEach { match -> + val extractedUrlM3u8 = match.groupValues[2] + val extractedRes = match.groupValues[1] + extractedLinksList.add( + ExtractorLink( + name, + "$name ${extractedRes}p", + extractedUrlM3u8, + extractedUrl, + getQualityFromName(extractedRes), + true + ) + ) + } + } + } + } + } + } + return extractedLinksList + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamTape.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamTape.kt index b8661f03..aefc067d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamTape.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/StreamTape.kt @@ -14,22 +14,19 @@ 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? { - try { - with(khttp.get(url)) { - linkRegex.find(this.text)?.let { - val extractedUrl = "https://streamtape.com/get_video?${it.groupValues[1]}".replace("""" + '""", "") - return listOf( - ExtractorLink( - name, - name, - extractedUrl, - url, - Qualities.Unknown.value, - ) + with(khttp.get(url)) { + linkRegex.find(this.text)?.let { + val extractedUrl = "https://streamtape.com/get_video?${it.groupValues[1]}".replace("""" + '""", "") + return listOf( + ExtractorLink( + name, + name, + extractedUrl, + url, + Qualities.Unknown.value, ) - } + ) } - } catch (e: Exception) { } return null } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt index 72ae464b..e89a62fa 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt @@ -20,7 +20,7 @@ class Vidstream { try { normalApis.pmap { api -> val url = api.getExtractorUrl(id) - val source = api.getUrl(url) + val source = api.getSafeUrl(url) source?.forEach { callback.invoke(it) } } @@ -38,7 +38,7 @@ class Vidstream { // Matches vidstream links with extractors extractorApis.filter { !it.requiresReferer || !isCasting }.pmap { api -> if (link.startsWith(api.mainUrl)) { - val extractedLinks = api.getUrl(link, url) + val extractedLinks = api.getSafeUrl(link, url) if (extractedLinks?.isNotEmpty() == true) { extractedLinks.forEach { callback.invoke(it) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt index 85321793..a124aede 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/WcoStream.kt @@ -11,52 +11,48 @@ class WcoStream : ExtractorApi() { override val requiresReferer = false override fun getUrl(url: String, referer: String?): List { - try { - 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 (Id) = "/e/(.*?)?domain".toRegex().find(url)!!.destructured - val (skey) = """skey\s=\s['\"](.*?)['\"];""".toRegex().find(html)!!.destructured + val html = khttp.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 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 = khttp.get(apiLink, headers = mapOf("Referer" to referrer)).text - data class Sources ( - @JsonProperty("file") val file : String, - @JsonProperty("label") val label : String - ) + data class Sources( + @JsonProperty("file") val file: String, + @JsonProperty("label") val label: String? + ) - data class Media ( - @JsonProperty("sources") val sources : List - ) + data class Media( + @JsonProperty("sources") val sources: List + ) - data class WcoResponse ( - @JsonProperty("success") val success : Boolean, - @JsonProperty("media") val media : Media - ) + data class WcoResponse( + @JsonProperty("success") val success: Boolean, + @JsonProperty("media") val media: Media + ) - val mapped = response.let { mapper.readValue(it) } - val sources = mutableListOf() + val mapped = response.let { mapper.readValue(it) } + val sources = mutableListOf() - if (mapped.success) { - mapped.media.sources.forEach { - sources.add( - ExtractorLink( - "WcoStream", - "WcoStream" + "- ${it.label}", - it.file, - "", - Qualities.HD.value, - it.file.contains(".m3u8") - ) + if (mapped.success) { + mapped.media.sources.forEach { + sources.add( + ExtractorLink( + name, + name + if (it.label != null) "- ${it.label}" else "", + it.file, + "", + Qualities.HD.value, + it.file.contains(".m3u8") ) - } + ) } - return sources - } catch (e: Exception) { - return listOf() } + return sources } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/XStreamCdn.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/XStreamCdn.kt index 6edf65dd..b30d9179 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/XStreamCdn.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/XStreamCdn.kt @@ -38,34 +38,29 @@ class XStreamCdn : ExtractorApi() { } override fun getUrl(url: String, referer: String?): List? { - try { - val headers = mapOf( - "Referer" to url, - "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0", - ) - val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/") - val extractedLinksList: MutableList = mutableListOf() - with(khttp.post(newUrl, headers = headers)) { - mapper.readValue(this.text)?.let { - if (it.success && it.data != null) { - it.data.forEach { data -> - extractedLinksList.add( - ExtractorLink( - name, - "$name ${data.label}", - data.file, - url, - getQuality(data.label), - ) + val headers = mapOf( + "Referer" to url, + "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0", + ) + val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/") + val extractedLinksList: MutableList = mutableListOf() + with(khttp.post(newUrl, headers = headers)) { + mapper.readValue(this.text)?.let { + if (it.success && it.data != null) { + it.data.forEach { data -> + extractedLinksList.add( + ExtractorLink( + name, + "$name ${data.label}", + data.file, + url, + getQuality(data.label), ) - } + ) } } } - return extractedLinksList - } catch (e: Exception) { } - return null + return extractedLinksList } - } \ No newline at end of file