Changes requested and clean up done

This commit is contained in:
Eddy 2022-11-08 00:03:02 +01:00
parent 48aa60a2fb
commit 50b934a0cf
2 changed files with 188 additions and 281 deletions

View file

@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import okhttp3.Interceptor import okhttp3.Interceptor
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.nicehttp.NiceResponse import com.lagradost.nicehttp.NiceResponse
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -15,18 +17,16 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
private val defaultmainUrl = private val defaultmainUrl =
"http://ky-iptv.com:25461/portalstb" "http://ky-iptv.com:25461/portalstb"
var defaultname = "ky-iptv |${lang.uppercase()}|" var defaultname = "ky-iptv |${lang.uppercase()}|"
override var name = "Box Iptv" var Basename = "Box Iptv"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val supportedTypes = override val supportedTypes =
setOf(TvType.Live) // live setOf(TvType.Live) // live
private var firstInitDone = false
private var key: String? = "" private var key: String? = ""
init {
private fun detectNewAccount(): Boolean { name = Basename + " |${lang.uppercase()}|"
return oldAthMac != loginMac || oldAthUrl != overrideUrl
} }
private fun accountInfoNotGood(url: String, mac: String?): Boolean { private fun accountInfoNotGood(url: String, mac: String?): Boolean {
@ -34,6 +34,9 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
?.trim() == "NONE" || mac.isNullOrBlank() ?.trim() == "NONE" || mac.isNullOrBlank()
} }
/**
Sometimes providers ask a key (token) in the headers
**/
private suspend fun getkey(mac: String) { private suspend fun getkey(mac: String) {
val adresseMac = if (!mac.contains("mac=")) { val adresseMac = if (!mac.contains("mac=")) {
"mac=$mac" "mac=$mac"
@ -53,26 +56,16 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
} }
init {
name = (companionName ?: name) + " |${lang.uppercase()}|"
}
private suspend fun getAuthHeader() { private suspend fun getAuthHeader() {
tags = tags ?: "" 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
tags = tags?.uppercase() tags = tags?.uppercase()
oldAthMac = loginMac
oldAthUrl = overrideUrl
mainUrl = overrideUrl.toString() mainUrl = overrideUrl.toString()
headerMac = when (true) { headerMac = when {
accountInfoNotGood(mainUrl, loginMac) -> { accountInfoNotGood(mainUrl, loginMac) -> { // do this if mainUrl or mac adresse is blank
mainUrl = defaultmainUrl mainUrl = defaultmainUrl
name = defaultname name = defaultname
if (!firstInitDone) { getkey(defaulmac_adresse)
getkey(defaulmac_adresse)
firstInitDone = true
}
mutableMapOf( mutableMapOf(
"Cookie" to defaulmac_adresse, "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", "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",
@ -80,12 +73,8 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
) )
} }
else -> { else -> {
name = (companionName ?: name) + " |${lang.uppercase()}|" name = (companionName ?: Basename) + " |${lang.uppercase()}|"
if (!firstInitDone) { getkey(loginMac.toString())
getkey(loginMac.toString())
firstInitDone = true
}
mutableMapOf( mutableMapOf(
"Cookie" to "mac=$loginMac", "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", "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",
@ -93,7 +82,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
) )
} }
} }
isNotInit = false
} }
@ -105,11 +94,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
var id: String?, var id: String?,
var tv_genre_id: String?, var tv_genre_id: String?,
var ch_id: String?, var ch_id: String?,
) { )
fun toStringCode(): String {
return "${this.title}*${this.url}*${this.url_image}*${this.lang}*${this.id}*${this.tv_genre_id}*${this.ch_id}"
}
}
private fun List<Channel>.sortByname(query: String?): List<Channel> { private fun List<Channel>.sortByname(query: String?): List<Channel> {
@ -126,27 +111,17 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
} }
/** private val resultsSearchNbr = 50 // show only the 50 results
Cherche le site pour un titre spécifique
La recherche retourne une SearchResponse, qui peut être des classes suivants: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse
Chaque classes nécessite des données différentes, mais a en commun le nom, le poster et l'url
**/
private val resultsSearchNbr = 50
override suspend fun search(query: String): List<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
val searchResutls = ArrayList<SearchResponse>() return arraymediaPlaylist.sortByname(query).take(resultsSearchNbr).map { media ->
arraymediaPlaylist.sortByname(query).take(resultsSearchNbr).forEach { media -> LiveSearchResponse(
searchResutls.add( media.title,
LiveSearchResponse( media.toJson(),
media.title, name,
media.toStringCode(), TvType.Live,
name, media.url_image,
TvType.Live,
media.url_image,
)
) )
} }
return searchResutls
} }
data class Root_epg( data class Root_epg(
@ -160,7 +135,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
@JsonProperty("t_time_to") var tTimeTo: String? = null, @JsonProperty("t_time_to") var tTimeTo: String? = null,
) )
private fun getEpg(response: String): String { private fun getEpg(response: String): String { // get the EPG to have get the schedual
val reponseJSON_0 = tryParseJson<Root_epg>(response) val reponseJSON_0 = tryParseJson<Root_epg>(response)
var description = "" var description = ""
reponseJSON_0?.js?.forEach { epg_i -> reponseJSON_0?.js?.forEach { epg_i ->
@ -177,16 +152,9 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
return description return description
} }
fun String.getDataChannelFromString(): Channel {
val res = this.split("*")
return Channel(res[0], res[1], res[2], res[3], res[4], res[5], res[6])
}
override suspend fun load(url: String): LoadResponse { override suspend fun load(url: String): LoadResponse {
val allresultshome: MutableList<SearchResponse> = mutableListOf() val media = parseJson<Channel>(url.replace(mainUrl, ""))
val media = url.replace(mainUrl, "").getDataChannelFromString()
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" // plot
val response = app.get(epg_url, headers = headerMac) val response = app.get(epg_url, headers = headerMac)
@ -196,41 +164,47 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
val a = cleanTitle(title).replace(rgxcodeCountry, "").trim() val a = cleanTitle(title).replace(rgxcodeCountry, "").trim()
val posterUrl = media.url_image.toString() val posterUrl = media.url_image.toString()
var b_new: String var b_new: String
arraymediaPlaylist.forEach { channel ->
val b = cleanTitle(channel.title).replace(rgxcodeCountry, "").trim()
b_new = b.take(6)
if (channel.id != media.id && a.take(6)
.contains(b_new) && media.tv_genre_id == channel.tv_genre_id
) {
val streamurl = channel.toStringCode() return LiveStreamLoadResponse(
val channelname = channel.title name = title,
val posterurl = channel.url_image.toString() url = link,
val uppername = channelname.uppercase() apiName = this.name,
val quality = getQualityFromString( dataUrl = link,
when (!channelname.isNullOrBlank()) { posterUrl = posterUrl,
uppername.contains(findKeyWord("UHD")) -> { plot = description,
"UHD" recommendations = arraymediaPlaylist.mapNotNull { channel ->
} val b = cleanTitle(channel.title).replace(rgxcodeCountry, "").trim()
uppername.contains(findKeyWord("HD")) -> { b_new = b.take(6)
"HD" if (channel.id != media.id && a.take(6)
} .contains(b_new) && media.tv_genre_id == channel.tv_genre_id
uppername.contains(findKeyWord("SD")) -> { ) {
"SD" val streamurl = channel.toJson()
} val channelname = channel.title
uppername.contains(findKeyWord("FHD")) -> { val posterurl = channel.url_image.toString()
"HD" val uppername = channelname.uppercase()
} val quality = getQualityFromString(
uppername.contains(findKeyWord("4K")) -> { when (!channelname.isBlank()) {
"FourK" uppername.contains(findKeyWord("UHD")) -> {
} "UHD"
}
uppername.contains(findKeyWord("HD")) -> {
"HD"
}
uppername.contains(findKeyWord("SD")) -> {
"SD"
}
uppername.contains(findKeyWord("FHD")) -> {
"HD"
}
uppername.contains(findKeyWord("4K")) -> {
"FourK"
}
else -> { else -> {
null null
}
} }
} )
)
allresultshome.add(
LiveSearchResponse( LiveSearchResponse(
name = cleanTitleButKeepNumber(channelname).replace( name = cleanTitleButKeepNumber(channelname).replace(
rgxcodeCountry, rgxcodeCountry,
@ -242,37 +216,12 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
posterUrl = posterurl, posterUrl = posterurl,
quality = quality, quality = quality,
) )
) } else {
null
}
} }
)
}
if (allresultshome.size >= 1) {
val recommendation = allresultshome
return LiveStreamLoadResponse(
name = title,
url = link,
apiName = this.name,
dataUrl = link,
posterUrl = posterUrl,
plot = description,
recommendations = recommendation
)
} else {
return LiveStreamLoadResponse(
name = title,
url = link,
apiName = this.name,
dataUrl = link,
posterUrl = posterUrl,
plot = description,
)
}
} }
/** get the channel id */ /** get the channel id */
@ -350,18 +299,21 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
) )
var lien = link val lien = when {
if (link.contains("extension")) { link.contains("extension") -> {
val headerlocation = app.get( val headerlocation = app.get(
link, link,
allowRedirects = false allowRedirects = false
).headers ).headers
val redirectlink = headerlocation.get("location") val redirectlink = headerlocation.get("location")
.toString() .toString()
if (redirectlink != "null") {
if (redirectlink != "null") { redirectlink
lien = redirectlink } else {
link
}
} }
else -> link
} }
val isM3u8 = false val isM3u8 = false
callback.invoke( callback.invoke(
@ -375,7 +327,6 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
headers = head headers = head
) )
) )
return true return true
} }
@ -435,26 +386,26 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
private var codeCountry = lang private var codeCountry = lang
val rgxcodeCountry = findKeyWord(codeCountry) 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 (!firstInitDone || arraymediaPlaylist.isEmpty() || detectNewAccount()) { if (isNotInit || arraymediaPlaylist.isEmpty()) {
if (detectNewAccount()) firstInitDone = false if (isNotInit) getAuthHeader()
getAuthHeader()
var reponseGetInfo: NiceResponse? = null
var responseGetgenre: NiceResponse? = null
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",
"$mainUrl/portal.php?type=itv&action=get_genres&JsHttpRequest=1-xml", "$mainUrl/portal.php?type=itv&action=get_genres&JsHttpRequest=1-xml",
"$mainUrl/portal.php?type=itv&action=get_all_channels&JsHttpRequest=1-xml", "$mainUrl/portal.php?type=itv&action=get_all_channels&JsHttpRequest=1-xml",
).apmap { url -> ).apmap { url ->
when (true) { when {
url.contains("action=get_main_info") -> { url.contains("action=get_main_info") -> {
reponseGetInfo = app.get(url, headers = headerMac) expiration = app.get(url, headers = headerMac)
.parsed<GetExpiration>().js?.phone.toString() // GET EXPIRATION
} }
url.contains("action=get_genre") -> { url.contains("action=get_genre") -> {
responseGetgenre = app.get(url, headers = headerMac) responseGetGenretoJSON = app.get(url, headers = headerMac)
.parsed<JsonGetGenre>().js // GET ALL GENRES
} }
url.contains("action=get_all_channels") -> { url.contains("action=get_all_channels") -> {
responseAllchannels = app.get(url, headers = headerMac) responseAllchannels = app.get(url, headers = headerMac)
@ -465,18 +416,9 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
} }
} }
///////////// GET EXPIRATION
val infoExpirationJson = reponseGetInfo!!.parsed<GetExpiration>()
expiration = infoExpirationJson.js?.phone.toString()
////////////////////////// GET ALL GENRES
responseGetGenretoJSON = responseGetgenre!!.parsed<JsonGetGenre>().js
////////////////////////// GET ALL CHANNELS
val responseAllchannelstoJSON = responseAllchannels!!.parsed<Root>() //parsedSafe
val AllchannelstoJSON = responseAllchannelstoJSON.js!!.data.sortByTitleNumber()
return HomePageResponse( return HomePageResponse(
HomeResponse( HomeResponse(
AllchannelstoJSON, responseAllchannels!!.parsed<Root>().js!!.data.sortByTitleNumber(),// GET ALL CHANNELS and Sort byTitle
).getHomePageListsInit(this), false ).getHomePageListsInit(this), false
) )
} else { } else {
@ -497,154 +439,122 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
private data class HomeResponse( private data class HomeResponse(
val channels: ArrayList<Data> = ArrayList(), val channels: MutableList<Data> = ArrayList(),
) { ) {
fun String.isContainsTargetCountry(provider: MacIPTVProvider): Boolean { fun String.isContainsTargetCountry(provider: MacIPTVProvider): Boolean {
val getLang = provider.lang.uppercase() val getLang = provider.lang.uppercase()
var resp = false val langs = hashMapOf(
when (true) { "FR" to arrayListOf("FRENCH", "FRANCE"),
getLang == "FR" -> { "EN" to arrayListOf("ENGLISH", "USA"),
arrayListOf("FRENCH", "FRANCE").forEach { "AR" to arrayListOf("ARABIC", "ARAB", "ARABIA")
if (this.uppercase().contains(findKeyWord(it))) { )
resp = true return langs[getLang]?.any { this.uppercase().contains(findKeyWord(it)) } ?: false
}
}
}
getLang == "EN" -> {
arrayListOf("ENGLISH", "USA").forEach {
if (this.uppercase().contains(findKeyWord(it))) {
resp = true
}
}
}
getLang == "AR" -> {
arrayListOf("ARABIC", "ARAB", "ARABIA").forEach {
if (this.uppercase().contains(findKeyWord(it))) {
resp = true
}
}
}
else -> resp = false
}
return resp
} }
fun getHomePageListsInit(provider: MacIPTVProvider): List<HomePageList> { fun getHomePageListsInit(provider: MacIPTVProvider): List<HomePageList> {
val arrayHomepage = mutableListOf<HomePageList>()
val rgxcodeCountry = provider.rgxcodeCountry val rgxcodeCountry = provider.rgxcodeCountry
var firstCat = true var firstCat = true
if (responseGetGenretoJSON.isNotEmpty() && channels.isNotEmpty()) { return responseGetGenretoJSON.mapNotNull { js ->
responseGetGenretoJSON.forEach { js -> val idGenre = js.id.toString()
val idGenre = js.id val categoryTitle = js.title.toString()
val categoryTitle = js.title.toString() val arraychannel = mutableListOf<Channel>()
val arraychannel = ArrayList<Channel>() if (channels.isNotEmpty() && idGenre.contains("""\d""".toRegex()) && (categoryTitle.uppercase()
if (idGenre!!.contains("""\d""".toRegex()) && (categoryTitle.uppercase() .contains(rgxcodeCountry) ||
.contains(rgxcodeCountry) || categoryTitle.isContainsTargetCountry(provider)
categoryTitle.isContainsTargetCountry(provider) ) || categoryTitle.uppercase()
) || categoryTitle.uppercase() .contains(findKeyWord(tags.toString()))
.contains(findKeyWord(tags.toString())) ) {
) { val itr = channels.iterator()
val itr = channels.iterator() while (itr.hasNext()) {
while (itr.hasNext()) { val data = itr.next()
val data = itr.next() val genre = data.tvGenreId
val genre = data.tvGenreId if (genre != null) {
if (genre != null) { if (genre == idGenre) {
if (genre == idGenre) { itr.remove()
itr.remove() val name = data.name.toString()
val name = data.name.toString() val tv_genre_id = data.tvGenreId
val tv_genre_id = data.tvGenreId val idCH = data.id
val idCH = data.id val link = "http://localhost/ch/$idCH" + "_"
val link = "http://localhost/ch/$idCH" + "_" val logo = data.logo?.replace("""\""", "")
val logo = data.logo?.replace("""\""", "") val ch_id = data.cmds[0].chId
val ch_id = data.cmds[0].chId arraychannel.add(
arraychannel.add( Channel(
Channel( name,
name, link,
link, logo,
logo, "",
"", idCH,
idCH, tv_genre_id,
tv_genre_id, ch_id
ch_id
)
) )
provider.arraymediaPlaylist.add( )
Channel( provider.arraymediaPlaylist.add(
name, Channel(
link, name,
logo, link,
"", logo,
idCH, "",
tv_genre_id, idCH,
ch_id tv_genre_id,
) ch_id
) )
} )
} }
} }
} }
/***************************************** */
val flag: String val flag = getFlag(categoryTitle)
if (categoryTitle.uppercase() val nameGenre = if (firstCat) {
.contains(rgxcodeCountry) || categoryTitle.isContainsTargetCountry( firstCat = false
provider "$flag ${
) || categoryTitle.uppercase() cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim()
.contains(findKeyWord(tags.toString())) } \uD83D\uDCFA ${provider.name} \uD83D\uDCFA ( $expiration)"
) { } else {
flag = getFlag(categoryTitle) "$flag ${cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim()}"
val nameGenre = if (firstCat) {
firstCat = false
"$flag ${
cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim()
} \uD83D\uDCFA ${provider.name} \uD83D\uDCFA ( $expiration)"
} else {
"$flag ${cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim()}"
}
arrayHomepage.add(
arraychannel.toHomePageList(nameGenre, provider, idGenre)
)
} }
arraychannel.toHomePageList(nameGenre, provider, idGenre)
} else {
null
} }
} }
return arrayHomepage
} }
fun getHomePageListsFromArrayChannel(provider: MacIPTVProvider): List<HomePageList> { fun getHomePageListsFromArrayChannel(provider: MacIPTVProvider): List<HomePageList> {
val arrayHomepage = mutableListOf<HomePageList>()
val rgxcodeCountry = provider.rgxcodeCountry val rgxcodeCountry = provider.rgxcodeCountry
var firstCat = true var firstCat = true
val mychannels = ArrayList(provider.arraymediaPlaylist) val arrayChannel = provider.arraymediaPlaylist.toMutableList()
if (responseGetGenretoJSON.isNotEmpty() && provider.arraymediaPlaylist.isNotEmpty()) { return responseGetGenretoJSON.mapNotNull { js ->
responseGetGenretoJSON.forEach { js -> val idGenre = js.id.toString()
val idGenre = js.id.toString() val categoryTitle = js.title.toString()
val categoryTitle = js.title.toString() val flag: String
if (categoryTitle.uppercase()
/***************************************** */ .contains(rgxcodeCountry) || categoryTitle.isContainsTargetCountry(
val flag: String provider
if (categoryTitle.uppercase() )
.contains(rgxcodeCountry) || categoryTitle.isContainsTargetCountry( ) {
provider flag = getFlag(categoryTitle)
) val nameGenre = if (firstCat) {
) { firstCat = false
flag = getFlag(categoryTitle) "$flag ${
val nameGenre = if (firstCat) { cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim()
firstCat = false } \uD83D\uDCFA ${provider.name} \uD83D\uDCFA ( $expiration)"
"$flag ${ } else {
cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim() "$flag ${
} \uD83D\uDCFA ${provider.name} \uD83D\uDCFA ( $expiration)" cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim()
} else { }"
"$flag ${cleanTitle(categoryTitle).replace(rgxcodeCountry, "").trim()}"
}
arrayHomepage.add(
mychannels.toHomePageList(nameGenre, provider, idGenre)
)
} }
arrayChannel.toHomePageList(
nameGenre,
provider,
idGenre
)
} else {
null
} }
} }
return arrayHomepage
} }
} }
@ -654,8 +564,6 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
var loginMac: String? = null var loginMac: String? = null
var overrideUrl: String? = null var overrideUrl: String? = null
var tags: String? = null var tags: String? = null
private var oldAthMac: String? = null
private var oldAthUrl: String? = null
private var headerMac = mutableMapOf<String, String>() private var headerMac = mutableMapOf<String, String>()
var expiration: String? = null var expiration: String? = null
var responseGetGenretoJSON = ArrayList<Js_category>() // all genres from the provider var responseGetGenretoJSON = ArrayList<Js_category>() // all genres from the provider
@ -683,8 +591,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
val US = findKeyWord("US|USA") val US = findKeyWord("US|USA")
val AR = findKeyWord("AR|ARAB|ARABIC|ARABIA") val AR = findKeyWord("AR|ARAB|ARABIC|ARABIA")
val UK = findKeyWord("UK") val UK = findKeyWord("UK")
val flag: String return when {
flag = when (true) {
sequence.uppercase() sequence.uppercase()
.contains(FR) -> "\uD83C\uDDE8\uD83C\uDDF5" .contains(FR) -> "\uD83C\uDDE8\uD83C\uDDF5"
sequence.uppercase() sequence.uppercase()
@ -695,7 +602,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
.contains(AR) -> " نظرة" .contains(AR) -> " نظرة"
else -> "" else -> ""
} }
return flag
} }
fun cleanTitle(title: String): String { fun cleanTitle(title: String): String {
@ -705,7 +612,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
) )
} }
fun ArrayList<Channel>.toSearchResponseHomePage( fun MutableList<Channel>.toSearchResponseHomePage(
provider: MacIPTVProvider, GenreId: String provider: MacIPTVProvider, GenreId: String
): List<SearchResponse> { ): List<SearchResponse> {
val groupChannel = ArrayList<String>() val groupChannel = ArrayList<String>()
@ -732,7 +639,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
home.add( home.add(
LiveSearchResponse( LiveSearchResponse(
groupName, groupName,
"${provider.mainUrl}${media.toStringCode()}", "${provider.mainUrl}${media.toJson()}",
provider.name, provider.name,
TvType.Live, TvType.Live,
media.url_image, media.url_image,
@ -746,7 +653,7 @@ class MacIPTVProvider(override var lang: String) : MainAPI() {
return home return home
} }
fun ArrayList<Channel>.toHomePageList( fun MutableList<Channel>.toHomePageList(
name: String, name: String,
provider: MacIPTVProvider, provider: MacIPTVProvider,
GenreId: String GenreId: String

View file

@ -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()) 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()