From 7cc37e316fd6257b88779e5a3440812f643d11c8 Mon Sep 17 00:00:00 2001 From: hexated Date: Thu, 29 Sep 2022 21:41:09 +0700 Subject: [PATCH] added DramaSerial --- DramaSerial/build.gradle.kts | 25 ++++ DramaSerial/src/main/AndroidManifest.xml | 2 + .../main/kotlin/com/hexated/DramaSerial.kt | 124 ++++++++++++++++++ .../kotlin/com/hexated/DramaSerialPlugin.kt | 15 +++ .../src/main/kotlin/com/hexated/Lkctwoone.kt | 8 ++ 5 files changed, 174 insertions(+) create mode 100644 DramaSerial/build.gradle.kts create mode 100644 DramaSerial/src/main/AndroidManifest.xml create mode 100644 DramaSerial/src/main/kotlin/com/hexated/DramaSerial.kt create mode 100644 DramaSerial/src/main/kotlin/com/hexated/DramaSerialPlugin.kt create mode 100644 DramaSerial/src/main/kotlin/com/hexated/Lkctwoone.kt diff --git a/DramaSerial/build.gradle.kts b/DramaSerial/build.gradle.kts new file mode 100644 index 00000000..19569e14 --- /dev/null +++ b/DramaSerial/build.gradle.kts @@ -0,0 +1,25 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + language = "id" + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + 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( + "AsianDrama", + ) + + iconUrl = "https://www.google.com/s2/favicons?domain=149.3.170.35&sz=%size%" +} \ No newline at end of file diff --git a/DramaSerial/src/main/AndroidManifest.xml b/DramaSerial/src/main/AndroidManifest.xml new file mode 100644 index 00000000..c98063f8 --- /dev/null +++ b/DramaSerial/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/DramaSerial/src/main/kotlin/com/hexated/DramaSerial.kt b/DramaSerial/src/main/kotlin/com/hexated/DramaSerial.kt new file mode 100644 index 00000000..01401d30 --- /dev/null +++ b/DramaSerial/src/main/kotlin/com/hexated/DramaSerial.kt @@ -0,0 +1,124 @@ +package com.hexated + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor +import org.jsoup.nodes.Element + +class DramaSerial : MainAPI() { + override var mainUrl = "https://149.3.170.35" + override var name = "DramaSerial" + override val hasMainPage = true + override var lang = "id" + override val hasDownloadSupport = true + override val supportedTypes = setOf(TvType.AsianDrama) + + override val mainPage = mainPageOf( + "$mainUrl/page/" to "Latest Movie", + "$mainUrl/Genre/ongoing/page/" to "Ongoing", + "$mainUrl/Genre/drama-serial-korea/page/" to "Drama Serial Korea", + "$mainUrl/Genre/drama-serial-jepang/page/" to "Drama Serial Jepang", + "$mainUrl/Genre/drama-serial-mandarin/page/" to "Drama Serial Mandarin", + "$mainUrl/Genre/drama-serial-filipina/page/" to "Drama Serial Filipina", + "$mainUrl/Genre/drama-serial-india/page/" to "Drama Serial India", + ) + + override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse { + val document = app.get(request.data + page).document + val home = document.select("main#main article").mapNotNull { + it.toSearchResult() + } + return newHomePageResponse(request.name, home) + } + + private fun Element.toSearchResult(): SearchResponse? { + val href = fixUrl(this.selectFirst("a")!!.attr("href")) + val title = this.selectFirst("h2.entry-title a")?.text()?.trim() ?: return null + val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src")) + val episode = + this.selectFirst("div.gmr-episode-item")?.text()?.filter { it.isDigit() }?.toIntOrNull() + + return newAnimeSearchResponse(title, href, TvType.AsianDrama) { + this.posterUrl = posterUrl + addSub(episode) + } + } + + override suspend fun search(query: String): List { + val link = "$mainUrl/?s=$query&post_type[]=post&post_type[]=tv" + val document = app.get(link).document + + return document.select("main#main article").mapNotNull { + it.toSearchResult() + } + } + + override suspend fun load(url: String): LoadResponse { + val document = app.get(url).document + + val title = document.selectFirst("h1.entry-title")!!.text().trim() + val poster = fixUrlNull(document.selectFirst("figure.pull-left img")?.attr("src")) + val tags = + document.select("div.gmr-movie-innermeta span:contains(Genre:) a").map { it.text() } + val year = + document.selectFirst("div.gmr-movie-innermeta span:contains(Year:) a")!!.text().trim() + .toIntOrNull() + val duration = + document.selectFirst("div.gmr-movie-innermeta span:contains(Duration:)")?.text() + ?.filter { it.isDigit() }?.toIntOrNull() + val description = document.select("div.entry-content.entry-content-single div.entry-content.entry-content-single").text().trim() + val type = if(document.select("div.page-links").isNullOrEmpty()) TvType.Movie else TvType.AsianDrama + + if (type == TvType.Movie) { + return newMovieLoadResponse(title, url, TvType.Movie, url) { + posterUrl = poster + this.year = year + plot = description + this.tags = tags + this.duration = duration + } + } else { + val episodes = document.select("div.page-links span.page-link-number").mapNotNull { eps -> + val episode = eps.text().filter { it.isDigit() }.toIntOrNull() + val link = if(episode == 1) { + url + } else { + eps.parent()?.attr("href") + } + Episode( + link ?: return@mapNotNull null, + episode = episode, + ) + } + return newTvSeriesLoadResponse(title, url, TvType.AsianDrama, episodes = episodes) { + posterUrl = poster + this.year = year + this.duration = duration + plot = description + this.tags = tags + } + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val document = app.get(data).document + + val iframe = document.select("div.gmr-server-wrap iframe").attr("src") + app.get(iframe, referer = "$mainUrl/").document.select("div#header-slider ul li").apmap { mLink -> + mLink.attr("onclick").substringAfter("frame('").substringBefore("')").let { iLink -> + val uLink = app.get(iLink, referer = iframe).document.select("script").find { it.data().contains("(document).ready") }?.data()?.substringAfter("replace(\"")?.substringBefore("\");") ?: return@apmap null + val link = app.get(uLink, referer = iLink).document.selectFirst("iframe")?.attr("src") ?: return@apmap null + loadExtractor(fixUrl(link), "$mainUrl/", subtitleCallback, callback) + } + } + + return true + + } + +} diff --git a/DramaSerial/src/main/kotlin/com/hexated/DramaSerialPlugin.kt b/DramaSerial/src/main/kotlin/com/hexated/DramaSerialPlugin.kt new file mode 100644 index 00000000..781dda9e --- /dev/null +++ b/DramaSerial/src/main/kotlin/com/hexated/DramaSerialPlugin.kt @@ -0,0 +1,15 @@ + +package com.hexated + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class DramaSerialPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(DramaSerial()) + registerExtractorAPI(Lkctwoone()) + } +} \ No newline at end of file diff --git a/DramaSerial/src/main/kotlin/com/hexated/Lkctwoone.kt b/DramaSerial/src/main/kotlin/com/hexated/Lkctwoone.kt new file mode 100644 index 00000000..1957e026 --- /dev/null +++ b/DramaSerial/src/main/kotlin/com/hexated/Lkctwoone.kt @@ -0,0 +1,8 @@ +package com.hexated + +import com.lagradost.cloudstream3.extractors.XStreamCdn + +class Lkctwoone: XStreamCdn() { + override val name: String = "LKC21" + override val mainUrl: String = "https://lkc21.net" +} \ No newline at end of file