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/7] 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/7] 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/7] 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/7] 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/7] 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/7] 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/7] 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))