forked from recloudstream/cloudstream
Fixes on providers and 3 new spanish sites (#511)
* Added Monoschinos and DoramasYT * Fixes on Monoschinos and DoramasYT * Monoschinos, PelisplusHD updates, 3 new spanish providers * fixes
This commit is contained in:
parent
e2405f2526
commit
0b8c02f9e2
8 changed files with 503 additions and 19 deletions
|
@ -30,17 +30,20 @@ object APIHolder {
|
||||||
val apis = arrayListOf(
|
val apis = arrayListOf(
|
||||||
PelisplusProvider(),
|
PelisplusProvider(),
|
||||||
PelisplusHDProvider(),
|
PelisplusHDProvider(),
|
||||||
|
PeliSmartProvider(),
|
||||||
GogoanimeProvider(),
|
GogoanimeProvider(),
|
||||||
AllAnimeProvider(),
|
AllAnimeProvider(),
|
||||||
//ShiroProvider(), // v2 fucked me
|
//ShiroProvider(), // v2 fucked me
|
||||||
//AnimePaheProvider(), //ddos guard
|
//AnimePaheProvider(), //ddos guard
|
||||||
AnimeFlickProvider(),
|
AnimeFlickProvider(),
|
||||||
|
AnimeflvnetProvider(),
|
||||||
|
|
||||||
TenshiProvider(),
|
TenshiProvider(),
|
||||||
WcoProvider(),
|
WcoProvider(),
|
||||||
// MeloMovieProvider(), // Captcha for links
|
// MeloMovieProvider(), // Captcha for links
|
||||||
DubbedAnimeProvider(),
|
DubbedAnimeProvider(),
|
||||||
DoramasYTProvider(),
|
DoramasYTProvider(),
|
||||||
|
CinecalidadProvider(),
|
||||||
IHaveNoTvProvider(), // Documentaries provider
|
IHaveNoTvProvider(), // Documentaries provider
|
||||||
//LookMovieProvider(), // RECAPTCHA (Please allow up to 5 seconds...)
|
//LookMovieProvider(), // RECAPTCHA (Please allow up to 5 seconds...)
|
||||||
VMoveeProvider(),
|
VMoveeProvider(),
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
class AnimeflvnetProvider:MainAPI() {
|
||||||
|
companion object {
|
||||||
|
fun getType(t: String): TvType {
|
||||||
|
return if (t.contains("OVA") || t.contains("Especial")) TvType.ONA
|
||||||
|
else if (t.contains("Película")) TvType.AnimeMovie
|
||||||
|
else TvType.Anime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override val mainUrl: String
|
||||||
|
get() = "https://m.animeflv.net"
|
||||||
|
override val name: String
|
||||||
|
get() = "AnimeFLV"
|
||||||
|
override val lang = "es"
|
||||||
|
override val hasMainPage = true
|
||||||
|
override val hasChromecastSupport = true
|
||||||
|
override val hasDownloadSupport = true
|
||||||
|
override val supportedTypes = setOf(
|
||||||
|
TvType.AnimeMovie,
|
||||||
|
TvType.ONA,
|
||||||
|
TvType.Anime,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override suspend fun getMainPage(): HomePageResponse {
|
||||||
|
val urls = listOf(
|
||||||
|
Pair("$mainUrl/browse?type[]=movie&order=updated", "Peliculas actualizadas"),
|
||||||
|
Pair("$mainUrl/browse?order=updated", "Animes recientemente actualizados"),
|
||||||
|
Pair("$mainUrl/browse?status[]=2&order=default", "Animes finalizados"),
|
||||||
|
Pair("$mainUrl/browse?status[]=1&order=rating", "En emision"),
|
||||||
|
)
|
||||||
|
val items = ArrayList<HomePageList>()
|
||||||
|
for (i in urls) {
|
||||||
|
try {
|
||||||
|
val doc = app.get(i.first).document
|
||||||
|
val home = doc.select("ul.List-Animes li.Anime").map {
|
||||||
|
val title = it.selectFirst("h2.title").text()
|
||||||
|
val poster = it.selectFirst(".Image img").attr("src")
|
||||||
|
AnimeSearchResponse(
|
||||||
|
title,
|
||||||
|
fixUrl(it.selectFirst("a").attr("href")),
|
||||||
|
this.name,
|
||||||
|
TvType.Anime,
|
||||||
|
fixUrl(poster),
|
||||||
|
null,
|
||||||
|
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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): ArrayList<SearchResponse> {
|
||||||
|
|
||||||
|
val url = "${mainUrl}/browse?q=${query}"
|
||||||
|
val doc = app.get(url).document
|
||||||
|
val episodes = doc.select("ul.List-Animes li.Anime").map {
|
||||||
|
val title = it.selectFirst("h2.title").text()
|
||||||
|
val href = fixUrl(it.selectFirst("a").attr("href"))
|
||||||
|
val image = it.selectFirst(".Image 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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return ArrayList(episodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun load(url: String): LoadResponse {
|
||||||
|
val doc = app.get(url).document
|
||||||
|
val title = doc.selectFirst("h1.Title").text()
|
||||||
|
val description = doc.selectFirst(".Anime > header:nth-child(1) > p:nth-child(3)").text().replace("Sinopsis: ","")
|
||||||
|
val poster = doc.selectFirst(".Image img").attr("src")
|
||||||
|
val episodes = doc.select("li.Episode").map { li ->
|
||||||
|
val href = fixUrl(li.selectFirst("a").attr("href"))
|
||||||
|
AnimeEpisode(
|
||||||
|
fixUrl(href), "Episodio" + li.selectFirst("a").text().replace(title,"")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val type = doc.selectFirst("span.Type.A").text()
|
||||||
|
val genre = doc.select("a.Tag")
|
||||||
|
.map { it?.text()?.trim().toString() }
|
||||||
|
|
||||||
|
val status = when (doc.selectFirst("article.Anime.Single.Bglg header p strong.Anm-On")?.text()) {
|
||||||
|
"En emisión" -> ShowStatus.Ongoing
|
||||||
|
"Finalizado" -> ShowStatus.Completed
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
return newAnimeLoadResponse(title, url, getType(type)) {
|
||||||
|
posterUrl = fixUrl(poster)
|
||||||
|
addEpisodes(DubStatus.Subbed, episodes)
|
||||||
|
showStatus = status
|
||||||
|
plot = description
|
||||||
|
tags = genre
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override suspend fun loadLinks(
|
||||||
|
data: String,
|
||||||
|
isCasting: Boolean,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
): Boolean {
|
||||||
|
//There might be a better way to do this, but this one works
|
||||||
|
val html = app.get(data).text
|
||||||
|
val linkRegex = Regex("""(https:.*?\.html.*)""")
|
||||||
|
val videos = linkRegex.findAll(html).map {
|
||||||
|
it.value.replace("\\/", "/")
|
||||||
|
}.toList()
|
||||||
|
val serversRegex = Regex("(https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&\\/\\/=]*))")
|
||||||
|
val links = serversRegex.findAll(videos.toString()).map {
|
||||||
|
it.value.replace("https://embedsb.com","https://watchsb.com")
|
||||||
|
}.toList()
|
||||||
|
for (link in links) {
|
||||||
|
for (extractor in extractorApis) {
|
||||||
|
if (link.startsWith(extractor.mainUrl)) {
|
||||||
|
extractor.getSafeUrl(link, data)?.forEach {
|
||||||
|
callback(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
package com.lagradost.cloudstream3.animeproviders
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import java.util.*
|
|
||||||
import com.lagradost.cloudstream3.extractors.FEmbed
|
import com.lagradost.cloudstream3.extractors.FEmbed
|
||||||
|
import java.util.*
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
@ -108,30 +109,26 @@ class MonoschinosProvider:MainAPI() {
|
||||||
val doc = app.get(url, timeout = 120).document
|
val doc = app.get(url, timeout = 120).document
|
||||||
val poster = doc.selectFirst(".chapterpic img").attr("src")
|
val poster = doc.selectFirst(".chapterpic img").attr("src")
|
||||||
val title = doc.selectFirst(".chapterdetails h1").text()
|
val title = doc.selectFirst(".chapterdetails h1").text()
|
||||||
val type = doc.selectFirst(".activecrumb a").text()
|
val type = doc.selectFirst("div.chapterdetls2").text()
|
||||||
val year = doc.selectFirst(".btn2").text().toIntOrNull()
|
|
||||||
val description = doc.selectFirst("p.textComplete").text().replace("Ver menos","")
|
val description = doc.selectFirst("p.textComplete").text().replace("Ver menos","")
|
||||||
val genres = doc.select(".breadcrumb-item a").map { it.text() }
|
val genres = doc.select(".breadcrumb-item a").map { it.text() }
|
||||||
val status = when (doc.selectFirst("btn1")?.text()) {
|
val status = when (doc.selectFirst("button.btn1")?.text()) {
|
||||||
"Estreno" -> ShowStatus.Ongoing
|
"Estreno" -> ShowStatus.Ongoing
|
||||||
"Finalizado" -> ShowStatus.Completed
|
"Finalizado" -> ShowStatus.Completed
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
val rat = doc.select(".chapterpic p").toString().toIntOrNull()
|
|
||||||
val episodes = doc.select("div.col-item").map {
|
val episodes = doc.select("div.col-item").map {
|
||||||
val name = it.selectFirst("p.animetitles").text()
|
val name = it.selectFirst("p.animetitles").text()
|
||||||
val link = it.selectFirst("a").attr("href")
|
val link = it.selectFirst("a").attr("href")
|
||||||
val epThumb = it.selectFirst("img.animeimghv").attr("data-src")
|
val epThumb = it.selectFirst(".animeimghv").attr("data-src")
|
||||||
AnimeEpisode(link, name, posterUrl = epThumb)
|
AnimeEpisode(link, name, posterUrl = epThumb)
|
||||||
}
|
}
|
||||||
return newAnimeLoadResponse(title, url, getType(type)) {
|
return newAnimeLoadResponse(title, url, getType(type)) {
|
||||||
posterUrl = poster
|
posterUrl = poster
|
||||||
this.year = year
|
|
||||||
addEpisodes(DubStatus.Subbed, episodes)
|
addEpisodes(DubStatus.Subbed, episodes)
|
||||||
showStatus = status
|
showStatus = status
|
||||||
plot = description
|
plot = description
|
||||||
tags = genres
|
tags = genres
|
||||||
rating = rat
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,11 @@ package com.lagradost.cloudstream3.extractors
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
|
|
||||||
|
class Evoload1 : Evoload() {
|
||||||
|
override val mainUrl = "https://evoload.io"
|
||||||
|
}
|
||||||
|
|
||||||
class Evoload : ExtractorApi() {
|
open class Evoload : ExtractorApi() {
|
||||||
override val name: String = "Evoload"
|
override val name: String = "Evoload"
|
||||||
override val mainUrl: String = "https://www.evoload.io"
|
override val mainUrl: String = "https://www.evoload.io"
|
||||||
//private val srcRegex = Regex("""video .*src="(.*)""""") // would be possible to use the parse and find src attribute
|
//private val srcRegex = Regex("""video .*src="(.*)""""") // would be possible to use the parse and find src attribute
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CinecalidadProvider:MainAPI() {
|
||||||
|
override val mainUrl: String
|
||||||
|
get() = "https://cinecalidad.lol"
|
||||||
|
override val name: String
|
||||||
|
get() = "Cinecalidad"
|
||||||
|
override val 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(): HomePageResponse {
|
||||||
|
val items = ArrayList<HomePageList>()
|
||||||
|
val urls = listOf(
|
||||||
|
Pair("$mainUrl/", "Peliculas"),
|
||||||
|
Pair("$mainUrl/genero-de-la-pelicula/peliculas-en-calidad-4k/", "4K UHD"),
|
||||||
|
)
|
||||||
|
|
||||||
|
items.add(HomePageList("Series",app.get("$mainUrl/ver-serie/").document.select(".item.tvshows").map{
|
||||||
|
val title = it.selectFirst("div.in_title").text()
|
||||||
|
TvSeriesSearchResponse(
|
||||||
|
title,
|
||||||
|
it.selectFirst("a").attr("href"),
|
||||||
|
this.name,
|
||||||
|
TvType.TvSeries,
|
||||||
|
it.selectFirst(".poster.custom img").attr("data-src"),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
|
||||||
|
for (i in urls) {
|
||||||
|
try {
|
||||||
|
val soup = app.get(i.first).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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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> {
|
||||||
|
val url = "$mainUrl/buscar/?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(".single_left > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2) > 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("div.imagen img").attr("data-src")
|
||||||
|
val name = li.selectFirst(".episodiotitle a").text()
|
||||||
|
TvSeriesEpisode(
|
||||||
|
name,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
href,
|
||||||
|
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 {
|
||||||
|
app.get(data).document.select(".ajax_mode .dooplay_player_option").forEach {
|
||||||
|
val movieID = it.attr("data-post")
|
||||||
|
val serverID = it.attr("data-nume")
|
||||||
|
val url = "$mainUrl/wp-json/dooplayer/v2/$movieID/movie/$serverID"
|
||||||
|
val urlserver = app.get(url).text
|
||||||
|
val serverRegex = Regex("(https:.*?\\\")")
|
||||||
|
val videos = serverRegex.findAll(urlserver).map {
|
||||||
|
it.value.replace("\\/", "/").replace("\"","")
|
||||||
|
}.toList()
|
||||||
|
val serversRegex = Regex("(https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&\\/\\/=]*))")
|
||||||
|
val links = serversRegex.findAll(videos.toString()).map { it.value }.toList()
|
||||||
|
for (link in links) {
|
||||||
|
for (extractor in extractorApis) {
|
||||||
|
if (link.startsWith(extractor.mainUrl)) {
|
||||||
|
extractor.getSafeUrl(link, data)?.forEach {
|
||||||
|
callback(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
class PeliSmartProvider: MainAPI() {
|
||||||
|
override val mainUrl: String
|
||||||
|
get() = "https://pelismart.com"
|
||||||
|
override val name: String
|
||||||
|
get() = "PeliSmart"
|
||||||
|
override val 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(): HomePageResponse {
|
||||||
|
val items = ArrayList<HomePageList>()
|
||||||
|
val urls = listOf(
|
||||||
|
Pair("$mainUrl/peliculas/", "Peliculas"),
|
||||||
|
Pair("$mainUrl/series/", "Series"),
|
||||||
|
Pair("$mainUrl/documentales/", "Documentales"),
|
||||||
|
)
|
||||||
|
|
||||||
|
for (i in urls) {
|
||||||
|
try {
|
||||||
|
val soup = app.get(i.first).document
|
||||||
|
val home = soup.select(".description-off").map {
|
||||||
|
val title = it.selectFirst("h3.entry-title a").text()
|
||||||
|
val link = it.selectFirst("a").attr("href")
|
||||||
|
TvSeriesSearchResponse(
|
||||||
|
title,
|
||||||
|
link,
|
||||||
|
this.name,
|
||||||
|
if (link.contains("pelicula")) TvType.Movie else TvType.TvSeries,
|
||||||
|
it.selectFirst("div img").attr("src"),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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> {
|
||||||
|
val url = "$mainUrl?s=${query}&post_type=post"
|
||||||
|
val document = app.get(url).document
|
||||||
|
|
||||||
|
return document.select(".description-off").map {
|
||||||
|
val title = it.selectFirst("h3.entry-title a").text()
|
||||||
|
val href = it.selectFirst("a").attr("href")
|
||||||
|
val image = it.selectFirst("div img").attr("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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override suspend fun load(url: String): LoadResponse? {
|
||||||
|
val soup = app.get(url, timeout = 120).document
|
||||||
|
val title = soup.selectFirst(".wpb_wrapper h1").text()
|
||||||
|
val description = soup.selectFirst("div.wpb_wrapper p")?.text()?.trim()
|
||||||
|
val poster: String? = soup.selectFirst(".vc_single_image-img").attr("src")
|
||||||
|
val episodes = soup.select("div.vc_tta-panel-body div a").map { li ->
|
||||||
|
val href = li.selectFirst("a").attr("href")
|
||||||
|
val preregex = Regex("(\\d+)\\. ")
|
||||||
|
val name = li.selectFirst("a").text().replace(preregex,"")
|
||||||
|
TvSeriesEpisode(
|
||||||
|
name,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
href,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return when (val tvType = if (episodes.isEmpty()) 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 soup = app.get(data).text
|
||||||
|
val linkRegex = Regex("""(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/\/=]*))""")
|
||||||
|
val link1 = linkRegex.findAll(soup).map {
|
||||||
|
it.value.replace("https://pelismart.com/p/1.php?v=","https://evoload.io/e/")
|
||||||
|
.replace("https://pelismart.com/p/2.php?v=","https://streamtape.com/e/")
|
||||||
|
.replace("https://pelismart.com/p/4.php?v=","https://dood.to/e/")
|
||||||
|
.replace("https://pelismarthd.com/p/1.php?v=","https://evoload.io/e/")
|
||||||
|
.replace("https://pelismarthd.com/p/2.php?v=","https://streamtape.com/e/")
|
||||||
|
.replace("https://pelismarthd.com/p/4.php?v=","https://dood.to/e/")
|
||||||
|
}.toList()
|
||||||
|
for (link in link1) {
|
||||||
|
for (extractor in extractorApis) {
|
||||||
|
if (link.startsWith(extractor.mainUrl)) {
|
||||||
|
extractor.getSafeUrl(link, data)?.forEach {
|
||||||
|
callback(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class PelisplusHDProvider:MainAPI() {
|
class PelisplusHDProvider:MainAPI() {
|
||||||
|
@ -29,8 +28,7 @@ class PelisplusHDProvider:MainAPI() {
|
||||||
)
|
)
|
||||||
for (i in urls) {
|
for (i in urls) {
|
||||||
try {
|
try {
|
||||||
val response = app.get(i.first)
|
val soup = app.get(i.first).document
|
||||||
val soup = Jsoup.parse(response.text)
|
|
||||||
val home = soup.select("a.Posters-link").map {
|
val home = soup.select("a.Posters-link").map {
|
||||||
val title = it.selectFirst(".listing-content p").text()
|
val title = it.selectFirst(".listing-content p").text()
|
||||||
val link = it.selectFirst("a").attr("href")
|
val link = it.selectFirst("a").attr("href")
|
||||||
|
@ -57,8 +55,7 @@ class PelisplusHDProvider:MainAPI() {
|
||||||
|
|
||||||
override suspend fun search(query: String): List<SearchResponse> {
|
override suspend fun search(query: String): List<SearchResponse> {
|
||||||
val url = "https://pelisplushd.net/search?s=${query}"
|
val url = "https://pelisplushd.net/search?s=${query}"
|
||||||
val html = app.get(url).text
|
val document = app.get(url).document
|
||||||
val document = Jsoup.parse(html)
|
|
||||||
|
|
||||||
return document.select("a.Posters-link").map {
|
return document.select("a.Posters-link").map {
|
||||||
val title = it.selectFirst(".listing-content p").text()
|
val title = it.selectFirst(".listing-content p").text()
|
||||||
|
@ -90,16 +87,16 @@ class PelisplusHDProvider:MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun load(url: String): LoadResponse? {
|
override suspend fun load(url: String): LoadResponse? {
|
||||||
val html = app.get(url).text
|
val soup = app.get(url, timeout = 120).document
|
||||||
val soup = Jsoup.parse(html)
|
|
||||||
|
|
||||||
val title = soup.selectFirst(".m-b-5").text()
|
val title = soup.selectFirst(".m-b-5").text()
|
||||||
val description = soup.selectFirst("div.text-large")?.text()?.trim()
|
val description = soup.selectFirst("div.text-large")?.text()?.trim()
|
||||||
val poster: String? = soup.selectFirst(".img-fluid").attr("src")
|
val poster: String? = soup.selectFirst(".img-fluid").attr("src")
|
||||||
val episodes = soup.select("div.tab-pane .btn").map { li ->
|
val episodes = soup.select("div.tab-pane .btn").map { li ->
|
||||||
val href = li.selectFirst("a").attr("href")
|
val href = li.selectFirst("a").attr("href")
|
||||||
|
val name = li.selectFirst(".btn-primary.btn-block").text()
|
||||||
TvSeriesEpisode(
|
TvSeriesEpisode(
|
||||||
null,
|
name,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
href,
|
href,
|
||||||
|
@ -152,12 +149,12 @@ class PelisplusHDProvider:MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val html = app.get(data).text
|
val soup = app.get(data).document
|
||||||
val soup = Jsoup.parse(html)
|
|
||||||
val selector = soup.selectFirst("div.player > script").toString()
|
val selector = soup.selectFirst("div.player > script").toString()
|
||||||
val linkRegex = Regex("""(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/\/=]*))""")
|
val linkRegex = Regex("""(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/\/=]*))""")
|
||||||
val links = linkRegex.findAll(selector).map {
|
val links = linkRegex.findAll(selector).map {
|
||||||
it.value.replace("https://pelisplushd.net/fembed.php?url=","https://www.fembed.com/v/")
|
it.value.replace("https://pelisplushd.net/fembed.php?url=","https://www.fembed.com/v/")
|
||||||
|
.replace("https://pelistop.co/","https://watchsb.com/")
|
||||||
}.toList()
|
}.toList()
|
||||||
for (link in links) {
|
for (link in links) {
|
||||||
for (extractor in extractorApis) {
|
for (extractor in extractorApis) {
|
||||||
|
|
|
@ -105,6 +105,7 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
|
||||||
Uqload(),
|
Uqload(),
|
||||||
Uqload1(),
|
Uqload1(),
|
||||||
Evoload(),
|
Evoload(),
|
||||||
|
Evoload1(),
|
||||||
VoeExtractor(),
|
VoeExtractor(),
|
||||||
UpstreamExtractor(),
|
UpstreamExtractor(),
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue