From df8099cc8c245bb77d41f56a4891d682e4420cc7 Mon Sep 17 00:00:00 2001 From: hexated Date: Tue, 20 Sep 2022 17:58:40 +0700 Subject: [PATCH] fixed Hdfilmcehennemi & OtakudesuProvider also added Paradisehill --- Hdfilmcehennemi/build.gradle.kts | 2 +- .../kotlin/com/hexated/Hdfilmcehennemi.kt | 31 +++-- OtakudesuProvider/build.gradle.kts | 2 +- .../kotlin/com/hexated/OtakudesuProvider.kt | 17 ++- Paradisehill/build.gradle.kts | 25 ++++ Paradisehill/src/main/AndroidManifest.xml | 2 + .../main/kotlin/com/hexated/Paradisehill.kt | 117 ++++++++++++++++++ .../kotlin/com/hexated/ParadisehillPlugin.kt | 13 ++ 8 files changed, 192 insertions(+), 17 deletions(-) create mode 100644 Paradisehill/build.gradle.kts create mode 100644 Paradisehill/src/main/AndroidManifest.xml create mode 100644 Paradisehill/src/main/kotlin/com/hexated/Paradisehill.kt create mode 100644 Paradisehill/src/main/kotlin/com/hexated/ParadisehillPlugin.kt diff --git a/Hdfilmcehennemi/build.gradle.kts b/Hdfilmcehennemi/build.gradle.kts index c10c4e99..4e64a14c 100644 --- a/Hdfilmcehennemi/build.gradle.kts +++ b/Hdfilmcehennemi/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/Hdfilmcehennemi/src/main/kotlin/com/hexated/Hdfilmcehennemi.kt b/Hdfilmcehennemi/src/main/kotlin/com/hexated/Hdfilmcehennemi.kt index 5440aa02..5ace2863 100644 --- a/Hdfilmcehennemi/src/main/kotlin/com/hexated/Hdfilmcehennemi.kt +++ b/Hdfilmcehennemi/src/main/kotlin/com/hexated/Hdfilmcehennemi.kt @@ -155,21 +155,32 @@ class Hdfilmcehennemi : MainAPI() { private suspend fun invokeLocalSource( source: String, url: String, - sourceCallback: (ExtractorLink) -> Unit + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit ) { - val m3uLink = - app.get(url, referer = "$mainUrl/").document.select("script") - .find { - it.data().contains("var sources = [];") || it.data() - .contains("playerInstance =") - }?.data() - ?.substringAfter("[{file:\"")?.substringBefore("\"}]") ?: return + val res = app.get(url, referer = "$mainUrl/") + val m3uLink = res.document.select("script") + .find { + it.data().contains("var sources = [];") || it.data() + .contains("playerInstance =") + }?.data() + ?.substringAfter("[{file:\"")?.substringBefore("\"}]") ?: return M3u8Helper.generateM3u8( source, m3uLink, if (url.startsWith(mainUrl)) "$mainUrl/" else "https://vidmoly.to/" - ).forEach(sourceCallback) + ).forEach(callback) + + Regex("\"(/srt\\S*?)\",\\slabel:\\s\"(\\S*?)\"").findAll(res.text) + .map { it.groupValues[1] to it.groupValues[2] }.toList().map { (url, lang) -> + subtitleCallback.invoke( + SubtitleFile( + lang, + fixUrl(url) + ) + ) + } } @@ -185,7 +196,7 @@ class Hdfilmcehennemi : MainAPI() { safeApiCall { app.get(url).document.select("div.card-video > iframe").attr("data-src") .let { link -> - invokeLocalSource(source, link, callback) + invokeLocalSource(source, link,subtitleCallback, callback) } } } diff --git a/OtakudesuProvider/build.gradle.kts b/OtakudesuProvider/build.gradle.kts index 6c3e2594..aefa349c 100644 --- a/OtakudesuProvider/build.gradle.kts +++ b/OtakudesuProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt b/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt index 9d1e9a0e..789e9a28 100644 --- a/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt +++ b/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt @@ -2,6 +2,7 @@ package com.hexated import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.network.CloudflareKiller import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor @@ -10,7 +11,7 @@ import org.jsoup.nodes.Element import java.util.ArrayList class OtakudesuProvider : MainAPI() { - override var mainUrl = "https://otakudesu.watch" + override var mainUrl = "https://otakudesu.video" override var name = "Otakudesu" override val hasMainPage = true override var lang = "id" @@ -23,6 +24,8 @@ class OtakudesuProvider : MainAPI() { ) companion object { + private val interceptor = CloudflareKiller() + fun getType(t: String): TvType { return if (t.contains("OVA") || t.contains("Special")) TvType.OVA else if (t.contains("Movie")) TvType.AnimeMovie @@ -47,7 +50,7 @@ class OtakudesuProvider : MainAPI() { page: Int, request: MainPageRequest ): HomePageResponse { - val document = app.get(request.data + page).document + val document = app.get(request.data + page, interceptor = interceptor).document val home = document.select("div.venz > ul > li").mapNotNull { it.toSearchResult() } @@ -63,13 +66,14 @@ class OtakudesuProvider : MainAPI() { return newAnimeSearchResponse(title, href, TvType.Anime) { this.posterUrl = posterUrl addSub(epNum) + posterHeaders = interceptor.getCookieHeaders(url).toMap() } } override suspend fun search(query: String): List { val link = "$mainUrl/?s=$query&post_type=anime" - val document = app.get(link).document + val document = app.get(link, interceptor = interceptor).document return document.select("ul.chivsrc > li").map { val title = it.selectFirst("h2 > a")!!.ownText().trim() @@ -77,13 +81,14 @@ class OtakudesuProvider : MainAPI() { val posterUrl = it.selectFirst("img")!!.attr("src").toString() newAnimeSearchResponse(title, href, TvType.Anime) { this.posterUrl = posterUrl + posterHeaders = interceptor.getCookieHeaders(url).toMap() } } } override suspend fun load(url: String): LoadResponse { - val document = app.get(url).document + val document = app.get(url, interceptor = interceptor).document val title = document.selectFirst("div.infozingle > p:nth-child(1) > span")?.ownText() ?.replace(":", "")?.trim().toString() @@ -118,6 +123,7 @@ class OtakudesuProvider : MainAPI() { val recPosterUrl = it.selectFirst("a > img")?.attr("src").toString() newAnimeSearchResponse(recName, recHref, TvType.Anime) { this.posterUrl = recPosterUrl + posterHeaders = interceptor.getCookieHeaders(url).toMap() } } @@ -130,6 +136,7 @@ class OtakudesuProvider : MainAPI() { plot = description this.tags = tags this.recommendations = recommendations + posterHeaders = interceptor.getCookieHeaders(url).toMap() } } @@ -151,7 +158,7 @@ class OtakudesuProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { - val document = app.get(data).document + val document = app.get(data, interceptor = interceptor).document val scriptData = document.select("script").last()?.data() val token = scriptData?.substringAfter("{action:\"")?.substringBefore("\"}").toString() diff --git a/Paradisehill/build.gradle.kts b/Paradisehill/build.gradle.kts new file mode 100644 index 00000000..bc46142b --- /dev/null +++ b/Paradisehill/build.gradle.kts @@ -0,0 +1,25 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + language = "en" + // All of these properties are optional, you can safely remove them + + description = "Full movie porn (use VPN if links not working)" + authors = listOf("Hexated") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + tvTypes = listOf( + "NSFW", + ) + + iconUrl = "https://www.google.com/s2/favicons?domain=en.paradisehill.cc&sz=%size%" +} \ No newline at end of file diff --git a/Paradisehill/src/main/AndroidManifest.xml b/Paradisehill/src/main/AndroidManifest.xml new file mode 100644 index 00000000..c98063f8 --- /dev/null +++ b/Paradisehill/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Paradisehill/src/main/kotlin/com/hexated/Paradisehill.kt b/Paradisehill/src/main/kotlin/com/hexated/Paradisehill.kt new file mode 100644 index 00000000..86debaea --- /dev/null +++ b/Paradisehill/src/main/kotlin/com/hexated/Paradisehill.kt @@ -0,0 +1,117 @@ +package com.hexated + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addActors +import com.lagradost.cloudstream3.utils.* +import org.jsoup.nodes.Element +import java.util.* + +class Paradisehill : MainAPI() { + override var mainUrl = "https://en.paradisehill.cc" + override var name = "Paradisehill" + override val hasMainPage = true + override val hasDownloadSupport = true + override val vpnStatus = VPNStatus.MightBeNeeded + override val supportedTypes = setOf(TvType.NSFW) + + override val mainPage = mainPageOf( + "$mainUrl/all/?sort=created_at&page=" to "New Porn Movies", + "$mainUrl/popular/?filter=all&sort=by_likes&page=" to "Popular Porn Movies", + "$mainUrl/studio/89/?sort=created_at&page=" to "Brazzers", + "$mainUrl/studio/29/?sort=created_at&page=" to "Digital Playground", + "$mainUrl/studio/16/?sort=created_at&page=" to "Evil Angel", + "$mainUrl/studio/6/?sort=created_at&page=" to "Bang Bros Productions", + "$mainUrl/studio/78/?sort=created_at&page=" to "Jules Jordan Video", + "$mainUrl/studio/64/?sort=created_at&page=" to "Reality Kings", + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val document = app.get(request.data + page, verify = false).document + val home = + document.select("div.content div.item") + .mapNotNull { + it.toSearchResult() + } + return newHomePageResponse(request.name, home) + } + + private fun Element.toSearchResult(): SearchResponse? { + val title = this.selectFirst("span[itemprop=name]")?.text() ?: return null + val href = fixUrl(this.selectFirst("a")!!.attr("href")) + val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src")) + return newMovieSearchResponse(title, href, TvType.Movie) { + this.posterUrl = posterUrl + } + + } + + override suspend fun search(query: String): List { + val document = app.get("$mainUrl/search/?pattern=$query&what=1").document + return document.select("div.content div.item") + .mapNotNull { + it.toSearchResult() + } + } + + override suspend fun load(url: String): LoadResponse? { + val document = app.get(url).document + + val title = document.selectFirst("h1.title-inside")?.text()?.trim() ?: return null + val poster = fixUrlNull(document.selectFirst("img[itemprop=thumbnailUrl]")?.attr("src")) + val tags = document.select("div.opisanie span[itemprop=genre] a").map { it.text() } + val year = document.select("div.opisanie span[itemprop=releasedEvent]").text() + .let { Regex("[0-9]{4}").find(it)?.groupValues?.getOrNull(0)?.toIntOrNull() } + val description = document.select("div.opisanie span[itemprop=description]").text().trim() + val actors = document.select("div.opisanie p:contains(Actors:) a").map { it.text() } + + val dataEps = + document.select("script").find { it.data().contains("var videoList =") }?.data() + ?.substringAfter("videoList = [")?.substringBefore("];")?.let { data -> + Regex("\"src\":\"(\\S*?.mp4)\",").findAll(data).map { it.groupValues[1] } + .toList() + } + val episodes = dataEps?.mapIndexed { index, link -> + Episode(link, episode = index + 1) + } ?: throw ErrorLoadingException("No Episode Found") + + val recommendations = + document.select("div.content div.item") + .mapNotNull { + it.toSearchResult() + } + + return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { + this.posterUrl = poster + this.plot = description + this.tags = tags + addActors(actors) + this.year = year + this.recommendations = recommendations + } + + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + callback.invoke( + ExtractorLink( + this.name, + this.name, + data, + referer = mainUrl, + quality = Qualities.Unknown.value, +// headers = mapOf("Range" to "bytes=0-"), + ) + ) + return true + } + +} \ No newline at end of file diff --git a/Paradisehill/src/main/kotlin/com/hexated/ParadisehillPlugin.kt b/Paradisehill/src/main/kotlin/com/hexated/ParadisehillPlugin.kt new file mode 100644 index 00000000..0c876f29 --- /dev/null +++ b/Paradisehill/src/main/kotlin/com/hexated/ParadisehillPlugin.kt @@ -0,0 +1,13 @@ +package com.hexated + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class ParadisehillPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(Paradisehill()) + } +} \ No newline at end of file