|
|
|
@ -1,8 +1,6 @@
|
|
|
|
|
package com.jeluchu.features.anime.services
|
|
|
|
|
|
|
|
|
|
import com.jeluchu.core.connection.RestClient
|
|
|
|
|
import com.jeluchu.core.enums.AnimeTypes
|
|
|
|
|
import com.jeluchu.core.enums.Day
|
|
|
|
|
import com.jeluchu.core.enums.TimeUnit
|
|
|
|
|
import com.jeluchu.core.enums.parseAnimeType
|
|
|
|
|
import com.jeluchu.core.extensions.needsUpdate
|
|
|
|
@ -10,26 +8,31 @@ import com.jeluchu.core.extensions.update
|
|
|
|
|
import com.jeluchu.core.messages.ErrorMessages
|
|
|
|
|
import com.jeluchu.core.models.ErrorResponse
|
|
|
|
|
import com.jeluchu.core.models.PaginationResponse
|
|
|
|
|
import com.jeluchu.core.models.animeflv.lastepisodes.LastEpisodeData.Companion.toEpisodeEntity
|
|
|
|
|
import com.jeluchu.core.models.animeflv.lastepisodes.LastEpisodes
|
|
|
|
|
import com.jeluchu.core.models.jikan.anime.AnimeData.Companion.toDayEntity
|
|
|
|
|
import com.jeluchu.features.anime.models.lastepisodes.LastEpisodeData
|
|
|
|
|
import com.jeluchu.features.anime.models.lastepisodes.LastEpisodeData.Companion.toLastEpisodeData
|
|
|
|
|
import com.jeluchu.core.models.jikan.search.AnimeSearch
|
|
|
|
|
import com.jeluchu.core.utils.BaseUrls
|
|
|
|
|
import com.jeluchu.core.utils.Collections
|
|
|
|
|
import com.jeluchu.core.utils.Endpoints
|
|
|
|
|
import com.jeluchu.core.utils.TimerKey
|
|
|
|
|
import com.jeluchu.features.anime.mappers.*
|
|
|
|
|
import com.jeluchu.features.schedule.models.ScheduleEntity
|
|
|
|
|
import com.jeluchu.core.utils.parseDataToDocuments
|
|
|
|
|
import com.jeluchu.features.anime.mappers.documentToAnimeLastEpisodeEntity
|
|
|
|
|
import com.jeluchu.features.anime.mappers.documentToAnimeTypeEntity
|
|
|
|
|
import com.jeluchu.features.anime.mappers.documentToMoreInfoEntity
|
|
|
|
|
import com.mongodb.client.MongoDatabase
|
|
|
|
|
import com.mongodb.client.model.Filters
|
|
|
|
|
import com.mongodb.client.model.Filters.eq
|
|
|
|
|
import io.ktor.http.*
|
|
|
|
|
import io.ktor.server.response.*
|
|
|
|
|
import io.ktor.server.routing.*
|
|
|
|
|
import kotlinx.coroutines.delay
|
|
|
|
|
import kotlinx.serialization.encodeToString
|
|
|
|
|
import kotlinx.serialization.json.Json
|
|
|
|
|
import org.bson.Document
|
|
|
|
|
import java.time.LocalDate
|
|
|
|
|
import java.time.format.TextStyle
|
|
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
|
|
class AnimeService(
|
|
|
|
|
database: MongoDatabase
|
|
|
|
|
private val database: MongoDatabase
|
|
|
|
|
) {
|
|
|
|
|
private val timers = database.getCollection(Collections.TIMERS)
|
|
|
|
|
private val directoryCollection = database.getCollection(Collections.ANIME_DETAILS)
|
|
|
|
@ -61,7 +64,7 @@ class AnimeService(
|
|
|
|
|
call.respond(HttpStatusCode.OK, Json.encodeToString(response))
|
|
|
|
|
} else {
|
|
|
|
|
val animes = directoryCollection
|
|
|
|
|
.find(Filters.eq("type", type.uppercase()))
|
|
|
|
|
.find(eq("type", type.uppercase()))
|
|
|
|
|
.skip(skipCount)
|
|
|
|
|
.limit(size)
|
|
|
|
|
.toList()
|
|
|
|
@ -82,7 +85,7 @@ class AnimeService(
|
|
|
|
|
|
|
|
|
|
suspend fun getAnimeByMalId(call: RoutingCall) = try {
|
|
|
|
|
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)
|
|
|
|
|
call.respond(HttpStatusCode.OK, Json.encodeToString(info))
|
|
|
|
|
} ?: call.respond(HttpStatusCode.NotFound, ErrorResponse(ErrorMessages.AnimeNotFound.message))
|
|
|
|
@ -91,36 +94,61 @@ class AnimeService(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
suspend fun getLastEpisodes(call: RoutingCall) = try {
|
|
|
|
|
val dayOfWeek = LocalDate.now()
|
|
|
|
|
.dayOfWeek
|
|
|
|
|
.getDisplayName(TextStyle.FULL, Locale.ENGLISH)
|
|
|
|
|
.plus("s")
|
|
|
|
|
|
|
|
|
|
val timerKey = TimerKey.LAST_EPISODES
|
|
|
|
|
val collection = database.getCollection(timerKey)
|
|
|
|
|
|
|
|
|
|
val needsUpdate = timers.needsUpdate(
|
|
|
|
|
amount = 3,
|
|
|
|
|
amount = 6,
|
|
|
|
|
key = timerKey,
|
|
|
|
|
unit = TimeUnit.HOUR,
|
|
|
|
|
key = TimerKey.LAST_EPISODES
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (needsUpdate) {
|
|
|
|
|
lastEpisodesCollection.deleteMany(Document())
|
|
|
|
|
collection.deleteMany(Document())
|
|
|
|
|
|
|
|
|
|
val response = RestClient.request(
|
|
|
|
|
BaseUrls.JIKAN + "anime?status=airing&type=tv",
|
|
|
|
|
AnimeSearch.serializer()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
val animes = mutableListOf<LastEpisodeData>()
|
|
|
|
|
val totalPage = response.pagination?.lastPage ?: 0
|
|
|
|
|
response.data?.map { it.toLastEpisodeData() }.orEmpty().let { animes.addAll(it) }
|
|
|
|
|
|
|
|
|
|
for (page in 2..totalPage) {
|
|
|
|
|
val responsePage = RestClient.request(
|
|
|
|
|
BaseUrls.JIKAN + "anime?status=airing&type=tv&page=$page",
|
|
|
|
|
AnimeSearch.serializer()
|
|
|
|
|
).data?.map { it.toLastEpisodeData() }.orEmpty()
|
|
|
|
|
|
|
|
|
|
animes.addAll(responsePage)
|
|
|
|
|
delay(1000)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val episodes = getLastedEpisodes().data?.map { it.toEpisodeEntity() }.orEmpty()
|
|
|
|
|
val documents = episodes.map { anime -> Document.parse(Json.encodeToString(anime)) }
|
|
|
|
|
if (documents.isNotEmpty()) lastEpisodesCollection.insertMany(documents)
|
|
|
|
|
timers.update(TimerKey.LAST_EPISODES)
|
|
|
|
|
val documentsToInsert = parseDataToDocuments(animes, LastEpisodeData.serializer())
|
|
|
|
|
if (documentsToInsert.isNotEmpty()) collection.insertMany(documentsToInsert)
|
|
|
|
|
timers.update(timerKey)
|
|
|
|
|
|
|
|
|
|
call.respond(HttpStatusCode.OK, Json.encodeToString(episodes))
|
|
|
|
|
val queryDb = collection
|
|
|
|
|
.find(eq("day", dayOfWeek))
|
|
|
|
|
.toList()
|
|
|
|
|
|
|
|
|
|
val elements = queryDb.map { documentToAnimeLastEpisodeEntity(it) }
|
|
|
|
|
call.respond(HttpStatusCode.OK, Json.encodeToString(elements))
|
|
|
|
|
} else {
|
|
|
|
|
val elements = lastEpisodesCollection.find().toList()
|
|
|
|
|
call.respond(HttpStatusCode.OK, elements.documentToLastEpisodesEntity())
|
|
|
|
|
val elements = collection
|
|
|
|
|
.find(eq("day", dayOfWeek))
|
|
|
|
|
.toList()
|
|
|
|
|
.map { documentToAnimeLastEpisodeEntity(it) }
|
|
|
|
|
|
|
|
|
|
call.respond(HttpStatusCode.OK, Json.encodeToString(elements))
|
|
|
|
|
}
|
|
|
|
|
} catch (ex: Exception) {
|
|
|
|
|
call.respond(HttpStatusCode.Unauthorized, ErrorResponse(ErrorMessages.UnauthorizedMongo.message))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private suspend fun getLastedEpisodes() = RestClient.requestWithDelay(
|
|
|
|
|
url = BaseUrls.ANIME_FLV + Endpoints.LAST_EPISODES,
|
|
|
|
|
deserializer = LastEpisodes.serializer()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
private fun List<Document>.documentToLastEpisodesEntity(): String {
|
|
|
|
|
val directory = map { documentToLastEpisodesEntity(it) }
|
|
|
|
|
return Json.encodeToString(directory)
|
|
|
|
|
}
|
|
|
|
|
}
|