Anichi: added lib/sync support

This commit is contained in:
hexated 2023-08-13 00:42:08 +07:00
parent 017d861b00
commit 8a61d0891e
5 changed files with 64 additions and 3 deletions

View file

@ -1,7 +1,7 @@
import org.jetbrains.kotlin.konan.properties.Properties
// use an integer for version numbers
version = 7
version = 8
android {
defaultConfig {

View file

@ -7,6 +7,7 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.syncproviders.SyncIdName
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.nicehttp.RequestBodyTypes
@ -27,6 +28,7 @@ open class Anichi : MainAPI() {
}
}
override val supportedSyncNames = setOf(SyncIdName.Anilist, SyncIdName.MyAnimeList)
override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie)
private val popularTitle = "Popular"
@ -110,6 +112,29 @@ open class Anichi : MainAPI() {
}
}
override suspend fun getLoadUrl(name: SyncIdName, id: String): String? {
val syncId = id.split("/").last()
val malId = if (name == SyncIdName.MyAnimeList) {
syncId
} else {
aniToMal(syncId)
}
val media = app.get("$jikanApi/anime/$malId").parsedSafe<JikanResponse>()?.data
val link =
"""$apiUrl?variables={"search":{"allowAdult":false,"allowUnknown":false,"query":"${media?.title}"},"limit":26,"page":1,"translationType":"sub","countryOrigin":"ALL"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$mainHash"}}"""
val res = app.get(
link,
headers = headers
).parsedSafe<AnichiQuery>()?.data?.shows?.edges
return res?.find {
(it.name.equals(media?.title, true) || it.englishName.equals(
media?.title_english,
true
) || it.nativeName.equals(media?.title_japanese, true)) && it.airedStart?.year == media?.year
}?.Id
}
override suspend fun load(url: String): LoadResponse? {
val id = url.substringAfterLast("/")
@ -218,6 +243,8 @@ open class Anichi : MainAPI() {
const val serverUrl = BuildConfig.ANICHI_SERVER
const val apiEndPoint = BuildConfig.ANICHI_ENDPOINT
const val anilistApi = "https://graphql.anilist.co"
const val jikanApi = "https://api.jikan.moe/v4"
const val marinHost = "https://marin.moe"
private const val mainHash = "e42a4466d984b2c0a2cecae5dd13aa68867f634b16ee0f17b380047d14482406"

View file

@ -69,7 +69,7 @@ object AnichiExtractors : Anichi() {
links.forEach { server ->
val host = server.link.getHost()
when {
source.sourceName == "Default" -> {
source.sourceName?.contains("Default") == true -> {
if (server.resolutionStr == "SUB" || server.resolutionStr == "Alt vo_SUB") {
getM3u8Qualities(
server.link,

View file

@ -9,6 +9,31 @@ data class AnichiLoadData(
val idMal: Int? = null,
)
data class JikanData(
@JsonProperty("title") val title: String? = null,
@JsonProperty("title_english") val title_english: String? = null,
@JsonProperty("title_japanese") val title_japanese: String? = null,
@JsonProperty("year") val year: Int? = null,
@JsonProperty("season") val season: String? = null,
@JsonProperty("type") val type: String? = null,
)
data class JikanResponse(
@JsonProperty("data") val data: JikanData? = null,
)
data class IdMal(
@JsonProperty("idMal") val idMal: String? = null,
)
data class MediaAni(
@JsonProperty("Media") val media: IdMal? = null,
)
data class DataAni(
@JsonProperty("data") val data: MediaAni? = null,
)
data class CoverImage(
@JsonProperty("extraLarge") var extraLarge: String? = null,
@JsonProperty("large") var large: String? = null,

View file

@ -1,5 +1,6 @@
package com.hexated
import com.hexated.Anichi.Companion.anilistApi
import com.hexated.Anichi.Companion.apiEndPoint
import com.lagradost.cloudstream3.Episode
import com.lagradost.cloudstream3.app
@ -69,7 +70,7 @@ suspend fun fetchId(title: String?, year: Int?, season: String?, type: String?):
).toJson().toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull())
return try {
app.post("https://graphql.anilist.co", requestBody = data)
app.post(anilistApi, requestBody = data)
.parsedSafe<AniSearch>()?.data?.Page?.media?.firstOrNull()
} catch (t: Throwable) {
logError(t)
@ -78,6 +79,14 @@ suspend fun fetchId(title: String?, year: Int?, season: String?, type: String?):
}
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
}
fun decode(input: String): String = URLDecoder.decode(input, "utf-8")
private val embedBlackList = listOf(