diff --git a/src/main/kotlin/com/jeluchu/core/utils/Constants.kt b/src/main/kotlin/com/jeluchu/core/utils/Constants.kt index 45099c8..d4923cf 100644 --- a/src/main/kotlin/com/jeluchu/core/utils/Constants.kt +++ b/src/main/kotlin/com/jeluchu/core/utils/Constants.kt @@ -57,6 +57,7 @@ object Routes { const val MANGA = "/manga" const val PEOPLE = "/people" const val SEARCH = "/search" + const val TOP_TEN = "/topTen" const val GALLERY = "/gallery" const val SCHEDULE = "/schedule" const val RADIO_STATIONS = "/radio" @@ -86,6 +87,7 @@ object TimerKey { object Collections { const val TIMERS = "timers" + const val TOP_TEN = "top_ten" const val NEWS_ES = "news_es" const val NEWS_EN = "news_en" const val SCHEDULES = "schedule" @@ -100,5 +102,6 @@ object Collections { const val ANIME_DIRECTORY = "anime_directory" const val CHARACTER_RANKING = "character_ranking" const val ANIME_PICTURES_QUERY = "anime_pictures_query" + const val ANIME_RANKING_TOP_TEN = "anime_ranking_top_ten" const val ANIME_PICTURES_RECENT = "anime_pictures_recent" } \ No newline at end of file diff --git a/src/main/kotlin/com/jeluchu/features/rankings/routes/RankingsRoutes.kt b/src/main/kotlin/com/jeluchu/features/rankings/routes/RankingsRoutes.kt index d62e74e..be6ab69 100644 --- a/src/main/kotlin/com/jeluchu/features/rankings/routes/RankingsRoutes.kt +++ b/src/main/kotlin/com/jeluchu/features/rankings/routes/RankingsRoutes.kt @@ -12,6 +12,10 @@ fun Route.rankingsEndpoints( ) = route(Routes.TOP) { route(Routes.ANIME) { getToJson { service.getAnimeRanking(call) } + + route(Routes.TOP_TEN) { + getToJson { service.getAnimeTopTenRanking(call) } + } } route(Routes.MANGA) { getToJson { service.getMangaRanking(call) } diff --git a/src/main/kotlin/com/jeluchu/features/rankings/services/RankingsService.kt b/src/main/kotlin/com/jeluchu/features/rankings/services/RankingsService.kt index 409f17b..f2979c3 100644 --- a/src/main/kotlin/com/jeluchu/features/rankings/services/RankingsService.kt +++ b/src/main/kotlin/com/jeluchu/features/rankings/services/RankingsService.kt @@ -43,6 +43,7 @@ class RankingsService( private val mangaRanking = database.getCollection(Collections.MANGA_RANKING) private val peopleRanking = database.getCollection(Collections.PEOPLE_RANKING) private val characterRanking = database.getCollection(Collections.CHARACTER_RANKING) + private val animeRankingTopTen = database.getCollection(Collections.ANIME_RANKING_TOP_TEN) suspend fun getAnimeRanking(call: RoutingCall) { val filter = call.request.queryParameters["filter"] ?: "airing" @@ -327,4 +328,65 @@ class RankingsService( call.respond(HttpStatusCode.OK, Json.encodeToString(response)) } } + + suspend fun getAnimeTopTenRanking(call: RoutingCall) { + val filter = call.request.queryParameters["filter"] ?: "airing" + val type = call.parameters["type"] ?: throw IllegalArgumentException(ErrorMessages.InvalidTopAnimeType.message) + + if (parseAnimeType(type) == null) call.respond(HttpStatusCode.BadRequest, ErrorResponse(ErrorMessages.InvalidTopAnimeType.message)) + + val timerKey = "${Collections.ANIME_RANKING}_${Collections.TOP_TEN}_${type}_${filter}" + + val needsUpdate = timers.needsUpdate( + amount = 7, + key = timerKey, + unit = TimeUnit.DAY + ) + + if (needsUpdate) { + animeRankingTopTen.deleteMany( + Filters.and( + Filters.eq("type", type), + Filters.eq("subtype", filter) + ) + ) + + val params = mutableListOf() + params.add("type=$type") + params.add("filter=$filter") + + val response = RestClient.request( + BaseUrls.JIKAN + Endpoints.TOP_ANIME + "?${params.joinToString("&")}", + AnimeSearch.serializer() + ).data?.map { anime -> + anime.toAnimeTopEntity( + page = 0, + top = "anime", + type = type, + subType = filter + ) + }.orEmpty().take(11).distinctBy { it.malId } + + val documentsToInsert = parseDataToDocuments(response, AnimeTopEntity.serializer()) + if (documentsToInsert.isNotEmpty()) animeRankingTopTen .insertMany(documentsToInsert) + timers.update(timerKey) + + val elements = documentsToInsert.map { documentToAnimeTopEntity(it) } + + call.respond(HttpStatusCode.OK, Json.encodeToString(elements)) + } else { + val animes = animeRankingTopTen + .find( + Filters.and( + Filters.eq("type", type), + Filters.eq("subtype", filter) + ) + ) + .toList() + + val elements = animes.map { documentToAnimeTopEntity(it) } + + call.respond(HttpStatusCode.OK, Json.encodeToString(elements)) + } + } } \ No newline at end of file