From d7deb25fd1bb140acd82c434582a5e3b8b8e82a7 Mon Sep 17 00:00:00 2001 From: KillerDogeEmpire Date: Mon, 12 Feb 2024 17:17:00 -0800 Subject: [PATCH] New Source NoodleMagazine --- NoodleMagazineProvider/build.gradle.kts | 24 ++++ .../src/main/AndroidManifest.xml | 2 + .../KillerDogeEmpire/NoodleMagazinePlugin.kt | 13 ++ .../NoodleMagazineProvider.kt | 120 ++++++++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 NoodleMagazineProvider/build.gradle.kts create mode 100644 NoodleMagazineProvider/src/main/AndroidManifest.xml create mode 100644 NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazinePlugin.kt create mode 100644 NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazineProvider.kt diff --git a/NoodleMagazineProvider/build.gradle.kts b/NoodleMagazineProvider/build.gradle.kts new file mode 100644 index 0000000..710e454 --- /dev/null +++ b/NoodleMagazineProvider/build.gradle.kts @@ -0,0 +1,24 @@ +version = 7 + + +cloudstream { + language = "en" + // All of these properties are optional, you can safely remove them + + description = "type .nofap in discord - Full Length" + authors = listOf("KillerDogeEmpire, Coxju") + + /** + * 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=noodlemagazine.com/&sz=%size%" +} diff --git a/NoodleMagazineProvider/src/main/AndroidManifest.xml b/NoodleMagazineProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d2a6ed7 --- /dev/null +++ b/NoodleMagazineProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazinePlugin.kt b/NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazinePlugin.kt new file mode 100644 index 0000000..5cc0393 --- /dev/null +++ b/NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazinePlugin.kt @@ -0,0 +1,13 @@ +package com.KillerDogeEmpire + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class NoodleMagazinePlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(NoodleMagazineProvider()) + } +} diff --git a/NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazineProvider.kt b/NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazineProvider.kt new file mode 100644 index 0000000..d70231d --- /dev/null +++ b/NoodleMagazineProvider/src/main/kotlin/com/KillerDogeEmpire/NoodleMagazineProvider.kt @@ -0,0 +1,120 @@ +package com.KillerDogeEmpire + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.network.WebViewResolver +import com.lagradost.cloudstream3.utils.* +import org.jsoup.nodes.Element + +class NoodleMagazineProvider : MainAPI() { // all providers must be an instance of MainAPI + override var mainUrl = "https://noodlemagazine.com" + override var name = "Noodle Magazine" + override val hasMainPage = true + override var lang = "en" + override val hasDownloadSupport = true + override val supportedTypes = setOf( + TvType.NSFW + ) + + override val mainPage = mainPageOf( + "latest" to "Latest", + "onlyfans" to "Onlyfans", + "latina" to "Latina", + "blonde" to "Blonde", + "milf" to "MILF", + "jav" to "JAV", + "hentai" to "Hentai", + "lesbian" to "Lesbian", + ) + + + override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse { + val curpage = page - 1 + val link = "$mainUrl/video/${request.data}?p=$curpage" + val document = app.get(link).document + val home = document.select("div.item").mapNotNull { + it.toSearchResult() + } + return newHomePageResponse(request.name, home) + } + + private fun Element.toSearchResult(): AnimeSearchResponse? { + val href = fixUrl(this.selectFirst("a")?.attr("href") ?: return null) + val title = this.selectFirst("a div.i_info div.title")?.text() ?: return null + val posterUrl = fixUrlNull(this.selectFirst("a div.i_img img")?.attr("data-src")) + + return newAnimeSearchResponse(title, href, TvType.Anime) { + this.posterUrl = posterUrl + } + } + + override suspend fun search(query: String): List { + val searchresult = mutableListOf() + (0..10).toList().apmap { page -> + val doc = app.get("$mainUrl/video/$query?p=$page").document + //return document.select("div.post-filter-image").mapNotNull { + doc.select("div.item").apmap { res -> + searchresult.add(res.toSearchResult()!!) + } + + } + + return searchresult + } + + override suspend fun load(url: String): LoadResponse { + val document = app.get(url).document + val title = document.selectFirst("div.l_info h1")?.text()?.trim() ?: "null" + val poster = + document.selectFirst("""meta[property="og:image"]""")?.attr("content") ?: "null" + + val recommendations = document.select("div.item").mapNotNull { + it.toSearchResult() + } + + return newMovieLoadResponse(title, url, TvType.NSFW, url) { + this.posterUrl = poster + this.recommendations = recommendations + } + + } + + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val jason = app.get( + data, interceptor = WebViewResolver(Regex("""/playlist/""")) + ).parsed() + val extlinkList = mutableListOf() + jason.sources.map { + extlinkList.add( + ExtractorLink( + source = name, + name = name, + url = it.streamlink!!, + referer = "$mainUrl/", + quality = getQualityFromName(it.qualityfile) + ) + ) + } + extlinkList.forEach(callback) + return true + } + + data class SusJSON( + @JsonProperty("image") val img: String? = null, + @JsonProperty("sources") val sources: ArrayList = arrayListOf() + ) + + data class Streams( + @JsonProperty("file") val streamlink: String? = null,//the link + @JsonProperty("label") val qualityfile: String? = null,//720 480 360 240 + @JsonProperty("type") val type: String? = null,//mp4 + ) + +} +