From 019a3bcb2c3cd04da8eda39ea233540cfda8ddee Mon Sep 17 00:00:00 2001 From: Jace <54625750+Jacekun@users.noreply.github.com> Date: Sat, 8 Oct 2022 17:33:14 +0800 Subject: [PATCH] [Beta Providers] HpJav, JavMost, Jav Guru --- HpJav/build.gradle.kts | 26 +++ HpJav/src/main/AndroidManifest.xml | 2 + HpJav/src/main/kotlin/com/jacekun/HpJav.kt | 118 +++++++++++++ .../main/kotlin/com/jacekun/HpJavPlugin.kt | 13 ++ JavGuru/build.gradle.kts | 26 +++ JavGuru/src/main/AndroidManifest.xml | 2 + .../src/main/kotlin/com/jacekun/JavGuru.kt | 130 ++++++++++++++ .../main/kotlin/com/jacekun/JavGuruPlugin.kt | 13 ++ JavMost/build.gradle.kts | 26 +++ JavMost/src/main/AndroidManifest.xml | 2 + .../src/main/kotlin/com/jacekun/JavMost.kt | 159 ++++++++++++++++++ .../main/kotlin/com/jacekun/JavMostPlugin.kt | 13 ++ Pornhub/build.gradle.kts | 2 +- XvideosProvider/build.gradle.kts | 2 +- 14 files changed, 532 insertions(+), 2 deletions(-) create mode 100644 HpJav/build.gradle.kts create mode 100644 HpJav/src/main/AndroidManifest.xml create mode 100644 HpJav/src/main/kotlin/com/jacekun/HpJav.kt create mode 100644 HpJav/src/main/kotlin/com/jacekun/HpJavPlugin.kt create mode 100644 JavGuru/build.gradle.kts create mode 100644 JavGuru/src/main/AndroidManifest.xml create mode 100644 JavGuru/src/main/kotlin/com/jacekun/JavGuru.kt create mode 100644 JavGuru/src/main/kotlin/com/jacekun/JavGuruPlugin.kt create mode 100644 JavMost/build.gradle.kts create mode 100644 JavMost/src/main/AndroidManifest.xml create mode 100644 JavMost/src/main/kotlin/com/jacekun/JavMost.kt create mode 100644 JavMost/src/main/kotlin/com/jacekun/JavMostPlugin.kt diff --git a/HpJav/build.gradle.kts b/HpJav/build.gradle.kts new file mode 100644 index 0000000..2c61ba7 --- /dev/null +++ b/HpJav/build.gradle.kts @@ -0,0 +1,26 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + description = "" + authors = listOf("Jace") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 3 // will be 3 if unspecified + + // List of video source types. Users are able to filter for extensions in a given category. + // You can find a list of avaliable types here: + // https://recloudstream.github.io/cloudstream/html/app/com.lagradost.cloudstream3/-tv-type/index.html + tvTypes = listOf("NSFW") + + iconUrl = "https://www.google.com/s2/favicons?domain=hpjav.tv&sz=%size%" +} diff --git a/HpJav/src/main/AndroidManifest.xml b/HpJav/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/HpJav/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/HpJav/src/main/kotlin/com/jacekun/HpJav.kt b/HpJav/src/main/kotlin/com/jacekun/HpJav.kt new file mode 100644 index 0000000..02ce649 --- /dev/null +++ b/HpJav/src/main/kotlin/com/jacekun/HpJav.kt @@ -0,0 +1,118 @@ +package com.jacekun + +import com.lagradost.cloudstream3.MainAPI +import com.lagradost.cloudstream3.TvType +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.app +import org.jsoup.Jsoup + +class HpJav : MainAPI() { + private val DEV = "DevDebug" + private val globaltvType = TvType.Movie + + override var name = "HpJav TV" + override var mainUrl = "https://hpjav.tv" + override val supportedTypes = setOf(TvType.NSFW) + override val hasDownloadSupport = false + override val hasMainPage = true + override val hasQuickSearch = false + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val document = app.get(mainUrl).document + val all = ArrayList() + document.getElementsByTag("body")?.select("div.container")?.forEach { it2 -> + // Fetch row title + val title = it2.select("div.category-count > h3")?.text() ?: "" + // Fetch list of items and map + val elements = it2.select("div.post-list > div")?.mapNotNull { + //Fetch entries + val aa = it.selectFirst("div.video-item > div > a") ?: return@mapNotNull null + val linkTitle = it.select("div.entry-title > a") ?: return@mapNotNull null + val link = fixUrlNull(linkTitle.attr("href")) ?: return@mapNotNull null + val name = linkTitle.text() ?: "" + val image = if (link != "") { aa.select("img")?.attr("data-original") } else { null } + val year = null + //Log.i(DEV, "Result => (image) ${image} , (linkCode) ${linkCode}, (link) ${link}") + + MovieSearchResponse( + name, + link, + this.name, + globaltvType, + image, + year, + null, + ) + }?.distinctBy { it.url } ?: listOf() + if (elements.isNotEmpty()) { + all.add( + HomePageList( + title, elements + ) + ) + } + } + return HomePageResponse(all.filter { hp -> hp.list.isNotEmpty() }) + } + + //TODO: Fix search + override suspend fun search(query: String): List { + val url = "$mainUrl/?s=$query" + val document = app.get(url).document.getElementsByTag("body") + .select("div.container > div > div.post-list") + .select("div.col-md-3.col-sm-6.col-xs-6") + //Log.i(DEV, "Result => $document") + return document.map { + val content = it.select("div.video-item > div > a").firstOrNull() + //Log.i(DEV, "Result => $content") + val linkCode = content?.attr("href") ?: "" + val href = fixUrl(linkCode) + val imgContent = content?.select("img") + val title = imgContent?.attr("alt") ?: "" + val image = imgContent?.attr("data-original")?.trim('\'') + val year = null + //Log.i(DEV, "Result => Title: ${title}, Image: ${image}") + + MovieSearchResponse( + title, + href, + this.name, + globaltvType, + image, + year + ) + } + } + //TODO: Fix load + override suspend fun load(url: String): LoadResponse { + val response = app.get(url).text + val document = Jsoup.parse(response) + //Log.i(DEV, "Url => ${url}") + val body = document.getElementsByTag("body") + .select("div.video-box-ather.container > div.container > div") + .select("div > div > img")?.firstOrNull() + //Log.i(DEV, "Result => ${body}") + // Video details + val poster = body?.attr("src") + val title = body?.attr("alt") ?: "" + val descript = "" + val year = null + + // Video link + val streamUrl = "" + return MovieLoadResponse( + name = title, + url = url, + apiName = this.name, + type = globaltvType, + dataUrl = streamUrl, + posterUrl = poster, + year = year, + plot = descript, + comingSoon = true + ) + } +} \ No newline at end of file diff --git a/HpJav/src/main/kotlin/com/jacekun/HpJavPlugin.kt b/HpJav/src/main/kotlin/com/jacekun/HpJavPlugin.kt new file mode 100644 index 0000000..0c6b1ac --- /dev/null +++ b/HpJav/src/main/kotlin/com/jacekun/HpJavPlugin.kt @@ -0,0 +1,13 @@ +package com.jacekun + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class HpJavPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(HpJav()) + } +} \ No newline at end of file diff --git a/JavGuru/build.gradle.kts b/JavGuru/build.gradle.kts new file mode 100644 index 0000000..c8b0c6c --- /dev/null +++ b/JavGuru/build.gradle.kts @@ -0,0 +1,26 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + description = "" + authors = listOf("Jace") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 3 // will be 3 if unspecified + + // List of video source types. Users are able to filter for extensions in a given category. + // You can find a list of avaliable types here: + // https://recloudstream.github.io/cloudstream/html/app/com.lagradost.cloudstream3/-tv-type/index.html + tvTypes = listOf("NSFW") + + iconUrl = "https://www.google.com/s2/favicons?domain=jav.guru&sz=%size%" +} diff --git a/JavGuru/src/main/AndroidManifest.xml b/JavGuru/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/JavGuru/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/JavGuru/src/main/kotlin/com/jacekun/JavGuru.kt b/JavGuru/src/main/kotlin/com/jacekun/JavGuru.kt new file mode 100644 index 0000000..a429d57 --- /dev/null +++ b/JavGuru/src/main/kotlin/com/jacekun/JavGuru.kt @@ -0,0 +1,130 @@ +package com.jacekun + +import com.lagradost.cloudstream3.MainAPI +import com.lagradost.cloudstream3.TvType +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.app +import org.jsoup.Jsoup + +class JavGuru : MainAPI() { + private val DEV = "DevDebug" + private val globaltvType = TvType.Movie + + override var name = "Jav Guru" + override var mainUrl = "https://jav.guru" + override val supportedTypes = setOf(TvType.NSFW) + override val hasDownloadSupport = false + override val hasMainPage = true + override val hasQuickSearch = false + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val html = app.get(mainUrl).text + val document = Jsoup.parse(html) + val all = ArrayList() + + val mainbody = document.getElementsByTag("body").select("div#page") + .select("div#content").select("div#primary") + .select("main") + + //Log.i(DEV, "Main body => $mainbody") + // Fetch row title + val title = "Homepage" + // Fetch list of items and map + mainbody.select("div.row").let { inner -> + val elements: List = inner.map { + + val innerArticle = it.select("div.column") + .select("div.inside-article").select("div.imgg") + //Log.i(DEV, "Inner content => $innerArticle") + val aa = innerArticle.select("a").firstOrNull() + val link = fixUrl(aa?.attr("href") ?: "") + + val imgArticle = aa?.select("img") + val name = imgArticle?.attr("alt") ?: "" + var image = imgArticle?.attr("src") ?: "" + val year = null + + MovieSearchResponse( + name, + link, + this.name, + globaltvType, + image, + year, + null, + ) + } + + all.add( + HomePageList( + title, elements + ) + ) + } + return HomePageResponse(all) + } + + override suspend fun search(query: String): List { + val url = "$mainUrl/?s=${query}" + val html = app.get(url).text + val document = Jsoup.parse(html).select("main.site-main").select("div.row") + + return document.map { + val aa = it.select("div.column").select("div.inside-article") + .select("div.imgg").select("a") + val imgrow = aa.select("img") + + val href = fixUrl(aa.attr("href")) + val title = imgrow.attr("alt") + val image = imgrow.attr("src").trim('\'') + val year = Regex("(?<=\\/)(.[0-9]{3})(?=\\/)") + .find(image)?.groupValues?.get(1)?.toIntOrNull() + + MovieSearchResponse( + title, + href, + this.name, + globaltvType, + image, + year + ) + } + } + + override suspend fun load(url: String): LoadResponse { + val response = app.get(url).text + val document = Jsoup.parse(response) + + //Log.i(DEV, "Url => ${url}") + val body = document.getElementsByTag("body") + .select("div#page") + .select("div#content").select("div.content-area") + .select("main").select("article") + .select("div.inside-article").select("div.content") + .select("div.posts") + + //Log.i(DEV, "Result => ${body}") + val poster = body.select("div.large-screenshot").select("div.large-screenimg") + .select("img").attr("src") + val title = body.select("h1.titl").text() + val descript = body.select("div.wp-content").select("p").firstOrNull()?.text() + val streamUrl = "" + val year = body.select("div.infometa > div.infoleft > ul > li") + ?.get(1)?.text()?.takeLast(10)?.substring(0, 4)?.toIntOrNull() + + return MovieLoadResponse( + name = title, + url = url, + apiName = this.name, + type = globaltvType, + dataUrl = streamUrl, + posterUrl = poster, + year = year, + plot = descript, + comingSoon = true + ) + } +} \ No newline at end of file diff --git a/JavGuru/src/main/kotlin/com/jacekun/JavGuruPlugin.kt b/JavGuru/src/main/kotlin/com/jacekun/JavGuruPlugin.kt new file mode 100644 index 0000000..5c23ca1 --- /dev/null +++ b/JavGuru/src/main/kotlin/com/jacekun/JavGuruPlugin.kt @@ -0,0 +1,13 @@ +package com.jacekun + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class JavGuruPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(JavGuru()) + } +} \ No newline at end of file diff --git a/JavMost/build.gradle.kts b/JavMost/build.gradle.kts new file mode 100644 index 0000000..7317acf --- /dev/null +++ b/JavMost/build.gradle.kts @@ -0,0 +1,26 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + description = "" + authors = listOf("Jace") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 3 // will be 3 if unspecified + + // List of video source types. Users are able to filter for extensions in a given category. + // You can find a list of avaliable types here: + // https://recloudstream.github.io/cloudstream/html/app/com.lagradost.cloudstream3/-tv-type/index.html + tvTypes = listOf("NSFW") + + iconUrl = "https://www.google.com/s2/favicons?domain=www5.javmost.com&sz=%size%" +} diff --git a/JavMost/src/main/AndroidManifest.xml b/JavMost/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/JavMost/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/JavMost/src/main/kotlin/com/jacekun/JavMost.kt b/JavMost/src/main/kotlin/com/jacekun/JavMost.kt new file mode 100644 index 0000000..035325a --- /dev/null +++ b/JavMost/src/main/kotlin/com/jacekun/JavMost.kt @@ -0,0 +1,159 @@ +package com.jacekun + +import com.lagradost.cloudstream3.MainAPI +import com.lagradost.cloudstream3.TvType +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.app +import org.jsoup.Jsoup + +class JavMost : MainAPI() { + private val DEV = "DevDebug" + private val globaltvType = TvType.Movie + + override var name = "JAVMost.com" + override var mainUrl = "https://www5.javmost.com" + override val supportedTypes = setOf(TvType.NSFW) + override val hasDownloadSupport = false + override val hasMainPage = true + override val hasQuickSearch = false + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val html = app.get(mainUrl).text + val document = Jsoup.parse(html) + val all = ArrayList() + + val mainbody = document.getElementsByTag("body") + ?.select("div#page-container > div#content > div#content-update > div") + ?.select("div.col-md-4.col-sm-6") + val title = "Homepage" + // Fetch list of items and map + val elements: List = mainbody!!.map { + + val inner = it.select("div.card") + val linkA = inner.select("div.card-block > a") + val link = linkA?.firstOrNull()?.attr("href") ?: "" + val name = listOfNotNull(linkA?.firstOrNull()?.text(), linkA?.getOrNull(1)?.text()).joinToString(" ") + //Log.i(DEV, "Result => (name and link) ${name} / ${link}") + var image = inner?.select("center > a > img")?.attr("data-src") + if (image == null) { + image = inner?.select("center > a > img")?.attr("src") + } else { + if (image == "http") { + image = inner?.select("center > a > img")?.attr("src") + } + } + //Log.i(DEV, "Result => (image) ${image}") + val year = inner.select("div.card-block > p")?.text() + ?.substring(0, 20)?.replace("Release", "")?.trim() + ?.substring(0, 4)?.toIntOrNull() + + MovieSearchResponse( + name, + link, + this.name, + globaltvType, + image, + year, + null, + ) + } + + all.add( + HomePageList( + title, elements + ) + ) + + return HomePageResponse(all) + } + + override suspend fun search(query: String): List? { + val html = app.get("$mainUrl/search/${query}/").text + val document = Jsoup.parse(html) + val mainbody = document.getElementsByTag("body") + ?.select("div#page-container > div#content > div#content-update > div") + ?.select("div.col-md-4.col-sm-6") + //Log.i(DEV, "Result => $document") + if (mainbody != null) { + return mainbody.map { + val content = it.select("div.card").firstOrNull() + val linkImg = content?.select("a")?.firstOrNull() + + val href = fixUrl(linkImg?.attr("href") ?: "") + var image = linkImg?.select("img")?.attr("data-src")?.trim('\'') + if (image != null) { image = fixUrl(image) } + //Log.i(DEV, "Result => (link) ${href}, (img) ${image}") + val titleContent = content?.select("div.card-block > a") + //Log.i(DEV, "Result => (titleContent) ${titleContent}") + val title = when (titleContent?.size) { + 2 -> listOfNotNull( + titleContent[0]?.text(), + titleContent[1]?.text() + ).joinToString(" ") + 1 -> titleContent[0]?.text() + else -> "" + } ?: "" + //Log.i(DEV, "Result => (title) ${title}") + var year: Int? = null + val yearP = content?.select("div.card-block")?.firstOrNull()?.select("p") + //Log.i(DEV, "Result => (yearP) ${yearP}") + val yearElem = when(yearP != null) { + true -> yearP?.filter { yearit -> yearit.text()?.contains("Release") == true } + false -> null + } + val yearString = when (yearElem?.size!! > 0) { + true -> yearElem?.get(0)?.text()?.substring(0, 22)?.trim() + ?.replace("Release", "")?.trim() + false -> null + } + //Log.i(DEV, "Result => (yearString) ${yearString}") + if (yearString != null) { + val maxSize = if (yearString.length > 4) { 4 } else { yearString.length } + year = yearString?.substring(0, maxSize)?.toIntOrNull() + } + //Log.i(DEV, "Result => (year) ${year}") + + MovieSearchResponse( + title, + href, + this.name, + globaltvType, + image, + year + ) + } + } + return null + } + + override suspend fun load(url: String): LoadResponse { + val response = app.get(url).text + val document = Jsoup.parse(response) + //Log.i(DEV, "Url => ${url}") + val body = document.getElementsByTag("head") + + //Log.i(DEV, "Result => ${body}") + var poster = body?.select("meta[property=og:image]")?.firstOrNull()?.attr("content") + if (poster != null) { poster = fixUrl(poster) } + //Log.i(DEV, "Result (image) => ${poster}") + val title = body?.select("meta[property=og:title]")?.firstOrNull()?.attr("content") ?: "" + val descript = body?.select("meta[property=og:description]")?.firstOrNull()?.attr("content") ?: "" + //Log.i(DEV, "Result => ${descript}") + val streamUrl = "" + val year = null + return MovieLoadResponse( + name = title, + url = url, + apiName = this.name, + type = globaltvType, + dataUrl = streamUrl, + posterUrl = poster, + year = year, + plot = descript, + comingSoon = true + ) + } +} \ No newline at end of file diff --git a/JavMost/src/main/kotlin/com/jacekun/JavMostPlugin.kt b/JavMost/src/main/kotlin/com/jacekun/JavMostPlugin.kt new file mode 100644 index 0000000..0bc51b3 --- /dev/null +++ b/JavMost/src/main/kotlin/com/jacekun/JavMostPlugin.kt @@ -0,0 +1,13 @@ +package com.jacekun + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class JavMostPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(JavMost()) + } +} \ No newline at end of file diff --git a/Pornhub/build.gradle.kts b/Pornhub/build.gradle.kts index 156c158..4a79585 100644 --- a/Pornhub/build.gradle.kts +++ b/Pornhub/build.gradle.kts @@ -6,7 +6,7 @@ cloudstream { // All of these properties are optional, you can safely remove them description = "Cornhub" - authors = listOf("Jace") + authors = listOf("Stormunblessed", "Jace") /** * Status int as the following: diff --git a/XvideosProvider/build.gradle.kts b/XvideosProvider/build.gradle.kts index 836c1dc..7cf9dec 100644 --- a/XvideosProvider/build.gradle.kts +++ b/XvideosProvider/build.gradle.kts @@ -6,7 +6,7 @@ cloudstream { // All of these properties are optional, you can safely remove them description = "The best free NSFW site" - authors = listOf("Jace") + authors = listOf("Stormunblessed", "Jace") /** * Status int as the following: