clone site feature don't work with witflix, add alternative for wiflix and french stream
in mainpage see episode number nekosama
This commit is contained in:
parent
50b934a0cf
commit
9bd6623187
|
@ -1,10 +1,13 @@
|
|||
package com.lagradost
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
|
||||
import com.lagradost.cloudstream3.utils.AppUtils
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.extractorApis
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
|
||||
|
@ -16,6 +19,35 @@ class FrenchStreamProvider : MainAPI() {
|
|||
override var lang = "fr"
|
||||
override val supportedTypes = setOf(TvType.Movie, TvType.TvSeries)
|
||||
|
||||
init {
|
||||
runBlocking {
|
||||
try {
|
||||
val document = app.get(mainUrl).document
|
||||
val newMainUrl = document.select("link[rel*=\"canonical\"]").attr("href")
|
||||
if (!newMainUrl.isNullOrBlank() && newMainUrl.contains("french-stream")) {
|
||||
mainUrl = newMainUrl
|
||||
} else {
|
||||
val data =
|
||||
AppUtils.tryParseJson<ArrayList<mediaData>>(app.get("https://raw.githubusercontent.com/Eddy976/cloudstream-extensions-eddy/ressources/fetchwebsite.json").text)!!
|
||||
data.forEach {
|
||||
if (it.title.lowercase().contains("french-stream")) {
|
||||
mainUrl = it.url
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) { // url changed
|
||||
val data =
|
||||
AppUtils.tryParseJson<ArrayList<mediaData>>(app.get("https://raw.githubusercontent.com/Eddy976/cloudstream-extensions-eddy/ressources/fetchwebsite.json").text)!!
|
||||
data.forEach {
|
||||
if (it.title.lowercase().contains("french-stream")) {
|
||||
mainUrl = it.url
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun search(query: String): List<SearchResponse> {
|
||||
val link = "$mainUrl/?do=search&subaction=search&story=$query" // search'
|
||||
val document =
|
||||
|
@ -29,20 +61,57 @@ class FrenchStreamProvider : MainAPI() {
|
|||
return allresultshome
|
||||
}
|
||||
|
||||
private fun Element.takeEpisode(
|
||||
url: String,
|
||||
): MutableList<Episode> {
|
||||
return this.select("a").map { a ->
|
||||
val epNum =
|
||||
Regex("""pisode[\s]+(\d+)""").find(a.text().lowercase())?.groupValues?.get(1)
|
||||
?.toIntOrNull()
|
||||
val epTitle = if (a.text().contains("Episode")) {
|
||||
val type = if ("honey" in a.attr("id")) {
|
||||
"VF"
|
||||
} else {
|
||||
"Vostfr"
|
||||
}
|
||||
"Episode " + type
|
||||
} else {
|
||||
a.text()
|
||||
}
|
||||
|
||||
Episode(
|
||||
fixUrl(url).plus("-episodenumber:$epNum") + if (epTitle.contains("Vostfr")) {
|
||||
"*vostfr*"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
epTitle,
|
||||
null,
|
||||
epNum,
|
||||
a.selectFirst("div.fposter > img")?.attr("src"),
|
||||
)
|
||||
}.toMutableList()
|
||||
}
|
||||
|
||||
override suspend fun load(url: String): LoadResponse {
|
||||
val soup = app.get(url).document
|
||||
|
||||
var subEpisodes = mutableListOf<Episode>()
|
||||
var dubEpisodes = mutableListOf<Episode>()
|
||||
val title = soup.selectFirst("h1#s-title")!!.text().toString()
|
||||
val isMovie = !title.contains("saison", ignoreCase = true)
|
||||
val description =
|
||||
soup.selectFirst("div.fdesc")!!.text().toString()
|
||||
.split("streaming", ignoreCase = true)[1].replace(":", "")
|
||||
var poster = soup.selectFirst("div.fposter > img")?.attr("src")
|
||||
val poster = soup.selectFirst("div.fposter > img")?.attr("src")
|
||||
val listEpisode = soup.select("div.elink")
|
||||
val tags = soup.select("ul.flist-col > li").getOrNull(1)
|
||||
//val rating = soup.select("span[id^=vote-num-id]")?.getOrNull(1)?.text()?.toInt()
|
||||
|
||||
if (isMovie) {
|
||||
if ("<a" in (listEpisode[1]).toString()) { // check if VF is empty
|
||||
subEpisodes = listEpisode[1].takeEpisode(url) // return vostfr
|
||||
}
|
||||
if ("<a" in (listEpisode[0]).toString()) {
|
||||
dubEpisodes = listEpisode[0].takeEpisode(url)// return vf
|
||||
}
|
||||
if (subEpisodes.isEmpty() && dubEpisodes.isEmpty()) {
|
||||
val yearRegex = Regex("""ate de sortie\: (\d*)""")
|
||||
val year = yearRegex.find(soup.text())?.groupValues?.get(1)
|
||||
val tagsList = tags?.select("a")
|
||||
|
@ -57,56 +126,21 @@ class FrenchStreamProvider : MainAPI() {
|
|||
//this.rating = rating
|
||||
addTrailer(soup.selectFirst("button#myBtn > a")?.attr("href"))
|
||||
}
|
||||
} else // a tv serie
|
||||
{
|
||||
} else {
|
||||
|
||||
val episodeList = if ("<a" !in (listEpisode[0]).toString()) { // check if VF is empty
|
||||
listEpisode[1] // no vf, return vostfr
|
||||
} else {
|
||||
listEpisode[0] // no vostfr, return vf
|
||||
}
|
||||
|
||||
val episodes = episodeList.select("a").map { a ->
|
||||
val epNum = a.text().split("Episode")[1].trim().toIntOrNull()
|
||||
val epTitle = if (a.text().contains("Episode")) {
|
||||
val type = if ("honey" in a.attr("id")) {
|
||||
"VF"
|
||||
} else {
|
||||
"Vostfr"
|
||||
}
|
||||
"Episode " + type
|
||||
} else {
|
||||
a.text()
|
||||
}
|
||||
if (poster == null) {
|
||||
poster = a.selectFirst("div.fposter > img")?.attr("src")
|
||||
}
|
||||
Episode(
|
||||
fixUrl(url).plus("-episodenumber:$epNum"),
|
||||
epTitle,
|
||||
null,
|
||||
epNum,
|
||||
null, // episode Thumbnail
|
||||
null // episode date
|
||||
)
|
||||
}
|
||||
|
||||
// val tagsList = tags?.text()?.replace("Genre :","")
|
||||
val yearRegex = Regex("""Titre .* \/ (\d*)""")
|
||||
val year = yearRegex.find(soup.text())?.groupValues?.get(1)
|
||||
return newTvSeriesLoadResponse(
|
||||
return newAnimeLoadResponse(
|
||||
title,
|
||||
url,
|
||||
TvType.TvSeries,
|
||||
episodes,
|
||||
) {
|
||||
this.posterUrl = poster
|
||||
this.plot = description
|
||||
this.year = year?.toInt()
|
||||
//this.rating = rating
|
||||
//this.showStatus = ShowStatus.Ongoing
|
||||
//this.tags = tagsList
|
||||
addTrailer(soup.selectFirst("button#myBtn > a")?.attr("href"))
|
||||
if (subEpisodes.isNotEmpty()) addEpisodes(DubStatus.Subbed, subEpisodes)
|
||||
if (dubEpisodes.isNotEmpty()) addEpisodes(DubStatus.Dubbed, dubEpisodes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +161,7 @@ class FrenchStreamProvider : MainAPI() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
override suspend fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
|
@ -136,8 +171,14 @@ class FrenchStreamProvider : MainAPI() {
|
|||
val servers =
|
||||
if (data.contains("-episodenumber:"))// It's a serie:
|
||||
{
|
||||
val isvostfr = data.takeLast(8) == "*vostfr*"
|
||||
|
||||
val split =
|
||||
data.split("-episodenumber:") // the data contains the url and the wanted episode number (a temporary dirty fix that will last forever)
|
||||
if (isvostfr) {
|
||||
data.dropLast(8).split("-episodenumber:")
|
||||
} else {
|
||||
data.split("-episodenumber:")
|
||||
} // the data contains the url and the wanted episode number (a temporary dirty fix that will last forever)
|
||||
val url = split[0]
|
||||
val wantedEpisode =
|
||||
if (split[1] == "2") { // the episode number 2 has id of ABCDE, don't ask any question
|
||||
|
@ -185,7 +226,11 @@ class FrenchStreamProvider : MainAPI() {
|
|||
null
|
||||
}
|
||||
}
|
||||
serversvf + serversvo
|
||||
if (isvostfr) {
|
||||
serversvo
|
||||
} else {
|
||||
serversvf
|
||||
}
|
||||
} else { // it's a movie
|
||||
val movieServers =
|
||||
app.get(fixUrl(data)).document.select("nav#primary_nav_wrap > ul > li > ul > li > a")
|
||||
|
@ -218,7 +263,7 @@ class FrenchStreamProvider : MainAPI() {
|
|||
allowRedirects = false
|
||||
).headers
|
||||
val urlplayer = it.second
|
||||
var playerUrl = when (!urlplayer.isNullOrEmpty()) {
|
||||
val playerUrl = when (!urlplayer.isNullOrEmpty()) {
|
||||
urlplayer.contains("opsktp.com") -> header.get("location")
|
||||
.toString() // case where there is redirection to opsktp
|
||||
|
||||
|
@ -238,19 +283,20 @@ class FrenchStreamProvider : MainAPI() {
|
|||
|
||||
val posterUrl = fixUrl(select("a.short-poster > img").attr("src"))
|
||||
val qualityExtracted = select("span.film-ripz > a").text()
|
||||
val type = select("span.mli-eps").text()
|
||||
val type = select("span.mli-eps").text().lowercase()
|
||||
val title = select("div.short-title").text()
|
||||
val link = select("a.short-poster").attr("href").replace("wvw.", "") //wvw is an issue
|
||||
var quality = when (!qualityExtracted.isNullOrBlank()) {
|
||||
qualityExtracted.contains("HDLight") -> getQualityFromString("HD")
|
||||
qualityExtracted.contains("Bdrip") -> getQualityFromString("BlueRay")
|
||||
qualityExtracted.contains("DVD") -> getQualityFromString("DVD")
|
||||
qualityExtracted.contains("CAM") -> getQualityFromString("Cam")
|
||||
val quality = getQualityFromString(
|
||||
when (!qualityExtracted.isNullOrBlank()) {
|
||||
qualityExtracted.contains("HDLight") -> "HD"
|
||||
qualityExtracted.contains("Bdrip") -> "BlueRay"
|
||||
qualityExtracted.contains("DVD") -> "DVD"
|
||||
qualityExtracted.contains("CAM") -> "Cam"
|
||||
else -> null
|
||||
}
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (type.contains("Eps", false)) {
|
||||
if (!type.contains("eps")) {
|
||||
return MovieSearchResponse(
|
||||
name = title,
|
||||
url = link,
|
||||
|
@ -264,20 +310,28 @@ class FrenchStreamProvider : MainAPI() {
|
|||
|
||||
} else // an Serie
|
||||
{
|
||||
|
||||
return TvSeriesSearchResponse(
|
||||
return newAnimeSearchResponse(
|
||||
name = title,
|
||||
url = link,
|
||||
apiName = title,
|
||||
type = TvType.TvSeries,
|
||||
posterUrl = posterUrl,
|
||||
quality = quality,
|
||||
//
|
||||
)
|
||||
|
||||
) {
|
||||
this.posterUrl = posterUrl
|
||||
addDubStatus(
|
||||
isDub = select("span.film-verz").text().uppercase().contains("VF"),
|
||||
episodes = select("span.mli-eps>i").text().toIntOrNull()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
data class mediaData(
|
||||
@JsonProperty("title") var title: String,
|
||||
@JsonProperty("url") val url: String,
|
||||
)
|
||||
|
||||
override val mainPage = mainPageOf(
|
||||
Pair("$mainUrl/xfsearch/version-film/page/", "Derniers films"),
|
||||
Pair("$mainUrl/xfsearch/version-serie/page/", "Derniers séries"),
|
||||
|
@ -288,17 +342,9 @@ class FrenchStreamProvider : MainAPI() {
|
|||
Pair("$mainUrl/film/documentaire/page/", "Documentaire")
|
||||
|
||||
)
|
||||
private var ismainUrlChecked = false
|
||||
|
||||
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
|
||||
val url = request.data + page
|
||||
if (!ismainUrlChecked) {
|
||||
ismainUrlChecked = true
|
||||
val document = app.get(mainUrl).document
|
||||
val newMainUrl = document.select("link[rel*=\"canonical\"]").attr("href")
|
||||
if (!newMainUrl.isNullOrBlank() && newMainUrl.contains("french-stream")) {
|
||||
mainUrl = newMainUrl
|
||||
}
|
||||
}
|
||||
val document = app.get(url).document
|
||||
val movies = document.select("div#dle-content > div.short")
|
||||
|
||||
|
@ -308,5 +354,6 @@ class FrenchStreamProvider : MainAPI() {
|
|||
}
|
||||
return newHomePageResponse(request.name, home)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -4,8 +4,6 @@ package com.lagradost
|
|||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.utils.*
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
|
@ -59,7 +57,7 @@ class NekosamaProvider : MainAPI() {
|
|||
|
||||
if (query == null) {
|
||||
// No shorting so return the first title
|
||||
var title = this.title
|
||||
val title = this.title
|
||||
|
||||
return title
|
||||
} else {
|
||||
|
@ -333,7 +331,7 @@ class NekosamaProvider : MainAPI() {
|
|||
val type = select("div.info > p.year").text()
|
||||
val title = select("div.info > a.title > div.limit").text()
|
||||
val link = fixUrl(select("div.cover > a").attr("href"))
|
||||
if (type.contains("Film")) {
|
||||
if (type.uppercase().contains("FILM")) {
|
||||
return newMovieSearchResponse(
|
||||
title,
|
||||
link,
|
||||
|
@ -341,6 +339,7 @@ class NekosamaProvider : MainAPI() {
|
|||
false,
|
||||
) {
|
||||
this.posterUrl = posterUrl
|
||||
|
||||
}
|
||||
|
||||
} else // an Anime
|
||||
|
@ -352,6 +351,11 @@ class NekosamaProvider : MainAPI() {
|
|||
false,
|
||||
) {
|
||||
this.posterUrl = posterUrl
|
||||
addDubStatus(
|
||||
isDub = link.contains("-vf"),
|
||||
episodes = Regex("""(\d*) Eps""").find(type)?.groupValues?.get(1)
|
||||
?.toIntOrNull()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,17 +375,13 @@ class NekosamaProvider : MainAPI() {
|
|||
|
||||
private fun LastEpisodeData.tomainHome(): SearchResponse {
|
||||
|
||||
var posterUrl = this.url_image?.replace("""\""", "")
|
||||
val posterUrl = this.url_image?.replace("""\""", "")
|
||||
val link = this.anime_url?.replace("""\""", "")?.let { fixUrl(it) }
|
||||
?: throw error("Error parsing")
|
||||
val title = this.title ?: throw error("Error parsing")
|
||||
val type = this.episode ?: ""
|
||||
var lang = this.lang
|
||||
val dubStatus = if (lang?.contains("vf") == true) {
|
||||
DubStatus.Dubbed
|
||||
} else {
|
||||
DubStatus.Subbed
|
||||
}
|
||||
val lang = this.lang
|
||||
|
||||
|
||||
if (type.contains("Ep")) {
|
||||
return newAnimeSearchResponse(
|
||||
|
@ -391,8 +391,11 @@ class NekosamaProvider : MainAPI() {
|
|||
false,
|
||||
) {
|
||||
this.posterUrl = posterUrl
|
||||
this.dubStatus = EnumSet.of(dubStatus)
|
||||
|
||||
addDubStatus(
|
||||
isDub = lang?.contains("vf")==true,
|
||||
episodes = Regex("""Ep[\.][\s]+(\d*)""").find(type)?.groupValues?.get(1)
|
||||
?.toIntOrNull()
|
||||
)
|
||||
}
|
||||
|
||||
} else // a movie
|
||||
|
@ -404,8 +407,11 @@ class NekosamaProvider : MainAPI() {
|
|||
false,
|
||||
) {
|
||||
this.posterUrl = posterUrl
|
||||
this.dubStatus = EnumSet.of(dubStatus)
|
||||
}
|
||||
addDubStatus(
|
||||
isDub = lang?.contains("vf")==true,
|
||||
episodes = Regex("""(\d*) Eps""").find(type)?.groupValues?.get(1)
|
||||
?.toIntOrNull()
|
||||
) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,18 +8,39 @@ import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
|||
import org.jsoup.nodes.Element
|
||||
import org.jsoup.select.Elements
|
||||
import kotlin.collections.ArrayList
|
||||
import com.lagradost.cloudstream3.network.CloudflareKiller
|
||||
import com.lagradost.nicehttp.NiceResponse
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
|
||||
class WiflixProvider : MainAPI() {
|
||||
|
||||
|
||||
override var mainUrl = "https://wiflix.zone"
|
||||
override var mainUrl = "https://wiflix.cafe"
|
||||
override var name = "Wiflix"
|
||||
override val hasQuickSearch = false // recherche rapide (optionel, pas vraimet utile)
|
||||
override val hasMainPage = true // page d'accueil (optionel mais encoragé)
|
||||
override var lang = "fr" // fournisseur est en francais
|
||||
override val supportedTypes =
|
||||
setOf(TvType.Movie, TvType.TvSeries) // series, films
|
||||
// liste des types: https://recloudstream.github.io/dokka/app/com.lagradost.cloudstream3/-tv-type/index.html
|
||||
private val interceptor = CloudflareKiller()
|
||||
|
||||
init {
|
||||
runBlocking {
|
||||
try {
|
||||
app.get(mainUrl)
|
||||
} catch (e: Exception) { // url changed
|
||||
val data =
|
||||
tryParseJson<ArrayList<mediaData>>(app.get("https://raw.githubusercontent.com/Eddy976/cloudstream-extensions-eddy/ressources/fetchwebsite.json").text)!!
|
||||
data.forEach {
|
||||
if (it.title.lowercase().contains("wiflix")) {
|
||||
mainUrl = it.url
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Cherche le site pour un titre spécifique
|
||||
|
@ -29,7 +50,7 @@ class WiflixProvider : MainAPI() {
|
|||
**/
|
||||
override suspend fun search(query: String): List<SearchResponse> {
|
||||
val link =
|
||||
"$mainUrl/index.php?do=search&subaction=search&search_start=0&full_search=1&result_from=1&story=$query&titleonly=3&searchuser=&replyless=0&replylimit=0&searchdate=0&beforeafter=after&sortby=date&resorder=desc&showposts=0&catlist%5B%5D=0" // search'
|
||||
"$mainUrl/index.php?do=search&subaction=search&search_start=0&full_search=1&result_from=1&story=$query&titleonly=3&searchuser=&replyless=0&replylimit=0&searchdate=0&beforeafter=after&sortby=date&resorder=desc&showposts=0&catlist%5B%5D=0" // search'
|
||||
val document =
|
||||
app.post(link).document // app.get() permet de télécharger la page html avec une requete HTTP (get)
|
||||
val results = document.select("div#dle-content > div.clearfix")
|
||||
|
@ -50,13 +71,17 @@ class WiflixProvider : MainAPI() {
|
|||
@JsonProperty("episodeNumber") val episodeNumber: String,
|
||||
)
|
||||
|
||||
private fun Elements.takeEpisode(url: String, duborSub: String?): ArrayList<Episode> {
|
||||
private fun Elements.takeEpisode(
|
||||
url: String,
|
||||
posterUrl: String?,
|
||||
duborSub: String?
|
||||
): ArrayList<Episode> {
|
||||
|
||||
val episodes = ArrayList<Episode>()
|
||||
this.select("ul.eplist > li").forEach {
|
||||
|
||||
val strEpisode = it.text()
|
||||
val strEpisodeN = strEpisode.replace("Episode ", "")
|
||||
val strEpisodeN =
|
||||
Regex("""pisode[\s]+(\d+)""").find(it.text())?.groupValues?.get(1).toString()
|
||||
val link =
|
||||
EpisodeData(
|
||||
url,
|
||||
|
@ -66,9 +91,14 @@ class WiflixProvider : MainAPI() {
|
|||
|
||||
episodes.add(
|
||||
Episode(
|
||||
link,
|
||||
name = duborSub,
|
||||
episode = strEpisodeN.toInt(),
|
||||
link + if (duborSub=="vostfr") {
|
||||
"*$duborSub*"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
name = "Episode en " + duborSub,
|
||||
episode = strEpisodeN.toIntOrNull(),
|
||||
posterUrl = posterUrl
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -77,11 +107,11 @@ class WiflixProvider : MainAPI() {
|
|||
}
|
||||
|
||||
override suspend fun load(url: String): LoadResponse {
|
||||
val document = app.get(url).document //
|
||||
val document = avoidCloudflare(url).document //
|
||||
// url est le lien retourné par la fonction search (la variable href) ou la fonction getMainPage
|
||||
|
||||
var episodes = ArrayList<Episode>()
|
||||
var mediaType: TvType
|
||||
var subEpisodes = ArrayList<Episode>()
|
||||
var dubEpisodes = ArrayList<Episode>()
|
||||
val mediaType: TvType
|
||||
val episodeFrfound =
|
||||
document.select("div.blocfr")
|
||||
|
||||
|
@ -97,27 +127,23 @@ class WiflixProvider : MainAPI() {
|
|||
|
||||
val tags = document.select("[itemprop=genre] > a")
|
||||
.map { it.text() } // séléctione tous les tags et les ajoutes à une liste
|
||||
|
||||
if (episodeFrfound.text().contains("Episode")) {
|
||||
mediaType = TvType.TvSeries
|
||||
val duborSub = "Episode en VF"
|
||||
episodes = episodeFrfound.takeEpisode(url, duborSub)
|
||||
} else if (episodeVostfrfound.text().contains("Episode")) {
|
||||
mediaType = TvType.TvSeries
|
||||
val duborSub = "Episode sous-titré"
|
||||
episodes = episodeVostfrfound.takeEpisode(url, duborSub)
|
||||
} else {
|
||||
|
||||
mediaType = TvType.Movie
|
||||
mediaType = TvType.TvSeries
|
||||
if (episodeFrfound.text().lowercase().contains("episode")) {
|
||||
val duborSub = "\uD83C\uDDE8\uD83C\uDDF5"
|
||||
dubEpisodes = episodeFrfound.takeEpisode(url, fixUrl(posterUrl), duborSub)
|
||||
}
|
||||
if (episodeVostfrfound.text().lowercase().contains("episode")) {
|
||||
val duborSub = "vostfr"
|
||||
subEpisodes = episodeVostfrfound.takeEpisode(url, fixUrl(posterUrl), duborSub)
|
||||
}
|
||||
///////////////////////////////////////////
|
||||
///////////////////////////////////////////
|
||||
var type_rec: TvType
|
||||
val recommendations =
|
||||
document.select("div.clearfixme > div > div")?.mapNotNull { element ->
|
||||
document.select("div.clearfixme > div > div").mapNotNull { element ->
|
||||
val recTitle =
|
||||
element.select("a").text() ?: return@mapNotNull null
|
||||
val image = element.select("a >img")?.attr("src")
|
||||
val image = element.select("a >img").attr("src")
|
||||
val recUrl = element.select("a").attr("href")
|
||||
type_rec = TvType.TvSeries
|
||||
if (recUrl.contains("film")) type_rec = TvType.Movie
|
||||
|
@ -138,15 +164,14 @@ class WiflixProvider : MainAPI() {
|
|||
this.name,
|
||||
TvType.Movie,
|
||||
image?.let { fixUrl(it) },
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
var comingSoon = url.contains("films-prochainement")
|
||||
val comingSoon = url.contains("films-prochainement")
|
||||
|
||||
|
||||
if (mediaType == TvType.Movie) {
|
||||
if (subEpisodes.isEmpty() && dubEpisodes.isEmpty()) {
|
||||
val description = document.selectFirst("div.screenshots-full")?.text()
|
||||
?.replace("(.* .ynopsis)".toRegex(), "")
|
||||
return newMovieLoadResponse(
|
||||
|
@ -165,11 +190,10 @@ class WiflixProvider : MainAPI() {
|
|||
}
|
||||
} else {
|
||||
val description = document.selectFirst("span[itemprop=description]")?.text()
|
||||
return newTvSeriesLoadResponse(
|
||||
return newAnimeLoadResponse(
|
||||
title,
|
||||
url,
|
||||
mediaType,
|
||||
episodes
|
||||
) {
|
||||
this.posterUrl = fixUrl(posterUrl)
|
||||
this.plot = description
|
||||
|
@ -177,6 +201,8 @@ class WiflixProvider : MainAPI() {
|
|||
this.year = year?.toIntOrNull()
|
||||
this.comingSoon = comingSoon
|
||||
this.tags = tags
|
||||
if (subEpisodes.isNotEmpty()) addEpisodes(DubStatus.Subbed, subEpisodes)
|
||||
if (dubEpisodes.isNotEmpty()) addEpisodes(DubStatus.Dubbed, dubEpisodes)
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -190,30 +216,43 @@ class WiflixProvider : MainAPI() {
|
|||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit,
|
||||
): Boolean {
|
||||
val parsedInfo =
|
||||
var isvostfr = false
|
||||
val parsedInfo = if (data.takeLast(8) == "*vostfr*") {
|
||||
isvostfr = true
|
||||
tryParseJson<EpisodeData>(data.dropLast(6))
|
||||
} else {
|
||||
tryParseJson<EpisodeData>(data)
|
||||
}
|
||||
|
||||
val url = parsedInfo?.url ?: data
|
||||
|
||||
val numeroEpisode = parsedInfo?.episodeNumber ?: null
|
||||
val numeroEpisode = parsedInfo?.episodeNumber
|
||||
|
||||
val document = app.get(url).document
|
||||
val document = avoidCloudflare(url).document
|
||||
val episodeFrfound =
|
||||
document.select("div.blocfr")
|
||||
val episodeVostfrfound =
|
||||
document.select("div.blocvostfr")
|
||||
var flag = "\uD83C\uDDE8\uD83C\uDDF5"
|
||||
|
||||
val cssCodeForPlayer = if (episodeFrfound.text().contains("Episode")) {
|
||||
val cssCodeForPlayer = if (episodeFrfound.text().contains("Episode") && !isvostfr) {
|
||||
"div.ep${numeroEpisode}vf > a"
|
||||
|
||||
} else if (episodeVostfrfound.text().contains("Episode")) {
|
||||
"div.ep${numeroEpisode}vs > a"
|
||||
|
||||
} else {
|
||||
"div.linkstab > a"
|
||||
}
|
||||
|
||||
if (cssCodeForPlayer.contains("vs")) {
|
||||
flag = " \uD83D\uDCDC \uD83C\uDDEC\uD83C\uDDE7"
|
||||
}
|
||||
|
||||
document.select("$cssCodeForPlayer").apmap { player -> // séléctione tous les players
|
||||
var playerUrl = "https"+player.attr("href").replace("(.*)https".toRegex(), "")
|
||||
if (!playerUrl.isNullOrBlank())
|
||||
|
||||
document.select(cssCodeForPlayer).apmap { player -> // séléctione tous les players
|
||||
var playerUrl = "https" + player.attr("href").replace("(.*)https".toRegex(), "")
|
||||
if (!playerUrl.isBlank())
|
||||
if (playerUrl.contains("dood")) {
|
||||
playerUrl = playerUrl.replace("doodstream.com", "dood.wf")
|
||||
}
|
||||
|
@ -225,7 +264,7 @@ class WiflixProvider : MainAPI() {
|
|||
callback.invoke(
|
||||
ExtractorLink( // ici je modifie le callback pour ajouter des informations, normalement ce n'est pas nécessaire
|
||||
link.source,
|
||||
link.name + "",
|
||||
link.name + flag,
|
||||
link.url,
|
||||
link.referer,
|
||||
getQualityFromName("HD"),
|
||||
|
@ -245,18 +284,20 @@ class WiflixProvider : MainAPI() {
|
|||
|
||||
val posterUrl = fixUrl(select("div.img-box > img").attr("src"))
|
||||
val qualityExtracted = select("div.nbloc1-2 >span").text()
|
||||
val type = select("div.nbloc3").text()
|
||||
val type = select("div.nbloc3").text().lowercase()
|
||||
val title = select("a.nowrap").text()
|
||||
val link = select("a.nowrap").attr("href")
|
||||
var quality = when (!qualityExtracted.isNullOrBlank()) {
|
||||
qualityExtracted.contains("HDLight") -> getQualityFromString("HD")
|
||||
qualityExtracted.contains("Bdrip") -> getQualityFromString("BlueRay")
|
||||
qualityExtracted.contains("DVD") -> getQualityFromString("DVD")
|
||||
qualityExtracted.contains("CAM") -> getQualityFromString("Cam")
|
||||
val quality = getQualityFromString(
|
||||
when (!qualityExtracted.isNullOrBlank()) {
|
||||
qualityExtracted.contains("HDLight") -> "HD"
|
||||
qualityExtracted.contains("Bdrip") -> "BlueRay"
|
||||
qualityExtracted.contains("DVD") -> "DVD"
|
||||
qualityExtracted.contains("CAM") -> "Cam"
|
||||
|
||||
else -> null
|
||||
}
|
||||
if (type.contains("Film")) {
|
||||
else -> null
|
||||
}
|
||||
)
|
||||
if (type.contains("film")) {
|
||||
return MovieSearchResponse(
|
||||
name = title,
|
||||
url = link,
|
||||
|
@ -271,19 +312,40 @@ class WiflixProvider : MainAPI() {
|
|||
} else // an Serie
|
||||
{
|
||||
|
||||
return TvSeriesSearchResponse(
|
||||
return newAnimeSearchResponse(
|
||||
name = title,
|
||||
url = link,
|
||||
apiName = title,
|
||||
type = TvType.TvSeries,
|
||||
posterUrl = posterUrl,
|
||||
quality = quality,
|
||||
//
|
||||
)
|
||||
|
||||
) {
|
||||
this.posterUrl = posterUrl
|
||||
this.quality = quality
|
||||
addDubStatus(
|
||||
isDub = !select("span.block-sai").text().uppercase().contains("VOSTFR"),
|
||||
episodes = Regex("""pisode[\s]+(\d+)""").find(select("div.block-ep").text())?.groupValues?.get(
|
||||
1
|
||||
)?.toIntOrNull()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun avoidCloudflare(url: String): NiceResponse {
|
||||
if (!app.get(url).isSuccessful) {
|
||||
return app.get(url, interceptor = interceptor)
|
||||
} else {
|
||||
return app.get(url)
|
||||
}
|
||||
}
|
||||
|
||||
data class mediaData(
|
||||
@JsonProperty("title") var title: String,
|
||||
@JsonProperty("url") val url: String,
|
||||
)
|
||||
|
||||
|
||||
override val mainPage = mainPageOf(
|
||||
Pair("$mainUrl/films-prochainement/page/", "Film Prochainement en Streaming"),
|
||||
Pair("$mainUrl/film-en-streaming/page/", "Top Films cette année"),
|
||||
|
@ -294,7 +356,11 @@ class WiflixProvider : MainAPI() {
|
|||
|
||||
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
|
||||
val url = request.data + page
|
||||
val document = app.get(url).document
|
||||
val document =
|
||||
avoidCloudflare(url).document
|
||||
|
||||
//posterHeaders = interceptor.getCookieHeaders(url).toMap()
|
||||
|
||||
val movies = document.select("div#dle-content > div.clearfix")
|
||||
|
||||
val home =
|
||||
|
@ -305,3 +371,5 @@ class WiflixProvider : MainAPI() {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue