mirror of https://github.com/aruppi/aruppi-api
Compare commits
No commits in common. "a113b7e677843741290bd6f816b53217467cf582" and "d7ca2965d2e3c7456f6b830a3c9209f9994c2ee3" have entirely different histories.
a113b7e677
...
d7ca2965d2
|
@ -1,11 +0,0 @@
|
||||||
package com.jeluchu.core.enums
|
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
enum class AnimeStatusTypes {
|
|
||||||
FINISHED, ONGOING, UPCOMING, UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
val animeStatusTypesErrorList = AnimeStatusTypes.entries.joinToString(", ") { it.name.lowercase() }
|
|
||||||
fun parseAnimeStatusType(type: String) = AnimeStatusTypes.entries.firstOrNull { it.name.equals(type, ignoreCase = true) }
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.jeluchu.core.enums
|
|
||||||
|
|
||||||
enum class Season {
|
|
||||||
WINTER, SPRING, SUMMER, FALL
|
|
||||||
}
|
|
||||||
|
|
||||||
val seasonsErrorList = AnimeTypes.entries.joinToString(", ") { it.name.lowercase() }
|
|
||||||
fun parseSeasons(type: String) = Season.entries.firstOrNull { it.name.equals(type, ignoreCase = true) }
|
|
|
@ -12,7 +12,6 @@ sealed class ErrorMessages(val message: String) {
|
||||||
data object InvalidMangaType : ErrorMessages("Invalid 'type' parameter. Valid values are: ${MangaTypes.entries.joinToString(", ") { it.name.lowercase() }}")
|
data object InvalidMangaType : ErrorMessages("Invalid 'type' parameter. Valid values are: ${MangaTypes.entries.joinToString(", ") { it.name.lowercase() }}")
|
||||||
data object InvalidSizeAndPage : ErrorMessages("Invalid page and size parameters")
|
data object InvalidSizeAndPage : ErrorMessages("Invalid page and size parameters")
|
||||||
data object InvalidTopAnimeType : ErrorMessages("Invalid 'type' parameter. Valid values are: $animeTypesErrorList")
|
data object InvalidTopAnimeType : ErrorMessages("Invalid 'type' parameter. Valid values are: $animeTypesErrorList")
|
||||||
data object InvalidAnimeStatusType : ErrorMessages("Invalid 'status' parameter. Valid values are: $animeStatusTypesErrorList")
|
|
||||||
data object InvalidTopAnimeFilterType : ErrorMessages("Invalid 'type' parameter. Valid values are: $animeFilterTypesErrorList")
|
data object InvalidTopAnimeFilterType : ErrorMessages("Invalid 'type' parameter. Valid values are: $animeFilterTypesErrorList")
|
||||||
data object InvalidTopMangaType : ErrorMessages("Invalid 'type' parameter. Valid values are: $mangaTypesErrorList")
|
data object InvalidTopMangaType : ErrorMessages("Invalid 'type' parameter. Valid values are: $mangaTypesErrorList")
|
||||||
data object InvalidTopMangaFilterType : ErrorMessages("Invalid 'type' parameter. Valid values are: $mangaFilterTypesErrorList")
|
data object InvalidTopMangaFilterType : ErrorMessages("Invalid 'type' parameter. Valid values are: $mangaFilterTypesErrorList")
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
package com.jeluchu.core.models
|
|
||||||
|
|
||||||
import com.jeluchu.core.extensions.getDocumentSafe
|
|
||||||
import com.jeluchu.core.extensions.getIntSafe
|
|
||||||
import com.jeluchu.core.extensions.getStringSafe
|
|
||||||
import com.jeluchu.core.utils.SeasonCalendar
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import org.bson.Document
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class SimpleAnimeEntity(
|
|
||||||
val malId: Int,
|
|
||||||
val type: String,
|
|
||||||
val title: String,
|
|
||||||
val image: String,
|
|
||||||
val score: String,
|
|
||||||
val season: SeasonInfo
|
|
||||||
) {
|
|
||||||
@Serializable
|
|
||||||
data class SeasonInfo(
|
|
||||||
val year: Int? = null,
|
|
||||||
val station: String? = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun documentToSimpleAnimeEntity(doc: Document) = SimpleAnimeEntity(
|
|
||||||
malId = doc.getIntSafe("malId"),
|
|
||||||
title = doc.getStringSafe("title"),
|
|
||||||
type = doc.getStringSafe("type"),
|
|
||||||
score = doc.getStringSafe("score"),
|
|
||||||
image = doc.getStringSafe("poster"),
|
|
||||||
season = doc.getDocumentSafe("season")?.let { documentToSeasonInfo(it) } ?: SimpleAnimeEntity.SeasonInfo(),
|
|
||||||
)
|
|
||||||
|
|
||||||
fun documentToSeasonInfo(doc: Document) = SimpleAnimeEntity.SeasonInfo(
|
|
||||||
year = doc.getIntSafe("year"),
|
|
||||||
station = doc.getStringSafe("station")
|
|
||||||
)
|
|
|
@ -1,47 +0,0 @@
|
||||||
package com.jeluchu.core.utils
|
|
||||||
|
|
||||||
import com.jeluchu.core.models.PaginationResponse
|
|
||||||
import com.mongodb.client.MongoCollection
|
|
||||||
import org.bson.Document
|
|
||||||
import org.bson.conversions.Bson
|
|
||||||
|
|
||||||
fun <T> getRemoteData(
|
|
||||||
filters: Bson,
|
|
||||||
mapper: (Document) -> T,
|
|
||||||
onQuerySuccess: (List<T>) -> Unit,
|
|
||||||
newCollection: MongoCollection<Document>,
|
|
||||||
remoteCollection: MongoCollection<Document>,
|
|
||||||
) {
|
|
||||||
newCollection.deleteMany(Document())
|
|
||||||
|
|
||||||
val query = remoteCollection
|
|
||||||
.find(filters)
|
|
||||||
.toList()
|
|
||||||
.map { mapper(it) }
|
|
||||||
|
|
||||||
onQuerySuccess(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun <T> getLocalData(
|
|
||||||
page: Int,
|
|
||||||
size: Int,
|
|
||||||
skipCount: Int,
|
|
||||||
mapper: (Document) -> T,
|
|
||||||
collection: MongoCollection<Document>,
|
|
||||||
onQuerySuccess: suspend (PaginationResponse<T>) -> Unit
|
|
||||||
) {
|
|
||||||
val query = collection
|
|
||||||
.find()
|
|
||||||
.skip(skipCount)
|
|
||||||
.limit(size)
|
|
||||||
.toList()
|
|
||||||
.map { mapper(it) }
|
|
||||||
|
|
||||||
val paginate = PaginationResponse(
|
|
||||||
page = page,
|
|
||||||
data = query,
|
|
||||||
size = query.size
|
|
||||||
)
|
|
||||||
|
|
||||||
onQuerySuccess(paginate)
|
|
||||||
}
|
|
|
@ -52,13 +52,11 @@ object Routes {
|
||||||
const val ES = "/es"
|
const val ES = "/es"
|
||||||
const val EN = "/en"
|
const val EN = "/en"
|
||||||
const val TOP = "/top"
|
const val TOP = "/top"
|
||||||
const val TAGS = "/tags"
|
|
||||||
const val NEWS = "/news"
|
const val NEWS = "/news"
|
||||||
const val ANIME = "/anime"
|
const val ANIME = "/anime"
|
||||||
const val MANGA = "/manga"
|
const val MANGA = "/manga"
|
||||||
const val PEOPLE = "/people"
|
const val PEOPLE = "/people"
|
||||||
const val SEARCH = "/search"
|
const val SEARCH = "/search"
|
||||||
const val TOP_TEN = "/topTen"
|
|
||||||
const val GALLERY = "/gallery"
|
const val GALLERY = "/gallery"
|
||||||
const val SCHEDULE = "/schedule"
|
const val SCHEDULE = "/schedule"
|
||||||
const val RADIO_STATIONS = "/radio"
|
const val RADIO_STATIONS = "/radio"
|
||||||
|
@ -70,13 +68,9 @@ object Routes {
|
||||||
const val EPISODES = "/episodes"
|
const val EPISODES = "/episodes"
|
||||||
const val ID = "/{id}"
|
const val ID = "/{id}"
|
||||||
const val TYPE = "/{type}"
|
const val TYPE = "/{type}"
|
||||||
const val SEASON = "/season"
|
const val SEASON = "/{year}/{season}"
|
||||||
const val SEASON_PARAMS = "/{year}/{season}"
|
|
||||||
const val DAY = "/{day}"
|
const val DAY = "/{day}"
|
||||||
const val THEMES = "/themes"
|
const val THEMES = "/themes"
|
||||||
const val SUGGESTIONS = "/suggestions"
|
|
||||||
const val YEAR_INDEX = "/yearIndex"
|
|
||||||
const val RANDOM = "/random"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object TimerKey {
|
object TimerKey {
|
||||||
|
@ -92,7 +86,6 @@ object TimerKey {
|
||||||
|
|
||||||
object Collections {
|
object Collections {
|
||||||
const val TIMERS = "timers"
|
const val TIMERS = "timers"
|
||||||
const val TOP_TEN = "top_ten"
|
|
||||||
const val NEWS_ES = "news_es"
|
const val NEWS_ES = "news_es"
|
||||||
const val NEWS_EN = "news_en"
|
const val NEWS_EN = "news_en"
|
||||||
const val SCHEDULES = "schedule"
|
const val SCHEDULES = "schedule"
|
||||||
|
@ -107,6 +100,5 @@ object Collections {
|
||||||
const val ANIME_DIRECTORY = "anime_directory"
|
const val ANIME_DIRECTORY = "anime_directory"
|
||||||
const val CHARACTER_RANKING = "character_ranking"
|
const val CHARACTER_RANKING = "character_ranking"
|
||||||
const val ANIME_PICTURES_QUERY = "anime_pictures_query"
|
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"
|
const val ANIME_PICTURES_RECENT = "anime_pictures_recent"
|
||||||
}
|
}
|
|
@ -1,9 +1,44 @@
|
||||||
package com.jeluchu.core.utils
|
package com.jeluchu.core.utils
|
||||||
|
|
||||||
|
import com.jeluchu.features.rankings.models.AnimeTopEntity
|
||||||
|
import com.jeluchu.features.schedule.models.DayEntity
|
||||||
|
import com.jeluchu.features.schedule.models.ScheduleData
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.bson.Document
|
import org.bson.Document
|
||||||
|
|
||||||
|
fun parseTopDataToDocuments(data: ScheduleData): List<Document> {
|
||||||
|
val documents = mutableListOf<Document>()
|
||||||
|
fun processDay(dayList: List<DayEntity>?) {
|
||||||
|
dayList?.forEach { animeData ->
|
||||||
|
val animeJsonString = Json.encodeToString(animeData)
|
||||||
|
val document = Document.parse(animeJsonString)
|
||||||
|
documents.add(document)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
processDay(data.monday)
|
||||||
|
processDay(data.tuesday)
|
||||||
|
processDay(data.wednesday)
|
||||||
|
processDay(data.thursday)
|
||||||
|
processDay(data.friday)
|
||||||
|
processDay(data.saturday)
|
||||||
|
processDay(data.sunday)
|
||||||
|
|
||||||
|
return documents
|
||||||
|
}
|
||||||
|
|
||||||
|
fun parseTopDataToDocuments(data: List<AnimeTopEntity>?): List<Document> {
|
||||||
|
val documents = mutableListOf<Document>()
|
||||||
|
data?.forEach { animeData ->
|
||||||
|
val animeJsonString = Json.encodeToString(animeData)
|
||||||
|
val document = Document.parse(animeJsonString)
|
||||||
|
documents.add(document)
|
||||||
|
}
|
||||||
|
return documents
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> parseDataToDocuments(data: List<T>?, serializer: KSerializer<T>): List<Document> {
|
fun <T> parseDataToDocuments(data: List<T>?, serializer: KSerializer<T>): List<Document> {
|
||||||
val documents = mutableListOf<Document>()
|
val documents = mutableListOf<Document>()
|
||||||
data?.forEach { item ->
|
data?.forEach { item ->
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.jeluchu.core.utils
|
|
||||||
|
|
||||||
import com.jeluchu.core.enums.Season
|
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
object SeasonCalendar {
|
|
||||||
private val calendar: Calendar by lazy {
|
|
||||||
Calendar.getInstance(Locale.getDefault())
|
|
||||||
}
|
|
||||||
|
|
||||||
val currentYear = calendar.get(Calendar.YEAR)
|
|
||||||
private val month = calendar.get(Calendar.MONTH)
|
|
||||||
|
|
||||||
val currentSeason = when (month) {
|
|
||||||
0, 1, 11 -> Season.WINTER
|
|
||||||
2, 3, 4 -> Season.SPRING
|
|
||||||
5, 6, 7 -> Season.SUMMER
|
|
||||||
8, 9, 10 -> Season.FALL
|
|
||||||
else -> Season.SPRING
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package com.jeluchu.features.anime.models.seasons
|
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class YearSeasons(
|
|
||||||
@SerialName("year") val year: Int,
|
|
||||||
@SerialName("seasons") val seasons: List<String>
|
|
||||||
)
|
|
|
@ -4,34 +4,20 @@ import com.jeluchu.core.extensions.getToJson
|
||||||
import com.jeluchu.core.utils.Routes
|
import com.jeluchu.core.utils.Routes
|
||||||
import com.jeluchu.features.anime.services.AnimeService
|
import com.jeluchu.features.anime.services.AnimeService
|
||||||
import com.jeluchu.features.anime.services.DirectoryService
|
import com.jeluchu.features.anime.services.DirectoryService
|
||||||
import com.jeluchu.features.anime.services.SeasonService
|
|
||||||
import com.jeluchu.features.anime.services.TagsService
|
|
||||||
import com.mongodb.client.MongoDatabase
|
import com.mongodb.client.MongoDatabase
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
fun Route.animeEndpoints(
|
fun Route.animeEndpoints(
|
||||||
mongoDatabase: MongoDatabase,
|
mongoDatabase: MongoDatabase,
|
||||||
service: AnimeService = AnimeService(mongoDatabase),
|
service: AnimeService = AnimeService(mongoDatabase),
|
||||||
tagsService: TagsService = TagsService(mongoDatabase),
|
|
||||||
seasonService: SeasonService = SeasonService(mongoDatabase),
|
|
||||||
directoryService: DirectoryService = DirectoryService(mongoDatabase),
|
directoryService: DirectoryService = DirectoryService(mongoDatabase),
|
||||||
) = route(Routes.ANIME) {
|
) = route(Routes.ANIME) {
|
||||||
getToJson { service.getAnimeByType(call) }
|
|
||||||
getToJson(Routes.ID) { service.getAnimeByMalId(call) }
|
getToJson(Routes.ID) { service.getAnimeByMalId(call) }
|
||||||
getToJson(Routes.RANDOM) { service.getRandomAnime(call) }
|
|
||||||
getToJson(Routes.LAST_EPISODES) { service.getLastEpisodes(call) }
|
getToJson(Routes.LAST_EPISODES) { service.getLastEpisodes(call) }
|
||||||
|
|
||||||
route(Routes.SUGGESTIONS) {
|
|
||||||
getToJson { tagsService.getAnimeByAnyTag(call) }
|
|
||||||
}
|
|
||||||
|
|
||||||
route(Routes.SEASON) {
|
|
||||||
getToJson { seasonService.getAnimeBySeason(call) }
|
|
||||||
getToJson(Routes.YEAR_INDEX) { seasonService.getYearsAndSeasons(call) }
|
|
||||||
}
|
|
||||||
|
|
||||||
route(Routes.DIRECTORY) {
|
route(Routes.DIRECTORY) {
|
||||||
getToJson { service.getDirectory(call) }
|
getToJson { service.getDirectory(call) }
|
||||||
getToJson(Routes.TYPE) { directoryService.getAnimeByType(call) }
|
getToJson(Routes.TYPE) { directoryService.getAnimeByType(call) }
|
||||||
|
getToJson(Routes.SEASON) { directoryService.getAnimeBySeason(call) }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,17 +1,13 @@
|
||||||
package com.jeluchu.features.anime.services
|
package com.jeluchu.features.anime.services
|
||||||
|
|
||||||
import com.jeluchu.core.connection.RestClient
|
import com.jeluchu.core.connection.RestClient
|
||||||
import com.jeluchu.core.enums.AnimeStatusTypes
|
|
||||||
import com.jeluchu.core.enums.AnimeTypes
|
|
||||||
import com.jeluchu.core.enums.TimeUnit
|
import com.jeluchu.core.enums.TimeUnit
|
||||||
import com.jeluchu.core.enums.parseAnimeStatusType
|
|
||||||
import com.jeluchu.core.enums.parseAnimeType
|
import com.jeluchu.core.enums.parseAnimeType
|
||||||
import com.jeluchu.core.extensions.needsUpdate
|
import com.jeluchu.core.extensions.needsUpdate
|
||||||
import com.jeluchu.core.extensions.update
|
import com.jeluchu.core.extensions.update
|
||||||
import com.jeluchu.core.messages.ErrorMessages
|
import com.jeluchu.core.messages.ErrorMessages
|
||||||
import com.jeluchu.core.models.ErrorResponse
|
import com.jeluchu.core.models.ErrorResponse
|
||||||
import com.jeluchu.core.models.PaginationResponse
|
import com.jeluchu.core.models.PaginationResponse
|
||||||
import com.jeluchu.core.models.documentToSimpleAnimeEntity
|
|
||||||
import com.jeluchu.features.anime.models.lastepisodes.LastEpisodeEntity
|
import com.jeluchu.features.anime.models.lastepisodes.LastEpisodeEntity
|
||||||
import com.jeluchu.features.anime.models.lastepisodes.LastEpisodeEntity.Companion.toLastEpisodeData
|
import com.jeluchu.features.anime.models.lastepisodes.LastEpisodeEntity.Companion.toLastEpisodeData
|
||||||
import com.jeluchu.core.models.jikan.search.AnimeSearch
|
import com.jeluchu.core.models.jikan.search.AnimeSearch
|
||||||
|
@ -23,9 +19,7 @@ import com.jeluchu.features.anime.mappers.documentToAnimeLastEpisodeEntity
|
||||||
import com.jeluchu.features.anime.mappers.documentToAnimeTypeEntity
|
import com.jeluchu.features.anime.mappers.documentToAnimeTypeEntity
|
||||||
import com.jeluchu.features.anime.mappers.documentToMoreInfoEntity
|
import com.jeluchu.features.anime.mappers.documentToMoreInfoEntity
|
||||||
import com.mongodb.client.MongoDatabase
|
import com.mongodb.client.MongoDatabase
|
||||||
import com.mongodb.client.model.Aggregates
|
import com.mongodb.client.model.Filters.eq
|
||||||
import com.mongodb.client.model.Filters
|
|
||||||
import com.mongodb.client.model.Sorts
|
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
@ -69,7 +63,7 @@ class AnimeService(
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(response))
|
call.respond(HttpStatusCode.OK, Json.encodeToString(response))
|
||||||
} else {
|
} else {
|
||||||
val animes = directoryCollection
|
val animes = directoryCollection
|
||||||
.find(Filters.eq("type", type.uppercase()))
|
.find(eq("type", type.uppercase()))
|
||||||
.skip(skipCount)
|
.skip(skipCount)
|
||||||
.limit(size)
|
.limit(size)
|
||||||
.toList()
|
.toList()
|
||||||
|
@ -90,7 +84,7 @@ class AnimeService(
|
||||||
|
|
||||||
suspend fun getAnimeByMalId(call: RoutingCall) = try {
|
suspend fun getAnimeByMalId(call: RoutingCall) = try {
|
||||||
val id = call.parameters["id"]?.toInt() ?: throw IllegalArgumentException(ErrorMessages.InvalidMalId.message)
|
val id = call.parameters["id"]?.toInt() ?: throw IllegalArgumentException(ErrorMessages.InvalidMalId.message)
|
||||||
directoryCollection.find(Filters.eq("malId", id)).firstOrNull()?.let { anime ->
|
directoryCollection.find(eq("malId", id)).firstOrNull()?.let { anime ->
|
||||||
val info = documentToMoreInfoEntity(anime)
|
val info = documentToMoreInfoEntity(anime)
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(info))
|
call.respond(HttpStatusCode.OK, Json.encodeToString(info))
|
||||||
} ?: call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.AnimeNotFound.message))
|
} ?: call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.AnimeNotFound.message))
|
||||||
|
@ -98,42 +92,6 @@ class AnimeService(
|
||||||
call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.InvalidInput.message))
|
call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.InvalidInput.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getRandomAnime(call: RoutingCall) = try {
|
|
||||||
val nsfw = call.request.queryParameters["nsfw"]?.toBoolean() ?: false
|
|
||||||
|
|
||||||
val filters = mutableListOf<org.bson.conversions.Bson>().apply {
|
|
||||||
add(Filters.`in`("type", listOf(
|
|
||||||
AnimeTypes.TV,
|
|
||||||
AnimeTypes.MOVIE,
|
|
||||||
AnimeTypes.OVA,
|
|
||||||
AnimeTypes.SPECIAL,
|
|
||||||
AnimeTypes.ONA,
|
|
||||||
AnimeTypes.TV_SPECIAL
|
|
||||||
)))
|
|
||||||
|
|
||||||
add(Filters.nin("status", listOf(
|
|
||||||
AnimeStatusTypes.UPCOMING
|
|
||||||
)))
|
|
||||||
|
|
||||||
if (!nsfw) add(Filters.eq("nsfw", false))
|
|
||||||
}
|
|
||||||
|
|
||||||
val aggregates = listOf(
|
|
||||||
Aggregates.match(Filters.and(filters)),
|
|
||||||
Aggregates.sample(1)
|
|
||||||
)
|
|
||||||
|
|
||||||
directoryCollection.aggregate(aggregates).firstOrNull()?.let { anime ->
|
|
||||||
val info = documentToMoreInfoEntity(anime)
|
|
||||||
|
|
||||||
call.response.headers.append("Cache-Control", "no-store")
|
|
||||||
|
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(info))
|
|
||||||
} ?: call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.AnimeNotFound.message))
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.InvalidInput.message))
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getLastEpisodes(call: RoutingCall) = try {
|
suspend fun getLastEpisodes(call: RoutingCall) = try {
|
||||||
val dayOfWeek = LocalDate.now()
|
val dayOfWeek = LocalDate.now()
|
||||||
.dayOfWeek
|
.dayOfWeek
|
||||||
|
@ -152,42 +110,38 @@ class AnimeService(
|
||||||
if (needsUpdate) {
|
if (needsUpdate) {
|
||||||
collection.deleteMany(Document())
|
collection.deleteMany(Document())
|
||||||
|
|
||||||
val animes = mutableListOf<LastEpisodeEntity>()
|
val response = RestClient.request(
|
||||||
|
BaseUrls.JIKAN + "anime?status=airing&type=tv",
|
||||||
RestClient.request(
|
|
||||||
BaseUrls.JIKAN + "anime?status=airing&type=tv&page=1",
|
|
||||||
AnimeSearch.serializer()
|
AnimeSearch.serializer()
|
||||||
).let { firstPage ->
|
)
|
||||||
val totalPage = firstPage.pagination?.lastPage ?: 2
|
|
||||||
|
|
||||||
firstPage.data?.let { firstAnimes ->
|
val animes = mutableListOf<LastEpisodeEntity>()
|
||||||
firstAnimes.map { it.toLastEpisodeData() }.let { animes.addAll(it) }
|
val totalPage = response.pagination?.lastPage ?: 0
|
||||||
}
|
response.data?.map { it.toLastEpisodeData() }.orEmpty().let { animes.addAll(it) }
|
||||||
|
|
||||||
for (page in 2..totalPage) {
|
for (page in 2..totalPage) {
|
||||||
RestClient.request(
|
val responsePage = RestClient.request(
|
||||||
BaseUrls.JIKAN + "anime?status=airing&type=tv&page=$page",
|
BaseUrls.JIKAN + "anime?status=airing&type=tv&page=$page",
|
||||||
AnimeSearch.serializer()
|
AnimeSearch.serializer()
|
||||||
).data?.let { pagesAnimes ->
|
).data?.map { it.toLastEpisodeData() }.orEmpty()
|
||||||
animes.addAll(pagesAnimes.map { it.toLastEpisodeData() })
|
|
||||||
|
animes.addAll(responsePage)
|
||||||
delay(1000)
|
delay(1000)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val documentsToInsert = parseDataToDocuments(animes.distinctBy { it.malId }, LastEpisodeEntity.serializer())
|
val documentsToInsert = parseDataToDocuments(animes, LastEpisodeEntity.serializer())
|
||||||
if (documentsToInsert.isNotEmpty()) collection.insertMany(documentsToInsert)
|
if (documentsToInsert.isNotEmpty()) collection.insertMany(documentsToInsert)
|
||||||
timers.update(timerKey)
|
timers.update(timerKey)
|
||||||
|
|
||||||
val queryDb = collection
|
val queryDb = collection
|
||||||
.find(Filters.eq("day", dayOfWeek))
|
.find(eq("day", dayOfWeek))
|
||||||
.toList()
|
.toList()
|
||||||
|
|
||||||
val elements = queryDb.map { documentToAnimeLastEpisodeEntity(it) }
|
val elements = queryDb.map { documentToAnimeLastEpisodeEntity(it) }
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(elements))
|
call.respond(HttpStatusCode.OK, Json.encodeToString(elements))
|
||||||
} else {
|
} else {
|
||||||
val elements = collection
|
val elements = collection
|
||||||
.find(Filters.eq("day", dayOfWeek))
|
.find(eq("day", dayOfWeek))
|
||||||
.toList()
|
.toList()
|
||||||
.map { documentToAnimeLastEpisodeEntity(it) }
|
.map { documentToAnimeLastEpisodeEntity(it) }
|
||||||
|
|
||||||
|
@ -196,25 +150,4 @@ class AnimeService(
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
call.respond(HttpStatusCode.Unauthorized, ErrorResponse(ErrorMessages.UnauthorizedMongo.message))
|
call.respond(HttpStatusCode.Unauthorized, ErrorResponse(ErrorMessages.UnauthorizedMongo.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getAnimeByType(call: RoutingCall) = try {
|
|
||||||
val type = call.request.queryParameters["type"] ?: throw IllegalArgumentException(ErrorMessages.InvalidTopAnimeType.message)
|
|
||||||
val status = call.request.queryParameters["status"] ?: throw IllegalArgumentException(ErrorMessages.InvalidAnimeStatusType.message)
|
|
||||||
val nsfw = call.request.queryParameters["nsfw"].toBoolean()
|
|
||||||
|
|
||||||
val animes = directoryCollection.find(
|
|
||||||
Filters.and(
|
|
||||||
Filters.eq("type", parseAnimeType(type)),
|
|
||||||
Filters.eq("status", parseAnimeStatusType(status)),
|
|
||||||
Filters.eq("nsfw", nsfw),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.sort(Sorts.descending("aired.from"))
|
|
||||||
.toList()
|
|
||||||
|
|
||||||
val elements = animes.map { documentToSimpleAnimeEntity(it) }
|
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(elements))
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.InvalidInput.message))
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -4,10 +4,9 @@ import com.jeluchu.core.enums.TimeUnit
|
||||||
import com.jeluchu.core.enums.parseAnimeType
|
import com.jeluchu.core.enums.parseAnimeType
|
||||||
import com.jeluchu.core.extensions.*
|
import com.jeluchu.core.extensions.*
|
||||||
import com.jeluchu.core.messages.ErrorMessages
|
import com.jeluchu.core.messages.ErrorMessages
|
||||||
|
import com.jeluchu.core.models.PaginationResponse
|
||||||
import com.jeluchu.core.utils.Collections
|
import com.jeluchu.core.utils.Collections
|
||||||
import com.jeluchu.core.utils.TimerKey
|
import com.jeluchu.core.utils.TimerKey
|
||||||
import com.jeluchu.core.utils.getLocalData
|
|
||||||
import com.jeluchu.core.utils.getRemoteData
|
|
||||||
import com.jeluchu.features.anime.mappers.documentToAnimeDirectoryEntity
|
import com.jeluchu.features.anime.mappers.documentToAnimeDirectoryEntity
|
||||||
import com.mongodb.client.MongoCollection
|
import com.mongodb.client.MongoCollection
|
||||||
import com.mongodb.client.MongoDatabase
|
import com.mongodb.client.MongoDatabase
|
||||||
|
@ -18,6 +17,7 @@ import io.ktor.server.routing.*
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.bson.Document
|
import org.bson.Document
|
||||||
|
import org.bson.conversions.Bson
|
||||||
|
|
||||||
class DirectoryService(
|
class DirectoryService(
|
||||||
private val database: MongoDatabase,
|
private val database: MongoDatabase,
|
||||||
|
@ -58,4 +58,83 @@ class DirectoryService(
|
||||||
onQuerySuccess = { data -> call.respond(HttpStatusCode.OK, Json.encodeToString(data)) }
|
onQuerySuccess = { data -> call.respond(HttpStatusCode.OK, Json.encodeToString(data)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getAnimeBySeason(call: RoutingCall) {
|
||||||
|
val year = call.getIntSafeParam("year")
|
||||||
|
val season = call.getStringSafeParam("season")
|
||||||
|
val page = call.getIntSafeQueryParam("page", 1)
|
||||||
|
val size = call.getIntSafeQueryParam("size", 10)
|
||||||
|
|
||||||
|
val skipCount = (page - 1) * size
|
||||||
|
val timerKey = "${TimerKey.ANIME_TYPE}${year}_${season.lowercase()}"
|
||||||
|
val collection = database.getCollection(timerKey)
|
||||||
|
if (page < 1 || size < 1) call.badRequestError(ErrorMessages.InvalidSizeAndPage.message)
|
||||||
|
|
||||||
|
if (timers.needsUpdate(timerKey, 30, TimeUnit.DAY)) {
|
||||||
|
getRemoteData(
|
||||||
|
newCollection = collection,
|
||||||
|
remoteCollection = directory,
|
||||||
|
mapper = { documentToAnimeDirectoryEntity(it) },
|
||||||
|
filters = Filters.and(
|
||||||
|
Filters.eq("year", year),
|
||||||
|
Filters.eq("season", season.lowercase())
|
||||||
|
),
|
||||||
|
onQuerySuccess = { data ->
|
||||||
|
val documents = data.map { Document.parse(Json.encodeToString(it)) }
|
||||||
|
if (documents.isNotEmpty()) collection.insertMany(documents)
|
||||||
|
timers.update(timerKey)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
getLocalData(
|
||||||
|
page = page,
|
||||||
|
size = size,
|
||||||
|
skipCount = skipCount,
|
||||||
|
collection = collection,
|
||||||
|
mapper = { documentToAnimeDirectoryEntity(it) },
|
||||||
|
onQuerySuccess = { data -> call.respond(HttpStatusCode.OK, Json.encodeToString(data)) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> getRemoteData(
|
||||||
|
filters: Bson,
|
||||||
|
mapper: (Document) -> T,
|
||||||
|
onQuerySuccess: (List<T>) -> Unit,
|
||||||
|
newCollection: MongoCollection<Document>,
|
||||||
|
remoteCollection: MongoCollection<Document>,
|
||||||
|
) {
|
||||||
|
newCollection.deleteMany(Document())
|
||||||
|
|
||||||
|
val query = remoteCollection
|
||||||
|
.find(filters)
|
||||||
|
.toList()
|
||||||
|
.map { mapper(it) }
|
||||||
|
|
||||||
|
onQuerySuccess(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun <T> getLocalData(
|
||||||
|
page: Int,
|
||||||
|
size: Int,
|
||||||
|
skipCount: Int,
|
||||||
|
mapper: (Document) -> T,
|
||||||
|
collection: MongoCollection<Document>,
|
||||||
|
onQuerySuccess: suspend (PaginationResponse<T>) -> Unit
|
||||||
|
) {
|
||||||
|
val query = collection
|
||||||
|
.find()
|
||||||
|
.skip(skipCount)
|
||||||
|
.limit(size)
|
||||||
|
.toList()
|
||||||
|
.map { mapper(it) }
|
||||||
|
|
||||||
|
val paginate = PaginationResponse(
|
||||||
|
page = page,
|
||||||
|
data = query,
|
||||||
|
size = query.size
|
||||||
|
)
|
||||||
|
|
||||||
|
onQuerySuccess(paginate)
|
||||||
}
|
}
|
|
@ -1,83 +0,0 @@
|
||||||
package com.jeluchu.features.anime.services
|
|
||||||
|
|
||||||
import com.jeluchu.core.enums.parseSeasons
|
|
||||||
import com.jeluchu.core.models.documentToSimpleAnimeEntity
|
|
||||||
import com.jeluchu.core.utils.Collections
|
|
||||||
import com.jeluchu.core.utils.SeasonCalendar
|
|
||||||
import com.jeluchu.features.anime.models.seasons.YearSeasons
|
|
||||||
import com.mongodb.client.MongoCollection
|
|
||||||
import com.mongodb.client.MongoDatabase
|
|
||||||
import com.mongodb.client.model.Accumulators
|
|
||||||
import com.mongodb.client.model.Aggregates
|
|
||||||
import com.mongodb.client.model.Filters
|
|
||||||
import com.mongodb.client.model.Sorts
|
|
||||||
import io.ktor.http.*
|
|
||||||
import io.ktor.server.response.*
|
|
||||||
import io.ktor.server.routing.*
|
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import org.bson.Document
|
|
||||||
import java.time.Year
|
|
||||||
|
|
||||||
class SeasonService(
|
|
||||||
private val database: MongoDatabase,
|
|
||||||
private val directory: MongoCollection<Document> = database.getCollection(Collections.ANIME_DIRECTORY)
|
|
||||||
) {
|
|
||||||
suspend fun getAnimeBySeason(call: RoutingCall) {
|
|
||||||
val year = call.request.queryParameters["year"]?.toInt() ?: SeasonCalendar.currentYear
|
|
||||||
val station = parseSeasons(call.request.queryParameters["station"] ?: SeasonCalendar.currentSeason.name)
|
|
||||||
?: SeasonCalendar.currentSeason
|
|
||||||
|
|
||||||
val query = directory.find(
|
|
||||||
Filters.and(
|
|
||||||
Filters.eq("season.year", year),
|
|
||||||
Filters.eq("season.station", station),
|
|
||||||
Filters.ne("type", "MUSIC"),
|
|
||||||
Filters.ne("type", "PV"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.toList()
|
|
||||||
.map { documentToSimpleAnimeEntity(it) }
|
|
||||||
|
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(query))
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getYearsAndSeasons(call: RoutingCall) {
|
|
||||||
val currentYear = Year.now().value
|
|
||||||
val validSeasons = listOf("SUMMER", "FALL", "WINTER", "SPRING")
|
|
||||||
|
|
||||||
val pipeline = listOf(
|
|
||||||
Aggregates.match(
|
|
||||||
Document(
|
|
||||||
"\$and", listOf(
|
|
||||||
Document("season.year", Document("\$gt", 0)),
|
|
||||||
Document("season.year", Document("\$lte", currentYear)),
|
|
||||||
Document("season.station", Document("\$in", validSeasons))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Aggregates.group(
|
|
||||||
"\$season.year",
|
|
||||||
Accumulators.addToSet("seasons", "\$season.station")
|
|
||||||
),
|
|
||||||
Aggregates.project(
|
|
||||||
Document().apply {
|
|
||||||
put("year", "\$_id")
|
|
||||||
put("seasons", 1)
|
|
||||||
put("_id", 0)
|
|
||||||
}
|
|
||||||
),
|
|
||||||
Aggregates.sort(Sorts.descending("year"))
|
|
||||||
)
|
|
||||||
|
|
||||||
val results = directory.aggregate(pipeline).toList()
|
|
||||||
val index = results.map { document ->
|
|
||||||
YearSeasons(
|
|
||||||
year = document.getInteger("year"),
|
|
||||||
seasons = document.getList("seasons", String::class.java)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(index))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package com.jeluchu.features.anime.services
|
|
||||||
|
|
||||||
import com.jeluchu.core.enums.AnimeStatusTypes
|
|
||||||
import com.jeluchu.core.enums.AnimeTypes
|
|
||||||
import com.jeluchu.core.models.documentToSimpleAnimeEntity
|
|
||||||
import com.jeluchu.core.utils.Collections
|
|
||||||
import com.mongodb.client.MongoCollection
|
|
||||||
import com.mongodb.client.MongoDatabase
|
|
||||||
import com.mongodb.client.model.Filters
|
|
||||||
import io.ktor.http.*
|
|
||||||
import io.ktor.server.response.*
|
|
||||||
import io.ktor.server.routing.*
|
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import org.bson.Document
|
|
||||||
|
|
||||||
class TagsService(
|
|
||||||
private val database: MongoDatabase,
|
|
||||||
private val directory: MongoCollection<Document> = database.getCollection(Collections.ANIME_DIRECTORY)
|
|
||||||
) {
|
|
||||||
suspend fun getAnimeByAnyTag(call: RoutingCall) {
|
|
||||||
val tags = call.request.queryParameters["tags"].orEmpty()
|
|
||||||
val nsfw = call.request.queryParameters["nsfw"].toBoolean()
|
|
||||||
|
|
||||||
val tagsList = if (tags.isNotEmpty()) {
|
|
||||||
tags.split(",").map { it.trim() }
|
|
||||||
} else emptyList()
|
|
||||||
|
|
||||||
if (tagsList.isEmpty()) {
|
|
||||||
call.respond(HttpStatusCode.BadRequest, "No tags provided")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val filters = mutableListOf<org.bson.conversions.Bson>().apply {
|
|
||||||
add(Filters.or(
|
|
||||||
Filters.`in`("tags.es", tagsList),
|
|
||||||
Filters.`in`("tags.en", tagsList)
|
|
||||||
))
|
|
||||||
|
|
||||||
add(Filters.`in`("status", listOf(AnimeStatusTypes.FINISHED, AnimeStatusTypes.ONGOING)))
|
|
||||||
|
|
||||||
add(Filters.ne("type", AnimeTypes.MUSIC))
|
|
||||||
add(Filters.ne("type", AnimeTypes.PV))
|
|
||||||
add(Filters.ne("type", AnimeTypes.CM))
|
|
||||||
|
|
||||||
if (!nsfw) add(Filters.eq("nsfw", false))
|
|
||||||
}
|
|
||||||
|
|
||||||
val query = directory.find(Filters.and(filters))
|
|
||||||
.toList()
|
|
||||||
.map { documentToSimpleAnimeEntity(it) }
|
|
||||||
|
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(query))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,10 +12,6 @@ fun Route.rankingsEndpoints(
|
||||||
) = route(Routes.TOP) {
|
) = route(Routes.TOP) {
|
||||||
route(Routes.ANIME) {
|
route(Routes.ANIME) {
|
||||||
getToJson { service.getAnimeRanking(call) }
|
getToJson { service.getAnimeRanking(call) }
|
||||||
|
|
||||||
route(Routes.TOP_TEN) {
|
|
||||||
getToJson { service.getAnimeTopTenRanking(call) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
route(Routes.MANGA) {
|
route(Routes.MANGA) {
|
||||||
getToJson { service.getMangaRanking(call) }
|
getToJson { service.getMangaRanking(call) }
|
||||||
|
|
|
@ -43,7 +43,6 @@ class RankingsService(
|
||||||
private val mangaRanking = database.getCollection(Collections.MANGA_RANKING)
|
private val mangaRanking = database.getCollection(Collections.MANGA_RANKING)
|
||||||
private val peopleRanking = database.getCollection(Collections.PEOPLE_RANKING)
|
private val peopleRanking = database.getCollection(Collections.PEOPLE_RANKING)
|
||||||
private val characterRanking = database.getCollection(Collections.CHARACTER_RANKING)
|
private val characterRanking = database.getCollection(Collections.CHARACTER_RANKING)
|
||||||
private val animeRankingTopTen = database.getCollection(Collections.ANIME_RANKING_TOP_TEN)
|
|
||||||
|
|
||||||
suspend fun getAnimeRanking(call: RoutingCall) {
|
suspend fun getAnimeRanking(call: RoutingCall) {
|
||||||
val filter = call.request.queryParameters["filter"] ?: "airing"
|
val filter = call.request.queryParameters["filter"] ?: "airing"
|
||||||
|
@ -328,65 +327,4 @@ class RankingsService(
|
||||||
call.respond(HttpStatusCode.OK, Json.encodeToString(response))
|
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<String>()
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -11,7 +11,6 @@ import com.jeluchu.core.models.ErrorResponse
|
||||||
import com.jeluchu.core.models.jikan.anime.AnimeData.Companion.toDayEntity
|
import com.jeluchu.core.models.jikan.anime.AnimeData.Companion.toDayEntity
|
||||||
import com.jeluchu.core.utils.*
|
import com.jeluchu.core.utils.*
|
||||||
import com.jeluchu.features.anime.mappers.documentToScheduleDayEntity
|
import com.jeluchu.features.anime.mappers.documentToScheduleDayEntity
|
||||||
import com.jeluchu.features.schedule.models.DayEntity
|
|
||||||
import com.jeluchu.features.schedule.models.ScheduleData
|
import com.jeluchu.features.schedule.models.ScheduleData
|
||||||
import com.jeluchu.features.schedule.models.ScheduleEntity
|
import com.jeluchu.features.schedule.models.ScheduleEntity
|
||||||
import com.mongodb.client.MongoDatabase
|
import com.mongodb.client.MongoDatabase
|
||||||
|
@ -38,20 +37,22 @@ class ScheduleService(
|
||||||
|
|
||||||
if (needsUpdate) {
|
if (needsUpdate) {
|
||||||
schedules.deleteMany(Document())
|
schedules.deleteMany(Document())
|
||||||
val documents = mutableListOf<Document>()
|
|
||||||
|
|
||||||
Day.entries.forEach { day ->
|
val response = ScheduleData(
|
||||||
val animes = getSchedule(day).data?.map { it.toDayEntity(day) }.orEmpty()
|
sunday = getSchedule(Day.SUNDAY).data?.map { it.toDayEntity(Day.SUNDAY) }.orEmpty(),
|
||||||
val documentsToInsert = parseDataToDocuments(animes, DayEntity.serializer())
|
friday = getSchedule(Day.FRIDAY).data?.map { it.toDayEntity(Day.FRIDAY) }.orEmpty(),
|
||||||
if (documentsToInsert.isNotEmpty()) {
|
monday = getSchedule(Day.MONDAY).data?.map { it.toDayEntity(Day.MONDAY) }.orEmpty(),
|
||||||
documents.addAll(documentsToInsert)
|
tuesday = getSchedule(Day.TUESDAY).data?.map { it.toDayEntity(Day.TUESDAY) }.orEmpty(),
|
||||||
schedules.insertMany(documentsToInsert)
|
thursday = getSchedule(Day.THURSDAY).data?.map { it.toDayEntity(Day.THURSDAY) }.orEmpty(),
|
||||||
}
|
saturday = getSchedule(Day.SATURDAY).data?.map { it.toDayEntity(Day.SATURDAY) }.orEmpty(),
|
||||||
}
|
wednesday = getSchedule(Day.WEDNESDAY).data?.map { it.toDayEntity(Day.WEDNESDAY) }.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
|
val elements = parseTopDataToDocuments(response)
|
||||||
|
if (elements.isNotEmpty()) schedules.insertMany(elements)
|
||||||
timers.update(TimerKey.SCHEDULE)
|
timers.update(TimerKey.SCHEDULE)
|
||||||
|
|
||||||
call.respond(HttpStatusCode.OK, documents.documentWeekMapper())
|
call.respond(HttpStatusCode.OK, elements.documentWeekMapper())
|
||||||
} else {
|
} else {
|
||||||
val elements = schedules.find().toList()
|
val elements = schedules.find().toList()
|
||||||
call.respond(HttpStatusCode.OK, elements.documentWeekMapper())
|
call.respond(HttpStatusCode.OK, elements.documentWeekMapper())
|
||||||
|
@ -77,16 +78,7 @@ class ScheduleService(
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun List<Document>.documentWeekMapper(): String {
|
private fun List<Document>.documentWeekMapper(): String {
|
||||||
val elements = map { documentToScheduleDayEntity(it) }
|
val directory = map { documentToScheduleDayEntity(it) }
|
||||||
|
return Json.encodeToString(directory)
|
||||||
return Json.encodeToString(ScheduleData(
|
|
||||||
monday = elements.filter { it.day == Day.MONDAY.name.lowercase() }.distinctBy { it.malId },
|
|
||||||
tuesday = elements.filter { it.day == Day.TUESDAY.name.lowercase() }.distinctBy { it.malId },
|
|
||||||
wednesday = elements.filter { it.day == Day.WEDNESDAY.name.lowercase() }.distinctBy { it.malId },
|
|
||||||
thursday = elements.filter { it.day == Day.THURSDAY.name.lowercase() }.distinctBy { it.malId },
|
|
||||||
friday = elements.filter { it.day == Day.FRIDAY.name.lowercase() }.distinctBy { it.malId },
|
|
||||||
saturday = elements.filter { it.day == Day.SATURDAY.name.lowercase() }.distinctBy { it.malId },
|
|
||||||
sunday = elements.filter { it.day == Day.SUNDAY.name.lowercase() }.distinctBy { it.malId }
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue