1
1
package com.jeluchu.features.anime.services
2
2
3
3
import com.jeluchu.core.connection.RestClient
4
- import com.jeluchu.core.enums.AnimeTypes
5
- import com.jeluchu.core.enums.Day
6
4
import com.jeluchu.core.enums.TimeUnit
7
5
import com.jeluchu.core.enums.parseAnimeType
8
6
import com.jeluchu.core.extensions.needsUpdate
9
7
import com.jeluchu.core.extensions.update
10
8
import com.jeluchu.core.messages.ErrorMessages
11
9
import com.jeluchu.core.models.ErrorResponse
12
10
import com.jeluchu.core.models.PaginationResponse
13
- import com.jeluchu.core. models.animeflv. lastepisodes.LastEpisodeData.Companion.toEpisodeEntity
14
- import com.jeluchu.core. models.animeflv. lastepisodes.LastEpisodes
15
- import com.jeluchu.core.models.jikan.anime.AnimeData.Companion.toDayEntity
11
+ import com.jeluchu.features.anime. models.lastepisodes.LastEpisodeData
12
+ import com.jeluchu.features.anime. models.lastepisodes.LastEpisodeData.Companion.toLastEpisodeData
13
+ import com.jeluchu.core.models.jikan.search.AnimeSearch
16
14
import com.jeluchu.core.utils.BaseUrls
17
15
import com.jeluchu.core.utils.Collections
18
- import com.jeluchu.core.utils.Endpoints
19
16
import com.jeluchu.core.utils.TimerKey
20
- import com.jeluchu.features.anime.mappers.*
21
- import com.jeluchu.features.schedule.models.ScheduleEntity
17
+ import com.jeluchu.core.utils.parseDataToDocuments
18
+ import com.jeluchu.features.anime.mappers.documentToAnimeLastEpisodeEntity
19
+ import com.jeluchu.features.anime.mappers.documentToAnimeTypeEntity
20
+ import com.jeluchu.features.anime.mappers.documentToMoreInfoEntity
22
21
import com.mongodb.client.MongoDatabase
23
- import com.mongodb.client.model.Filters
22
+ import com.mongodb.client.model.Filters.eq
24
23
import io.ktor.http.*
25
24
import io.ktor.server.response.*
26
25
import io.ktor.server.routing.*
26
+ import kotlinx.coroutines.delay
27
27
import kotlinx.serialization.encodeToString
28
28
import kotlinx.serialization.json.Json
29
29
import org.bson.Document
30
+ import java.time.LocalDate
31
+ import java.time.format.TextStyle
32
+ import java.util.*
30
33
31
34
class AnimeService (
32
- database : MongoDatabase
35
+ private val database : MongoDatabase
33
36
) {
34
37
private val timers = database.getCollection(Collections .TIMERS )
35
38
private val directoryCollection = database.getCollection(Collections .ANIME_DETAILS )
@@ -61,7 +64,7 @@ class AnimeService(
61
64
call.respond(HttpStatusCode .OK , Json .encodeToString(response))
62
65
} else {
63
66
val animes = directoryCollection
64
- .find(Filters . eq(" type" , type.uppercase()))
67
+ .find(eq(" type" , type.uppercase()))
65
68
.skip(skipCount)
66
69
.limit(size)
67
70
.toList()
@@ -82,7 +85,7 @@ class AnimeService(
82
85
83
86
suspend fun getAnimeByMalId (call : RoutingCall ) = try {
84
87
val id = call.parameters[" id" ]?.toInt() ? : throw IllegalArgumentException (ErrorMessages .InvalidMalId .message)
85
- directoryCollection.find(Filters . eq(" malId" , id)).firstOrNull()?.let { anime ->
88
+ directoryCollection.find(eq(" malId" , id)).firstOrNull()?.let { anime ->
86
89
val info = documentToMoreInfoEntity(anime)
87
90
call.respond(HttpStatusCode .OK , Json .encodeToString(info))
88
91
} ? : call.respond(HttpStatusCode .NotFound , ErrorResponse (ErrorMessages .AnimeNotFound .message))
@@ -91,36 +94,61 @@ class AnimeService(
91
94
}
92
95
93
96
suspend fun getLastEpisodes (call : RoutingCall ) = try {
97
+ val dayOfWeek = LocalDate .now()
98
+ .dayOfWeek
99
+ .getDisplayName(TextStyle .FULL , Locale .ENGLISH )
100
+ .plus(" s" )
101
+
102
+ val timerKey = TimerKey .LAST_EPISODES
103
+ val collection = database.getCollection(timerKey)
104
+
94
105
val needsUpdate = timers.needsUpdate(
95
- amount = 3 ,
106
+ amount = 6 ,
107
+ key = timerKey,
96
108
unit = TimeUnit .HOUR ,
97
- key = TimerKey .LAST_EPISODES
98
109
)
99
110
100
111
if (needsUpdate) {
101
- lastEpisodesCollection.deleteMany(Document ())
112
+ collection.deleteMany(Document ())
113
+
114
+ val response = RestClient .request(
115
+ BaseUrls .JIKAN + " anime?status=airing&type=tv" ,
116
+ AnimeSearch .serializer()
117
+ )
118
+
119
+ val animes = mutableListOf<LastEpisodeData >()
120
+ val totalPage = response.pagination?.lastPage ? : 0
121
+ response.data?.map { it.toLastEpisodeData() }.orEmpty().let { animes.addAll(it) }
122
+
123
+ for (page in 2 .. totalPage) {
124
+ val responsePage = RestClient .request(
125
+ BaseUrls .JIKAN + " anime?status=airing&type=tv&page=$page " ,
126
+ AnimeSearch .serializer()
127
+ ).data?.map { it.toLastEpisodeData() }.orEmpty()
128
+
129
+ animes.addAll(responsePage)
130
+ delay(1000 )
131
+ }
102
132
103
- val episodes = getLastedEpisodes().data?.map { it.toEpisodeEntity() }.orEmpty()
104
- val documents = episodes.map { anime -> Document .parse(Json .encodeToString(anime)) }
105
- if (documents.isNotEmpty()) lastEpisodesCollection.insertMany(documents)
106
- timers.update(TimerKey .LAST_EPISODES )
133
+ val documentsToInsert = parseDataToDocuments(animes, LastEpisodeData .serializer())
134
+ if (documentsToInsert.isNotEmpty()) collection.insertMany(documentsToInsert)
135
+ timers.update(timerKey)
107
136
108
- call.respond(HttpStatusCode .OK , Json .encodeToString(episodes))
137
+ val queryDb = collection
138
+ .find(eq(" day" , dayOfWeek))
139
+ .toList()
140
+
141
+ val elements = queryDb.map { documentToAnimeLastEpisodeEntity(it) }
142
+ call.respond(HttpStatusCode .OK , Json .encodeToString(elements))
109
143
} else {
110
- val elements = lastEpisodesCollection.find().toList()
111
- call.respond(HttpStatusCode .OK , elements.documentToLastEpisodesEntity())
144
+ val elements = collection
145
+ .find(eq(" day" , dayOfWeek))
146
+ .toList()
147
+ .map { documentToAnimeLastEpisodeEntity(it) }
148
+
149
+ call.respond(HttpStatusCode .OK , Json .encodeToString(elements))
112
150
}
113
151
} catch (ex: Exception ) {
114
152
call.respond(HttpStatusCode .Unauthorized , ErrorResponse (ErrorMessages .UnauthorizedMongo .message))
115
153
}
116
-
117
- private suspend fun getLastedEpisodes () = RestClient .requestWithDelay(
118
- url = BaseUrls .ANIME_FLV + Endpoints .LAST_EPISODES ,
119
- deserializer = LastEpisodes .serializer()
120
- )
121
-
122
- private fun List<Document>.documentToLastEpisodesEntity (): String {
123
- val directory = map { documentToLastEpisodesEntity(it) }
124
- return Json .encodeToString(directory)
125
- }
126
154
}
0 commit comments