From 3e2c2a5c86b93b9cd29ff1b8fd27a4a32a163a86 Mon Sep 17 00:00:00 2001 From: Sir Aguacata <87155550+KillerDogeEmpire@users.noreply.github.com> Date: Wed, 8 Feb 2023 15:58:15 -0800 Subject: [PATCH] Added a way for easy mal and anilist tracker (#359) * Added a way for easy mal and anilist tracker, All credit gos to Hexated for helping me * Made CodeFactor Fucking Happy * prettified the getTracker method * remove parenthesis * fixed --------- Co-authored-by: Blatzar <46196380+Blatzar@users.noreply.github.com> Co-authored-by: reduplicated <110570621+reduplicated@users.noreply.github.com> --- .../com/lagradost/cloudstream3/MainAPI.kt | 108 +++++++++++++++++- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 73859021..4014e34d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -15,12 +15,9 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.aniList import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.malApi import com.lagradost.cloudstream3.syncproviders.SyncIdName import com.lagradost.cloudstream3.ui.player.SubtitleData -import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.utils.* -import com.lagradost.cloudstream3.ui.result.UiText import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.Coroutines.threadSafeListOf -import com.lagradost.cloudstream3.utils.ExtractorLink import okhttp3.Interceptor import java.text.SimpleDateFormat import java.util.* @@ -163,6 +160,53 @@ object APIHolder { return null } + private var trackerCache: HashMap = hashMapOf() + + /** + * Get anime tracker information based on title, year and type. + * Both titles are attempted to be matched with both Romaji and English title. + * Uses the consumet api. + * + * @param titles uses first index to search, but if you have multiple titles and want extra guarantee to match you can also have that + * @param types Optional parameter to narrow down the scope to Movies, TV, etc. See TrackerType.getTypes() + * @param year Optional parameter to only get anime with a specific year + **/ + suspend fun getTracker( + titles: List, + types: Set?, + year: Int? + ): Tracker? { + return try { + require(titles.isNotEmpty()) { "titles must no be empty when calling getTracker" } + + val mainTitle = titles[0] + val search = + trackerCache[mainTitle] + ?: app.get("https://api.consumet.org/meta/anilist/$mainTitle") + .parsedSafe()?.also { + trackerCache[mainTitle] = it + } ?: return null + + val res = search.results?.find { media -> + val matchingYears = year == null || media.releaseDate == year + val matchingTitles = media.title?.let { title -> + titles.any { userTitle -> + title.isMatchingTitles(userTitle) + } + } ?: false + + val matchingTypes = types?.any { it.name.equals(media.type, true) } == true + matchingTitles && matchingTypes && matchingYears + } ?: return null + + Tracker(res.malId, res.aniId, res.image, res.cover) + } catch (t: Throwable) { + logError(t) + null + } + } + + fun Context.getApiSettings(): HashSet { //val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) @@ -1590,3 +1634,61 @@ fun fetchUrls(text: String?): List { fun String?.toRatingInt(): Int? = this?.replace(" ", "")?.trim()?.toDoubleOrNull()?.absoluteValue?.times(1000f)?.toInt() + +data class Tracker( + val malId: Int? = null, + val aniId: String? = null, + val image: String? = null, + val cover: String? = null, +) + +data class Title( + @JsonProperty("romaji") val romaji: String? = null, + @JsonProperty("english") val english: String? = null, +) { + fun isMatchingTitles(title: String?): Boolean { + if (title == null) return false + return english.equals(title, true) || romaji.equals(title, true) + } +} + +data class Results( + @JsonProperty("id") val aniId: String? = null, + @JsonProperty("malId") val malId: Int? = null, + @JsonProperty("title") val title: Title? = null, + @JsonProperty("releaseDate") val releaseDate: Int? = null, + @JsonProperty("type") val type: String? = null, + @JsonProperty("image") val image: String? = null, + @JsonProperty("cover") val cover: String? = null, +) + +data class AniSearch( + @JsonProperty("results") val results: ArrayList? = arrayListOf() +) + +/** + * used for the getTracker() method + **/ +enum class TrackerType { + MOVIE, + TV, + TV_SHORT, + ONA, + OVA, + SPECIAL, + MUSIC; + + companion object { + fun getTypes(type: TvType): Set { + return when (type) { + TvType.Movie -> setOf(MOVIE) + TvType.AnimeMovie -> setOf(MOVIE) + TvType.TvSeries -> setOf(TV, TV_SHORT) + TvType.Anime -> setOf(TV, TV_SHORT, ONA, OVA) + TvType.OVA -> setOf(OVA, SPECIAL, ONA) + TvType.Others -> setOf(MUSIC) + else -> emptySet() + } + } + } +}