diff --git a/ArabSeedProvider/build.gradle.kts b/ArabSeedProvider/build.gradle.kts new file mode 100644 index 0000000..04f9493 --- /dev/null +++ b/ArabSeedProvider/build.gradle.kts @@ -0,0 +1,14 @@ +version = 1 + +cloudstream { + description = "" + authors = listOf( "ImZaw" ) + + language = "ar" + + status = 1 + + tvTypes = listOf( "TvSeries" , "Movie" ) + + iconUrl = "https://www.google.com/s2/favicons?domain=arabseed.ink&sz=%size%" +} diff --git a/ArabSeedProvider/src/main/AndroidManifest.xml b/ArabSeedProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2a12952 --- /dev/null +++ b/ArabSeedProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/ArabSeedProvider/src/main/kotlin/com/arabseed/ArabSeedPlugin.kt b/ArabSeedProvider/src/main/kotlin/com/arabseed/ArabSeedPlugin.kt new file mode 100644 index 0000000..1a2210d --- /dev/null +++ b/ArabSeedProvider/src/main/kotlin/com/arabseed/ArabSeedPlugin.kt @@ -0,0 +1,11 @@ +package com.arabseed +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class ArabSeedPlugin: Plugin() { + override fun load(context: Context) { + registerMainAPI(ArabSeed()) + } +} \ No newline at end of file diff --git a/ArabSeedProvider/src/main/kotlin/com/arabseed/ArabSeedProvider.kt b/ArabSeedProvider/src/main/kotlin/com/arabseed/ArabSeedProvider.kt new file mode 100644 index 0000000..a114bb4 --- /dev/null +++ b/ArabSeedProvider/src/main/kotlin/com/arabseed/ArabSeedProvider.kt @@ -0,0 +1,227 @@ +package com.arabseed + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities +import com.lagradost.cloudstream3.utils.loadExtractor +import org.jsoup.nodes.Element +import java.net.URI +import java.util.* +import kotlin.collections.ArrayList + +class ArabSeed : MainAPI() { + override var lang = "ar" + override var mainUrl = "https://m5.arabseed.ink" + override var name = "ArabSeed" + override val usesWebView = false + override val hasMainPage = true + override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) + + private fun String.getIntFromText(): Int? { + return Regex("""\d+""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull() + } + + + private fun Element.toSearchResponse(): SearchResponse? { + val title = select("h4").text() + val posterUrl = select("img.imgOptimzer").attr("data-image").ifEmpty { select("div.Poster img").attr("data-src") } + val tvType = if (select("span.category").text().contains("مسلسلات")) TvType.TvSeries else TvType.Movie + return MovieSearchResponse( + title, + select("a").attr("href"), + this@ArabSeed.name, + tvType, + posterUrl, + ) + } + + override val mainPage = mainPageOf( + "$mainUrl/movies/?offset=" to "Movies", + "$mainUrl/series/?offset=" to "Series", + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val document = app.get(request.data + page, timeout = 120).document + val home = document.select("ul.Blocks-UL > div").mapNotNull { + it.toSearchResponse() + } + return newHomePageResponse(request.name, home) + } + + override suspend fun search(query: String): List { + val list = arrayListOf() + arrayListOf( + mainUrl to "series", + mainUrl to "movies" + ).apmap { (url, type) -> + val doc = app.post( + "$url/wp-content/themes/Elshaikh2021/Ajaxat/SearchingTwo.php", + data = mapOf("search" to query, "type" to type), + referer = mainUrl + ).document + doc.select("ul.Blocks-UL > div").mapNotNull { + it.toSearchResponse()?.let { it1 -> list.add(it1) } + } + } + return list + } + + override suspend fun load(url: String): LoadResponse { + val doc = app.get(url, timeout = 120).document + val title = doc.select("h1.Title").text().ifEmpty { doc.select("div.Title").text() } + val isMovie = title.contains("فيلم") + + val posterUrl = doc.select("div.Poster > img").let{ it.attr("data-src").ifEmpty { it.attr("src") } } + val rating = doc.select("div.RatingImdb em").text().getIntFromText() + val synopsis = doc.select("p.descrip").last()?.text() + val year = doc.select("li:contains(السنه) a").text().getIntFromText() + val tags = doc.select("li:contains(النوع) > a, li:contains(التصنيف) > a")?.map { it.text() } + + val actors = doc.select("div.WorkTeamIteM").mapNotNull { + val name = it.selectFirst("h4 > em")?.text() ?: return@mapNotNull null + val image = it.selectFirst("div.Icon img")?.attr("src") ?: return@mapNotNull null + val roleString = it.select("h4 > span").text() + val mainActor = Actor(name, image) + ActorData(actor = mainActor, roleString = roleString) + } + + val recommendations = doc.select("ul.Blocks-UL > div").mapNotNull { element -> + element.toSearchResponse() + } + + return if (isMovie) { + newMovieLoadResponse( + title, + url, + TvType.Movie, + url + ) { + this.posterUrl = posterUrl + this.recommendations = recommendations + this.plot = synopsis + this.tags = tags + this.actors = actors + this.rating = rating + this.year = year + } + } else { + val seasonList = doc.select("div.SeasonsListHolder ul > li") + val episodes = arrayListOf() + if(seasonList.isNotEmpty()) { + seasonList.apmap { season -> + app.post( + "$mainUrl/wp-content/themes/Elshaikh2021/Ajaxat/Single/Episodes.php", + data = mapOf("season" to season.attr("data-season"), "post_id" to season.attr("data-id")) + ).document.select("a").apmap { + episodes.add(Episode( + it.attr("href"), + it.text(), + season.attr("data-season")[0].toString().toIntOrNull(), + it.text().getIntFromText() + )) + } + } + } else { + doc.select("div.ContainerEpisodesList > a").apmap { + episodes.add(Episode( + it.attr("href"), + it.text(), + 0, + it.text().getIntFromText() + )) + } + } + newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes.distinct().sortedBy { it.episode }) { + this.posterUrl = posterUrl + this.tags = tags + this.plot = synopsis + this.actors = actors + this.recommendations = recommendations + this.rating = rating + this.year = year + } + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + println(data) + val doc = app.get(data).document + val watchUrl = doc.select("a.watchBTn").attr("href") + println(watchUrl) + val watchDoc = app.get(watchUrl, headers = mapOf("Referer" to mainUrl)).document + val indexOperators = arrayListOf() + val list: List = watchDoc.select("ul > li[data-link], ul > h3").mapIndexed { index, element -> + if(element.`is`("h3")) { + indexOperators.add(index) + element + } else element + } + var watchLinks: List>>; + if(indexOperators.isNotEmpty()) { + watchLinks = indexOperators.mapIndexed { index, it -> + var endIndex = list.size + if (index != indexOperators.size - 1) endIndex = (indexOperators[index + 1]) - 1 + list[it].text().getIntFromText() as Int to list.subList(it + 1, endIndex) as List + } + } else { + watchLinks = arrayListOf(0 to list) + } + println(watchLinks) + watchLinks.apmap { (quality, links) -> + links.apmap { + val iframeUrl = it.attr("data-link") + println(iframeUrl) + if(it.text().contains("عرب سيد")) { + val sourceElement = app.get(iframeUrl).document.select("source") + callback.invoke( + ExtractorLink( + this.name, + "ArabSeed", + sourceElement.attr("src"), + data, + if(quality != 0) quality else it.text().replace("\\D".toRegex(),"").toInt(), + !sourceElement.attr("type").contains("mp4") + ) + ) + } else if (iframeUrl.contains("voe.sx")) { + val doc = app.get(iframeUrl).document + val script = doc.select("script").map { it.data() }.first { it.contains("sources") } + val m3u8 = script.substringAfter("'hls': '").substringBefore("'") + val mp4 = script.substringAfter("'mp4': '").substringBefore("'") + val voeSxquality = script.substringAfter("'video_height': ").substringBefore(",").toInt() + callback.invoke( + ExtractorLink( + this.name, + "Voe.sx m3u8", + m3u8, + data, + voeSxquality, + true + ) + ) + callback.invoke( + ExtractorLink( + this.name, + "Voe.sx mp4", + mp4, + data, + voeSxquality, + ) + ) + } else loadExtractor(iframeUrl, data, subtitleCallback, callback) + } + } + return true + } +} \ No newline at end of file diff --git a/FajerShowProvider/build.gradle.kts b/FajerShowProvider/build.gradle.kts index dc00b82..b00b977 100644 --- a/FajerShowProvider/build.gradle.kts +++ b/FajerShowProvider/build.gradle.kts @@ -1,4 +1,4 @@ -version = 1 +version = 2 cloudstream { description = "" diff --git a/FajerShowProvider/src/main/kotlin/com/fajershow/FajerShowProvider.kt b/FajerShowProvider/src/main/kotlin/com/fajershow/FajerShowProvider.kt index dd05bbf..9eb8093 100644 --- a/FajerShowProvider/src/main/kotlin/com/fajershow/FajerShowProvider.kt +++ b/FajerShowProvider/src/main/kotlin/com/fajershow/FajerShowProvider.kt @@ -234,7 +234,7 @@ class FajerShow : MainAPI() { "Voe.sx mp4", mp4, data, - Qualities.Unknown.value, + quality, ) ) println("VOE.SX\n$m3u8\n$mp4\n$quality\n") diff --git a/MyCimaProvider/build.gradle.kts b/MyCimaProvider/build.gradle.kts index b12e0ea..1a24c02 100644 --- a/MyCimaProvider/build.gradle.kts +++ b/MyCimaProvider/build.gradle.kts @@ -1,4 +1,4 @@ -version = 1 +version = 2 cloudstream { description = "" diff --git a/MyCimaProvider/src/main/kotlin/com/mycima/MyCimaProvider.kt b/MyCimaProvider/src/main/kotlin/com/mycima/MyCimaProvider.kt index b9531e1..d31e8f9 100644 --- a/MyCimaProvider/src/main/kotlin/com/mycima/MyCimaProvider.kt +++ b/MyCimaProvider/src/main/kotlin/com/mycima/MyCimaProvider.kt @@ -10,7 +10,7 @@ import org.jsoup.nodes.Element class MyCima : MainAPI() { override var lang = "ar" - override var mainUrl = "https://mycima.tv" + override var mainUrl = "https://mycimaaa.click" override var name = "MyCima" override val usesWebView = false override val hasMainPage = true