From c7c1f12dade36a515fb7a09ececc3f1d10a7b0d1 Mon Sep 17 00:00:00 2001 From: KillerDogeEmpire Date: Mon, 6 Feb 2023 15:28:40 -0800 Subject: [PATCH 1/5] Added a way for easy mal and anilist tracker, All credit gos to Hexated for helping me --- .../com/lagradost/cloudstream3/MainAPI.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 73859021..98367b11 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -163,6 +163,18 @@ object APIHolder { return null } + private suspend fun getTracker(title: String?, type: String?, year: Int?): Tracker { + val res = app.get("https://api.consumet.org/meta/anilist/$title") + .parsedSafe()?.results?.find { media -> + (media.title?.english.equals(title, true) || media.title?.romaji.equals( + title, + true + )) || (media.type.equals(type, true) && media.releaseDate == year) + } + return Tracker(res?.malId, res?.aniId, res?.image, res?.cover) + } + + fun Context.getApiSettings(): HashSet { //val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) @@ -1590,3 +1602,30 @@ 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, +) + +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(), + + ) From 830fd7ee55882353c80c3c6939cda8d98b97f4e9 Mon Sep 17 00:00:00 2001 From: KillerDogeEmpire Date: Tue, 7 Feb 2023 14:52:34 -0800 Subject: [PATCH 2/5] Made CodeFactor Fucking Happy --- app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 98367b11..89ec315c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -166,10 +166,8 @@ object APIHolder { private suspend fun getTracker(title: String?, type: String?, year: Int?): Tracker { val res = app.get("https://api.consumet.org/meta/anilist/$title") .parsedSafe()?.results?.find { media -> - (media.title?.english.equals(title, true) || media.title?.romaji.equals( - title, - true - )) || (media.type.equals(type, true) && media.releaseDate == year) + media.title?.english.equals(title, true) || media.title?.romaji.equals( title, true ) + || media.type.equals(type, true) && media.releaseDate == year } return Tracker(res?.malId, res?.aniId, res?.image, res?.cover) } From b08608d31a0b6813135ec89d6ce61ce55f49bc1b Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Wed, 8 Feb 2023 10:19:08 +0100 Subject: [PATCH 3/5] prettified the getTracker method --- .../com/lagradost/cloudstream3/MainAPI.kt | 67 +++++++++++++++++-- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 89ec315c..5ccaa762 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -163,12 +163,34 @@ object APIHolder { return null } - private suspend fun getTracker(title: String?, type: String?, year: Int?): Tracker { - val res = app.get("https://api.consumet.org/meta/anilist/$title") + /** + * 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 mainTitle Title to search by and match + * @param secondaryTitle Optional extra title if you have multiple titles and want extra guarantee to match. + * @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( + mainTitle: String, + secondaryTitle: String?, + types: Set?, + year: Int? + ): Tracker { + val res = app.get("https://api.consumet.org/meta/anilist/$mainTitle") .parsedSafe()?.results?.find { media -> - media.title?.english.equals(title, true) || media.title?.romaji.equals( title, true ) - || media.type.equals(type, true) && media.releaseDate == year + val matchingYears = year == null || media.releaseDate == year + val matchingTitles = + (media.title?.isMatchingTitles(mainTitle) == true || media.title?.isMatchingTitles( + secondaryTitle + ) == true) + + val matchingTypes = types?.any { it.name.equals(media.type, true) } == true + matchingTitles && matchingTypes && matchingYears } + return Tracker(res?.malId, res?.aniId, res?.image, res?.cover) } @@ -1611,7 +1633,12 @@ data class Tracker( 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, @@ -1624,6 +1651,32 @@ data class Results( ) data class AniSearch( - @JsonProperty("results") val results: ArrayList? = arrayListOf(), + @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() + } + } + } +} From 58763708f7888899ced9fe79a2d9a90666010631 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Wed, 8 Feb 2023 10:20:48 +0100 Subject: [PATCH 4/5] remove parenthesis --- app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 5ccaa762..36b1c83d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -183,9 +183,9 @@ object APIHolder { .parsedSafe()?.results?.find { media -> val matchingYears = year == null || media.releaseDate == year val matchingTitles = - (media.title?.isMatchingTitles(mainTitle) == true || media.title?.isMatchingTitles( + media.title?.isMatchingTitles(mainTitle) == true || media.title?.isMatchingTitles( secondaryTitle - ) == true) + ) == true val matchingTypes = types?.any { it.name.equals(media.type, true) } == true matchingTitles && matchingTypes && matchingYears From eac7c2b2e3abbcc2b82428eedfd552dcfed9b827 Mon Sep 17 00:00:00 2001 From: reduplicated <110570621+reduplicated@users.noreply.github.com> Date: Thu, 9 Feb 2023 00:37:29 +0100 Subject: [PATCH 5/5] fixed --- .../com/lagradost/cloudstream3/MainAPI.kt | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 36b1c83d..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,35 +160,50 @@ 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 mainTitle Title to search by and match - * @param secondaryTitle Optional extra title if you have multiple titles and want extra guarantee to match. + * @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( - mainTitle: String, - secondaryTitle: String?, + titles: List, types: Set?, year: Int? - ): Tracker { - val res = app.get("https://api.consumet.org/meta/anilist/$mainTitle") - .parsedSafe()?.results?.find { media -> + ): 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?.isMatchingTitles(mainTitle) == true || media.title?.isMatchingTitles( - secondaryTitle - ) == true + 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 - return Tracker(res?.malId, res?.aniId, res?.image, res?.cover) + Tracker(res.malId, res.aniId, res.image, res.cover) + } catch (t: Throwable) { + logError(t) + null + } }