Remove no french provider

This commit is contained in:
Eddy 2022-09-09 13:59:40 +02:00
parent 7a45516ca5
commit b177de518d
278 changed files with 0 additions and 18133 deletions

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "ar"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Anime",
"Cartoon",
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=akwam.to&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,224 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import org.jsoup.nodes.Element
class AkwamProvider : MainAPI() {
override var lang = "ar"
override var mainUrl = "https://akwam.to"
override var name = "Akwam"
override val usesWebView = false
override val hasMainPage = true
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie, TvType.Anime, TvType.Cartoon)
private fun Element.toSearchResponse(): SearchResponse? {
val url = select("a.box").attr("href") ?: return null
if (url.contains("/games/") || url.contains("/programs/")) return null
val poster = select("picture > img")
val title = poster.attr("alt")
val posterUrl = poster.attr("data-src")
val year = select(".badge-secondary").text().toIntOrNull()
// If you need to differentiate use the url.
return MovieSearchResponse(
title,
url,
this@AkwamProvider.name,
TvType.TvSeries,
posterUrl,
year,
null,
)
}
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
// Title, Url
val moviesUrl = listOf(
"Movies" to "$mainUrl/movies",
"Series" to "$mainUrl/series",
"Shows" to "$mainUrl/shows"
)
val pages = moviesUrl.apmap {
val doc = app.get(it.second).document
val list = doc.select("div.col-lg-auto.col-md-4.col-6.mb-12").mapNotNull { element ->
element.toSearchResponse()
}
HomePageList(it.first, list)
}.sortedBy { it.name }
return HomePageResponse(pages)
}
override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/search?q=$query"
val doc = app.get(url).document
return doc.select("div.col-lg-auto").mapNotNull {
it.toSearchResponse()
}
}
private fun String.getIntFromText(): Int? {
return Regex("""\d+""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull()
}
private fun Element.toEpisode(): Episode {
val a = select("a.text-white")
val url = a.attr("href")
val title = a.text()
val thumbUrl = select("picture > img").attr("src")
val date = select("p.entry-date").text()
return newEpisode(url) {
name = title
episode = title.getIntFromText()
posterUrl = thumbUrl
addDate(date)
}
}
override suspend fun load(url: String): LoadResponse {
val doc = app.get(url).document
val isMovie = url.contains("/movie/")
val title = doc.select("h1.entry-title").text()
val posterUrl = doc.select("picture > img").attr("src")
val year =
doc.select("div.font-size-16.text-white.mt-2").firstOrNull {
it.text().contains("السنة")
}?.text()?.getIntFromText()
// A bit iffy to parse twice like this, but it'll do.
val duration =
doc.select("div.font-size-16.text-white.mt-2").firstOrNull {
it.text().contains("مدة الفيلم")
}?.text()?.getIntFromText()
val synopsis = doc.select("div.widget-body p:first-child").text()
val rating = doc.select("span.mx-2").text().split("/").lastOrNull()?.toRatingInt()
val tags = doc.select("div.font-size-16.d-flex.align-items-center.mt-3 > a").map {
it.text()
}
val actors = doc.select("div.widget-body > div > div.entry-box > a").mapNotNull {
val name = it?.selectFirst("div > .entry-title")?.text() ?: return@mapNotNull null
val image = it.selectFirst("div > img")?.attr("src") ?: return@mapNotNull null
Actor(name, image)
}
val recommendations =
doc.select("div > div.widget-body > div.row > div > div.entry-box").mapNotNull {
val recTitle = it?.selectFirst("div.entry-body > .entry-title > .text-white")
?: return@mapNotNull null
val href = recTitle.attr("href") ?: return@mapNotNull null
val name = recTitle.text() ?: return@mapNotNull null
val poster = it.selectFirst(".entry-image > a > picture > img")?.attr("data-src")
?: return@mapNotNull null
MovieSearchResponse(name, href, this.name, TvType.Movie, fixUrl(poster))
}
return if (isMovie) {
newMovieLoadResponse(
title,
url,
TvType.Movie,
url
) {
this.posterUrl = posterUrl
this.year = year
this.plot = synopsis
this.rating = rating
this.tags = tags
this.duration = duration
this.recommendations = recommendations
addActors(actors)
}
} else {
val episodes = doc.select("div.bg-primary2.p-4.col-lg-4.col-md-6.col-12").map {
it.toEpisode()
}.let {
val isReversed = (it.lastOrNull()?.episode ?: 1) < (it.firstOrNull()?.episode ?: 0)
if (isReversed)
it.reversed()
else it
}
newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) {
this.duration = duration
this.posterUrl = posterUrl
this.tags = tags.filterNotNull()
this.rating = rating
this.year = year
this.plot = synopsis
this.recommendations = recommendations
addActors(actors)
}
}
}
// // Maybe possible to not use the url shortener but cba investigating that.
// private suspend fun skipUrlShortener(url: String): AppResponse {
// return app.get(app.get(url).document.select("a.download-link").attr("href"))
// }
private fun getQualityFromId(id: Int?): Qualities {
return when (id) {
2 -> Qualities.P360 // Extrapolated
3 -> Qualities.P480
4 -> Qualities.P720
5 -> Qualities.P1080
else -> Qualities.Unknown
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val doc = app.get(data).document
val links = doc.select("div.tab-content.quality").map { element ->
val quality = getQualityFromId(element.attr("id").getIntFromText())
element.select(".col-lg-6 > a:contains(تحميل)").map { linkElement ->
if (linkElement.attr("href").contains("/download/")) {
Pair(
linkElement.attr("href"),
quality,
)
} else {
val url = "$mainUrl/download${
linkElement.attr("href").split("/link")[1]
}${data.split("/movie|/episode|/show/episode".toRegex())[1]}"
Pair(
url,
quality,
)
// just in case if they add the shorts urls again
}
}
}.flatten()
links.map {
val linkDoc = app.get(it.first).document
val button = linkDoc.select("div.btn-loader > a")
val url = button.attr("href")
callback.invoke(
ExtractorLink(
this.name,
this.name,
url,
this.mainUrl,
it.second.value
)
)
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AkwamProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AkwamProvider())
}
}

View File

@ -1,25 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=altadefinizione.tienda&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,159 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
import com.lagradost.cloudstream3.utils.AppUtils.html
class AltadefinizioneProvider : MainAPI() {
override var lang = "it"
override var mainUrl = "https://altadefinizione.tienda"
override var name = "Altadefinizione"
override val hasMainPage = true
override val hasChromecastSupport = true
override val supportedTypes = setOf(
TvType.Movie
)
override val mainPage = mainPageOf(
Pair("$mainUrl/cerca/anno/2022/page/", "Ultimi Film"),
Pair("$mainUrl/cerca/openload-quality/HD/page/", "Film in HD"),
Pair("$mainUrl/cinema/page/", "Ora al cinema")
)
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
val url = request.data + page
val soup = app.get(url).document
val home = soup.select("div.box").map {
val title = it.selectFirst("img")!!.attr("alt")
val link = it.selectFirst("a")!!.attr("href")
val image = mainUrl + it.selectFirst("img")!!.attr("src")
val quality = getQualityFromString(it.selectFirst("span")!!.text())
MovieSearchResponse(
title,
link,
this.name,
TvType.Movie,
image,
null,
null,
quality,
)
}
return newHomePageResponse(request.name, home)
}
override suspend fun search(query: String): List<SearchResponse> {
val doc = app.post(
"$mainUrl/index.php", data = mapOf(
"do" to "search",
"subaction" to "search",
"story" to query,
"sortby" to "news_read"
)
).document
return doc.select("div.box").map {
val title = it.selectFirst("img")!!.attr("alt")
val link = it.selectFirst("a")!!.attr("href")
val image = mainUrl + it.selectFirst("img")!!.attr("src")
val quality = getQualityFromString(it.selectFirst("span")!!.text())
MovieSearchResponse(
title,
link,
this.name,
TvType.Movie,
image,
null,
null,
quality,
)
}
}
override suspend fun load(url: String): LoadResponse {
val page = app.get(url)
val document = page.document
val title = document.selectFirst(" h1 > a")!!.text().replace("streaming", "")
val description = document.select("#sfull").toString().substringAfter("altadefinizione")
.substringBeforeLast("fonte trama").html().toString()
val rating = null
val year = document.selectFirst("#details > li:nth-child(2)")!!.childNode(2).toString()
.filter { it.isDigit() }.toInt()
val poster = fixUrl(document.selectFirst("div.thumbphoto > img")!!.attr("src"))
val recomm = document.select("ul.related-list > li").map {
val href = it.selectFirst("a")!!.attr("href")
val posterUrl = mainUrl + it.selectFirst("img")!!.attr("src")
val name = it.selectFirst("img")!!.attr("alt")
MovieSearchResponse(
name,
href,
this.name,
TvType.Movie,
posterUrl,
null
)
}
val actors: List<ActorData> =
document.select("#staring > a").map {
ActorData(actor = Actor(it.text()))
}
val tags: List<String> = document.select("#details > li:nth-child(1) > a").map { it.text() }
val trailerurl = document.selectFirst("#showtrailer > div > div > iframe")?.attr("src")
return newMovieLoadResponse(
title,
url,
TvType.Movie,
url
) {
posterUrl = fixUrlNull(poster)
this.year = year
this.plot = description
this.rating = rating
this.recommendations = recomm
this.duration = null
this.actors = actors
this.tags = tags
addTrailer(trailerurl)
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val doc = app.get(data).document
if (doc.select("div.guardahd-player").isNullOrEmpty()) {
val videoUrl =
doc.select("input").last { it.hasAttr("data-mirror") }.attr("value")
loadExtractor(videoUrl, data, subtitleCallback, callback)
doc.select("#mirrors > li > a").forEach {
loadExtractor(fixUrl(it.attr("data-target")), data, subtitleCallback, callback)
}
} else {
val pagelinks = doc.select("div.guardahd-player").select("iframe").attr("src")
val docLinks = app.get(pagelinks).document
docLinks.select("body > div > ul > li").forEach {
loadExtractor(fixUrl(it.attr("data-link")), data, subtitleCallback, callback)
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AltadefinizioneProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AltadefinizioneProvider())
}
}

View File

@ -1,28 +0,0 @@
// use an integer for version numbers
version = 2
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AnimeMovie",
"Anime",
"OVA"
)
iconUrl = "https://www.google.com/s2/favicons?domain=aniplay.it&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,216 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
import com.lagradost.cloudstream3.LoadResponse.Companion.addDuration
import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.M3u8Helper
import com.lagradost.cloudstream3.utils.Qualities
class AniPlayProvider : MainAPI() {
override var mainUrl = "https://aniplay.it"
override var name = "AniPlay"
override var lang = "it"
override val hasMainPage = true
private val dubIdentifier = " (ITA)"
override val supportedTypes = setOf(
TvType.Anime,
TvType.AnimeMovie,
TvType.OVA
)
companion object {
fun getStatus(t: String?): ShowStatus? {
return when (t?.lowercase()) {
"completato" -> ShowStatus.Completed
"in corso" -> ShowStatus.Ongoing
else -> null // "annunciato"
}
}
fun getType(t: String?): TvType {
return when (t?.lowercase()) {
"ona" -> TvType.OVA
"movie" -> TvType.AnimeMovie
else -> TvType.Anime //"serie", "special"
}
}
}
private fun isDub(title: String): Boolean{
return title.contains(dubIdentifier)
}
data class ApiPoster(
@JsonProperty("imageFull") val posterUrl: String
)
data class ApiMainPageAnime(
@JsonProperty("animeId") val id: Int,
@JsonProperty("episodeNumber") val episode: String?,
@JsonProperty("animeTitle") val title: String,
@JsonProperty("animeType") val type: String,
@JsonProperty("fullHd") val fullHD: Boolean,
@JsonProperty("animeVerticalImages") val posters: List<ApiPoster>
)
data class ApiSearchResult(
@JsonProperty("id") val id: Int,
@JsonProperty("title") val title: String,
@JsonProperty("status") val status: String,
@JsonProperty("type") val type: String,
@JsonProperty("verticalImages") val posters: List<ApiPoster>
)
data class ApiGenres(
@JsonProperty("description") val name: String
)
data class ApiWebsite(
@JsonProperty("listWebsiteId") val websiteId: Int,
@JsonProperty("url") val url: String
)
data class ApiEpisode(
@JsonProperty("id") val id: Int,
@JsonProperty("title") val title: String?,
@JsonProperty("episodeNumber") val number: String,
)
private fun ApiEpisode.toEpisode() : Episode? {
val number = this.number.toIntOrNull() ?: return null
return Episode(
data = "$mainUrl/api/episode/${this.id}",
episode = number,
name = this.title
)
}
data class ApiSeason(
@JsonProperty("id") val id: Int,
@JsonProperty("name") val name: String
)
private suspend fun ApiSeason.toEpisodeList(url: String) : List<Episode> {
return parseJson<List<ApiEpisode>>(app.get("$url/season/${this.id}").text).mapNotNull { it.toEpisode() }
}
data class ApiAnime(
@JsonProperty("title") val title: String,
@JsonProperty("alternativeTitle") val japTitle: String?,
@JsonProperty("episodeDuration") val duration: Int,
@JsonProperty("storyline") val plot: String,
@JsonProperty("type") val type: String,
@JsonProperty("status") val status: String,
@JsonProperty("genres") val genres: List<ApiGenres>,
@JsonProperty("verticalImages") val posters: List<ApiPoster>,
@JsonProperty("listWebsites") val websites: List<ApiWebsite>,
@JsonProperty("episodes") val episodes: List<ApiEpisode>,
@JsonProperty("seasons") val seasons: List<ApiSeason>?
)
data class ApiEpisodeUrl(
@JsonProperty("videoUrl") val url: String
)
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val response = parseJson<List<ApiMainPageAnime>>(app.get("$mainUrl/api/home/latest-episodes?page=0").text)
val results = response.map{
val isDub = isDub(it.title)
newAnimeSearchResponse(
name = if (isDub) it.title.replace(dubIdentifier, "") else it.title,
url = "$mainUrl/api/anime/${it.id}",
type = getType(it.type),
){
addDubStatus(isDub, it.episode?.toIntOrNull())
this.posterUrl = it.posters.first().posterUrl
this.quality = if (it.fullHD) SearchQuality.HD else null
}
}
return HomePageResponse(listOf(HomePageList("Ultime uscite",results)))
}
override suspend fun search(query: String): List<SearchResponse> {
val response = parseJson<List<ApiSearchResult>>(app.get("$mainUrl/api/anime/advanced-search?page=0&size=36&query=$query").text)
return response.map {
val isDub = isDub(it.title)
newAnimeSearchResponse(
name = if (isDub) it.title.replace(dubIdentifier, "") else it.title,
url = "$mainUrl/api/anime/${it.id}",
type = getType(it.type),
){
addDubStatus(isDub)
this.posterUrl = it.posters.first().posterUrl
}
}
}
override suspend fun load(url: String): LoadResponse {
val response = parseJson<ApiAnime>(app.get(url).text)
val tags: List<String> = response.genres.map { it.name }
val malId: Int? = response.websites.find { it.websiteId == 1 }?.url?.removePrefix("https://myanimelist.net/anime/")?.split("/")?.first()?.toIntOrNull()
val aniListId: Int? = response.websites.find { it.websiteId == 4 }?.url?.removePrefix("https://anilist.co/anime/")?.split("/")?.first()?.toIntOrNull()
val episodes = if (response.seasons.isNullOrEmpty()) response.episodes.mapNotNull { it.toEpisode() } else response.seasons.map{ it.toEpisodeList(url) }.flatten()
val isDub = isDub(response.title)
return newAnimeLoadResponse(response.title, url, getType(response.type)) {
this.name = if (isDub) response.title.replace(dubIdentifier, "") else response.title
this.japName = response.japTitle
this.plot = response.plot
this.tags = tags
this.showStatus = getStatus(response.status)
addPoster(response.posters.first().posterUrl)
addEpisodes(if (isDub) DubStatus.Dubbed else DubStatus.Subbed, episodes)
addMalId(malId)
addAniListId(aniListId)
addDuration(response.duration.toString())
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val episode = parseJson<ApiEpisodeUrl>(app.get(data).text)
if(episode.url.contains(".m3u8")){
val m3u8Helper = M3u8Helper()
val streams = m3u8Helper.m3u8Generation(M3u8Helper.M3u8Stream(episode.url,Qualities.Unknown.value), false)
streams.forEach {
callback.invoke(
ExtractorLink(
name,
name,
it.streamUrl,
referer = mainUrl,
quality = it.quality ?: Qualities.Unknown.value,
isM3u8 = it.streamUrl.contains(".m3u8"))) }
return true
}
callback.invoke(
ExtractorLink(
name,
name,
episode.url,
referer = mainUrl,
quality = Qualities.Unknown.value,
isM3u8 = false,
)
)
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AniPlayProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AniPlayProvider())
}
}

View File

@ -1,27 +0,0 @@
// 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("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AnimeMovie",
"OVA",
"Anime",
)
iconUrl = "https://www.google.com/s2/favicons?domain=animeindo.sbs&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,192 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
import com.lagradost.nicehttp.NiceResponse
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
class AnimeIndoProvider : MainAPI() {
override var mainUrl = "https://animeindo.sbs"
override var name = "AnimeIndo"
override val hasMainPage = true
override var lang = "id"
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.Anime,
TvType.AnimeMovie,
TvType.OVA
)
companion object {
fun getType(t: String): TvType {
return if (t.contains("OVA") || t.contains("Special")) TvType.OVA
else if (t.contains("Movie")) TvType.AnimeMovie
else TvType.Anime
}
fun getStatus(t: String): ShowStatus {
return when (t) {
"Finished Airing" -> ShowStatus.Completed
"Currently Airing" -> ShowStatus.Ongoing
else -> ShowStatus.Completed
}
}
private suspend fun request(url: String): NiceResponse {
val req = app.get(
url,
cookies = mapOf("recaptcha_cookie" to "#Asia/Jakarta#-420#win32#Windows#0,false,false#Google Inc. (Intel)~ANGLE (Intel, Intel(R) HD Graphics 400 Direct3D11 vs_5_0 ps_5_0)")
)
if (req.isSuccessful) {
return req
} else {
val document = app.get(url).document
val captchaKey =
document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]")
.attr("src").substringAfter("render=").substringBefore("&amp")
val token = getCaptchaToken(url, captchaKey)
return app.post(
url,
data = mapOf(
"action" to "recaptcha_for_all",
"token" to "$token",
"sitekey" to captchaKey
)
)
}
}
}
override val mainPage = mainPageOf(
"$mainUrl/anime-terbaru/page/" to "Anime Terbaru",
"$mainUrl/donghua-terbaru/page/" to "Donghua Terbaru"
)
override suspend fun getMainPage(
page: Int,
request: MainPageRequest
): HomePageResponse {
val document = request(request.data + page).document
val home = document.select("div.post-show > article").mapNotNull {
it.toSearchResult()
}
return newHomePageResponse(request.name, home)
}
private fun getProperAnimeLink(uri: String): String {
return if (uri.contains("/anime/")) {
uri
} else {
var title = uri.substringAfter("$mainUrl/")
title = when {
(title.contains("-episode")) && !(title.contains("-movie")) -> Regex("(.+)-episode").find(
title
)?.groupValues?.get(1).toString()
(title.contains("-movie")) -> Regex("(.+)-movie").find(title)?.groupValues?.get(
1
).toString()
else -> title
}
"$mainUrl/anime/$title"
}
}
private fun Element.toSearchResult(): AnimeSearchResponse? {
val title = this.selectFirst("div.title")?.text()?.trim() ?: return null
val href = getProperAnimeLink(this.selectFirst("a")!!.attr("href"))
val posterUrl = this.select("img[itemprop=image]").attr("src").toString()
val type = getType(this.select("div.type").text().trim())
val epNum =
this.selectFirst("span.episode")?.ownText()?.replace(Regex("[^0-9]"), "")?.trim()
?.toIntOrNull()
return newAnimeSearchResponse(title, href, type) {
this.posterUrl = posterUrl
addSub(epNum)
}
}
override suspend fun search(query: String): List<SearchResponse> {
val link = "$mainUrl/?s=$query"
val document = request(link).document
return document.select(".site-main.relat > article").map {
val title = it.selectFirst("div.title > h2")!!.ownText().trim()
val href = it.selectFirst("a")!!.attr("href")
val posterUrl = it.selectFirst("img")!!.attr("src").toString()
val type = getType(it.select("div.type").text().trim())
newAnimeSearchResponse(title, href, type) {
this.posterUrl = posterUrl
}
}
}
override suspend fun load(url: String): LoadResponse {
val document = request(url).document
val title = document.selectFirst("h1.entry-title")?.text().toString().trim()
val poster = document.selectFirst("div.thumb > img[itemprop=image]")?.attr("src")
val tags = document.select("div.genxed > a").map { it.text() }
val type = getType(
document.selectFirst("div.info-content > div.spe > span:nth-child(6)")?.ownText()
.toString()
)
val year = Regex("\\d, ([0-9]*)").find(
document.select("div.info-content > div.spe > span:nth-child(9) > time").text()
)?.groupValues?.get(1)?.toIntOrNull()
val status = getStatus(
document.selectFirst("div.info-content > div.spe > span:nth-child(1)")!!.ownText()
.trim()
)
val description = document.select("div[itemprop=description] > p").text()
val trailer = document.selectFirst("div.player-embed iframe")?.attr("src")
val episodes = document.select("div.lstepsiode.listeps ul li").mapNotNull {
val header = it.selectFirst("span.lchx > a") ?: return@mapNotNull null
val name = header.text().trim()
val episode = header.text().trim().replace("Episode", "").trim().toIntOrNull()
val link = fixUrl(header.attr("href"))
Episode(link, name = name, episode = episode)
}.reversed()
return newAnimeLoadResponse(title, url, type) {
engName = title
posterUrl = poster
this.year = year
addEpisodes(DubStatus.Subbed, episodes)
showStatus = status
plot = description
this.tags = tags
addTrailer(trailer)
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val document = request(data).document
document.select("div.itemleft > .mirror > option").mapNotNull {
fixUrl(Jsoup.parse(base64Decode(it.attr("value"))).select("iframe").attr("src"))
}.apmap {
if (it.startsWith("https://uservideo.xyz")) {
app.get(it, referer = "$mainUrl/").document.select("iframe").attr("src")
} else {
it
}
}.apmap {
loadExtractor(it, data, subtitleCallback, callback)
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AnimeIndoProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AnimeIndoProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 2
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(
"AnimeMovie",
"Anime",
"OVA",
)
iconUrl = "https://www.google.com/s2/favicons?domain=111.90.143.42&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,195 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor
import com.lagradost.nicehttp.NiceResponse
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
class AnimeSailProvider : MainAPI() {
override var mainUrl = "https://111.90.143.42"
override var name = "AnimeSail"
override val hasMainPage = true
override var lang = "id"
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.Anime,
TvType.AnimeMovie,
TvType.OVA
)
companion object {
fun getType(t: String): TvType {
return if (t.contains("OVA") || t.contains("Special")) TvType.OVA
else if (t.contains("Movie")) TvType.AnimeMovie
else TvType.Anime
}
fun getStatus(t: String): ShowStatus {
return when (t) {
"Completed" -> ShowStatus.Completed
"Ongoing" -> ShowStatus.Ongoing
else -> ShowStatus.Completed
}
}
}
private suspend fun request(url: String, ref: String? = null): NiceResponse {
return app.get(
url,
headers = mapOf("Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"),
cookies = mapOf("_as_ipin_ct" to "ID"),
referer = ref
)
}
override val mainPage = mainPageOf(
"$mainUrl/page/" to "Episode Terbaru",
"$mainUrl/movie-terbaru/page/" to "Movie Terbaru",
"$mainUrl/genres/donghua/page/" to "Donghua"
)
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
val document = request(request.data + page).document
val home = document.select("article").map {
it.toSearchResult()
}
return newHomePageResponse(request.name, home)
}
private fun getProperAnimeLink(uri: String): String {
return if (uri.contains("/anime/")) {
uri
} else {
var title = uri.substringAfter("$mainUrl/")
title = when {
(title.contains("-episode")) && !(title.contains("-movie")) -> title.substringBefore(
"-episode"
)
(title.contains("-movie")) -> title.substringBefore("-movie")
else -> title
}
"$mainUrl/anime/$title"
}
}
private fun Element.toSearchResult(): AnimeSearchResponse {
val href = getProperAnimeLink(fixUrlNull(this.selectFirst("a")?.attr("href")).toString())
val title = this.select(".tt > h2").text().trim()
val posterUrl = fixUrlNull(this.selectFirst("div.limit img")?.attr("src"))
val epNum = this.selectFirst(".tt > h2")?.text()?.let {
Regex("Episode\\s?([0-9]+)").find(it)?.groupValues?.getOrNull(1)?.toIntOrNull()
}
return newAnimeSearchResponse(title, href, TvType.Anime) {
this.posterUrl = posterUrl
addSub(epNum)
}
}
override suspend fun search(query: String): List<SearchResponse> {
val link = "$mainUrl/?s=$query"
val document = request(link).document
return document.select("div.listupd article").map {
it.toSearchResult()
}
}
override suspend fun load(url: String): LoadResponse {
val document = request(url).document
val title = document.selectFirst("h1.entry-title")?.text().toString().trim()
val type = getType(
document.select("tbody th:contains(Tipe)").next().text()
)
val episodes = document.select("ul.daftar > li").map {
val header = it.select("a").text().trim()
val name =
Regex("(Episode\\s?[0-9]+)").find(header)?.groupValues?.getOrNull(0) ?: header
val link = fixUrl(it.select("a").attr("href"))
Episode(link, name = name)
}.reversed()
return newAnimeLoadResponse(title, url, type) {
posterUrl = document.selectFirst("div.entry-content > img")?.attr("src")
this.year =
document.select("tbody th:contains(Dirilis)").next().text().trim().toIntOrNull()
addEpisodes(DubStatus.Subbed, episodes)
showStatus =
getStatus(document.select("tbody th:contains(Status)").next().text().trim())
plot = document.selectFirst("div.entry-content > p")?.text()
this.tags =
document.select("tbody th:contains(Genre)").next().select("a").map { it.text() }
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val document = request(data).document
document.select(".mobius > .mirror > option").apmap {
safeApiCall {
val iframe = fixUrl(
Jsoup.parse(base64Decode(it.attr("data-em"))).select("iframe").attr("src")
?: throw ErrorLoadingException("No iframe found")
)
when {
iframe.startsWith("$mainUrl/utils/player/arch/") || iframe.startsWith(
"$mainUrl/utils/player/race/"
) -> request(iframe, ref = data).document.select("source").attr("src")
.let { link ->
val source =
when {
iframe.contains("/arch/") -> "Arch"
iframe.contains("/race/") -> "Race"
else -> this.name
}
val quality =
Regex("\\.([0-9]{3,4})\\.").find(link)?.groupValues?.get(1)
callback.invoke(
ExtractorLink(
source = source,
name = source,
url = link,
referer = mainUrl,
quality = quality?.toIntOrNull() ?: Qualities.Unknown.value
)
)
}
// skip for now
// iframe.startsWith("$mainUrl/utils/player/fichan/") -> ""
// iframe.startsWith("$mainUrl/utils/player/blogger/") -> ""
iframe.startsWith("https://aghanim.xyz/tools/redirect/") -> {
val link = "https://rasa-cintaku-semakin-berantai.xyz/v/${iframe.substringAfter("id=").substringBefore("&token")}"
loadExtractor(link, mainUrl, subtitleCallback, callback)
}
iframe.startsWith("$mainUrl/utils/player/framezilla/") || iframe.startsWith("https://uservideo.xyz") -> {
request(iframe, ref = data).document.select("iframe").attr("src")
.let { link ->
loadExtractor(fixUrl(link), mainUrl, subtitleCallback, callback)
}
}
else -> {
loadExtractor(iframe, mainUrl, subtitleCallback, callback)
}
}
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AnimeSailProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AnimeSailProvider())
}
}

View File

@ -1,26 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Anime",
"AnimeMovie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=www.animesaturn.cc&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,201 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
import com.lagradost.cloudstream3.LoadResponse.Companion.addDuration
import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId
import com.lagradost.cloudstream3.LoadResponse.Companion.addRating
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import org.jsoup.nodes.Element
class AnimeSaturnProvider : MainAPI() {
override var mainUrl = "https://www.animesaturn.cc"
override var name = "AnimeSaturn"
override var lang = "it"
override val hasMainPage = true
override val supportedTypes = setOf(
TvType.Anime,
TvType.AnimeMovie,
TvType.OVA
)
companion object {
fun getStatus(t: String?): ShowStatus? {
return when (t?.lowercase()) {
"finito" -> ShowStatus.Completed
"in corso" -> ShowStatus.Ongoing
else -> null
}
}
}
private fun Element.toSearchResult(): AnimeSearchResponse {
var title = this.select("a.badge-archivio").first()!!.text()
var isDubbed = false
if (title.contains(" (ITA)")){
title = title.replace(" (ITA)", "")
isDubbed = true
}
val url = this.select("a.badge-archivio").first()!!.attr("href")
val posterUrl = this.select("img.locandina-archivio[src]").first()!!.attr("src")
return newAnimeSearchResponse(title, url, TvType.Anime) {
addDubStatus(isDubbed)
this.posterUrl = posterUrl
}
}
private fun Element.toEpisode(): Episode? {
var episode = this.text().split(" ")[1]
if(episode.contains(".")) return null
if(episode.contains("-"))
episode = episode.split("-")[0]
return Episode(
data = this.attr("href"),
episode = episode.toInt()
)
}
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val document = app.get(mainUrl).document
val list = ArrayList<HomePageList>()
document.select("div.container:has(span.badge-saturn)").forEach {
val tabName = it.select("span.badge-saturn").first()!!.text()
if (tabName.equals("Ultimi episodi")) return@forEach
val results = ArrayList<AnimeSearchResponse>()
it.select(".main-anime-card").forEach { card ->
var title = card.select("a[title]").first()!!.attr("title")
var isDubbed = false
if(title.contains(" (ITA)")){
title = title.replace(" (ITA)", "")
isDubbed = true
}
val posterUrl = card.select("img.new-anime").first()!!.attr("src")
val url = card.select("a").first()!!.attr("href")
results.add(newAnimeSearchResponse(title, url, TvType.Anime){
addDubStatus(isDubbed)
this.posterUrl = posterUrl
})
}
list.add(HomePageList(tabName, results))
}
return HomePageResponse(list)
}
override suspend fun search(query: String): List<SearchResponse> {
val document = app.get("$mainUrl/animelist?search=$query").document
return document.select("div.item-archivio").map {
it.toSearchResult()
}
}
override suspend fun load(url: String): LoadResponse {
val document = app.get(url).document
val title = document.select("img.cover-anime").first()!!.attr("alt")
val japTitle = document.select("div.box-trasparente-alternativo").first()!!.text()
val posterUrl = document.select("img.cover-anime[src]").first()!!.attr("src")
var malId : Int? = null
var aniListId : Int? = null
document.select("[rel=\"noopener noreferrer\"]").forEach {
if(it.attr("href").contains("myanimelist"))
malId = it.attr("href").removeSuffix("/").split('/').last().toIntOrNull()
else
aniListId = it.attr("href").removeSuffix("/").split('/').last().toIntOrNull()
}
val plot = document.select("div#shown-trama").first()?.text()
val tags = document.select("a.generi-as").map { it.text() }
val details : List<String>? = document.select("div.container:contains(Stato: )").first()?.text()?.split(" ")
var status : String? = null
var duration : String? = null
var year : String? = null
var score : String? = null
val isDubbed = document.select("div.anime-title-as").first()!!.text().contains("(ITA)")
if (!details.isNullOrEmpty()) {
details.forEach {
val index = details.indexOf(it) +1
when (it) {
"Stato:" -> status = details[index]
"episodi:" -> duration = details[index]
"uscita:" -> year = details[index + 2]
"Voto:" -> score = details[index].split("/")[0]
else -> return@forEach
}
}
}
val episodes = document.select("a.bottone-ep").mapNotNull{ it.toEpisode() }
return newAnimeLoadResponse(title, url, TvType.Anime) {
this.engName = title
this.japName = japTitle
this.year = year?.toIntOrNull()
this.plot = plot
this.tags = tags
this.showStatus = getStatus(status)
addPoster(posterUrl)
addRating(score)
addEpisodes(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed, episodes)
addMalId(malId)
addAniListId(aniListId)
addDuration(duration)
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val page = app.get(data).document
val episodeLink = page.select("div.card-body > a[href]").find {it1 ->
it1.attr("href").contains("watch?")
}?.attr("href")
val episodePage = app.get(episodeLink!!).document
val episodeUrl: String?
var isM3U8 = false
if(episodePage.select("video.afterglow > source").isNotEmpty()) //Old player
episodeUrl = episodePage.select("video.afterglow > source").first()!!.attr("src")
else{ //New player
val script = episodePage.select("script").find {
it.toString().contains("jwplayer('player_hls').setup({")
}!!.toString()
episodeUrl = script.split(" ").find { it.contains(".m3u8") and !it.contains(".replace") }!!.replace("\"","").replace(",", "")
isM3U8 = true
}
callback.invoke(
ExtractorLink(
name,
name,
episodeUrl!!,
isM3u8 = isM3U8,
referer = "https://www.animesaturn.io/", //Some servers need the old host as referer, and the new ones accept it too
quality = Qualities.Unknown.value
)
)
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AnimeSaturnProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AnimeSaturnProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AnimeMovie",
"Anime",
"OVA",
)
iconUrl = "https://www.google.com/s2/favicons?domain=www.animeworld.tv&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

File diff suppressed because one or more lines are too long

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AnimeWorldProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AnimeWorldProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AnimeMovie",
"OVA",
"Anime",
)
iconUrl = "https://www.google.com/s2/favicons?domain=animefenix.com&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,249 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
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.Jsoup
import java.util.*
class AnimefenixProvider:MainAPI() {
override var mainUrl = "https://animefenix.com"
override var name = "Animefenix"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.AnimeMovie,
TvType.OVA,
TvType.Anime,
)
fun getDubStatus(title: String): DubStatus {
return if (title.contains("Latino") || title.contains("Castellano"))
DubStatus.Dubbed
else DubStatus.Subbed
}
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val urls = listOf(
Pair("$mainUrl/", "Animes"),
Pair("$mainUrl/animes?type[]=movie&order=default", "Peliculas", ),
Pair("$mainUrl/animes?type[]=ova&order=default", "OVA's", ),
)
val items = ArrayList<HomePageList>()
items.add(
HomePageList(
"Últimos episodios",
app.get(mainUrl).document.select(".capitulos-grid div.item").map {
val title = it.selectFirst("div.overtitle")?.text()
val poster = it.selectFirst("a img")?.attr("src")
val epRegex = Regex("(-(\\d+)\$|-(\\d+)\\.(\\d+))")
val url = it.selectFirst("a")?.attr("href")?.replace(epRegex,"")
?.replace("/ver/","/")
val epNum = it.selectFirst(".is-size-7")?.text()?.replace("Episodio ","")?.toIntOrNull()
newAnimeSearchResponse(title!!, url!!) {
this.posterUrl = poster
addDubStatus(getDubStatus(title), epNum)
}
})
)
urls.apmap { (url, name) ->
val response = app.get(url)
val soup = Jsoup.parse(response.text)
val home = soup.select(".list-series article").map {
val title = it.selectFirst("h3 a")?.text()
val poster = it.selectFirst("figure img")?.attr("src")
AnimeSearchResponse(
title!!,
it.selectFirst("a")?.attr("href") ?: "",
this.name,
TvType.Anime,
poster,
null,
if (title.contains("Latino")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed),
)
}
items.add(HomePageList(name, home))
}
if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items)
}
override suspend fun search(query: String): List<SearchResponse> {
return app.get("$mainUrl/animes?q=$query").document.select(".list-series article").map {
val title = it.selectFirst("h3 a")?.text()
val href = it.selectFirst("a")?.attr("href")
val image = it.selectFirst("figure img")?.attr("src")
AnimeSearchResponse(
title!!,
href!!,
this.name,
TvType.Anime,
fixUrl(image ?: ""),
null,
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(
DubStatus.Subbed),
)
}
}
override suspend fun load(url: String): LoadResponse {
val doc = Jsoup.parse(app.get(url, timeout = 120).text)
val poster = doc.selectFirst(".image > img")?.attr("src")
val title = doc.selectFirst("h1.title.has-text-orange")?.text()
val description = doc.selectFirst("p.has-text-light")?.text()
val genres = doc.select(".genres a").map { it.text() }
val status = when (doc.selectFirst(".is-narrow-desktop a.button")?.text()) {
"Emisión" -> ShowStatus.Ongoing
"Finalizado" -> ShowStatus.Completed
else -> null
}
val episodes = doc.select(".anime-page__episode-list li").map {
val name = it.selectFirst("span")?.text()
val link = it.selectFirst("a")?.attr("href")
Episode(link!!, name)
}.reversed()
val type = if (doc.selectFirst("ul.has-text-light")?.text()
!!.contains("Película") && episodes.size == 1
) TvType.AnimeMovie else TvType.Anime
return newAnimeLoadResponse(title!!, url, type) {
japName = null
engName = title
posterUrl = poster
addEpisodes(DubStatus.Subbed, episodes)
plot = description
tags = genres
showStatus = status
}
}
private fun cleanStreamID(input: String): String = input.replace(Regex("player=.*&amp;code=|&"),"")
data class Amazon (
@JsonProperty("file") var file : String? = null,
@JsonProperty("type") var type : String? = null,
@JsonProperty("label") var label : String? = null
)
private fun cleanExtractor(
source: String,
name: String,
url: String,
callback: (ExtractorLink) -> Unit
): Boolean {
callback(
ExtractorLink(
source,
name,
url,
"",
Qualities.Unknown.value,
false
)
)
return true
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val soup = app.get(data).document
val script = soup.selectFirst(".player-container script")?.data()
if (script!!.contains("var tabsArray =")) {
val sourcesRegex = Regex("player=.*&amp;code(.*)&")
val test = sourcesRegex.findAll(script).toList()
test.apmap {
val codestream = it.value
val links = when {
codestream.contains("player=2&amp") -> "https://embedsito.com/v/"+cleanStreamID(codestream)
codestream.contains("player=3&amp") -> "https://www.mp4upload.com/embed-"+cleanStreamID(codestream)+".html"
codestream.contains("player=6&amp") -> "https://www.yourupload.com/embed/"+cleanStreamID(codestream)
codestream.contains("player=12&amp") -> "http://ok.ru/videoembed/"+cleanStreamID(codestream)
codestream.contains("player=4&amp") -> "https://sendvid.com/"+cleanStreamID(codestream)
codestream.contains("player=9&amp") -> "AmaNormal https://www.animefenix.com/stream/amz.php?v="+cleanStreamID(codestream)
codestream.contains("player=11&amp") -> "AmazonES https://www.animefenix.com/stream/amz.php?v="+cleanStreamID(codestream)
codestream.contains("player=22&amp") -> "Fireload https://www.animefenix.com/stream/fl.php?v="+cleanStreamID(codestream)
else -> ""
}
loadExtractor(links, data, subtitleCallback, callback)
argamap({
if (links.contains("AmaNormal")) {
val doc = app.get(links.replace("AmaNormal ","")).document
doc.select("script").map { script ->
if (script.data().contains("sources: [{\"file\"")) {
val text = script.data().substringAfter("sources:").substringBefore("]").replace("[","")
val json = parseJson<Amazon>(text)
if (json.file != null) {
cleanExtractor(
"Amazon",
"Amazon ${json.label}",
json.file!!,
callback
)
}
}
}
}
if (links.contains("AmazonES")) {
val amazonES = links.replace("AmazonES ", "")
val doc = app.get("$amazonES&ext=es").document
doc.select("script").map { script ->
if (script.data().contains("sources: [{\"file\"")) {
val text = script.data().substringAfter("sources:").substringBefore("]").replace("[","")
val json = parseJson<Amazon>(text)
if (json.file != null) {
cleanExtractor(
"AmazonES",
"AmazonES ${json.label}",
json.file!!,
callback
)
}
}
}
}
if (links.contains("Fireload")) {
val doc = app.get(links.replace("Fireload ", "")).document
doc.select("script").map { script ->
if (script.data().contains("sources: [{\"file\"")) {
val text = script.data().substringAfter("sources:").substringBefore("]").replace("[","")
val json = parseJson<Amazon>(text)
val testurl = if (json.file?.contains("fireload") == true) {
app.get("https://${json.file}").text
} else null
if (testurl?.contains("error") == true) {
//
} else if (json.file?.contains("fireload") == true) {
cleanExtractor(
"Fireload",
"Fireload ${json.label}",
"https://"+json.file!!,
callback
)
}
}
}
}
})
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AnimefenixProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AnimefenixProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AnimeMovie",
"Anime",
"OVA",
)
iconUrl = "https://www.google.com/s2/favicons?domain=animeflv.io&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,239 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.getQualityFromName
import com.lagradost.cloudstream3.utils.loadExtractor
import java.util.*
class AnimeflvIOProvider : MainAPI() {
override var mainUrl = "https://animeflv.io" //Also scrapes from animeid.to
override var name = "Animeflv.io"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.AnimeMovie,
TvType.OVA,
TvType.Anime,
)
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
val items = ArrayList<HomePageList>()
val urls = listOf(
Pair("$mainUrl/series", "Series actualizadas"),
Pair("$mainUrl/peliculas", "Peliculas actualizadas"),
)
items.add(
HomePageList(
"Estrenos",
app.get(mainUrl).document.select("div#owl-demo-premiere-movies .pull-left").map {
val title = it.selectFirst("p")?.text() ?: ""
AnimeSearchResponse(
title,
fixUrl(it.selectFirst("a")?.attr("href") ?: ""),
this.name,
TvType.Anime,
it.selectFirst("img")?.attr("src"),
it.selectFirst("span.year").toString().toIntOrNull(),
EnumSet.of(DubStatus.Subbed),
)
})
)
urls.apmap { (url, name) ->
val soup = app.get(url).document
val home = soup.select("div.item-pelicula").map {
val title = it.selectFirst(".item-detail p")?.text() ?: ""
val poster = it.selectFirst("figure img")?.attr("src")
AnimeSearchResponse(
title,
fixUrl(it.selectFirst("a")?.attr("href") ?: ""),
this.name,
TvType.Anime,
poster,
null,
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
DubStatus.Dubbed
) else EnumSet.of(DubStatus.Subbed),
)
}
items.add(HomePageList(name, home))
}
if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items)
}
override suspend fun search(query: String): List<SearchResponse> {
val headers = mapOf(
"Host" to "animeflv.io",
"User-Agent" to USER_AGENT,
"X-Requested-With" to "XMLHttpRequest",
"DNT" to "1",
"Alt-Used" to "animeflv.io",
"Connection" to "keep-alive",
"Referer" to "https://animeflv.io",
)
val url = "$mainUrl/search.html?keyword=$query"
val document = app.get(
url,
headers = headers
).document
return document.select(".item-pelicula.pull-left").map {
val title = it.selectFirst("div.item-detail p")?.text() ?: ""
val href = fixUrl(it.selectFirst("a")?.attr("href") ?: "")
var image = it.selectFirst("figure img")?.attr("src") ?: ""
val isMovie = href.contains("/pelicula/")
if (image.contains("/static/img/picture.png")) {
image = ""
}
if (isMovie) {
MovieSearchResponse(
title,
href,
this.name,
TvType.AnimeMovie,
image,
null
)
} else {
AnimeSearchResponse(
title,
href,
this.name,
TvType.Anime,
image,
null,
EnumSet.of(DubStatus.Subbed),
)
}
}
}
override suspend fun load(url: String): LoadResponse? {
// Gets the url returned from searching.
val soup = app.get(url).document
val title = soup.selectFirst(".info-content h1")?.text()
val description = soup.selectFirst("span.sinopsis")?.text()?.trim()
val poster: String? = soup.selectFirst(".poster img")?.attr("src")
val episodes = soup.select(".item-season-episodes a").map { li ->
val href = fixUrl(li.selectFirst("a")?.attr("href") ?: "")
val name = li.selectFirst("a")?.text() ?: ""
Episode(
href, name,
)
}.reversed()
val year = Regex("(\\d*)").find(soup.select(".info-half").text())
val tvType = if (url.contains("/pelicula/")) TvType.AnimeMovie else TvType.Anime
val genre = soup.select(".content-type-a a")
.map { it?.text()?.trim().toString().replace(", ", "") }
val duration = Regex("""(\d*)""").find(
soup.select("p.info-half:nth-child(4)").text()
)
return when (tvType) {
TvType.Anime -> {
return newAnimeLoadResponse(title ?: "", url, tvType) {
japName = null
engName = title
posterUrl = poster
this.year = null
addEpisodes(DubStatus.Subbed, episodes)
plot = description
tags = genre
showStatus = null
}
}
TvType.AnimeMovie -> {
MovieLoadResponse(
title ?: "",
url,
this.name,
tvType,
url,
poster,
year.toString().toIntOrNull(),
description,
null,
genre,
duration.toString().toIntOrNull(),
)
}
else -> null
}
}
data class MainJson(
@JsonProperty("source") val source: List<Source>,
@JsonProperty("source_bk") val sourceBk: String?,
@JsonProperty("track") val track: List<String>?,
@JsonProperty("advertising") val advertising: List<String>?,
@JsonProperty("linkiframe") val linkiframe: String?
)
data class Source(
@JsonProperty("file") val file: String,
@JsonProperty("label") val label: String,
@JsonProperty("default") val default: String,
@JsonProperty("type") val type: String
)
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
app.get(data).document.select("li.tab-video").apmap {
val url = fixUrl(it.attr("data-video"))
if (url.contains("animeid")) {
val ajaxurl = url.replace("streaming.php", "ajax.php")
val ajaxurltext = app.get(ajaxurl).text
val json = parseJson<MainJson>(ajaxurltext)
json.source.forEach { source ->
if (source.file.contains("m3u8")) {
generateM3u8(
"Animeflv.io",
source.file,
"https://animeid.to",
headers = mapOf("Referer" to "https://animeid.to")
).apmap {
callback(
ExtractorLink(
"Animeflv.io",
"Animeflv.io",
it.url,
"https://animeid.to",
getQualityFromName(it.quality.toString()),
it.url.contains("m3u8")
)
)
}
} else {
callback(
ExtractorLink(
name,
"$name ${source.label}",
source.file,
"https://animeid.to",
Qualities.Unknown.value,
isM3u8 = source.file.contains("m3u8")
)
)
}
}
}
loadExtractor(url, data, subtitleCallback, callback)
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AnimeflvIOProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AnimeflvIOProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AnimeMovie",
"Anime",
"OVA",
)
iconUrl = "https://www.google.com/s2/favicons?domain=www3.animeflv.net&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,182 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
import java.util.*
class AnimeflvnetProvider : MainAPI() {
companion object {
fun getType(t: String): TvType {
return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA
else if (t.contains("Película")) TvType.AnimeMovie
else TvType.Anime
}
fun getDubStatus(title: String): DubStatus {
return if (title.contains("Latino") || title.contains("Castellano"))
DubStatus.Dubbed
else DubStatus.Subbed
}
}
override var mainUrl = "https://www3.animeflv.net"
override var name = "Animeflv.net"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.AnimeMovie,
TvType.OVA,
TvType.Anime,
)
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val urls = listOf(
Pair("$mainUrl/browse?type[]=movie&order=updated", "Películas"),
Pair("$mainUrl/browse?status[]=2&order=default", "Animes"),
Pair("$mainUrl/browse?status[]=1&order=rating", "En emision"),
)
val items = ArrayList<HomePageList>()
items.add(
HomePageList(
"Últimos episodios",
app.get(mainUrl).document.select("main.Main ul.ListEpisodios li").mapNotNull {
val title = it.selectFirst("strong.Title")?.text() ?: return@mapNotNull null
val poster = it.selectFirst("span img")?.attr("src") ?: return@mapNotNull null
val epRegex = Regex("(-(\\d+)\$)")
val url = it.selectFirst("a")?.attr("href")?.replace(epRegex, "")
?.replace("ver/", "anime/") ?: return@mapNotNull null
val epNum =
it.selectFirst("span.Capi")?.text()?.replace("Episodio ", "")?.toIntOrNull()
newAnimeSearchResponse(title, url) {
this.posterUrl = fixUrl(poster)
addDubStatus(getDubStatus(title), epNum)
}
})
)
for ((url, name) in urls) {
try {
val doc = app.get(url).document
val home = doc.select("ul.ListAnimes li article").mapNotNull {
val title = it.selectFirst("h3.Title")?.text() ?: return@mapNotNull null
val poster = it.selectFirst("figure img")?.attr("src") ?: return@mapNotNull null
newAnimeSearchResponse(
title,
fixUrl(it.selectFirst("a")?.attr("href") ?: return@mapNotNull null)
) {
this.posterUrl = fixUrl(poster)
addDubStatus(getDubStatus(title))
}
}
items.add(HomePageList(name, home))
} catch (e: Exception) {
e.printStackTrace()
}
}
if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items)
}
data class SearchObject(
@JsonProperty("id") val id: String,
@JsonProperty("title") val title: String,
@JsonProperty("type") val type: String,
@JsonProperty("last_id") val lastId: String,
@JsonProperty("slug") val slug: String
)
override suspend fun search(query: String): List<SearchResponse> {
val response = app.post(
"https://www3.animeflv.net/api/animes/search",
data = mapOf(Pair("value", query))
).text
val json = parseJson<List<SearchObject>>(response)
return json.map { searchr ->
val title = searchr.title
val href = "$mainUrl/anime/${searchr.slug}"
val image = "$mainUrl/uploads/animes/covers/${searchr.id}.jpg"
AnimeSearchResponse(
title,
href,
this.name,
TvType.Anime,
fixUrl(image),
null,
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(
DubStatus.Subbed
),
)
}
}
override suspend fun load(url: String): LoadResponse {
val doc = app.get(url).document
val episodes = ArrayList<Episode>()
val title = doc.selectFirst("h1.Title")!!.text()
val poster = doc.selectFirst("div.AnimeCover div.Image figure img")?.attr("src")!!
val description = doc.selectFirst("div.Description p")?.text()
val type = doc.selectFirst("span.Type")?.text() ?: ""
val status = when (doc.selectFirst("p.AnmStts span")?.text()) {
"En emision" -> ShowStatus.Ongoing
"Finalizado" -> ShowStatus.Completed
else -> null
}
val genre = doc.select("nav.Nvgnrs a")
.map { it?.text()?.trim().toString() }
doc.select("script").map { script ->
if (script.data().contains("var episodes = [")) {
val data = script.data().substringAfter("var episodes = [").substringBefore("];")
data.split("],").forEach {
val epNum = it.removePrefix("[").substringBefore(",")
// val epthumbid = it.removePrefix("[").substringAfter(",").substringBefore("]")
val animeid = doc.selectFirst("div.Strs.RateIt")?.attr("data-id")
val epthumb = "https://cdn.animeflv.net/screenshots/$animeid/$epNum/th_3.jpg"
val link = url.replace("/anime/", "/ver/") + "-$epNum"
episodes.add(
Episode(
link,
null,
posterUrl = epthumb,
episode = epNum.toIntOrNull()
)
)
}
}
}
return newAnimeLoadResponse(title, url, getType(type)) {
posterUrl = fixUrl(poster)
addEpisodes(DubStatus.Subbed, episodes.reversed())
showStatus = status
plot = description
tags = genre
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
app.get(data).document.select("script").apmap { script ->
if (script.data().contains("var videos = {") || script.data()
.contains("var anime_id =") || script.data().contains("server")
) {
val videos = script.data().replace("\\/", "/")
fetchUrls(videos).map {
it.replace("https://embedsb.com/e/", "https://watchsb.com/e/")
.replace("https://ok.ru", "http://ok.ru")
}.apmap {
loadExtractor(it, data, subtitleCallback, callback)
}
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class AnimeflvnetProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(AnimeflvnetProvider())
}
}

View File

@ -1,25 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Live",
)
iconUrl = "https://www.google.com/s2/favicons?domain=calciostreaming.live&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,107 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.*
class CalcioStreamingProvider : MainAPI() {
override var lang = "it"
override var mainUrl = "https://calciostreaming.live"
override var name = "CalcioStreaming"
override val hasMainPage = true
override val hasChromecastSupport = true
override val supportedTypes = setOf(
TvType.Live,
)
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
val document = app.get(mainUrl+"/partite-streaming.html").document
val sections = document.select("div.slider-title").filter {it -> it.select("div.item").isNotEmpty()}
if (sections.isEmpty()) throw ErrorLoadingException()
return HomePageResponse(sections.map { it ->
val categoryname = it.selectFirst("h2 > strong")!!.text()
val shows = it.select("div.item").map {
val href = it.selectFirst("a")!!.attr("href")
val name = it.selectFirst("a > div > h1")!!.text()
val posterurl = fixUrl(it.selectFirst("a > img")!!.attr("src"))
LiveSearchResponse(
name,
href,
this@CalcioStreamingProvider.name,
TvType.Live,
posterurl,
)
}
HomePageList(
categoryname,
shows,
isHorizontalImages = true
)
})
}
override suspend fun load(url: String): LoadResponse {
val document = app.get(url).document
val poster = fixUrl(document.select("#title-single > div").attr("style").substringAfter("url(").substringBeforeLast(")"))
val Matchstart = document.select("div.info-wrap > div").textNodes().joinToString("").trim()
return LiveStreamLoadResponse(
document.selectFirst(" div.info-t > h1")!!.text(),
url,
this.name,
url,
poster,
plot = Matchstart
)
}
private suspend fun extractVideoLinks(
url: String,
callback: (ExtractorLink) -> Unit
) {
val document = app.get(url).document
document.select("button.btn").forEach { button ->
val link1 = button.attr("data-link")
val doc2 = app.get(link1).document
val truelink = doc2.selectFirst("iframe")!!.attr("src")
val newpage = app.get(truelink, referer = link1).document
val streamurl = Regex(""""((.|\n)*?).";""").find(
getAndUnpack(
newpage.select("script")[6].childNode(0).toString()
))!!.value.replace("""src="""", "").replace(""""""", "").replace(";", "")
callback(
ExtractorLink(
this.name,
button.text(),
streamurl,
truelink,
quality = 0,
true
)
)
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
extractVideoLinks(data, callback)
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class CalcioStreamingProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(CalcioStreamingProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=cb01.rip&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,187 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
class CineBlogProvider : MainAPI() {
override var lang = "it"
override var mainUrl = "https://cb01.rip"
override var name = "CineBlog"
override val hasMainPage = true
override val hasChromecastSupport = true
override val supportedTypes = setOf(
TvType.Movie,
TvType.TvSeries,
)
override val mainPage = mainPageOf(
Pair("$mainUrl/popolari/page/number/?get=movies", "Film Popolari"),
Pair("$mainUrl/popolari/page/number/?get=tv", "Serie Tv Popolari"),
Pair("$mainUrl/i-piu-votati/page/number/?get=movies", "Film più votati"),
Pair("$mainUrl/i-piu-votati/page/number/?get=tv", "Serie Tv più votate"),
Pair("$mainUrl/anno/2022/page/number", "Ultime uscite"),
)
override suspend fun getMainPage(
page: Int,
request : MainPageRequest
): HomePageResponse {
val url = request.data.replace("number", page.toString())
val soup = app.get(url, referer = url.substringBefore("page")).document
val home = soup.select("article.item").map {
val title = it.selectFirst("div.data > h3 > a")!!.text().substringBefore("(")
val link = it.selectFirst("div.poster > a")!!.attr("href")
val quality = getQualityFromString(it.selectFirst("span.quality")?.text())
TvSeriesSearchResponse(
title,
link,
this.name,
TvType.Movie,
it.selectFirst("img")!!.attr("src"),
null,
null,
quality = quality
)
}
return newHomePageResponse(request.name, home)
}
override suspend fun search(query: String): List<SearchResponse> {
val queryformatted = query.replace(" ", "+")
val url = "$mainUrl?s=$queryformatted"
val doc = app.get(url,referer= mainUrl ).document
return doc.select("div.result-item").map {
val href = it.selectFirst("div.image > div > a")!!.attr("href")
val poster = it.selectFirst("div.image > div > a > img")!!.attr("src")
val name = it.selectFirst("div.details > div.title > a")!!.text().substringBefore("(")
MovieSearchResponse(
name,
href,
this.name,
TvType.Movie,
poster
)
}
}
override suspend fun load(url: String): LoadResponse {
val page = app.get(url)
val document = page.document
val type = if (url.contains("film")) TvType.Movie else TvType.TvSeries
val title = document.selectFirst("div.data > h1")!!.text().substringBefore("(")
val description = document.select("#info > div.wp-content > p").html().toString()
val rating = null
var year = document.selectFirst(" div.data > div.extra > span.date")!!.text().substringAfter(",")
.filter { it.isDigit() }
if (year.length > 4) {
year = year.dropLast(4)
}
val poster = document.selectFirst("div.poster > img")!!.attr("src")
val recomm = document.select("#single_relacionados >article").map {
val href = it.selectFirst("a")!!.attr("href")
val posterUrl = it.selectFirst("a > img")!!.attr("src")
val name = it.selectFirst("a > img")!!.attr("alt").substringBeforeLast("(")
MovieSearchResponse(
name,
href,
this.name,
TvType.Movie,
posterUrl
)
}
if (type == TvType.TvSeries) {
val episodeList = ArrayList<Episode>()
document.select("#seasons > div").reversed().map { element ->
val season = element.selectFirst("div.se-q > span.se-t")!!.text().toInt()
element.select("div.se-a > ul > li").filter { it -> it.text()!="There are still no episodes this season" }.map{ episode ->
val href = episode.selectFirst("div.episodiotitle > a")!!.attr("href")
val epNum =episode.selectFirst("div.numerando")!!.text().substringAfter("-").filter { it.isDigit() }.toIntOrNull()
val epTitle = episode.selectFirst("div.episodiotitle > a")!!.text()
val posterUrl = episode.selectFirst("div.imagen > img")!!.attr("src")
episodeList.add(
Episode(
href,
epTitle,
season,
epNum,
posterUrl,
)
)
}
}
return TvSeriesLoadResponse(
title,
url,
this.name,
type,
episodeList,
fixUrlNull(poster),
year.toIntOrNull(),
description,
null,
rating,
null,
null,
mutableListOf(),
recomm
)
} else {
val actors: List<ActorData> =
document.select("div.person").filter{ it -> it.selectFirst("div.img > a > img")?.attr("src")!!.contains("/no/cast.png").not()}.map { actordata ->
val actorName = actordata.selectFirst("div.data > div.name > a")!!.text()
val actorImage : String? = actordata.selectFirst("div.img > a > img")?.attr("src")
val roleActor = actordata.selectFirst("div.data > div.caracter")!!.text()
ActorData(actor = Actor(actorName, image = actorImage), roleString = roleActor )
}
return newMovieLoadResponse(
title,
url,
type,
url
) {
posterUrl = fixUrlNull(poster)
this.year = year.toIntOrNull()
this.plot = description
this.rating = rating
this.recommendations = recomm
this.duration = null
this.actors = actors
}
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val doc = app.get(data).document
val type = if( data.contains("film") ){"movie"} else {"tv"}
val idpost=doc.select("#player-option-1").attr("data-post")
val test = app.post("$mainUrl/wp-admin/admin-ajax.php", headers = mapOf(
"content-type" to "application/x-www-form-urlencoded; charset=UTF-8",
"accept" to "*/*",
"X-Requested-With" to "XMLHttpRequest",
), data = mapOf(
"action" to "doo_player_ajax",
"post" to idpost,
"nume" to "1",
"type" to type,
))
val url2= Regex("""src='((.|\\n)*?)'""").find(test.text)?.groups?.get(1)?.value.toString()
val trueUrl = app.get(url2, headers = mapOf("referer" to mainUrl)).url
loadExtractor(trueUrl, data, subtitleCallback, callback)
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class CineBlogProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(CineBlogProvider())
}
}

View File

@ -1,26 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=cinecalidad.lol&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,258 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
// import com.lagradost.cloudstream3.extractors.Cinestart
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
class CinecalidadProvider : MainAPI() {
override var mainUrl = "https://cinecalidad.lol"
override var name = "Cinecalidad"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.Movie,
TvType.TvSeries,
)
override val vpnStatus = VPNStatus.MightBeNeeded //Due to evoload sometimes not loading
override val mainPage = mainPageOf(
Pair("$mainUrl/ver-serie/page/", "Series"),
Pair("$mainUrl/page/", "Peliculas"),
Pair("$mainUrl/genero-de-la-pelicula/peliculas-en-calidad-4k/page/", "4K UHD"),
)
override suspend fun getMainPage(
page: Int,
request : MainPageRequest
): HomePageResponse {
val url = request.data + page
val soup = app.get(url).document
val home = soup.select(".item.movies").map {
val title = it.selectFirst("div.in_title")!!.text()
val link = it.selectFirst("a")!!.attr("href")
TvSeriesSearchResponse(
title,
link,
this.name,
if (link.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries,
it.selectFirst(".poster.custom img")!!.attr("data-src"),
null,
null,
)
}
return newHomePageResponse(request.name, home)
}
override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/?s=${query}"
val document = app.get(url).document
return document.select("article").map {
val title = it.selectFirst("div.in_title")!!.text()
val href = it.selectFirst("a")!!.attr("href")
val image = it.selectFirst(".poster.custom img")!!.attr("data-src")
val isMovie = href.contains("/ver-pelicula/")
if (isMovie) {
MovieSearchResponse(
title,
href,
this.name,
TvType.Movie,
image,
null
)
} else {
TvSeriesSearchResponse(
title,
href,
this.name,
TvType.TvSeries,
image,
null,
null
)
}
}
}
override suspend fun load(url: String): LoadResponse? {
val soup = app.get(url, timeout = 120).document
val title = soup.selectFirst(".single_left h1")!!.text()
val description = soup.selectFirst("div.single_left table tbody tr td p")?.text()?.trim()
val poster: String? = soup.selectFirst(".alignnone")!!.attr("data-src")
val episodes = soup.select("div.se-c div.se-a ul.episodios li").map { li ->
val href = li.selectFirst("a")!!.attr("href")
val epThumb = li.selectFirst("img.lazy")!!.attr("data-src")
val name = li.selectFirst(".episodiotitle a")!!.text()
val seasonid =
li.selectFirst(".numerando")!!.text().replace(Regex("(S|E)"), "").let { str ->
str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() }
}
val isValid = seasonid.size == 2
val episode = if (isValid) seasonid.getOrNull(1) else null
val season = if (isValid) seasonid.getOrNull(0) else null
Episode(
href,
name,
season,
episode,
if (epThumb.contains("svg")) null else epThumb
)
}
return when (val tvType =
if (url.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries) {
TvType.TvSeries -> {
TvSeriesLoadResponse(
title,
url,
this.name,
tvType,
episodes,
poster,
null,
description,
)
}
TvType.Movie -> {
MovieLoadResponse(
title,
url,
this.name,
tvType,
url,
poster,
null,
description,
)
}
else -> null
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val datam = app.get(data)
val doc = datam.document
val datatext = datam.text
doc.select(".dooplay_player_option").apmap {
val url = it.attr("data-option")
// if (url.startsWith("https://cinestart.net")) {
// val extractor = Cinestart()
// extractor.getSafeUrl(url, null, subtitleCallback, callback)
// } else {
loadExtractor(url, mainUrl, subtitleCallback, callback)
// }
if (url.startsWith("https://cinecalidad.lol")) {
val cineurlregex =
Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
cineurlregex.findAll(url).map {
it.value.replace("/play/", "/play/r.php")
}.toList().apmap {
app.get(
it,
headers = mapOf(
"Host" to "cinecalidad.lol",
"User-Agent" to USER_AGENT,
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language" to "en-US,en;q=0.5",
"DNT" to "1",
"Connection" to "keep-alive",
"Referer" to data,
"Upgrade-Insecure-Requests" to "1",
"Sec-Fetch-Dest" to "iframe",
"Sec-Fetch-Mode" to "navigate",
"Sec-Fetch-Site" to "same-origin",
"Sec-Fetch-User" to "?1",
),
allowRedirects = false
).okhttpResponse.headers.values("location").apmap { extractedurl ->
if (extractedurl.contains("cinestart")) {
loadExtractor(extractedurl, mainUrl, subtitleCallback, callback)
}
}
}
}
}
if (datatext.contains("en castellano")) app.get("$data?ref=es").document.select(".dooplay_player_option")
.apmap {
val url = it.attr("data-option")
// if (url.startsWith("https://cinestart.net")) {
// val extractor = Cinestart()
// extractor.getSafeUrl(url, null, subtitleCallback, callback)
// } else {
loadExtractor(url, mainUrl, subtitleCallback, callback)
// }
if (url.startsWith("https://cinecalidad.lol")) {
val cineurlregex =
Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
cineurlregex.findAll(url).map {
it.value.replace("/play/", "/play/r.php")
}.toList().apmap {
app.get(
it,
headers = mapOf(
"Host" to "cinecalidad.lol",
"User-Agent" to USER_AGENT,
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language" to "en-US,en;q=0.5",
"DNT" to "1",
"Connection" to "keep-alive",
"Referer" to data,
"Upgrade-Insecure-Requests" to "1",
"Sec-Fetch-Dest" to "iframe",
"Sec-Fetch-Mode" to "navigate",
"Sec-Fetch-Site" to "same-origin",
"Sec-Fetch-User" to "?1",
),
allowRedirects = false
).okhttpResponse.headers.values("location").apmap { extractedurl ->
if (extractedurl.contains("cinestart")) {
loadExtractor(extractedurl, mainUrl, subtitleCallback, callback)
}
}
}
}
}
if (datatext.contains("Subtítulo LAT") || datatext.contains("Forzados LAT")) {
doc.select("#panel_descarga.pane a").apmap {
val link =
if (data.contains("serie") || data.contains("episodio")) "${data}${it.attr("href")}"
else it.attr("href")
val docsub = app.get(link)
val linksub = docsub.document
val validsub = docsub.text
if (validsub.contains("Subtítulo") || validsub.contains("Forzados")) {
val langregex = Regex("(Subtítulo.*\$|Forzados.*\$)")
val langdoc = linksub.selectFirst("div.titulo h3")!!.text()
val reallang = langregex.find(langdoc)?.destructured?.component1()
linksub.select("a.link").apmap {
val sublink =
if (data.contains("serie") || data.contains("episodio")) "${data}${
it.attr("href")
}"
else it.attr("href")
subtitleCallback(
SubtitleFile(reallang!!, sublink)
)
}
}
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class CinecalidadProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(CinecalidadProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Anime",
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=cuevana3.me&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,324 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
class CuevanaProvider : MainAPI() {
override var mainUrl = "https://cuevana3.me"
override var name = "Cuevana"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.Movie,
TvType.TvSeries,
)
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val items = ArrayList<HomePageList>()
val urls = listOf(
Pair(mainUrl, "Recientemente actualizadas"),
Pair("$mainUrl/estrenos/", "Estrenos"),
)
items.add(
HomePageList(
"Series",
app.get("$mainUrl/serie", timeout = 120).document.select("section.home-series li")
.map {
val title = it.selectFirst("h2.Title")!!.text()
val poster = it.selectFirst("img.lazy")!!.attr("data-src")
val url = it.selectFirst("a")!!.attr("href")
TvSeriesSearchResponse(
title,
url,
this.name,
TvType.Anime,
poster,
null,
null,
)
})
)
for ((url, name) in urls) {
try {
val soup = app.get(url).document
val home = soup.select("section li.xxx.TPostMv").map {
val title = it.selectFirst("h2.Title")!!.text()
val link = it.selectFirst("a")!!.attr("href")
TvSeriesSearchResponse(
title,
link,
this.name,
if (link.contains("/pelicula/")) TvType.Movie else TvType.TvSeries,
it.selectFirst("img.lazy")!!.attr("data-src"),
null,
null,
)
}
items.add(HomePageList(name, home))
} catch (e: Exception) {
logError(e)
}
}
if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items)
}
override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/?s=${query}"
val document = app.get(url).document
return document.select("li.xxx.TPostMv").map {
val title = it.selectFirst("h2.Title")!!.text()
val href = it.selectFirst("a")!!.attr("href")
val image = it.selectFirst("img.lazy")!!.attr("data-src")
val isSerie = href.contains("/serie/")
if (isSerie) {
TvSeriesSearchResponse(
title,
href,
this.name,
TvType.TvSeries,
image,
null,
null
)
} else {
MovieSearchResponse(
title,
href,
this.name,
TvType.Movie,
image,
null
)
}
}
}
override suspend fun load(url: String): LoadResponse? {
val soup = app.get(url, timeout = 120).document
val title = soup.selectFirst("h1.Title")!!.text()
val description = soup.selectFirst(".Description p")?.text()?.trim()
val poster: String? = soup.selectFirst(".movtv-info div.Image img")!!.attr("data-src")
val year1 = soup.selectFirst("footer p.meta").toString()
val yearRegex = Regex("<span>(\\d+)</span>")
val yearf =
yearRegex.find(year1)?.destructured?.component1()?.replace(Regex("<span>|</span>"), "")
val year = if (yearf.isNullOrBlank()) null else yearf.toIntOrNull()
val episodes = soup.select(".all-episodes li.TPostMv article").map { li ->
val href = li.select("a").attr("href")
val epThumb =
li.selectFirst("div.Image img")?.attr("data-src") ?: li.selectFirst("img.lazy")!!
.attr("data-srcc")
val seasonid = li.selectFirst("span.Year")!!.text().let { str ->
str.split("x").mapNotNull { subStr -> subStr.toIntOrNull() }
}
val isValid = seasonid.size == 2
val episode = if (isValid) seasonid.getOrNull(1) else null
val season = if (isValid) seasonid.getOrNull(0) else null
Episode(
href,
null,
season,
episode,
fixUrl(epThumb)
)
}
val tags = soup.select("ul.InfoList li.AAIco-adjust:contains(Genero) a").map { it.text() }
val tvType = if (episodes.isEmpty()) TvType.Movie else TvType.TvSeries
val recelement =
if (tvType == TvType.TvSeries) "main section div.series_listado.series div.xxx"
else "main section ul.MovieList li"
val recommendations =
soup.select(recelement).mapNotNull { element ->
val recTitle = element.select("h2.Title").text() ?: return@mapNotNull null
val image = element.select("figure img")?.attr("data-src")
val recUrl = fixUrl(element.select("a").attr("href"))
MovieSearchResponse(
recTitle,
recUrl,
this.name,
TvType.Movie,
image,
year = null
)
}
return when (tvType) {
TvType.TvSeries -> {
TvSeriesLoadResponse(
title,
url,
this.name,
tvType,
episodes,
poster,
year,
description,
tags = tags,
recommendations = recommendations
)
}
TvType.Movie -> {
MovieLoadResponse(
title,
url,
this.name,
tvType,
url,
poster,
year,
description,
tags = tags,
recommendations = recommendations
)
}
else -> null
}
}
data class Femcuevana(
@JsonProperty("url") val url: String,
)
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
app.get(data).document.select("div.TPlayer.embed_div iframe").apmap {
val iframe = fixUrl(it.attr("data-src"))
if (iframe.contains("api.cuevana3.me/fembed/")) {
val femregex =
Regex("(https.\\/\\/api\\.cuevana3\\.me\\/fembed\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
femregex.findAll(iframe).map { femreg ->
femreg.value
}.toList().apmap { fem ->
val key = fem.replace("https://api.cuevana3.me/fembed/?h=", "")
val url = app.post(
"https://api.cuevana3.me/fembed/api.php",
allowRedirects = false,
headers = mapOf(
"Host" to "api.cuevana3.me",
"User-Agent" to USER_AGENT,
"Accept" to "application/json, text/javascript, */*; q=0.01",
"Accept-Language" to "en-US,en;q=0.5",
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With" to "XMLHttpRequest",
"Origin" to "https://api.cuevana3.me",
"DNT" to "1",
"Connection" to "keep-alive",
"Sec-Fetch-Dest" to "empty",
"Sec-Fetch-Mode" to "cors",
"Sec-Fetch-Site" to "same-origin",
),
data = mapOf(Pair("h", key))
).text
val json = parseJson<Femcuevana>(url)
val link = json.url
if (link.contains("fembed")) {
loadExtractor(link, data, subtitleCallback, callback)
}
}
}
if (iframe.contains("tomatomatela")) {
val tomatoRegex =
Regex("(\\/\\/apialfa.tomatomatela.com\\/ir\\/player.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
tomatoRegex.findAll(iframe).map { tomreg ->
tomreg.value
}.toList().apmap { tom ->
val tomkey = tom.replace("//apialfa.tomatomatela.com/ir/player.php?h=", "")
app.post(
"https://apialfa.tomatomatela.com/ir/rd.php", allowRedirects = false,
headers = mapOf(
"Host" to "apialfa.tomatomatela.com",
"User-Agent" to USER_AGENT,
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language" to "en-US,en;q=0.5",
"Content-Type" to "application/x-www-form-urlencoded",
"Origin" to "null",
"DNT" to "1",
"Connection" to "keep-alive",
"Upgrade-Insecure-Requests" to "1",
"Sec-Fetch-Dest" to "iframe",
"Sec-Fetch-Mode" to "navigate",
"Sec-Fetch-Site" to "same-origin",
),
data = mapOf(Pair("url", tomkey))
).okhttpResponse.headers.values("location").apmap { loc ->
if (loc.contains("goto_ddh.php")) {
val gotoregex =
Regex("(\\/\\/api.cuevana3.me\\/ir\\/goto_ddh.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
gotoregex.findAll(loc).map { goreg ->
goreg.value.replace("//api.cuevana3.me/ir/goto_ddh.php?h=", "")
}.toList().apmap { gotolink ->
app.post(
"https://api.cuevana3.me/ir/redirect_ddh.php",
allowRedirects = false,
headers = mapOf(
"Host" to "api.cuevana3.me",
"User-Agent" to USER_AGENT,
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language" to "en-US,en;q=0.5",
"Content-Type" to "application/x-www-form-urlencoded",
"Origin" to "null",
"DNT" to "1",
"Connection" to "keep-alive",
"Upgrade-Insecure-Requests" to "1",
"Sec-Fetch-Dest" to "iframe",
"Sec-Fetch-Mode" to "navigate",
"Sec-Fetch-Site" to "same-origin",
),
data = mapOf(Pair("url", gotolink))
).okhttpResponse.headers.values("location").apmap { golink ->
loadExtractor(golink, data, subtitleCallback, callback)
}
}
}
if (loc.contains("index.php?h=")) {
val indexRegex =
Regex("(\\/\\/api.cuevana3.me\\/sc\\/index.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
indexRegex.findAll(loc).map { indreg ->
indreg.value.replace("//api.cuevana3.me/sc/index.php?h=", "")
}.toList().apmap { inlink ->
app.post(
"https://api.cuevana3.me/sc/r.php", allowRedirects = false,
headers = mapOf(
"Host" to "api.cuevana3.me",
"User-Agent" to USER_AGENT,
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language" to "en-US,en;q=0.5",
"Accept-Encoding" to "gzip, deflate, br",
"Content-Type" to "application/x-www-form-urlencoded",
"Origin" to "null",
"DNT" to "1",
"Connection" to "keep-alive",
"Upgrade-Insecure-Requests" to "1",
"Sec-Fetch-Dest" to "iframe",
"Sec-Fetch-Mode" to "navigate",
"Sec-Fetch-Site" to "same-origin",
"Sec-Fetch-User" to "?1",
),
data = mapOf(Pair("h", inlink))
).okhttpResponse.headers.values("location").apmap { link ->
loadExtractor(link, data, subtitleCallback, callback)
}
}
}
}
}
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class CuevanaProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(CuevanaProvider())
}
}

View File

@ -1,26 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Anime",
"OVA",
)
iconUrl = "https://www.google.com/s2/favicons?domain=doramasyt.com&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,155 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
//import com.lagradost.cloudstream3.extractors.FEmbed
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
import java.util.*
class DoramasYTProvider : MainAPI() {
companion object {
fun getType(t: String): TvType {
return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA
else if (t.contains("Pelicula")) TvType.Movie
else TvType.TvSeries
}
fun getDubStatus(title: String): DubStatus {
return if (title.contains("Latino") || title.contains("Castellano"))
DubStatus.Dubbed
else DubStatus.Subbed
}
}
override var mainUrl = "https://doramasyt.com"
override var name = "DoramasYT"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.AsianDrama,
)
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val urls = listOf(
Pair("$mainUrl/emision", "En emisión"),
Pair(
"$mainUrl/doramas?categoria=pelicula&genero=false&fecha=false&letra=false",
"Peliculas"
),
Pair("$mainUrl/doramas", "Doramas"),
Pair(
"$mainUrl/doramas?categoria=live-action&genero=false&fecha=false&letra=false",
"Live Action"
),
)
val items = ArrayList<HomePageList>()
items.add(
HomePageList(
"Capítulos actualizados",
app.get(mainUrl, timeout = 120).document.select(".col-6").map {
val title = it.selectFirst("p")!!.text()
val poster = it.selectFirst(".chapter img")!!.attr("src")
val epRegex = Regex("episodio-(\\d+)")
val url = it.selectFirst("a")!!.attr("href").replace("ver/", "dorama/")
.replace(epRegex, "sub-espanol")
val epNum = it.selectFirst("h3")!!.text().toIntOrNull()
newAnimeSearchResponse(title,url) {
this.posterUrl = fixUrl(poster)
addDubStatus(getDubStatus(title), epNum)
}
})
)
for (i in urls) {
try {
val home = app.get(i.first, timeout = 120).document.select(".col-6").map {
val title = it.selectFirst(".animedtls p")!!.text()
val poster = it.selectFirst(".anithumb img")!!.attr("src")
newAnimeSearchResponse(title, fixUrl(it.selectFirst("a")!!.attr("href"))) {
this.posterUrl = fixUrl(poster)
addDubStatus(getDubStatus(title))
}
}
items.add(HomePageList(i.second, home))
} catch (e: Exception) {
e.printStackTrace()
}
}
if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items)
}
override suspend fun search(query: String): List<SearchResponse> {
return app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map {
val title = it.selectFirst(".animedtls p")!!.text()
val href = it.selectFirst("a")!!.attr("href")
val image = it.selectFirst(".animes img")!!.attr("src")
AnimeSearchResponse(
title,
href,
this.name,
TvType.Anime,
image,
null,
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
DubStatus.Dubbed
) else EnumSet.of(DubStatus.Subbed),
)
}
}
override suspend fun load(url: String): LoadResponse {
val doc = app.get(url, timeout = 120).document
val poster = doc.selectFirst("div.flimimg img.img1")!!.attr("src")
val title = doc.selectFirst("h1")!!.text()
val type = doc.selectFirst("h4")!!.text()
val description = doc.selectFirst("p.textComplete")!!.text().replace("Ver menos", "")
val genres = doc.select(".nobel a").map { it.text() }
val status = when (doc.selectFirst(".state h6")?.text()) {
"Estreno" -> ShowStatus.Ongoing
"Finalizado" -> ShowStatus.Completed
else -> null
}
val episodes = doc.select(".heromain .col-item").map {
val name = it.selectFirst(".dtlsflim p")!!.text()
val link = it.selectFirst("a")!!.attr("href")
val epThumb = it.selectFirst(".flimimg img.img1")!!.attr("src")
Episode(link, name, posterUrl = epThumb)
}
return newAnimeLoadResponse(title, url, getType(type)) {
posterUrl = poster
addEpisodes(DubStatus.Subbed, episodes)
showStatus = status
plot = description
tags = genres
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
app.get(data).document.select("div.playother p").apmap {
val encodedurl = it.select("p").attr("data-player")
val urlDecoded = base64Decode(encodedurl)
val url = (urlDecoded).replace("https://doramasyt.com/reproductor?url=", "")
if (url.startsWith("https://www.fembed.com")) {
val extractor = FEmbed()
extractor.getUrl(url).forEach { link ->
callback.invoke(link)
}
} else {
loadExtractor(url, mainUrl, subtitleCallback, callback)
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class DoramasYTProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(DoramasYTProvider())
}
}

View File

@ -1,67 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.AppUtils
import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getQualityFromName
class FEmbed: XStreamCdn() {
override val name: String = "FEmbed"
override val mainUrl: String = "https://www.fembed.com"
}
open class XStreamCdn : ExtractorApi() {
override val name: String = "XStreamCdn"
override val mainUrl: String = "https://embedsito.com"
override val requiresReferer = false
open var domainUrl: String = "embedsito.com"
private data class ResponseData(
@JsonProperty("file") val file: String,
@JsonProperty("label") val label: String,
//val type: String // Mp4
)
private data class ResponseJson(
@JsonProperty("success") val success: Boolean,
@JsonProperty("data") val data: List<ResponseData>?
)
override fun getExtractorUrl(id: String): String {
return "$domainUrl/api/source/$id"
}
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val headers = mapOf(
"Referer" to url,
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0",
)
val id = url.trimEnd('/').split("/").last()
val newUrl = "https://${domainUrl}/api/source/${id}"
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
with(app.post(newUrl, headers = headers)) {
if (this.code != 200) return listOf()
val text = this.text
if (text.isEmpty()) return listOf()
if (text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf()
AppUtils.parseJson<ResponseJson?>(text)?.let {
if (it.success && it.data != null) {
it.data.forEach { data ->
extractedLinksList.add(
ExtractorLink(
name,
name = name,
data.file,
url,
getQualityFromName(data.label),
)
)
}
}
}
}
return extractedLinksList
}
}

View File

@ -1,26 +0,0 @@
// 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("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AsianDrama",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=185.224.83.103&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,213 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getQualityFromName
import com.lagradost.cloudstream3.utils.loadExtractor
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
class DramaidProvider : MainAPI() {
override var mainUrl = "https://185.224.83.103"
override var name = "DramaId"
override val hasQuickSearch = false
override val hasMainPage = true
override var lang = "id"
override val hasDownloadSupport = true
override val hasChromecastSupport = false
override val supportedTypes = setOf(TvType.AsianDrama)
companion object {
fun getStatus(t: String): ShowStatus {
return when (t) {
"Completed" -> ShowStatus.Completed
"Ongoing" -> ShowStatus.Ongoing
else -> ShowStatus.Completed
}
}
}
override val mainPage = mainPageOf(
"&status=&type=&order=update" to "Drama Terbaru",
"&order=latest" to "Baru Ditambahkan",
"&status=&type=&order=popular" to "Drama Popular",
)
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
val document = app.get("$mainUrl/series/?page=$page${request.data}").document
val home = document.select("article[itemscope=itemscope]").mapNotNull {
it.toSearchResult()
}
return newHomePageResponse(request.name, home)
}
private fun getProperDramaLink(uri: String): String {
return if (uri.contains("/series/")) {
uri
} else {
"$mainUrl/series/" + Regex("$mainUrl/(.+)-ep.+").find(uri)?.groupValues?.get(1)
.toString()
}
}
private fun Element.toSearchResult(): SearchResponse? {
val href = getProperDramaLink(this.selectFirst("a.tip")!!.attr("href"))
val title = this.selectFirst("h2[itemprop=headline]")?.text()?.trim() ?: return null
val posterUrl = fixUrlNull(this.selectFirst(".limit > noscript > img")?.attr("src"))
return newTvSeriesSearchResponse(title, href, TvType.AsianDrama) {
this.posterUrl = posterUrl
}
}
override suspend fun search(query: String): List<SearchResponse> {
val link = "$mainUrl/?s=$query"
val document = app.get(link).document
return document.select("article[itemscope=itemscope]").map {
val title = it.selectFirst("h2[itemprop=headline]")!!.text().trim()
val poster = it.selectFirst(".limit > noscript > img")!!.attr("src")
val href = it.selectFirst("a.tip")!!.attr("href")
newTvSeriesSearchResponse(title, href, TvType.AsianDrama) {
this.posterUrl = poster
}
}
}
override suspend fun load(url: String): LoadResponse {
val document = app.get(url).document
val title = document.selectFirst("h1.entry-title")!!.text().trim()
val poster = document.select(".thumb > noscript > img").attr("src")
val tags = document.select(".genxed > a").map { it.text() }
val year = Regex("\\d, ([0-9]*)").find(
document.selectFirst(".info-content > .spe > span > time")!!.text().trim()
)?.groupValues?.get(1).toString().toIntOrNull()
val status = getStatus(
document.select(".info-content > .spe > span:nth-child(1)")
.text().trim().replace("Status: ", "")
)
val description = document.select(".entry-content > p").text().trim()
val episodes = document.select(".eplister > ul > li").map {
val name = it.selectFirst("a > .epl-title")!!.text().trim()
val link = it.select("a").attr("href")
val epNum = it.selectFirst("a > .epl-num")!!.text().trim().toIntOrNull()
newEpisode(link) {
this.name = name
this.episode = epNum
}
}.reversed()
val recommendations =
document.select(".listupd > article[itemscope=itemscope]").map { rec ->
val epTitle = rec.selectFirst("h2[itemprop=headline]")!!.text().trim()
val epPoster = rec.selectFirst(".limit > noscript > img")!!.attr("src")
val epHref = fixUrl(rec.selectFirst("a.tip")!!.attr("href"))
newTvSeriesSearchResponse(epTitle, epHref, TvType.AsianDrama) {
this.posterUrl = epPoster
}
}
if (episodes.size == 1) {
return newMovieLoadResponse(title, url, TvType.Movie, episodes[0].data) {
posterUrl = poster
this.year = year
plot = description
this.tags = tags
this.recommendations = recommendations
}
} else {
return newTvSeriesLoadResponse(title, url, TvType.AsianDrama, episodes = episodes) {
posterUrl = poster
this.year = year
showStatus = status
plot = description
this.tags = tags
this.recommendations = recommendations
}
}
}
private data class Sources(
@JsonProperty("file") val file: String,
@JsonProperty("label") val label: String,
@JsonProperty("type") val type: String,
@JsonProperty("default") val default: Boolean?
)
private data class Tracks(
@JsonProperty("file") val file: String,
@JsonProperty("label") val label: String,
@JsonProperty("kind") val type: String,
@JsonProperty("default") val default: Boolean?
)
private suspend fun invokeDriveSource(
url: String,
name: String,
subCallback: (SubtitleFile) -> Unit,
sourceCallback: (ExtractorLink) -> Unit
) {
val server = app.get(url).document.selectFirst(".picasa")?.nextElementSibling()?.data()
val source = "[${server!!.substringAfter("sources: [").substringBefore("],")}]".trimIndent()
val trackers = server.substringAfter("tracks:[").substringBefore("],")
.replace("//language", "")
.replace("file", "\"file\"")
.replace("label", "\"label\"")
.replace("kind", "\"kind\"").trimIndent()
tryParseJson<List<Sources>>(source)?.map {
sourceCallback(
ExtractorLink(
name,
"Drive",
fixUrl(it.file),
referer = "https://motonews.club/",
quality = getQualityFromName(it.label)
)
)
}
tryParseJson<Tracks>(trackers)?.let {
subCallback.invoke(
SubtitleFile(
if (it.label.contains("Indonesia")) "${it.label}n" else it.label,
it.file
)
)
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val document = app.get(data).document
val sources = document.select(".mobius > .mirror > option").mapNotNull {
fixUrl(Jsoup.parse(base64Decode(it.attr("value"))).select("iframe").attr("src"))
}
sources.map {
it.replace("https://ndrama.xyz", "https://www.fembed.com")
}.apmap {
when {
it.contains("motonews.club") -> invokeDriveSource(it, this.name, subtitleCallback, callback)
else -> loadExtractor(it, data, subtitleCallback, callback)
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class DramaidProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(DramaidProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "zh"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AsianDrama",
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=www.duboku.tv&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,133 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.M3u8Helper
import org.jsoup.nodes.Element
class DubokuProvider : MainAPI() {
override var mainUrl = "https://www.duboku.tv"
override var name = "Duboku"
override val hasMainPage = true
override var lang = "zh"
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.Movie,
TvType.TvSeries,
TvType.AsianDrama,
)
override val mainPage = mainPageOf(
"$mainUrl/vodshow/2--time------" to "连续剧 时间",
"$mainUrl/vodshow/2--hits------" to "连续剧 人气",
"$mainUrl/vodshow/13--time------" to "陆剧 时间",
"$mainUrl/vodshow/13--hits------" to "陆剧 人气",
"$mainUrl/vodshow/15--time------" to "日韩剧 时间",
"$mainUrl/vodshow/15--hits------" to "日韩剧 人气",
"$mainUrl/vodshow/21--time------" to "短剧 时间",
"$mainUrl/vodshow/21--hits------" to "短剧 人气",
"$mainUrl/vodshow/16--time------" to "英美剧 时间",
"$mainUrl/vodshow/16--hits------" to "英美剧 人气",
"$mainUrl/vodshow/14--time------" to "台泰剧 时间",
"$mainUrl/vodshow/14--hits------" to "台泰剧 人气",
"$mainUrl/vodshow/20--time------" to "港剧 时间",
"$mainUrl/vodshow/20--hits------" to "港剧 人气",
)
override suspend fun getMainPage(
page: Int,
request: MainPageRequest
): HomePageResponse {
val document = app.get("${request.data}$page---.html").document
val home = document.select("ul.myui-vodlist.clearfix li").mapNotNull {
it.toSearchResult()
}
return newHomePageResponse(request.name, home)
}
private fun Element.toSearchResult(): SearchResponse? {
val title = this.selectFirst("h4.title a")?.text()?.trim() ?: return null
val href = fixUrl(this.selectFirst("a")?.attr("href").toString())
val posterUrl = fixUrlNull(this.selectFirst("a")?.attr("data-original"))
val episode = this.selectFirst("span.pic-text.text-right")?.text()?.filter { it.isDigit() }
?.toIntOrNull()
return newAnimeSearchResponse(title, href, TvType.Movie) {
this.posterUrl = posterUrl
addSub(episode)
}
}
override suspend fun search(query: String): List<SearchResponse> {
val document = app.get("$mainUrl/vodsearch/-------------.html?wd=$query&submit=").document
return document.select("ul#searchList li").mapNotNull {
it.toSearchResult()
}
}
override suspend fun load(url: String): LoadResponse? {
val document = app.get(url).document
val title = document.selectFirst("h1.title")?.text()?.trim() ?: return null
val tvType = if (document.select("ul.myui-content__list li").size == 1
) TvType.Movie else TvType.TvSeries
val actors = document.select("p.data")[2].select("a").map { it.text() }
val episodes = document.select("ul.myui-content__list li").map {
val href = fixUrl(it.select("a").attr("href"))
val name = it.select("a").text().trim()
Episode(
data = href,
name = name,
)
}
return newTvSeriesLoadResponse(title, url, tvType, episodes) {
this.posterUrl = fixUrlNull(
document.selectFirst("a.myui-vodlist__thumb.picture img")?.attr("data-original")
)
this.year =
document.select("p.data")[0].select("a").last()?.text()?.trim()?.toIntOrNull()
this.plot = document.selectFirst("span.sketch.content")?.text()?.trim()
this.tags = document.select("p.data")[0].select("a").map { it.text() }
this.rating = document.select("div#rating span.branch").text().toRatingInt()
addActors(actors)
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
app.get(data).document.select("script").map { script ->
if (script.data().contains("var player_data={")) {
val dataJson =
script.data().substringAfter("var player_data={").substringBefore("}")
tryParseJson<Sources>("{$dataJson}")?.let { source ->
M3u8Helper.generateM3u8(
this.name,
source.url ?: return@map,
referer = "https://w.duboku.io/",
headers = mapOf("Origin" to "https://w.duboku.io")
).forEach(callback)
}
}
}
return true
}
data class Sources(
@JsonProperty("url") val url: String?,
)
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class DubokuProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(DubokuProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "ar"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Anime",
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=www.egy.best&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,237 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import org.jsoup.nodes.Element
class EgyBestProvider : MainAPI() {
override var lang = "ar"
override var mainUrl = "https://www.egy.best"
override var name = "EgyBest"
override val usesWebView = false
override val hasMainPage = true
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie, TvType.Anime)
private fun String.getIntFromText(): Int? {
return Regex("""\d+""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull()
}
private fun Element.toSearchResponse(): SearchResponse? {
val url = this.attr("href") ?: return null
val posterUrl = select("img")?.attr("src")
var title = select("span.title").text()
val year = title.getYearFromTitle()
val isMovie = Regex(".*/movie/.*|.*/masrahiya/.*").matches(url)
val tvType = if (isMovie) TvType.Movie else TvType.TvSeries
title = if (year !== null) title else title.split(" (")[0].trim()
val quality = select("span.ribbon span").text().replace("-", "")
// If you need to differentiate use the url.
return MovieSearchResponse(
title,
url,
this@EgyBestProvider.name,
tvType,
posterUrl,
year,
null,
quality = getQualityFromString(quality)
)
}
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
// url, title
val doc = app.get(mainUrl).document
val pages = arrayListOf<HomePageList>()
doc.select("#mainLoad div.mbox").apmap {
val name = it.select(".bdb.pda > strong").text()
if (it.select(".movie").first()?.attr("href")?.contains("season-(.....)|ep-(.....)".toRegex()) == true) return@apmap
val list = arrayListOf<SearchResponse>()
it.select(".movie").map { element ->
list.add(element.toSearchResponse()!!)
}
pages.add(HomePageList(name, list))
}
return HomePageResponse(pages)
}
override suspend fun search(query: String): List<SearchResponse> {
val q = query.replace(" ","%20")
val result = arrayListOf<SearchResponse>()
listOf("$mainUrl/explore/?q=$q").apmap { url ->
val d = app.get(url).document
d.select("div.movies a").not("a.auto.load.btn.b").mapNotNull {
it.toSearchResponse()?.let { it1 -> result.add(it1) }
}
}
return result.distinct().sortedBy { it.name }
}
private fun String.getYearFromTitle(): Int? {
return Regex("""\(\d{4}\)""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull()
}
override suspend fun load(url: String): LoadResponse {
val doc = app.get(url).document
val isMovie = Regex(".*/movie/.*|.*/masrahiya/.*").matches(url)
val posterUrl = doc.select("div.movie_img a img")?.attr("src")
val year = doc.select("div.movie_title h1 a")?.text()?.toIntOrNull()
val title = doc.select("div.movie_title h1 span").text()
val youtubeTrailer = doc.select("div.play")?.attr("url")
val synopsis = doc.select("div.mbox").firstOrNull {
it.text().contains("القصة")
}?.text()?.replace("القصة ", "")
val tags = doc.select("table.movieTable tbody tr").firstOrNull {
it.text().contains("النوع")
}?.select("a")?.map { it.text() }
val actors = doc.select("div.cast_list .cast_item").mapNotNull {
val name = it.selectFirst("div > a > img")?.attr("alt") ?: return@mapNotNull null
val image = it.selectFirst("div > a > img")?.attr("src") ?: return@mapNotNull null
val roleString = it.selectFirst("div > span")!!.text()
val mainActor = Actor(name, image)
ActorData(actor = mainActor, roleString = roleString)
}
return if (isMovie) {
val recommendations = doc.select(".movies_small .movie").mapNotNull { element ->
element.toSearchResponse()
}
newMovieLoadResponse(
title,
url,
TvType.Movie,
url
) {
this.posterUrl = posterUrl
this.year = year
this.recommendations = recommendations
this.plot = synopsis
this.tags = tags
this.actors = actors
addTrailer(youtubeTrailer)
}
} else {
val episodes = ArrayList<Episode>()
doc.select("#mainLoad > div:nth-child(2) > div.h_scroll > div a").map {
it.attr("href")
}.apmap {
val d = app.get(it).document
val season = Regex("season-(.....)").find(it)?.groupValues?.getOrNull(1)?.getIntFromText()
if(d.select("tr.published").isNotEmpty()) {
d.select("tr.published").map { element ->
val ep = Regex("ep-(.....)").find(element.select(".ep_title a").attr("href"))?.groupValues?.getOrNull(1)?.getIntFromText()
episodes.add(
Episode(
element.select(".ep_title a").attr("href"),
name = element.select("td.ep_title").html().replace(".*</span>|</a>".toRegex(), ""),
season,
ep,
rating = element.select("td.tam:not(.date, .ep_len)").text().getIntFromText()
)
)
}
} else {
d.select("#mainLoad > div:nth-child(3) > div.movies_small a").map { eit ->
val ep = Regex("ep-(.....)").find(eit.attr("href"))?.groupValues?.getOrNull(1)?.getIntFromText()
episodes.add(
Episode(
eit.attr("href"),
eit.select("span.title").text(),
season,
ep,
)
)
}
}
}
newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes.distinct().sortedBy { it.episode }) {
this.posterUrl = posterUrl
this.tags = tags
this.year = year
this.plot = synopsis
this.actors = actors
addTrailer(youtubeTrailer)
}
}
}
data class Sources (
@JsonProperty("quality") val quality: Int?,
@JsonProperty("link") val link: String
)
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
/*val baseURL = data.split("/")[0] + "//" + data.split("/")[2]
val episodeSoup = app.get(data).document
val vidstreamURL = fixUrlNull(episodeSoup.selectFirst("iframe.auto-size")?.attr("src") ) ?: throw ErrorLoadingException("No iframe")
val videoSoup = app.get(vidstreamURL).document
fixUrlNull( videoSoup.select("source").firstOrNull { it.hasAttr("src") }?.attr("src"))?.let {
callback.invoke(ExtractorLink(this.name,this.name,it,"",Qualities.Unknown.value,it.contains(".m3u8")))
} ?: run {
var jsCode = videoSoup.select("script")[1].data()
val verificationToken = Regex("{'[0-9a-zA-Z_]*':'ok'}").findAll(jsCode)[0][2:-7]
val encodedAdLinkVar = Regex("([0-9a-zA-Z_]{2,12}\[Math").findAll(jsCode)[0][1:-5]
val encodingArraysRegEx = Regex(",[0-9a-zA-Z_]{2,12}=\[\]").findAll(jsCode)
val firstEncodingArray = encodingArraysRegEx[1][1:-3]
val secondEncodingArray = encodingArraysRegEx[2][1:-3]
jsCode = Regex("^<script type=\"text/javascript\">", "", jsCode)
jsCode = Regex("[;,]\$\('\*'\)(.*)$", ";", jsCode)
jsCode = Regex(",ismob=(.*)\(navigator\[(.*)\]\)[,;]", ";", jsCode)
jsCode = Regex("var a0b=function\(\)(.*)a0a\(\);",).findAll( jsCode)
jsCode += "var link = ''; for (var i = 0; i <= $secondEncodingArray['length']; i++) { link += $firstEncodingArray[$secondEncodingArray[i]] || ''; } return [link, $encodedAdLinkVar[0]] }"
val jsCodeReturn = executeJS(jsCode)()
val verificationPath = jsCodeReturn[0]
val encodedAdPath = jsCodeReturn[1]
val adLink = baseURL + "/" + str(decode(encodedAdPath + "=" * (-len(encodedAdPath) % 4)), "utf-8")
val session.get(adLink)
val verificationLink = baseURL + "/tvc.php?verify=" + verificationPath
val session.post(verificationLink, data={verificationToken: "ok"})
val vidstreamResponseText = session.get(vidstreamURL).text
val videoSoup = BeautifulSoup(vidstreamResponseText, features="html.parser")
val qualityLinksFileURL = baseURL + videoSoup.body.find("source").get("src")
}
return true*/
val requestJSON = app.get("https://api.zr5.repl.co/egybest?url=$data").text
// To solve this you need to send a verify request which is pretty hidden, see
// https://vear.egybest.deals/tvc.php?verify=.......
val jsonArray = parseJson<List<Sources>>(requestJSON)
for (i in jsonArray) {
val quality = i.quality
val link = i.link
callback.invoke(
ExtractorLink(
this.name,
this.name,
link,
this.mainUrl,
quality!!,
true,
// Does not work without these headers!
headers = mapOf("range" to "bytes=0-"),
)
)
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class EgyBestProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(EgyBestProvider())
}
}

View File

@ -1,24 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Movie",
)
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,94 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
class ElifilmsProvider : MainAPI() {
override var mainUrl: String = "https://elifilms.net"
override var name: String = "Elifilms"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.Movie,
)
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val items = ArrayList<HomePageList>()
val newest = app.get(mainUrl).document.selectFirst("a.fav_link.premiera")?.attr("href")
val urls = listOf(
Pair(mainUrl, "Películas recientes"),
Pair("$mainUrl/4k-peliculas/", "Películas en 4k"),
Pair(newest, "Últimos estrenos"),
)
urls.apmap { (url, name) ->
val soup = app.get(url ?: "").document
val home = soup.select("article.shortstory.cf").map {
val title = it.selectFirst(".short_header")?.text() ?: ""
val link = it.selectFirst("div a")?.attr("href") ?: ""
TvSeriesSearchResponse(
title,
link,
this.name,
TvType.Movie,
it.selectFirst("a.ah-imagge img")?.attr("data-src"),
null,
null,
)
}
items.add(HomePageList(name, home))
}
if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items)
}
override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/?s=$query"
val doc = app.get(url).document
return doc.select("article.cf").map {
val href = it.selectFirst("div.short_content a")?.attr("href") ?: ""
val poster = it.selectFirst("a.ah-imagge img")?.attr("data-src")
val name = it.selectFirst(".short_header")?.text() ?: ""
(MovieSearchResponse(name, href, this.name, TvType.Movie, poster, null))
}
}
override suspend fun load(url: String): LoadResponse {
val document = app.get(url, timeout = 120).document
val title = document.selectFirst(".post_title h1")?.text() ?: ""
val rating = document.select("span.imdb.rki").toString().toIntOrNull()
val poster = document.selectFirst(".poster img")?.attr("src")
val desc = document.selectFirst("div.notext .actors p")?.text()
val tags = document.select("td.notext a")
.map { it?.text()?.trim().toString() }
return MovieLoadResponse(
title,
url,
this.name,
TvType.Movie,
url,
poster,
null,
desc,
rating,
tags
)
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
app.get(data).document.select("li.change-server a").apmap {
val encodedurl = it.attr("data-id")
val urlDecoded = base64Decode(encodedurl)
val url = fixUrl(urlDecoded)
loadExtractor(url, data, subtitleCallback, callback)
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class ElifilmsProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(ElifilmsProvider())
}
}

View File

@ -1,26 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=entrepeliculasyseries.nu&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,177 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
class EntrepeliculasyseriesProvider : MainAPI() {
override var mainUrl = "https://entrepeliculasyseries.nu"
override var name = "EntrePeliculasySeries"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.Movie,
TvType.TvSeries,
)
override val vpnStatus = VPNStatus.MightBeNeeded //Due to evoload sometimes not loading
override val mainPage = mainPageOf(
Pair("$mainUrl/series/page/", "Series"),
Pair("$mainUrl/peliculas/page/", "Peliculas"),
Pair("$mainUrl/anime/page/", "Animes"),
)
override suspend fun getMainPage(
page: Int,
request : MainPageRequest
): HomePageResponse {
val url = request.data + page
val soup = app.get(url).document
val home = soup.select("ul.list-movie li").map {
val title = it.selectFirst("a.link-title h2")!!.text()
val link = it.selectFirst("a")!!.attr("href")
TvSeriesSearchResponse(
title,
link,
this.name,
if (link.contains("/pelicula/")) TvType.Movie else TvType.TvSeries,
it.selectFirst("a.poster img")!!.attr("src"),
null,
null,
)
}
return newHomePageResponse(request.name, home)
}
override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/?s=${query}"
val document = app.get(url).document
return document.select("li.xxx.TPostMv").map {
val title = it.selectFirst("h2.Title")!!.text()
val href = it.selectFirst("a")!!.attr("href")
val image = it.selectFirst("img.lazy")!!.attr("data-src")
val isMovie = href.contains("/pelicula/")
if (isMovie) {
MovieSearchResponse(
title,
href,
this.name,
TvType.Movie,
image,
null
)
} else {
TvSeriesSearchResponse(
title,
href,
this.name,
TvType.TvSeries,
image,
null,
null
)
}
}.toList()
}
override suspend fun load(url: String): LoadResponse? {
val soup = app.get(url, timeout = 120).document
val title = soup.selectFirst("h1.title-post")!!.text()
val description = soup.selectFirst("p.text-content:nth-child(3)")?.text()?.trim()
val poster: String? = soup.selectFirst("article.TPost img.lazy")!!.attr("data-src")
val episodes = soup.select(".TPostMv article").map { li ->
val href = (li.select("a") ?: li.select(".C a") ?: li.select("article a")).attr("href")
val epThumb = li.selectFirst("div.Image img")!!.attr("data-src")
val seasonid = li.selectFirst("span.Year")!!.text().let { str ->
str.split("x").mapNotNull { subStr -> subStr.toIntOrNull() }
}
val isValid = seasonid.size == 2
val episode = if (isValid) seasonid.getOrNull(1) else null
val season = if (isValid) seasonid.getOrNull(0) else null
Episode(
href,
null,
season,
episode,
fixUrl(epThumb)
)
}
return when (val tvType =
if (url.contains("/pelicula/")) TvType.Movie else TvType.TvSeries) {
TvType.TvSeries -> {
TvSeriesLoadResponse(
title,
url,
this.name,
tvType,
episodes,
poster,
null,
description,
)
}
TvType.Movie -> {
MovieLoadResponse(
title,
url,
this.name,
tvType,
url,
poster,
null,
description,
)
}
else -> null
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
app.get(data).document.select(".video ul.dropdown-menu li").apmap {
val servers = it.attr("data-link")
val doc = app.get(servers).document
doc.select("input").apmap {
val postkey = it.attr("value")
app.post(
"https://entrepeliculasyseries.nu/r.php",
headers = mapOf(
"Host" to "entrepeliculasyseries.nu",
"User-Agent" to USER_AGENT,
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language" to "en-US,en;q=0.5",
"Content-Type" to "application/x-www-form-urlencoded",
"Origin" to "https://entrepeliculasyseries.nu",
"DNT" to "1",
"Connection" to "keep-alive",
"Referer" to servers,
"Upgrade-Insecure-Requests" to "1",
"Sec-Fetch-Dest" to "document",
"Sec-Fetch-Mode" to "navigate",
"Sec-Fetch-Site" to "same-origin",
"Sec-Fetch-User" to "?1",
),
//params = mapOf(Pair("h", postkey)),
data = mapOf(Pair("h", postkey)),
allowRedirects = false
).okhttpResponse.headers.values("location").apmap {
loadExtractor(it, data, subtitleCallback, callback)
}
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class EntrepeliculasyseriesProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(EntrepeliculasyseriesProvider())
}
}

View File

@ -1,27 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "es"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AsianDrama",
"Movie",
"OVA",
)
iconUrl = "https://www.google.com/s2/favicons?domain=www23.estrenosdoramas.net&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,286 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.network.WebViewResolver
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import java.util.*
import kotlin.collections.ArrayList
class EstrenosDoramasProvider : MainAPI() {
companion object {
fun getType(t: String): TvType {
return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA
else if (t.contains("Pelicula")) TvType.Movie
else TvType.TvSeries
}
}
override var mainUrl = "https://www23.estrenosdoramas.net"
override var name = "EstrenosDoramas"
override var lang = "es"
override val hasMainPage = true
override val hasChromecastSupport = true
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.AsianDrama,
)
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val urls = listOf(
Pair(mainUrl, "Últimas series"),
Pair("$mainUrl/category/peliculas", "Películas"),
)
val items = ArrayList<HomePageList>()
urls.apmap { (url, name) ->
val home = app.get(url, timeout = 120).document.select("div.clearfix").map {
val title = cleanTitle(it.selectFirst("h3 a")?.text()!!)
val poster = it.selectFirst("img.cate_thumb")?.attr("src")
AnimeSearchResponse(
title,
it.selectFirst("a")?.attr("href")!!,
this.name,
TvType.AsianDrama,
poster,
null,
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
DubStatus.Dubbed
) else EnumSet.of(DubStatus.Subbed),
)
}
items.add(HomePageList(name, home))
}
if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items)
}
override suspend fun search(query: String): List<SearchResponse> {
val searchob = ArrayList<AnimeSearchResponse>()
val search =
app.get("$mainUrl/?s=$query", timeout = 120).document.select("div.clearfix").map {
val title = cleanTitle(it.selectFirst("h3 a")?.text()!!)
val href = it.selectFirst("a")?.attr("href")
val image = it.selectFirst("img.cate_thumb")?.attr("src")
val lists =
AnimeSearchResponse(
title,
href!!,
this.name,
TvType.AsianDrama,
image,
null,
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
DubStatus.Dubbed
) else EnumSet.of(DubStatus.Subbed),
)
if (href.contains("capitulo")) {
//nothing
}
else {
searchob.add(lists)
}
}
return searchob
}
override suspend fun load(url: String): LoadResponse? {
val doc = app.get(url, timeout = 120).document
val poster = doc.selectFirst("head meta[property]")?.attr("content")
val title = doc.selectFirst("h1.titulo")?.text()
val description = try {
doc.selectFirst("div.post div.highlight div.font")?.text()
} catch (e:Exception){
null
}
val finaldesc = description?.substringAfter("Sinopsis")?.replace(": ", "")?.trim()
val epi = ArrayList<Episode>()
val episodes = doc.select("div.post .lcp_catlist a").map {
val name = it.selectFirst("a")?.text()
val link = it.selectFirst("a")?.attr("href")
val test = Episode(link!!, name)
if (!link.equals(url)) {
epi.add(test)
}
}.reversed()
return when (val type = if (episodes.isEmpty()) TvType.Movie else TvType.AsianDrama) {
TvType.AsianDrama -> {
return newAnimeLoadResponse(title!!, url, type) {
japName = null
engName = title.replace(Regex("[Pp]elicula |[Pp]elicula"),"")
posterUrl = poster
addEpisodes(DubStatus.Subbed, epi.reversed())
plot = finaldesc
}
}
TvType.Movie -> {
MovieLoadResponse(
cleanTitle(title!!),
url,
this.name,
TvType.Movie,
url,
poster,
null,
finaldesc,
null,
null,
)
}
else -> null
}
}
data class ReproDoramas (
@JsonProperty("link") val link: String,
@JsonProperty("time") val time: Int
)
private fun cleanTitle(title: String): String = title.replace(Regex("[Pp]elicula |[Pp]elicula"),"")
private fun cleanExtractor(
source: String,
name: String,
url: String,
referer: String,
m3u8: Boolean,
callback: (ExtractorLink) -> Unit
): Boolean {
callback(
ExtractorLink(
source,
name,
url,
referer,
Qualities.Unknown.value,
m3u8
)
)
return true
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val headers = mapOf("Host" to "repro3.estrenosdoramas.us",
"User-Agent" to USER_AGENT,
"Accept" to "*/*",
"Accept-Language" to "en-US,en;q=0.5",
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With" to "XMLHttpRequest",
"Origin" to "https://repro3.estrenosdoramas.us",
"DNT" to "1",
"Connection" to "keep-alive",
"Sec-Fetch-Dest" to "empty",
"Sec-Fetch-Mode" to "cors",
"Sec-Fetch-Site" to "same-origin",
"Cache-Control" to "max-age=0",)
val document = app.get(data).document
document.select("div.tab_container iframe").apmap { container ->
val directlink = fixUrl(container.attr("src"))
loadExtractor(directlink, data, subtitleCallback, callback)
if (directlink.contains("/repro/amz/")) {
val amzregex = Regex("https:\\/\\/repro3\\.estrenosdoramas\\.us\\/repro\\/amz\\/examples\\/.*\\.php\\?key=.*\$")
amzregex.findAll(directlink).map {
it.value.replace(Regex("https:\\/\\/repro3\\.estrenosdoramas\\.us\\/repro\\/amz\\/examples\\/.*\\.php\\?key="),"")
}.toList().apmap { key ->
val response = app.post("https://repro3.estrenosdoramas.us/repro/amz/examples/player/api/indexDCA.php",
headers = headers,
data = mapOf(
Pair("key",key),
Pair("token","MDAwMDAwMDAwMA=="),
),
allowRedirects = false
).text
val reprojson = parseJson<ReproDoramas>(response)
val decodeurl = base64Decode(reprojson.link)
if (decodeurl.contains("m3u8"))
cleanExtractor(
name,
name,
decodeurl,
"https://repro3.estrenosdoramas.us",
decodeurl.contains(".m3u8"),
callback
)
}
}
if (directlink.contains("reproducir14")) {
val regex = Regex("(https:\\/\\/repro.\\.estrenosdoramas\\.us\\/repro\\/reproducir14\\.php\\?key=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
regex.findAll(directlink).map {
it.value
}.toList().apmap {
val doc = app.get(it).text
val videoid = doc.substringAfter("vid=\"").substringBefore("\" n")
val token = doc.substringAfter("name=\"").substringBefore("\" s")
val acctkn = doc.substringAfter("{ acc: \"").substringBefore("\", id:")
val link = app.post("https://repro3.estrenosdoramas.us/repro/proto4.php",
headers = headers,
data = mapOf(
Pair("acc",acctkn),
Pair("id",videoid),
Pair("tk",token)),
allowRedirects = false
).text
val extracteklink = link.substringAfter("\"urlremoto\":\"").substringBefore("\"}")
.replace("\\/", "/").replace("//ok.ru/","http://ok.ru/")
loadExtractor(extracteklink, data, subtitleCallback, callback)
}
}
if (directlink.contains("reproducir120")) {
val regex = Regex("(https:\\/\\/repro3.estrenosdoramas.us\\/repro\\/reproducir120\\.php\\?\\nkey=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
regex.findAll(directlink).map {
it.value
}.toList().apmap {
val doc = app.get(it).text
val videoid = doc.substringAfter("var videoid = '").substringBefore("';")
val token = doc.substringAfter("var tokens = '").substringBefore("';")
val acctkn = doc.substringAfter("{ acc: \"").substringBefore("\", id:")
val link = app.post("https://repro3.estrenosdoramas.us/repro/api3.php",
headers = headers,
data = mapOf(
Pair("acc",acctkn),
Pair("id",videoid),
Pair("tk",token)),
allowRedirects = false
).text
val extractedlink = link.substringAfter("\"{file:'").substringBefore("',label:")
.replace("\\/", "/")
val quality = link.substringAfter(",label:'").substringBefore("',type:")
val type = link.substringAfter("type: '").substringBefore("'}\"")
if (extractedlink.isNotBlank())
if (quality.contains("File not found", ignoreCase = true)) {
//Nothing
} else {
cleanExtractor(
"Movil",
"Movil $quality",
extractedlink,
"",
!type.contains("mp4"),
callback
)
}
}
}
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class EstrenosDoramasProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(EstrenosDoramasProvider())
}
}

View File

@ -1,26 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"TvSeries"
)
iconUrl = "https://www.google.com/s2/favicons?domain=eurostreaming.social&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,113 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson
class EurostreamingProvider : MainAPI() {
override var lang = "it"
override var mainUrl = "https://eurostreaming.social"
override var name = "Eurostreaming"
override val hasMainPage = true
override val hasChromecastSupport = true
override val supportedTypes = setOf(
TvType.TvSeries
)
override val mainPage = mainPageOf(
Pair("$mainUrl/serie-tv-archive/page/", "Ultime serie Tv"),
Pair("$mainUrl/animazione/page/", "Ultime serie Animazione"),
)
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
val url = request.data + page
val soup = app.get(url).document
val home = soup.select("div.post-thumb").map {
val title = it.selectFirst("img")!!.attr("alt")
val link = it.selectFirst("a")!!.attr("href")
val image = fixUrl(it.selectFirst("img")!!.attr("src"))
MovieSearchResponse(
title,
link,
this.name,
TvType.Movie,
image
)
}
return newHomePageResponse(request.name, home)
}
override suspend fun search(query: String): List<SearchResponse> {
val doc = app.post(
"$mainUrl/index.php", data = mapOf(
"do" to "search",
"subaction" to "search",
"story" to query,
"sortby" to "news_read"
)
).document
return doc.select("div.post-thumb").map {
val title = it.selectFirst("img")!!.attr("alt")
val link = it.selectFirst("a")!!.attr("href")
val image = mainUrl + it.selectFirst("img")!!.attr("src")
MovieSearchResponse(
title,
link,
this.name,
TvType.Movie,
image
)
}
}
override suspend fun load(url: String): LoadResponse {
val page = app.get(url)
val document = page.document
val title = document.selectFirst("h2")!!.text().replace("^([1-9+]]$","")
val style = document.selectFirst("div.entry-cover")!!.attr("style")
val poster = fixUrl(Regex("(/upload.+\\))").find(style)!!.value.dropLast(1))
val episodeList = ArrayList<Episode>()
document.select("div.tab-pane.fade").map { element ->
val season = element.attr("id").filter { it.isDigit() }.toInt()
element.select("li").filter { it-> it.selectFirst("a")?.hasAttr("data-title")?:false }.map{episode ->
val data = episode.select("div.mirrors > a").map { it.attr("data-link") }.toJson()
val epnameData = episode.selectFirst("a")
val epTitle = epnameData!!.attr("data-title")
val epNum = epnameData.text().toInt()
episodeList.add(
Episode(
data,
epTitle,
season,
epNum
)
)
}
}
return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodeList) {
posterUrl = poster
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
parseJson<List<String>>(data).map { videoUrl ->
loadExtractor(videoUrl, data, subtitleCallback, callback)
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class EurostreamingProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(EurostreamingProvider())
}
}

View File

@ -1,28 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "ar"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"AsianDrama",
"Anime",
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=faselhd.io&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,163 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.ExtractorLink
import org.jsoup.nodes.Element
class FaselHDProvider : MainAPI() {
override var lang = "ar"
override var mainUrl = "https://faselhd.io"
override var name = "FaselHD"
override val usesWebView = false
override val hasMainPage = true
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie, TvType.AsianDrama, TvType.Anime)
private fun String.getIntFromText(): Int? {
return Regex("""\d+""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull()
}
private fun Element.toSearchResponse(): SearchResponse? {
val url = select("div.postDiv a").attr("href") ?: return null
val posterUrl = select("div.postDiv a div img").attr("data-src") ?:
select("div.postDiv a div img").attr("src")
val title = select("div.postDiv a div img").attr("alt")
val quality = select(".quality").first()?.text()?.replace("1080p |-".toRegex(), "")
val type = if(title.contains("فيلم")) TvType.Movie else TvType.TvSeries
return MovieSearchResponse(
title.replace("الموسم الأول|برنامج|فيلم|مترجم|اون لاين|مسلسل|مشاهدة|انمي|أنمي".toRegex(),""),
url,
this@FaselHDProvider.name,
type,
posterUrl,
null,
null,
quality = getQualityFromString(quality)
)
}
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
// Title, Url
val moviesUrl = listOf(
Pair("Movies", "$mainUrl/all-movies/page/"+(0..10).random()),
Pair("Series", "$mainUrl/series/page/"+(0..10).random()),
Pair("Top Movies IMDB", "$mainUrl/movies_top_imdb"),
)
val pages = moviesUrl.apmap { (title, url) ->
val doc = app.get(url).document
val list = doc.select("div[id=\"postList\"] div[class=\"col-xl-2 col-lg-2 col-md-3 col-sm-3\"]")
.mapNotNull { element ->
element.toSearchResponse()
}
HomePageList(title, list)
}
return HomePageResponse(pages)
}
override suspend fun search(query: String): List<SearchResponse> {
val q = query.replace(" ","+")
val d = app.get("$mainUrl/?s=$q").document
return d.select("div[id=\"postList\"] div[class=\"col-xl-2 col-lg-2 col-md-3 col-sm-3\"]")
.mapNotNull {
it.toSearchResponse()
}
}
override suspend fun load(url: String): LoadResponse {
val doc = app.get(url).document
val isMovie = doc.select("div.epAll").isEmpty()
val posterUrl = doc.select("div.posterImg img").attr("src")
.ifEmpty { doc.select("div.seasonDiv.active img").attr("data-src") }
val year = doc.select("div[id=\"singleList\"] div[class=\"col-xl-6 col-lg-6 col-md-6 col-sm-6\"]").firstOrNull {
it.text().contains("سنة|موعد".toRegex())
}?.text()?.getIntFromText()
val title =
doc.select("title").text().replace(" - فاصل إعلاني", "")
.replace("الموسم الأول|برنامج|فيلم|مترجم|اون لاين|مسلسل|مشاهدة|انمي|أنمي|$year".toRegex(),"")
// A bit iffy to parse twice like this, but it'll do.
val duration = doc.select("div[id=\"singleList\"] div[class=\"col-xl-6 col-lg-6 col-md-6 col-sm-6\"]").firstOrNull {
it.text().contains("مدة|توقيت".toRegex())
}?.text()?.getIntFromText()
val tags = doc.select("div[id=\"singleList\"] div[class=\"col-xl-6 col-lg-6 col-md-6 col-sm-6\"]:contains(تصنيف الفيلم) a").map {
it.text()
}
val recommendations = doc.select("div#postList div.postDiv").mapNotNull {
it.toSearchResponse()
}
val synopsis = doc.select("div.singleDesc p").text()
return if (isMovie) {
newMovieLoadResponse(
title,
url,
TvType.Movie,
url
) {
this.posterUrl = posterUrl
this.year = year
this.plot = synopsis
this.duration = duration
this.tags = tags
this.recommendations = recommendations
}
} else {
val episodes = ArrayList<Episode>()
doc.select("div.epAll a").map {
episodes.add(
Episode(
it.attr("href"),
it.text(),
doc.select("div.seasonDiv.active div.title").text().getIntFromText() ?: 1,
it.text().getIntFromText(),
)
)
}
doc.select("div[id=\"seasonList\"] div[class=\"col-xl-2 col-lg-3 col-md-6\"] div.seasonDiv")
.not(".active").apmap { it ->
val s = app.get("$mainUrl/?p="+it.attr("data-href")).document
s.select("div.epAll a").map {
episodes.add(
Episode(
it.attr("href"),
it.text(),
s.select("div.seasonDiv.active div.title").text().getIntFromText(),
it.text().getIntFromText(),
)
)
}
}
newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes.distinct().sortedBy { it.episode }) {
this.duration = duration
this.posterUrl = posterUrl
this.year = year
this.plot = synopsis
this.tags = tags
this.recommendations = recommendations
}
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val player = app.get(app.get(data).document.select("iframe[name=\"player_iframe\"]").attr("src")).document
player.select("div.quality_change button.hd_btn").map {
callback.invoke(
ExtractorLink(
this.name,
this.name,
it.attr("data-url"),
this.mainUrl,
quality = it.text().getIntFromText() ?: 0,
isM3u8 = true
)
)
}
return true
}
}

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class FaselHDProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(FaselHDProvider())
}
}

