mirror of https://github.com/aruppi/aruppi-api.git
parent
e40894d0e0
commit
03842ab1f9
@ -0,0 +1,11 @@
|
||||
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) }
|
@ -0,0 +1,8 @@
|
||||
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) }
|
@ -0,0 +1,47 @@
|
||||
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)
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
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
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.jeluchu.features.anime.mappers
|
||||
|
||||
import com.jeluchu.core.extensions.getIntSafe
|
||||
import com.jeluchu.core.extensions.getStringSafe
|
||||
import com.jeluchu.features.anime.models.seasons.SeasonAnimeEntity
|
||||
import org.bson.Document
|
||||
|
||||
fun documentToSeasonEntity(doc: Document) = SeasonAnimeEntity(
|
||||
score = doc.getStringSafe("score"),
|
||||
malId = doc.getIntSafe("malId"),
|
||||
image = doc.getStringSafe("poster"),
|
||||
title = doc.getStringSafe("title")
|
||||
)
|
@ -0,0 +1,11 @@
|
||||
package com.jeluchu.features.anime.models.seasons
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SeasonAnimeEntity(
|
||||
val malId: Int,
|
||||
val title: String,
|
||||
val image: String,
|
||||
val score: String,
|
||||
)
|
@ -0,0 +1,10 @@
|
||||
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>
|
||||
)
|
@ -0,0 +1,92 @@
|
||||
package com.jeluchu.features.anime.services
|
||||
|
||||
import com.jeluchu.core.enums.TimeUnit
|
||||
import com.jeluchu.core.enums.parseSeasons
|
||||
import com.jeluchu.core.extensions.badRequestError
|
||||
import com.jeluchu.core.extensions.getIntSafeQueryParam
|
||||
import com.jeluchu.core.extensions.needsUpdate
|
||||
import com.jeluchu.core.extensions.update
|
||||
import com.jeluchu.core.messages.ErrorMessages
|
||||
import com.jeluchu.core.utils.*
|
||||
import com.jeluchu.features.anime.mappers.documentToAnimeDirectoryEntity
|
||||
import com.jeluchu.features.anime.mappers.documentToSeasonEntity
|
||||
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["season"] ?: SeasonCalendar.currentSeason.name) ?: SeasonCalendar.currentSeason
|
||||
val page = call.getIntSafeQueryParam("page", 1)
|
||||
val size = call.getIntSafeQueryParam("size", 10)
|
||||
|
||||
val skipCount = (page - 1) * size
|
||||
if (page < 1 || size < 1) call.badRequestError(ErrorMessages.InvalidSizeAndPage.message)
|
||||
|
||||
val query = directory.find(
|
||||
Filters.and(
|
||||
Filters.eq("season.year", year),
|
||||
Filters.eq("season.station", station)
|
||||
)
|
||||
)
|
||||
.toList()
|
||||
.map { documentToSeasonEntity(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))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue