From 81adb6eb95d5ead7736d4fbc070ce02831f36f51 Mon Sep 17 00:00:00 2001 From: Jace <54625750+Jacekun@users.noreply.github.com> Date: Mon, 3 Jan 2022 08:57:36 +0800 Subject: [PATCH] [Provider] DramaSee (#385) * add dramasee provider --- .../com/lagradost/cloudstream3/MainAPI.kt | 7 + .../movieproviders/DramaSeeProvider.kt | 216 ++++++++++++++++++ .../movieproviders/PinoyHDXyzProvider.kt | 5 +- .../movieproviders/PinoyMoviePediaProvider.kt | 8 +- .../movieproviders/PinoyMoviesEsProvider.kt | 2 +- 5 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 7deaddef..f4da4231 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -66,6 +66,7 @@ object APIHolder { PinoyHDXyzProvider(), PinoyMoviesEsProvider(), TrailersTwoProvider(), + DramaSeeProvider() ) val restrictedApis = arrayListOf( @@ -272,6 +273,9 @@ fun parseRating(ratingString: String?): Int? { } fun MainAPI.fixUrlNull(url : String?) : String? { + if (url.isNullOrEmpty()) { + return null + } return fixUrl(url ?: return null) } @@ -279,6 +283,9 @@ fun MainAPI.fixUrl(url: String): String { if (url.startsWith("http")) { return url } + if (url.isEmpty()) { + return "" + } val startsWithNoHttp = url.startsWith("//") if (startsWithNoHttp) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt new file mode 100644 index 00000000..a0a5d5f1 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt @@ -0,0 +1,216 @@ +package com.lagradost.cloudstream3.movieproviders + +import android.util.Log +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.extractors.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor +import org.jsoup.Jsoup + +class DramaSeeProvider : MainAPI() { + override val mainUrl = "https://dramasee.net" + override val name = "DramaSee" + override val hasQuickSearch = false + override val hasMainPage = true + override val hasChromecastSupport = false + override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) + + override fun getMainPage(): HomePageResponse { + val headers = mapOf("X-Requested-By" to "dramasee.net") + val html = app.get(mainUrl, headers = headers).text + val document = Jsoup.parse(html) + val mainbody = document.getElementsByTag("body") + + return HomePageResponse( + mainbody?.select("section")?.map { row -> + val main = row?.select("main") + + val title = main?.select("div.title > div > h2")?.text() ?: "Main" + val inner = main?.select("li.series-item") ?: return@map null + + HomePageList( + title, + inner.mapNotNull { + // Get inner div from article + val innerBody = it?.selectFirst("a") + // Fetch details + val link = fixUrlNull(innerBody?.attr("href")) ?: return@mapNotNull null + val image = fixUrlNull(innerBody?.select("img")?.attr("src")) ?: "" + val name = it?.selectFirst("a.series-name")?.text() ?: "" + //Log.i(this.name, "Result => (innerBody, image) ${innerBody} / ${image}") + MovieSearchResponse( + name, + link, + this.name, + TvType.TvSeries, + image, + year = null, + id = null, + ) + }.distinctBy { c -> c.url }) + }?.filterNotNull() ?: listOf() + ) + } + + override fun search(query: String): List { + val url = "$mainUrl/search?q=$query" + val html = app.get(url).document + val document = html.getElementsByTag("body") + .select("section > main > ul.series > li") ?: return listOf() + + return document.map { + val innerA = it?.select("a.series-img") + val href = innerA?.attr("href") ?: return@map null + val link = fixUrlNull(href) ?: return@map null + val title = it?.select("a.series-name")?.text() ?: return@map null + val year = null + val imgsrc = innerA?.select("img")?.attr("src") ?: return@map null + val image = fixUrl(imgsrc) + + MovieSearchResponse( + title, + link, + this.name, + TvType.Movie, + image, + year + ) + }.filterNotNull() + } + + override fun load(url: String): LoadResponse { + val doc = app.get(url).document + val body = doc.getElementsByTag("body") + val inner = body?.select("div.series-info") + + // Video details + val poster = fixUrlNull(inner?.select("div.img > img")?.attr("src")) ?: "" + //Log.i(this.name, "Result => (imgLinkCode) ${imgLinkCode}") + val title = inner?.select("h1.series-name")?.text() ?: "" + val year = if (title.length > 5) { title.substring(title.length - 5) + .trim().trimEnd(')').toIntOrNull() } else { null } + //Log.i(this.name, "Result => (year) ${title.substring(title.length - 5)}") + val descript = body?.select("div.series-body")?.firstOrNull() + ?.select("div.js-content")?.text() + + // Episodes Links + val episodeList = ArrayList() + val eps = body?.select("ul.episodes > li.episode-item") + //Log.i(this.name, "Result => (eps) ${eps}") + if (!eps.isNullOrEmpty()) { + for (ep in eps) { + if (ep != null) { + val innerA = ep.select("a") + val count = innerA.select("span.episode")?.text()?.toIntOrNull() ?: 0 + val epLink = fixUrlNull(innerA.attr("href")) ?: continue + //Log.i(this.name, "Result => (epLink) ${epLink}") + if (epLink.isNotEmpty()) { + // Fetch video links + val epVidLinkEl = app.get(epLink, referer = mainUrl).document + val ajaxUrl = epVidLinkEl.select("div#js-player")?.attr("embed") + //Log.i(this.name, "Result => (ajaxUrl) ${ajaxUrl}") + if (!ajaxUrl.isNullOrEmpty()) { + val innerPage = Jsoup.parse(app.get(fixUrl(ajaxUrl), referer = epLink).text) + val listOfLinks = mutableListOf() + val serverAvail = innerPage?.select("div.player.active > main > div") + if (!serverAvail.isNullOrEmpty()) { + for (em in serverAvail) { + val href = em.attr("src") + if (!href.isNullOrEmpty()) { + listOfLinks.add(href) + } + } + } + //Log.i(this.name, "Result => (listOfLinks) ${listOfLinks}") + episodeList.add( + TvSeriesEpisode( + name = "Episode $count", + season = null, + episode = count, + data = listOfLinks.toString(), + posterUrl = poster, + date = null + ) + ) + } + } + } + } + } + //If there's only 1 episode, consider it a movie. + if (episodeList.size == 1) { + return MovieLoadResponse(title, url, this.name, TvType.Movie, episodeList[0].data, poster, year, descript, null, null) + } + return TvSeriesLoadResponse( + title, + url, + this.name, + TvType.TvSeries, + episodeList, + poster, + year, + descript, + null, + null, + null + ) + } + + override fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + if (data == "about:blank") return false + if (data == "[]") return false + if (data.isEmpty()) return false + + val urls = data.trim('[').trim(']').split(',') + if (!urls.isNullOrEmpty()) { + for (item in urls) { + if (item.isNotEmpty()) { + var url = item.trim() + if (url.startsWith("//")) { + url = "https:$url" + } + //Log.i(this.name, "Result => (url) ${url}") + if (url.startsWith("https://asianembed.io")) { + // Fetch links + val doc = app.get(url).document + val links = doc.select("div#list-server-more > ul > li.linkserver") + if (!links.isNullOrEmpty()) { + links.forEach { + val datavid = it.attr("data-video") ?: "" + //Log.i(this.name, "Result => (datavid) ${datavid}") + if (datavid.isNotEmpty()) { + if (datavid.startsWith("https://fembed-hd.com")) { + val extractor = XStreamCdn() + extractor.domainUrl = "fembed-hd.com" + val src = extractor.getUrl(datavid, url) + src.forEach { link -> + callback.invoke(link) + } + } else { + loadExtractor(datavid, url, callback) + } + } + } + } + } else if (url.startsWith("https://embedsito.com")) { + val extractor = XStreamCdn() + extractor.domainUrl = "embedsito.com" + val src = extractor.getUrl(url) + src.forEach { link -> + callback.invoke(link) + } + } else { + loadExtractor(url, url, callback) + } // end if + } + } + return true + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt index e5ee744c..f0e75180 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt @@ -68,9 +68,8 @@ class PinoyHDXyzProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/search/?q=${query.replace(" ", "+")}" - val html = app.get(url).text - val document = Jsoup.parse(html).select("div.portfolio-thumb") - if (document != null) { + val document = app.get(url).document.select("div.portfolio-thumb") + if (!document.isNullOrEmpty()) { return document.map { val link = it?.select("a")?.firstOrNull()?.attr("href") ?: "" diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt index d90f08f1..b8348d87 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt @@ -116,9 +116,9 @@ class PinoyMoviePediaProvider : MainAPI() { val isTvSeries = doc?.select("title")?.text()?.lowercase()?.contains("full episode -") ?: false // Video details - val poster = doc.select("meta[property=og:image]").firstOrNull()?.attr("content") - val title = inner?.select("div.data > h1")?.firstOrNull()?.text() ?: "" - val descript = body?.select("div#info")?.text() + val poster = inner?.select("div.poster > img")?.attr("src") + val title = inner?.select("div.data > h1")?.firstOrNull()?.text() ?: "" + val descript = body?.select("div#info > div.wp-content")?.text() val rex = Regex("\\((\\d+)") val yearRes = rex.find(title)?.value ?: "" //Log.i(this.name, "Result => (yearRes) ${yearRes}") @@ -150,7 +150,7 @@ class PinoyMoviePediaProvider : MainAPI() { //Log.i(this.name, "Result => (epLinks href) ${href}") episodeList.add( TvSeriesEpisode( - name, + "Episode $epNum", null, epNum, href, diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt index 331fab1b..ffa8e853 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt @@ -90,7 +90,7 @@ class PinoyMoviesEsProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/?s=${query}" val html = app.get(url, interceptor = DdosGuardKiller(true)).text - Log.i(this.name, "Result => (html) ${Jsoup.parse(html).getElementsByTag("body")}") + //Log.i(this.name, "Result => (html) ${Jsoup.parse(html).getElementsByTag("body")}") val document = Jsoup.parse(html).select("div#archive-content > article") if (document != null) { return document.map {