View File

@ -1,26 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "pl"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=filman.cc&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,149 +0,0 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
import org.jsoup.Jsoup
import org.jsoup.select.Elements
class FilmanProvider : MainAPI() {
override var mainUrl = "https://filman.cc"
override var name = "Filman.cc"
override var lang = "pl"
override val hasMainPage = true
override val supportedTypes = setOf(
TvType.Movie,
TvType.TvSeries
)
override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse {
val document = app.get(mainUrl).document
val lists = document.select("#item-list,#series-list")
val categories = ArrayList<HomePageList>()
for (l in lists) {
val title = capitalizeString(l.parent()!!.select("h3").text().lowercase())
val items = l.select(".poster").map { i ->
val name = i.select("a[href]").attr("title")
val href = i.select("a[href]").attr("href")
val poster = i.select("img[src]").attr("src")
val year = l.select(".film_year").text().toIntOrNull()
if (l.hasClass("series-list")) TvSeriesSearchResponse(
name,
href,
this.name,
TvType.TvSeries,
poster,
year,
null
) else MovieSearchResponse(
name,
href,
this.name,
TvType.Movie,
poster,
year
)
}
categories.add(HomePageList(title, items))
}
return HomePageResponse(categories)
}
override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/wyszukiwarka?phrase=$query"
val document = app.get(url).document
val lists = document.select("#advanced-search > div")
val movies = lists[1].select("#item-list > div:not(.clearfix)")
val series = lists[3].select("#item-list > div:not(.clearfix)")
if (movies.isEmpty() && series.isEmpty()) return ArrayList()
fun getVideos(type: TvType, items: Elements): List<SearchResponse> {
return items.mapNotNull { i ->
val href = i.selectFirst(".poster > a")?.attr("href") ?: return@mapNotNull null
val img =
i.selectFirst(".poster > a > img")?.attr("src")?.replace("/thumb/", "/big/")
val name = i.selectFirst(".film_title")?.text() ?: return@mapNotNull null
val year = i.selectFirst(".film_year")?.text()?.toIntOrNull()
if (type === TvType.TvSeries) {
TvSeriesSearchResponse(
name,
href,
this.name,
type,
img,
year,
null
)
} else {
MovieSearchResponse(name, href, this.name, type, img, year)
}
}
}
return getVideos(TvType.Movie, movies) + getVideos(TvType.TvSeries, series)
}
override suspend fun load(url: String): LoadResponse {
val document = app.get(url).document
val documentTitle = document.select("title").text().trim()
if (documentTitle.startsWith("Logowanie")) {
throw RuntimeException("This page seems to be locked behind a login-wall on the website, unable to scrape it. If it is not please report it.")
}
var title = document.select("span[itemprop=title]").text()
val data = document.select("#links").outerHtml()
val posterUrl = document.select("#single-poster > img").attr("src")
val year = document.select(".info > ul > li").getOrNull(1)?.text()?.toIntOrNull()
val plot = document.select(".description").text()
val episodesElements = document.select("#episode-list a[href]")
if (episodesElements.isEmpty()) {
return MovieLoadResponse(title, url, name, TvType.Movie, data, posterUrl, year, plot)
}
title = document.selectFirst(".info")?.parent()?.select("h2")?.text() ?: ""
val episodes = episodesElements.mapNotNull { episode ->
val e = episode.text()
val regex = Regex("""\[s(\d{1,3})e(\d{1,3})]""").find(e) ?: return@mapNotNull null
val eid = regex.groups
Episode(
episode.attr("href"),
e.split("]")[1].trim(),
eid[1]?.value?.toInt(),
eid[2]?.value?.toInt(),
)
}.toMutableList()
return TvSeriesLoadResponse(
title,
url,
name,
TvType.TvSeries,
episodes,
posterUrl,
year,
plot
)
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val document = if (data.startsWith("http"))
app.get(data).document.select("#links").first()
else Jsoup.parse(data)
document?.select(".link-to-video")?.apmap { item ->
val decoded = base64Decode(item.select("a").attr("data-iframe"))
val link = tryParseJson<LinkElement>(decoded)?.src ?: return@apmap
loadExtractor(link, subtitleCallback, callback)
}
return true
}
}
data class LinkElement(
@JsonProperty("src") val src: String
)

