mirror of
https://github.com/recloudstream/cloudstream-extensions-multilingual.git
synced 2024-08-15 03:15:14 +00:00
improve the plugin, changes requested and add comments
This commit is contained in:
parent
024bdd6342
commit
fbe6ad3fa2
3 changed files with 250 additions and 217 deletions
|
@ -1,53 +1,20 @@
|
||||||
package com.lagradost
|
package com.lagradost
|
||||||
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
|
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils
|
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.extractorApis
|
import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
|
||||||
|
|
||||||
class FrenchStreamProvider : MainAPI() {
|
class FrenchStreamProvider : MainAPI() {
|
||||||
override var mainUrl = "https://french-stream.ac" //re ou ac ou city
|
override var mainUrl = "https://french-stream.cx" //re ou ac ou city
|
||||||
override var name = "FrenchStream"
|
override var name = "FrenchStream"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override var lang = "fr"
|
override var lang = "fr"
|
||||||
override val supportedTypes = setOf(TvType.Movie, TvType.TvSeries)
|
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> {
|
override suspend fun search(query: String): List<SearchResponse> {
|
||||||
val link = "$mainUrl/?do=search&subaction=search&story=$query" // search'
|
val link = "$mainUrl/?do=search&subaction=search&story=$query" // search'
|
||||||
val document =
|
val document =
|
||||||
|
@ -61,48 +28,15 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
return allresultshome
|
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 {
|
override suspend fun load(url: String): LoadResponse {
|
||||||
val soup = app.get(url).document
|
val soup = app.get(url).document
|
||||||
var subEpisodes = mutableListOf<Episode>()
|
|
||||||
var dubEpisodes = mutableListOf<Episode>()
|
|
||||||
val title = soup.selectFirst("h1#s-title")!!.text().toString()
|
val title = soup.selectFirst("h1#s-title")!!.text().toString()
|
||||||
val isMovie = !url.contains("/serie/", ignoreCase = true)
|
val isMovie = !title.contains("saison", ignoreCase = true)
|
||||||
val description =
|
val description =
|
||||||
soup.selectFirst("div.fdesc")!!.text().toString()
|
soup.selectFirst("div.fdesc")!!.text().toString()
|
||||||
.split("streaming", ignoreCase = true)[1].replace(":", "")
|
.split("streaming", ignoreCase = true)[1].replace(":", "")
|
||||||
val poster = soup.selectFirst("div.fposter > img")?.attr("src")
|
var poster = soup.selectFirst("div.fposter > img")?.attr("src")
|
||||||
val listEpisode = soup.select("div.elink")
|
val listEpisode = soup.select("div.elink")
|
||||||
val tags = soup.select("ul.flist-col > li").getOrNull(1)
|
val tags = soup.select("ul.flist-col > li").getOrNull(1)
|
||||||
//val rating = soup.select("span[id^=vote-num-id]")?.getOrNull(1)?.text()?.toInt()
|
//val rating = soup.select("span[id^=vote-num-id]")?.getOrNull(1)?.text()?.toInt()
|
||||||
|
@ -122,26 +56,56 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
//this.rating = rating
|
//this.rating = rating
|
||||||
addTrailer(soup.selectFirst("button#myBtn > a")?.attr("href"))
|
addTrailer(soup.selectFirst("button#myBtn > a")?.attr("href"))
|
||||||
}
|
}
|
||||||
} else {
|
} else // a tv serie
|
||||||
if ("<a" in listEpisode[1].toString()) { // check if VF is empty
|
{
|
||||||
subEpisodes = listEpisode[1].takeEpisode(url) // return vostfr
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
if ("<a" in listEpisode[0].toString()) {
|
|
||||||
dubEpisodes = listEpisode[0].takeEpisode(url)// 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 yearRegex = Regex("""Titre .* \/ (\d*)""")
|
||||||
val year = yearRegex.find(soup.text())?.groupValues?.get(1)
|
val year = yearRegex.find(soup.text())?.groupValues?.get(1)
|
||||||
return newAnimeLoadResponse(
|
return newTvSeriesLoadResponse(
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
TvType.TvSeries,
|
TvType.TvSeries,
|
||||||
|
episodes,
|
||||||
) {
|
) {
|
||||||
this.posterUrl = poster
|
this.posterUrl = poster
|
||||||
this.plot = description
|
this.plot = description
|
||||||
this.year = year?.toInt()
|
this.year = year?.toInt()
|
||||||
|
//this.rating = rating
|
||||||
|
//this.showStatus = ShowStatus.Ongoing
|
||||||
|
//this.tags = tagsList
|
||||||
addTrailer(soup.selectFirst("button#myBtn > a")?.attr("href"))
|
addTrailer(soup.selectFirst("button#myBtn > a")?.attr("href"))
|
||||||
if (subEpisodes.isNotEmpty()) addEpisodes(DubStatus.Subbed, subEpisodes)
|
|
||||||
if (dubEpisodes.isNotEmpty()) addEpisodes(DubStatus.Dubbed, dubEpisodes)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,7 +126,6 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override suspend fun loadLinks(
|
override suspend fun loadLinks(
|
||||||
data: String,
|
data: String,
|
||||||
isCasting: Boolean,
|
isCasting: Boolean,
|
||||||
|
@ -172,14 +135,8 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
val servers =
|
val servers =
|
||||||
if (data.contains("-episodenumber:"))// It's a serie:
|
if (data.contains("-episodenumber:"))// It's a serie:
|
||||||
{
|
{
|
||||||
val isvostfr = data.takeLast(8) == "*vostfr*"
|
|
||||||
|
|
||||||
val split =
|
val split =
|
||||||
if (isvostfr) {
|
data.split("-episodenumber:") // the data contains the url and the wanted episode number (a temporary dirty fix that will last forever)
|
||||||
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 url = split[0]
|
||||||
val wantedEpisode =
|
val wantedEpisode =
|
||||||
if (split[1] == "2") { // the episode number 2 has id of ABCDE, don't ask any question
|
if (split[1] == "2") { // the episode number 2 has id of ABCDE, don't ask any question
|
||||||
|
@ -227,11 +184,7 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isvostfr) {
|
serversvf + serversvo
|
||||||
serversvo
|
|
||||||
} else {
|
|
||||||
serversvf
|
|
||||||
}
|
|
||||||
} else { // it's a movie
|
} else { // it's a movie
|
||||||
val movieServers =
|
val movieServers =
|
||||||
app.get(fixUrl(data)).document.select("nav#primary_nav_wrap > ul > li > ul > li > a")
|
app.get(fixUrl(data)).document.select("nav#primary_nav_wrap > ul > li > ul > li > a")
|
||||||
|
@ -264,7 +217,7 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
allowRedirects = false
|
allowRedirects = false
|
||||||
).headers
|
).headers
|
||||||
val urlplayer = it.second
|
val urlplayer = it.second
|
||||||
val playerUrl = when (!urlplayer.isNullOrEmpty()) {
|
var playerUrl = when (!urlplayer.isNullOrEmpty()) {
|
||||||
urlplayer.contains("opsktp.com") -> header.get("location")
|
urlplayer.contains("opsktp.com") -> header.get("location")
|
||||||
.toString() // case where there is redirection to opsktp
|
.toString() // case where there is redirection to opsktp
|
||||||
|
|
||||||
|
@ -284,20 +237,19 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
|
|
||||||
val posterUrl = fixUrl(select("a.short-poster > img").attr("src"))
|
val posterUrl = fixUrl(select("a.short-poster > img").attr("src"))
|
||||||
val qualityExtracted = select("span.film-ripz > a").text()
|
val qualityExtracted = select("span.film-ripz > a").text()
|
||||||
val type = select("span.mli-eps").text().lowercase()
|
val type = select("span.mli-eps").text()
|
||||||
val title = select("div.short-title").text()
|
val title = select("div.short-title").text()
|
||||||
val link = select("a.short-poster").attr("href").replace("wvw.", "") //wvw is an issue
|
val link = select("a.short-poster").attr("href").replace("wvw.", "") //wvw is an issue
|
||||||
val quality = getQualityFromString(
|
var quality = when (!qualityExtracted.isNullOrBlank()) {
|
||||||
when (!qualityExtracted.isNullOrBlank()) {
|
qualityExtracted.contains("HDLight") -> getQualityFromString("HD")
|
||||||
qualityExtracted.contains("HDLight") -> "HD"
|
qualityExtracted.contains("Bdrip") -> getQualityFromString("BlueRay")
|
||||||
qualityExtracted.contains("Bdrip") -> "BlueRay"
|
qualityExtracted.contains("DVD") -> getQualityFromString("DVD")
|
||||||
qualityExtracted.contains("DVD") -> "DVD"
|
qualityExtracted.contains("CAM") -> getQualityFromString("Cam")
|
||||||
qualityExtracted.contains("CAM") -> "Cam"
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!type.contains("eps")) {
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.contains("Eps", false)) {
|
||||||
return MovieSearchResponse(
|
return MovieSearchResponse(
|
||||||
name = title,
|
name = title,
|
||||||
url = link,
|
url = link,
|
||||||
|
@ -311,28 +263,20 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
|
|
||||||
} else // an Serie
|
} else // an Serie
|
||||||
{
|
{
|
||||||
return newAnimeSearchResponse(
|
|
||||||
|
return TvSeriesSearchResponse(
|
||||||
name = title,
|
name = title,
|
||||||
url = link,
|
url = link,
|
||||||
|
apiName = title,
|
||||||
type = TvType.TvSeries,
|
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(
|
override val mainPage = mainPageOf(
|
||||||
Pair("$mainUrl/xfsearch/version-film/page/", "Derniers films"),
|
Pair("$mainUrl/xfsearch/version-film/page/", "Derniers films"),
|
||||||
Pair("$mainUrl/xfsearch/version-serie/page/", "Derniers séries"),
|
Pair("$mainUrl/xfsearch/version-serie/page/", "Derniers séries"),
|
||||||
|
@ -355,6 +299,5 @@ class FrenchStreamProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
return newHomePageResponse(request.name, home)
|
return newHomePageResponse(request.name, home)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,8 @@ import kotlinx.coroutines.runBlocking
|
||||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||||
|
|
||||||
class MacIPTVProvider(override var lang: String) : MainAPI() {
|
class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
private val defaulmac_adresse =
|
private var defaulmac_adresse = "mac=00:1A:79:aa:53:65"
|
||||||
"mac=00:1A:79:aa:53:65"
|
private val defaultmainUrl = "http://ky-iptv.com:25461/portalstb"
|
||||||
private val defaultmainUrl =
|
|
||||||
"http://ky-iptv.com:25461/portalstb"
|
|
||||||
var defaultname = "ky-iptv |${lang.uppercase()}|"
|
var defaultname = "ky-iptv |${lang.uppercase()}|"
|
||||||
var Basename = "Box Iptv"
|
var Basename = "Box Iptv"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
|
@ -23,12 +21,20 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
override val supportedTypes =
|
override val supportedTypes =
|
||||||
setOf(TvType.Live) // live
|
setOf(TvType.Live) // live
|
||||||
|
|
||||||
private var key: String? = ""
|
private var key: String? = "" // key used in the header
|
||||||
|
private val arraymediaPlaylist =
|
||||||
|
ArrayList<Channel>() // store all channels for the search function
|
||||||
|
var allCategory =
|
||||||
|
arrayListOf<String>() // even if we don't display all countries or categories, we need to know those avalaible
|
||||||
|
var isNotInit = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
name = Basename + " |${lang.uppercase()}|"
|
name = Basename + " |${lang.uppercase()}|"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
check if the data are incorrect
|
||||||
|
**/
|
||||||
private fun accountInfoNotGood(url: String, mac: String?): Boolean {
|
private fun accountInfoNotGood(url: String, mac: String?): Boolean {
|
||||||
return url.uppercase().trim() == "NONE" || url.isBlank() || mac?.uppercase()
|
return url.uppercase().trim() == "NONE" || url.isBlank() || mac?.uppercase()
|
||||||
?.trim() == "NONE" || mac.isNullOrBlank()
|
?.trim() == "NONE" || mac.isNullOrBlank()
|
||||||
|
@ -44,18 +50,23 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
mac
|
mac
|
||||||
}
|
}
|
||||||
val url_key =
|
val url_key =
|
||||||
"$mainUrl/portal.php?type=stb&action=handshake&JsHttpRequest=1-xml"
|
"$mainUrl/portal.php?type=stb&action=handshake&token=&JsHttpRequest=1-xml"
|
||||||
val reponseGetkey = app.get(
|
val reponseGetkey = app.get(
|
||||||
url_key, headers = mapOf(
|
url_key, headers = mapOf(
|
||||||
"Cookie" to adresseMac,
|
"Cookie" to adresseMac,
|
||||||
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
||||||
)
|
"X-User-Agent" to "Model: MAG250; Link: WiFi",
|
||||||
|
|
||||||
|
)
|
||||||
)
|
)
|
||||||
val keyJson = reponseGetkey.parsed<Getkey>()
|
key = tryParseJson<Getkey>(
|
||||||
key = keyJson.js?.token
|
Regex("""\{\"js\"(.*[\r\n]*)+\}""").find(reponseGetkey.text)?.groupValues?.get(0)
|
||||||
|
)?.js?.token ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
From user account, get the tags (to select categories and countries), url , mac address ... if there are avalaible
|
||||||
|
**/
|
||||||
private suspend fun getAuthHeader() {
|
private suspend fun getAuthHeader() {
|
||||||
tags = tags ?: "" // tags will allow to select more contains
|
tags = tags ?: "" // tags will allow to select more contains
|
||||||
if (tags?.uppercase()?.trim() == "NONE" || tags?.isBlank() == true) tags = lang
|
if (tags?.uppercase()?.trim() == "NONE" || tags?.isBlank() == true) tags = lang
|
||||||
|
@ -66,22 +77,48 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
mainUrl = defaultmainUrl
|
mainUrl = defaultmainUrl
|
||||||
name = defaultname
|
name = defaultname
|
||||||
getkey(defaulmac_adresse)
|
getkey(defaulmac_adresse)
|
||||||
mutableMapOf(
|
if (key?.isNotBlank() == true) {
|
||||||
"Cookie" to defaulmac_adresse,
|
mutableMapOf(
|
||||||
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
"Cookie" to defaulmac_adresse,
|
||||||
"Authorization" to "Bearer $key",
|
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
||||||
)
|
"Authorization" to "Bearer $key",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
mutableMapOf(
|
||||||
|
"Cookie" to defaulmac_adresse,
|
||||||
|
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
name = (companionName ?: Basename) + " |${lang.uppercase()}|"
|
name = (companionName ?: Basename) + " |${lang.uppercase()}|"
|
||||||
getkey(loginMac.toString())
|
getkey(loginMac.toString())
|
||||||
mutableMapOf(
|
if (key?.isNotBlank() == true) {
|
||||||
"Cookie" to "mac=$loginMac",
|
defaulmac_adresse = "mac=$loginMac"
|
||||||
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
mutableMapOf(
|
||||||
"Authorization" to "Bearer $key",
|
"Cookie" to "mac=$loginMac",
|
||||||
)
|
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
||||||
|
"Authorization" to "Bearer $key",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
defaulmac_adresse = "mac=$loginMac"
|
||||||
|
mutableMapOf(
|
||||||
|
"Cookie" to "mac=$loginMac",
|
||||||
|
"User-Agent" to "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mainUrl = when (true) { // the "c" is not needed and some provider doesn't work with it
|
||||||
|
mainUrl.endsWith("/c/") -> mainUrl.dropLast(3)
|
||||||
|
mainUrl.endsWith("/c") -> mainUrl.dropLast(2)
|
||||||
|
mainUrl.endsWith("/") -> mainUrl.dropLast(1)
|
||||||
|
else -> mainUrl
|
||||||
|
}
|
||||||
|
app.get(
|
||||||
|
"$mainUrl/portal.php?type=stb&action=get_modules",
|
||||||
|
headers = headerMac
|
||||||
|
) // some providers need this request to work
|
||||||
isNotInit = false
|
isNotInit = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,24 +141,24 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
this.sortedBy {
|
this.sortedBy {
|
||||||
val name = cleanTitle(it.title).replace(rgxcodeCountry, "").trim()
|
val name = cleanTitle(it.title).replace(findKeyWord(lang), "").trim()
|
||||||
-FuzzySearch.ratio(name.lowercase(), query.lowercase())
|
-FuzzySearch.ratio(name.lowercase(), query.lowercase())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val resultsSearchNbr = 50 // show only the 50 results
|
|
||||||
override suspend fun search(query: String): List<SearchResponse> {
|
override suspend fun search(query: String): List<SearchResponse> {
|
||||||
return arraymediaPlaylist.sortByname(query).take(resultsSearchNbr).map { media ->
|
return arraymediaPlaylist.sortByname(query).take(50)
|
||||||
LiveSearchResponse(
|
.map { media -> // display only the 50 results
|
||||||
media.title,
|
LiveSearchResponse(
|
||||||
media.toJson(),
|
media.title,
|
||||||
name,
|
media.toJson(),
|
||||||
TvType.Live,
|
name,
|
||||||
media.url_image,
|
TvType.Live,
|
||||||
)
|
media.url_image,
|
||||||
}
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Root_epg(
|
data class Root_epg(
|
||||||
|
@ -154,25 +191,41 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
|
|
||||||
|
|
||||||
override suspend fun load(url: String): LoadResponse {
|
override suspend fun load(url: String): LoadResponse {
|
||||||
if (url.contains("I_Need_Help")) {
|
when {
|
||||||
return LiveStreamLoadResponse(
|
url.contains("I_Need_Help") -> { // go to see all the avalaible tags
|
||||||
name = "GO TO CREATE YOUR \uD83C\uDDF9\u200B\u200B\u200B\u200B\u200B\uD83C\uDDE6\u200B\u200B\u200B\u200B\u200B\uD83C\uDDEC\u200B\u200B\u200B\u200B\u200B ACCOUNT => italia|sport|crime|uk ",
|
return LiveStreamLoadResponse(
|
||||||
url = url,
|
name = "GO TO CREATE YOUR \uD83C\uDDF9\u200B\u200B\u200B\u200B\u200B\uD83C\uDDE6\u200B\u200B\u200B\u200B\u200B\uD83C\uDDEC\u200B\u200B\u200B\u200B\u200B ACCOUNT eg. italia|sport|crime|uk ",
|
||||||
apiName = this.name,
|
url = url,
|
||||||
dataUrl = url,
|
apiName = this.name,
|
||||||
posterUrl = "https://www.toutestpossible.be/wp-content/uploads/2017/05/comment-faire-des-choix-eclaires-en-10-etapes-01-300x167.jpg",
|
dataUrl = url,
|
||||||
plot = "ALL TAGS \uD83D\uDD0E ${allCategory.sortedBy { it }}",
|
posterUrl = "https://www.toutestpossible.be/wp-content/uploads/2017/05/comment-faire-des-choix-eclaires-en-10-etapes-01-300x167.jpg",
|
||||||
comingSoon = true
|
plot = "ALL TAGS \uD83D\uDD0E ${allCategory.sortedBy { it }}",
|
||||||
)
|
comingSoon = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
url.contains("There_is_an_error") -> { // case where the provider don't work
|
||||||
|
return LiveStreamLoadResponse(
|
||||||
|
name = "\uD83C\uDDF5\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF7\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF4\u200B\u200B\u200B\u200B\u200B\uD83C\uDDE7\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF1\u200B\u200B\u200B\u200B\u200B\uD83C\uDDEA\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF2\u200B\u200B\u200B\u200B\u200B",
|
||||||
|
url = url,
|
||||||
|
apiName = this.name,
|
||||||
|
dataUrl = url,
|
||||||
|
posterUrl = "https://www.toutestpossible.be/wp-content/uploads/2017/05/comment-faire-des-choix-eclaires-en-10-etapes-01-300x167.jpg",
|
||||||
|
plot = "There is a issue with this account. Please check your credentials or try another account",
|
||||||
|
comingSoon = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> ""
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val media = parseJson<Channel>(url.replace(mainUrl, ""))
|
val media = parseJson<Channel>(url.replace(mainUrl, ""))
|
||||||
val epg_url =
|
val epg_url =
|
||||||
"$mainUrl/portal.php?type=itv&action=get_short_epg&ch_id=${media.ch_id}&size=10&JsHttpRequest=1-xml" // plot
|
"$mainUrl/portal.php?type=itv&action=get_short_epg&ch_id=${media.ch_id}&size=10&JsHttpRequest=1-xml" // the plot when it's avalaible
|
||||||
val response = app.get(epg_url, headers = headerMac)
|
val response = app.get(epg_url, headers = headerMac)
|
||||||
val description = getEpg(response.text)
|
val description = getEpg(response.text)
|
||||||
val link = media.url
|
val link = media.url
|
||||||
val title = media.title
|
val title = media.title
|
||||||
val a = cleanTitle(title).replace(rgxcodeCountry, "").trim()
|
val a = cleanTitle(title).replace(findKeyWord(lang), "").trim()
|
||||||
val posterUrl = media.url_image.toString()
|
val posterUrl = media.url_image.toString()
|
||||||
var b_new: String
|
var b_new: String
|
||||||
|
|
||||||
|
@ -184,7 +237,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
posterUrl = posterUrl,
|
posterUrl = posterUrl,
|
||||||
plot = description,
|
plot = description,
|
||||||
recommendations = arraymediaPlaylist.mapNotNull { channel ->
|
recommendations = arraymediaPlaylist.mapNotNull { channel ->
|
||||||
val b = cleanTitle(channel.title).replace(rgxcodeCountry, "").trim()
|
val b = cleanTitle(channel.title).replace(findKeyWord(lang), "").trim()
|
||||||
b_new = b.take(6)
|
b_new = b.take(6)
|
||||||
if (channel.id != media.id && a.take(6)
|
if (channel.id != media.id && a.take(6)
|
||||||
.contains(b_new) && media.tv_genre_id == channel.tv_genre_id
|
.contains(b_new) && media.tv_genre_id == channel.tv_genre_id
|
||||||
|
@ -218,7 +271,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
)
|
)
|
||||||
LiveSearchResponse(
|
LiveSearchResponse(
|
||||||
name = cleanTitleButKeepNumber(channelname).replace(
|
name = cleanTitleButKeepNumber(channelname).replace(
|
||||||
rgxcodeCountry,
|
findKeyWord(lang),
|
||||||
""
|
""
|
||||||
).trim(),
|
).trim(),
|
||||||
url = streamurl,
|
url = streamurl,
|
||||||
|
@ -235,8 +288,6 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get the channel id */
|
|
||||||
val regexCode_ch = Regex("""\/(\d*)\?""")
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use new token.
|
* Use new token.
|
||||||
|
@ -249,7 +300,8 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
if (request.url.toString().contains("token")
|
if (request.url.toString().contains("token")
|
||||||
|
|
||||||
) {
|
) {
|
||||||
val chID = regexCode_ch.find(request.url.toString())!!.groupValues[1] + "_"
|
val chID =
|
||||||
|
Regex("""\/(\d*)\?""").find(request.url.toString())!!.groupValues[1] + "_"
|
||||||
val TokenLink =
|
val TokenLink =
|
||||||
"$mainUrl/portal.php?type=itv&action=create_link&cmd=ffmpeg%20http://localhost/ch/$chID&series=&forced_storage=0&disable_ad=0&download=0&force_ch_link_check=0&JsHttpRequest=1-xml"
|
"$mainUrl/portal.php?type=itv&action=create_link&cmd=ffmpeg%20http://localhost/ch/$chID&series=&forced_storage=0&disable_ad=0&download=0&force_ch_link_check=0&JsHttpRequest=1-xml"
|
||||||
|
|
||||||
|
@ -287,9 +339,8 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** récupere les liens .mp4 ou m3u8 directement à partir du paramètre data généré avec la fonction load()**/
|
|
||||||
override suspend fun loadLinks(
|
override suspend fun loadLinks(
|
||||||
data: String, // fournit par load()
|
data: String,
|
||||||
isCasting: Boolean,
|
isCasting: Boolean,
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit,
|
callback: (ExtractorLink) -> Unit,
|
||||||
|
@ -342,9 +393,6 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val arraymediaPlaylist = ArrayList<Channel>()
|
|
||||||
|
|
||||||
|
|
||||||
data class Cmds(
|
data class Cmds(
|
||||||
@JsonProperty("ch_id") var chId: String? = null,
|
@JsonProperty("ch_id") var chId: String? = null,
|
||||||
)
|
)
|
||||||
|
@ -394,29 +442,42 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
@JsonProperty("js") var js: Js? = Js()
|
@JsonProperty("js") var js: Js? = Js()
|
||||||
)
|
)
|
||||||
|
|
||||||
private var codeCountry = lang
|
|
||||||
var allCategory = mutableListOf<String>()
|
|
||||||
val rgxcodeCountry = findKeyWord(codeCountry)
|
|
||||||
var isNotInit = true
|
|
||||||
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
|
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
|
||||||
if (isNotInit || arraymediaPlaylist.isEmpty()) {
|
if (isNotInit || arraymediaPlaylist.isEmpty()) {
|
||||||
if (isNotInit) getAuthHeader()
|
if (isNotInit) getAuthHeader()
|
||||||
|
val rgxFindJson =
|
||||||
|
Regex("""\{\"js\"(.*[\r\n]*)+\}""") // select only the json part, some account give a bad json response
|
||||||
var responseAllchannels: NiceResponse? = null
|
var responseAllchannels: NiceResponse? = null
|
||||||
listOf(
|
listOf(
|
||||||
"$mainUrl/portal.php?type=account_info&action=get_main_info&JsHttpRequest=1-xml",
|
"$mainUrl/portal.php?type=account_info&action=get_main_info&JsHttpRequest=1-xml&$defaulmac_adresse", // GET EXPIRATION
|
||||||
"$mainUrl/portal.php?type=itv&action=get_genres&JsHttpRequest=1-xml",
|
"$mainUrl/portal.php?type=itv&action=get_genres", // GET ALL GENRES (Countries or categories)
|
||||||
"$mainUrl/portal.php?type=itv&action=get_all_channels&JsHttpRequest=1-xml",
|
"$mainUrl/portal.php?type=itv&action=get_all_channels", // GET ALL LIVE CAHNNELS
|
||||||
).apmap { url ->
|
).apmap { url ->
|
||||||
when {
|
when {
|
||||||
|
|
||||||
url.contains("action=get_main_info") -> {
|
url.contains("action=get_main_info") -> {
|
||||||
expiration = app.get(url, headers = headerMac)
|
val textJson = app.get(
|
||||||
.parsed<GetExpiration>().js?.phone.toString() // GET EXPIRATION
|
url,
|
||||||
|
headers = headerMac
|
||||||
|
).text
|
||||||
|
expiration = tryParseJson<GetExpiration>(
|
||||||
|
rgxFindJson.find(
|
||||||
|
textJson
|
||||||
|
)?.groupValues?.get(0)
|
||||||
|
)?.js?.phone.toString()
|
||||||
}
|
}
|
||||||
url.contains("action=get_genre") -> {
|
url.contains("action=get_genre") -> {
|
||||||
responseGetGenretoJSON = app.get(url, headers = headerMac)
|
responseGetGenretoJSON =
|
||||||
.parsed<JsonGetGenre>().js // GET ALL GENRES
|
tryParseJson<JsonGetGenre>(
|
||||||
|
rgxFindJson.find(
|
||||||
|
app.get(
|
||||||
|
url,
|
||||||
|
headers = headerMac
|
||||||
|
).text
|
||||||
|
)?.groupValues?.get(0)
|
||||||
|
)?.js
|
||||||
|
?: arrayListOf(Js_category("0", ".*"))
|
||||||
}
|
}
|
||||||
url.contains("action=get_all_channels") -> {
|
url.contains("action=get_all_channels") -> {
|
||||||
responseAllchannels = app.get(url, headers = headerMac)
|
responseAllchannels = app.get(url, headers = headerMac)
|
||||||
|
@ -426,12 +487,38 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val allDataJson =
|
||||||
|
tryParseJson<Root>(
|
||||||
|
rgxFindJson.find(responseAllchannels?.text.toString())?.groupValues?.get(
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)?.js?.data?.sortByTitleNumber() //use of tryPaseJson to be able to select the json part because sometime the json response is not good
|
||||||
|
if (!allDataJson.isNullOrEmpty()) {
|
||||||
|
return HomePageResponse(
|
||||||
|
HomeResponse(
|
||||||
|
allDataJson,
|
||||||
|
).getHomePageListsInit(this), false
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return HomePageResponse(
|
||||||
|
listOf(
|
||||||
|
HomePageList(
|
||||||
|
"\uD83C\uDDF5\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF7\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF4\u200B\u200B\u200B\u200B\u200B\uD83C\uDDE7\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF1\u200B\u200B\u200B\u200B\u200B\uD83C\uDDEA\u200B\u200B\u200B\u200B\u200B\uD83C\uDDF2\u200B\u200B\u200B\u200B\u200B",
|
||||||
|
listOf(
|
||||||
|
LiveSearchResponse(
|
||||||
|
"Contact the provider",
|
||||||
|
"${mainUrl}There_is_an_error", // trick to load the help page
|
||||||
|
name,
|
||||||
|
TvType.Live,
|
||||||
|
"https://bodhisattva4you.files.wordpress.com/2014/11/esprit-probleme-00.jpg",
|
||||||
|
)
|
||||||
|
),
|
||||||
|
isHorizontalImages = true
|
||||||
|
)
|
||||||
|
), false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return HomePageResponse(
|
|
||||||
HomeResponse(
|
|
||||||
responseAllchannels!!.parsed<Root>().js!!.data.sortByTitleNumber(),// GET ALL CHANNELS and Sort byTitle
|
|
||||||
).getHomePageListsInit(this), false
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
return HomePageResponse(
|
return HomePageResponse(
|
||||||
HomeResponse().getHomePageListsFromArrayChannel(this), false
|
HomeResponse().getHomePageListsFromArrayChannel(this), false
|
||||||
|
@ -464,7 +551,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
|
|
||||||
|
|
||||||
fun getHomePageListsInit(provider: MacIPTVProvider): List<HomePageList> {
|
fun getHomePageListsInit(provider: MacIPTVProvider): List<HomePageList> {
|
||||||
val rgxcodeCountry = provider.rgxcodeCountry
|
val rgxcodeCountry = findKeyWord(provider.lang)
|
||||||
var firstCat = true
|
var firstCat = true
|
||||||
provider.allCategory.clear()
|
provider.allCategory.clear()
|
||||||
|
|
||||||
|
@ -482,7 +569,8 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val arraychannel = mutableListOf<Channel>()
|
val arraychannel =
|
||||||
|
mutableListOf<Channel>() // toMutable because HomePageList need to remove element from the list
|
||||||
if (channels.isNotEmpty() && idGenre.contains("""\d""".toRegex()) && (categoryTitle.uppercase()
|
if (channels.isNotEmpty() && idGenre.contains("""\d""".toRegex()) && (categoryTitle.uppercase()
|
||||||
.contains(rgxcodeCountry) ||
|
.contains(rgxcodeCountry) ||
|
||||||
categoryTitle.isContainsTargetCountry(provider)
|
categoryTitle.isContainsTargetCountry(provider)
|
||||||
|
@ -490,7 +578,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
.contains(findKeyWord(tags.toString()))
|
.contains(findKeyWord(tags.toString()))
|
||||||
) {
|
) {
|
||||||
val itr = channels.iterator()
|
val itr = channels.iterator()
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) { // Remove elements from a list while iterating
|
||||||
val data = itr.next()
|
val data = itr.next()
|
||||||
val genre = data.tvGenreId
|
val genre = data.tvGenreId
|
||||||
if (genre != null) {
|
if (genre != null) {
|
||||||
|
@ -548,9 +636,10 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHomePageListsFromArrayChannel(provider: MacIPTVProvider): List<HomePageList> {
|
fun getHomePageListsFromArrayChannel(provider: MacIPTVProvider): List<HomePageList> {
|
||||||
val rgxcodeCountry = provider.rgxcodeCountry
|
val rgxcodeCountry = findKeyWord(provider.lang)
|
||||||
var firstCat = true
|
var firstCat = true
|
||||||
val arrayChannel = provider.arraymediaPlaylist.toMutableList()
|
val arrayChannel =
|
||||||
|
provider.arraymediaPlaylist.toMutableList() // toMutable because HomePageList need to remove element from the list
|
||||||
return getHelpHomePage(provider) + responseGetGenretoJSON.mapNotNull { js ->
|
return getHelpHomePage(provider) + responseGetGenretoJSON.mapNotNull { js ->
|
||||||
val idGenre = js.id.toString()
|
val idGenre = js.id.toString()
|
||||||
val categoryTitle = js.title.toString()
|
val categoryTitle = js.title.toString()
|
||||||
|
@ -583,23 +672,24 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Since I don't select all the content because it is too big, I want to at least display the countries and categories available.
|
||||||
|
* So the user will know what is available and can select his own country or categories via the account creation tag */
|
||||||
fun getHelpHomePage(provider: MacIPTVProvider): List<HomePageList> {
|
fun getHelpHomePage(provider: MacIPTVProvider): List<HomePageList> {
|
||||||
val arraychannel = mutableListOf<Channel>()
|
|
||||||
val helpCat =
|
val helpCat =
|
||||||
"\uD83C\uDDF9\u200B\u200B\u200B\u200B\u200B\uD83C\uDDE6\u200B\u200B\u200B\u200B\u200B\uD83C\uDDEC\u200B\u200B\u200B\u200B\u200B Account"
|
"\uD83C\uDDF9\u200B\u200B\u200B\u200B\u200B\uD83C\uDDE6\u200B\u200B\u200B\u200B\u200B\uD83C\uDDEC\u200B\u200B\u200B\u200B\u200B Account"
|
||||||
arraychannel.add(
|
|
||||||
Channel(
|
return arrayListOf(
|
||||||
"\uD83D\uDD0E TAG",
|
arrayListOf(
|
||||||
"${provider.mainUrl}I_Need_Help",
|
Channel(
|
||||||
"https://userguiding.com/wp-content/uploads/2021/06/best-help-center-software.jpg",
|
"\uD83D\uDD0E TAG",
|
||||||
"",
|
"${provider.mainUrl}I_Need_Help", // trick to load the help page
|
||||||
"000976000",
|
"https://userguiding.com/wp-content/uploads/2021/06/best-help-center-software.jpg",
|
||||||
"0097600",
|
"",
|
||||||
""
|
"000976000",
|
||||||
)
|
"0097600",
|
||||||
)
|
""
|
||||||
return mutableListOf(
|
)
|
||||||
arraychannel.toHomePageList(
|
).toHomePageList(
|
||||||
helpCat,
|
helpCat,
|
||||||
provider,
|
provider,
|
||||||
"0097600"
|
"0097600"
|
||||||
|
@ -619,8 +709,8 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
var responseGetGenretoJSON = ArrayList<Js_category>() // all genres from the provider
|
var responseGetGenretoJSON = ArrayList<Js_category>() // all genres from the provider
|
||||||
fun findKeyWord(str: String): Regex {
|
fun findKeyWord(str: String): Regex {
|
||||||
val upperSTR = str.uppercase()
|
val upperSTR = str.uppercase()
|
||||||
val sequence = when (true) {
|
val sequence = when (upperSTR) {
|
||||||
upperSTR == "EN" -> {
|
"EN" -> {
|
||||||
"US|UK"
|
"US|UK"
|
||||||
}
|
}
|
||||||
else -> upperSTR
|
else -> upperSTR
|
||||||
|
@ -662,16 +752,16 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableList<Channel>.toSearchResponseHomePage(
|
fun MutableList<Channel>.toSearchResponseHomePage( // require mutableList to be able to remove elements from the list while iterating
|
||||||
provider: MacIPTVProvider, GenreId: String
|
provider: MacIPTVProvider, GenreId: String
|
||||||
): List<SearchResponse> {
|
): List<SearchResponse> {
|
||||||
val groupChannel = ArrayList<String>()
|
val groupChannel = ArrayList<String>()
|
||||||
var b_new: String
|
var b_new: String
|
||||||
var newgroupChannel: Boolean
|
var newgroupChannel: Boolean
|
||||||
val rgxcodeCountry = provider.rgxcodeCountry
|
val rgxcodeCountry = findKeyWord(provider.lang)
|
||||||
val home = ArrayList<SearchResponse>()
|
val home = ArrayList<SearchResponse>()
|
||||||
val itr = this.iterator()
|
val itr = this.iterator()
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) { //permit to remove elements from the list while iterating
|
||||||
val media = itr.next()
|
val media = itr.next()
|
||||||
val b = cleanTitle(media.title).replace(rgxcodeCountry, "").trim()
|
val b = cleanTitle(media.title).replace(rgxcodeCountry, "").trim()
|
||||||
b_new = b.take(6)
|
b_new = b.take(6)
|
||||||
|
@ -685,7 +775,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
|
||||||
if (newgroupChannel && media.tv_genre_id == GenreId) {
|
if (newgroupChannel && media.tv_genre_id == GenreId) {
|
||||||
groupChannel.add(b_new)
|
groupChannel.add(b_new)
|
||||||
val groupName = cleanTitle(media.title).replace(rgxcodeCountry, "").trim()
|
val groupName = cleanTitle(media.title).replace(rgxcodeCountry, "").trim()
|
||||||
itr.remove()
|
itr.remove() //remove elements
|
||||||
home.add(
|
home.add(
|
||||||
LiveSearchResponse(
|
LiveSearchResponse(
|
||||||
groupName,
|
groupName,
|
||||||
|
|
|
@ -30,7 +30,7 @@ class MacIptvAPI(index: Int) : InAppAuthAPIManager(index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun login(data: InAppAuthAPI.LoginData): Boolean {
|
override suspend fun login(data: InAppAuthAPI.LoginData): Boolean {
|
||||||
if (data.server.isNullOrBlank() || !data.password?.contains("""(([0-9A-Za-z]{2}[:-]){5}[0-9A-Za-z]{2})""".toRegex())!!) return false // we require a server
|
if (data.server.isNullOrBlank() || !data.password?.contains("""(([0-9A-Za-z]{2}[:-]){5}[0-9A-Za-z]{2})""".toRegex())!!) return false // we require a server and a mac address
|
||||||
switchToNewAccount()
|
switchToNewAccount()
|
||||||
setKey(accountId, IPTVBOX_USER_KEY, data)
|
setKey(accountId, IPTVBOX_USER_KEY, data)
|
||||||
registerAccount()
|
registerAccount()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue