2023-07-13 16:34:46 +00:00
|
|
|
package com.hexated
|
|
|
|
|
2023-08-12 17:42:08 +00:00
|
|
|
import com.hexated.Anichi.Companion.anilistApi
|
2023-07-13 16:34:46 +00:00
|
|
|
import com.hexated.Anichi.Companion.apiEndPoint
|
|
|
|
import com.lagradost.cloudstream3.Episode
|
|
|
|
import com.lagradost.cloudstream3.app
|
|
|
|
import com.lagradost.cloudstream3.base64Decode
|
|
|
|
import com.lagradost.cloudstream3.fixTitle
|
|
|
|
import com.lagradost.cloudstream3.mvvm.logError
|
|
|
|
import com.lagradost.cloudstream3.utils.AppUtils
|
|
|
|
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
|
|
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
|
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
|
|
|
import com.lagradost.nicehttp.RequestBodyTypes
|
|
|
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
|
|
|
import okhttp3.RequestBody.Companion.toRequestBody
|
|
|
|
import java.net.URI
|
|
|
|
import java.net.URLDecoder
|
|
|
|
|
|
|
|
suspend fun getTracker(name: String?, altName: String?, year: Int?, season: String?, type: String?): AniMedia? {
|
|
|
|
return fetchId(name, year, season, type).takeIf { it?.id != null } ?: fetchId(
|
|
|
|
altName,
|
|
|
|
year,
|
|
|
|
season,
|
|
|
|
type
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
suspend fun fetchId(title: String?, year: Int?, season: String?, type: String?): AniMedia? {
|
|
|
|
val query = """
|
|
|
|
query (
|
|
|
|
${'$'}page: Int = 1
|
|
|
|
${'$'}search: String
|
|
|
|
${'$'}sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC]
|
|
|
|
${'$'}type: MediaType
|
|
|
|
${'$'}season: MediaSeason
|
|
|
|
${'$'}year: String
|
|
|
|
${'$'}format: [MediaFormat]
|
|
|
|
) {
|
|
|
|
Page(page: ${'$'}page, perPage: 20) {
|
|
|
|
media(
|
|
|
|
search: ${'$'}search
|
|
|
|
sort: ${'$'}sort
|
|
|
|
type: ${'$'}type
|
|
|
|
season: ${'$'}season
|
|
|
|
startDate_like: ${'$'}year
|
|
|
|
format_in: ${'$'}format
|
|
|
|
) {
|
|
|
|
id
|
|
|
|
idMal
|
|
|
|
coverImage { extraLarge large }
|
|
|
|
bannerImage
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
""".trimIndent().trim()
|
|
|
|
|
|
|
|
val variables = mapOf(
|
|
|
|
"search" to title,
|
|
|
|
"sort" to "SEARCH_MATCH",
|
|
|
|
"type" to "ANIME",
|
|
|
|
"season" to if(type.equals("ona", true)) "" else season?.uppercase(),
|
|
|
|
"year" to "$year%",
|
|
|
|
"format" to listOf(type?.uppercase())
|
|
|
|
).filterValues { value -> value != null && value.toString().isNotEmpty() }
|
|
|
|
|
|
|
|
val data = mapOf(
|
|
|
|
"query" to query,
|
|
|
|
"variables" to variables
|
|
|
|
).toJson().toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull())
|
|
|
|
|
|
|
|
return try {
|
2023-08-12 17:42:08 +00:00
|
|
|
app.post(anilistApi, requestBody = data)
|
2023-07-13 16:34:46 +00:00
|
|
|
.parsedSafe<AniSearch>()?.data?.Page?.media?.firstOrNull()
|
|
|
|
} catch (t: Throwable) {
|
|
|
|
logError(t)
|
|
|
|
null
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-08-12 17:42:08 +00:00
|
|
|
suspend fun aniToMal(id: String): String? {
|
|
|
|
return app.post(
|
|
|
|
anilistApi, data = mapOf(
|
|
|
|
"query" to "{Media(id:$id,type:ANIME){idMal}}",
|
|
|
|
)
|
|
|
|
).parsedSafe<DataAni>()?.data?.media?.idMal
|
|
|
|
}
|
|
|
|
|
2023-07-13 16:34:46 +00:00
|
|
|
fun decode(input: String): String = URLDecoder.decode(input, "utf-8")
|
|
|
|
|
|
|
|
private val embedBlackList = listOf(
|
|
|
|
"https://mp4upload.com/",
|
|
|
|
"https://streamsb.net/",
|
|
|
|
"https://dood.to/",
|
|
|
|
"https://videobin.co/",
|
|
|
|
"https://ok.ru",
|
|
|
|
"https://streamlare.com",
|
2023-07-22 18:20:33 +00:00
|
|
|
"https://filemoon",
|
2023-07-13 16:34:46 +00:00
|
|
|
"streaming.php",
|
|
|
|
)
|
|
|
|
|
|
|
|
fun embedIsBlacklisted(url: String): Boolean {
|
|
|
|
return embedBlackList.any { url.contains(it) }
|
|
|
|
}
|
|
|
|
|
|
|
|
fun AvailableEpisodesDetail.getEpisode(
|
|
|
|
lang: String,
|
|
|
|
id: String,
|
|
|
|
malId: Int?,
|
|
|
|
): List<Episode> {
|
|
|
|
val meta = if (lang == "sub") this.sub else this.dub
|
|
|
|
return meta.map { eps ->
|
|
|
|
Episode(
|
|
|
|
AnichiLoadData(id, lang, eps, malId).toJson(),
|
|
|
|
episode = eps.toIntOrNull()
|
|
|
|
)
|
|
|
|
}.reversed()
|
|
|
|
}
|
|
|
|
|
|
|
|
suspend fun getM3u8Qualities(
|
|
|
|
m3u8Link: String,
|
|
|
|
referer: String,
|
|
|
|
qualityName: String,
|
|
|
|
): List<ExtractorLink> {
|
|
|
|
return M3u8Helper.generateM3u8(
|
|
|
|
qualityName,
|
|
|
|
m3u8Link,
|
|
|
|
referer,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun String.getHost(): String {
|
|
|
|
return fixTitle(URI(this).host.substringBeforeLast(".").substringAfterLast("."))
|
|
|
|
}
|
|
|
|
|
|
|
|
fun String.fixUrlPath() : String {
|
|
|
|
return if(this.contains(".json?")) apiEndPoint + this else apiEndPoint + URI(this).path + ".json?" + URI(this).query
|
|
|
|
}
|
|
|
|
|
|
|
|
fun fixSourceUrls(url: String, source: String?) : String? {
|
|
|
|
return if(source == "Ak" || url.contains("/player/vitemb")) {
|
|
|
|
AppUtils.tryParseJson<AkIframe>(base64Decode(url.substringAfter("=")))?.idUrl
|
|
|
|
} else {
|
|
|
|
url.replace(" ", "%20")
|
|
|
|
}
|
|
|
|
}
|