View File

@ -1,14 +0,0 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class FilmanProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(FilmanProvider())
}
}

View File

@ -1,26 +0,0 @@
// use an integer for version numbers
version = 1
cloudstream {
language = "it"
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
// authors = listOf("Cloudburst")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"TvSeries",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=filmpertutti.photo&sz=%size%"
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View File

@ -1,193 +0,0 @@
package com.lagradost
//import androidx.core.text.parseAsHtml
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addRating
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ShortLink
import com.lagradost.cloudstream3.utils.loadExtractor
import org.jsoup.nodes.Element
import com.lagradost.cloudstream3.utils.AppUtils.html
class FilmpertuttiProvider : MainAPI() {
override var lang = "it"
override var mainUrl = "https://filmpertutti.photo"
override var name = "Filmpertutti"
override val hasMainPage = true
override val hasChromecastSupport = true
override val supportedTypes = setOf(
TvType.Movie,
TvType.TvSeries
)
override val mainPage = mainPageOf(
Pair("$mainUrl/category/film/page/", "Film Popolari"),
Pair("$mainUrl/category/serie-tv/page/", "Serie Tv Popolari"),
Pair("$mainUrl/prime-visioni/", "Ultime uscite"),
)
override suspend fun getMainPage(
page: Int,
request: MainPageRequest
): HomePageResponse {
val url = request.data + page
val soup = app.get(url).document
val home = soup.select("ul.posts > li").map {
val title = it.selectFirst("div.title")!!.text().substringBeforeLast("(")
.substringBeforeLast("[")
val link = it.selectFirst("a")!!.attr("href")
val image = it.selectFirst("a")!!.attr("data-thumbnail")
val qualitydata = it.selectFirst("div.hd")
val quality = if (qualitydata != null) {
getQualityFromString(qualitydata.text())
} else {
null
}
newTvSeriesSearchResponse(
title,
link
) {
this.posterUrl = image
this.quality = quality
}
}
return newHomePageResponse(request.name, home)
}
override suspend fun search(query: String): List<SearchResponse> {
val queryformatted = query.replace(" ", "+")
val url = "$mainUrl/?s=$queryformatted"
val doc = app.get(url).document
return doc.select("ul.posts > li").map {
val title = it.selectFirst("div.title")!!.text().substringBeforeLast("(")
.substringBeforeLast("[")
val link = it.selectFirst("a")!!.attr("href")
val image = it.selectFirst("a")!!.attr("data-thumbnail")
val quality = getQualityFromString(it.selectFirst("div.hd")?.text())
MovieSearchResponse(
title,
link,
this.name,
quality = quality,
posterUrl = image
)
}
}
override suspend fun load(url: String): LoadResponse {
val document = app.get(url).document
val type =
if (document.selectFirst("a.taxonomy.category")!!.attr("href").contains("serie-tv")
.not()
) TvType.Movie else TvType.TvSeries
val title = document.selectFirst("#content > h1")!!.text().substringBeforeLast("(")
.substringBeforeLast("[")
val description =
document.selectFirst("i.fa.fa-file-text-o.fa-fw")?.parent()?.nextSibling()?.toString()
?.html().toString()
val rating = document.selectFirst("div.rating > div.value")?.text()
val year =
document.selectFirst("#content > h1")?.text()?.substringAfterLast("(")
?.filter { it.isDigit() }?.toIntOrNull()
?: description.substringAfter("trasmessa nel").take(6).filter { it.isDigit() }
.toIntOrNull() ?: (document.selectFirst("i.fa.fa-calendar.fa-fw")?.parent()
?.nextSibling() as Element?)?.text()?.substringAfterLast(" ")
?.filter { it.isDigit() }?.toIntOrNull()
val poster = document.selectFirst("div.meta > div > img")?.attr("data-src")
val trailerurl =
document.selectFirst("div.youtube-player")?.attr("data-id")?.let { urldata ->
"https://www.youtube.com/watch?v=$urldata"
}
if (type == TvType.TvSeries) {
val episodeList = ArrayList<Episode>()
document.select("div.accordion-item").filter { a ->
a.selectFirst("#season > ul > li.s_title > span")!!.text().isNotEmpty()
}.map { element ->
val season =
element.selectFirst("#season > ul > li.s_title > span")!!.text().toInt()
element.select("div.episode-wrap").map { episode ->
val href =
episode.select("#links > div > div > table > tbody:nth-child(2) > tr")
.map { it.selectFirst("a")!!.attr("href") }.toJson()
val epNum = episode.selectFirst("li.season-no")!!.text().substringAfter("x")
.filter { it.isDigit() }.toIntOrNull()
val epTitle = episode.selectFirst("li.other_link > a")?.text()
val posterUrl = episode.selectFirst("figure > img")?.attr("data-src")
episodeList.add(
Episode(
href,
epTitle,
season,
epNum,
posterUrl,
)
)
}
}
return newTvSeriesLoadResponse(
title,
url, type, episodeList
) {
this.posterUrl = poster
this.year = year
this.plot = description
addRating(rating)
addTrailer(trailerurl)
}
} else {
val urls0 = document.select("div.embed-player")
val urls = if (urls0.isNotEmpty()) {
urls0.map { it.attr("data-id") }.toJson()
} else {
document.select("#info > ul > li ").mapNotNull { it.selectFirst("a")?.attr("href") }
.toJson()
}
return newMovieLoadResponse(
title,
url,
type,
urls
) {
posterUrl = fixUrlNull(poster)
this.year = year
this.plot = description
addRating(rating)
addTrailer(trailerurl)
}
}
}
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
tryParseJson<List<String>>(data)?.apmap { id ->
val link = ShortLink.unshorten(id).trim().replace("/v/", "/e/").replace("/f/", "/e/")
loadExtractor(link, data, subtitleCallback, callback)
}
return true
}
}

Some files were not shown because too many files have changed in this diff Show More