@@ -8,110 +8,212 @@ import kotlinx.serialization.Serializable
88import java.text.SimpleDateFormat
99import java.util.Locale
1010
11+ @Serializable
12+ class GenreDto (
13+ val id : String ,
14+ @SerialName(" genre_name" )
15+ val genreName : String ,
16+ )
17+
18+ @Serializable
19+ class TagDto (
20+ val id : String ,
21+ @SerialName(" tag_name" )
22+ val tagName : String ,
23+ )
24+
25+ @Serializable
26+ class SourcesDto (
27+ val sources : List <SourceDto >,
28+ )
29+
30+ @Serializable
31+ class SourceDto (
32+ @SerialName(" source_id" )
33+ val sourceId : String ,
34+ val title : String ,
35+ @SerialName(" source_type" )
36+ val sourceType : String ,
37+ )
38+
1139@Serializable
1240class SearchDto (
13- val content : List <Book >,
14- val last : Boolean ,
41+ val content : List <Book > = emptyList(),
42+ val last : Boolean = true ,
43+ @SerialName(" total_elements" )
44+ val totalElements : Int = 0 ,
45+ @SerialName(" total_pages" )
46+ val totalPages : Int = 0 ,
1547) {
1648 fun hasNextPage () = ! last
1749
1850 @Serializable
1951 class Book (
52+ @SerialName(" series_id" )
2053 val id : String ,
21- val name : String ,
22- val source : String ,
23- @SerialName(" books_count" )
54+ val title : String ,
55+ @SerialName(" source_id" )
56+ val sourceId : String? = null ,
57+ @SerialName(" current_books" )
2458 val booksCount : Int ,
25- @SerialName(" release_date" )
26- val releaseDate : String? ,
59+ @SerialName(" start_year" )
60+ val startYear : Int? = null ,
61+ @SerialName(" cover_image_id" )
62+ val coverImage : String? = null ,
63+ @SerialName(" alternate_titles" )
64+ val alternateTitles : List <String > = emptyList(),
2765 ) {
2866
29- fun toSManga (domain : String , showSource : Boolean ): SManga = SManga .create().apply {
30- title = if (showSource) " ${name. trim()} [$source ] " else name
67+ fun toSManga (domain : String , showSource : Boolean , sources : Map < String , String > ): SManga = SManga .create().apply {
68+ title = if (showSource) " ${this @Book.title. trim()} [${sources[ this @Book.sourceId]} ] " else this @Book.title.trim()
3169 url = id
32- thumbnail_url = " $domain /api/v1/series/ $id /thumbnail "
70+ thumbnail_url = coverImage?. let { " $domain /api/v2/image/ $it " }
3371 }
3472 }
3573}
3674
3775@Serializable
3876class AlternateSeries (
39- @SerialName(" books_count " )
77+ @SerialName(" current_books " )
4078 val booksCount : Int ,
41- @SerialName(" release_date " )
42- val releaseDate : String? ,
79+ @SerialName(" start_year " )
80+ val startYear : Int? = null ,
4381)
4482
4583@Serializable
4684class DetailsDto (
47- val source : String ,
48- val authors : List <String >,
49- val status : String ,
50- val summary : String? ,
51- val genres : List <String >,
52- @SerialName(" alternate_titles" )
53- val alternateTitles : List <AlternateTitles >,
85+ val title : String ,
86+ val description : String? ,
87+ @SerialName(" publication_status" )
88+ val publicationStatus : String ,
89+ @SerialName(" upload_status" )
90+ val uploadStatus : String ,
91+ val format : String? ,
92+ @SerialName(" source_id" )
93+ val sourceId : String? ,
94+ @SerialName(" series_staff" )
95+ val seriesStaff : List <SeriesStaff > = emptyList(),
96+ val genres : List <Genre > = emptyList(),
97+ val tags : List <Tag > = emptyList(),
98+ @SerialName(" series_alternate_titles" )
99+ val seriesAlternateTitles : List <AlternateTitle > = emptyList(),
100+ @SerialName(" series_books" )
101+ val seriesBooks : List <ChapterDto .Book > = emptyList(),
54102) {
55103 @Serializable
56- class AlternateTitles (
104+ class SeriesStaff (
105+ val name : String ,
106+ val role : String ,
107+ )
108+
109+ @Serializable
110+ class Genre (
111+ @SerialName(" genre_name" )
112+ val genreName : String ,
113+ )
114+
115+ @Serializable
116+ class Tag (
117+ @SerialName(" tag_name" )
118+ val tagName : String ,
119+ )
120+
121+ @Serializable
122+ class AlternateTitle (
57123 val title : String ,
124+ val label : String? ,
58125 )
59126
60- fun toSManga (): SManga = SManga .create().apply {
127+ fun toSManga (sourceName : String? = null ): SManga = SManga .create().apply {
61128 val desc = StringBuilder ()
62- if (! summary.isNullOrBlank()) desc.append(summary + " \n\n " )
63- desc.append(" Source: " ).append(source + " \n\n " )
64129
65- if (alternateTitles.isNotEmpty()) {
66- desc.append(" Associated Name(s):\n\n " )
67- alternateTitles.forEach { desc.append(" • ${it.title} \n " ) }
130+ // Add main description
131+ this @DetailsDto.description?.takeIf { it.isNotBlank() }?.let {
132+ desc.append(it.trim())
133+ desc.append(" \n " )
134+ }
135+
136+ // Add alternate titles at the end
137+ if (seriesAlternateTitles.isNotEmpty()) {
138+ if (desc.isNotEmpty()) desc.append(" \n " )
139+ desc.append(" Associated Name(s):\n " )
140+ seriesAlternateTitles.forEach {
141+ desc.append(" • ${it.title} \n " )
142+ }
143+ }
144+
145+ // Extract authors and artists from staff (roles like "Author", "Artist", "Story", "Art")
146+ val authors = seriesStaff.filter {
147+ it.role.contains(" Author" , ignoreCase = true ) || it.role.contains(" Story" , ignoreCase = true )
148+ }.map { it.name }.distinct()
149+ val artists = seriesStaff.filter {
150+ it.role.contains(" Artist" , ignoreCase = true ) || it.role.contains(" Art" , ignoreCase = true )
68151 }
152+ .map { it.name }
153+ .distinct()
154+ .joinToString(" , " )
69155
156+ artist = artists
70157 author = authors.joinToString()
71- description = desc.toString()
72- genre = ( listOf (source) + genres) .joinToString()
73- status = this @DetailsDto.status .toStatus()
158+ description = desc.toString().trim()
159+ genre = genres.joinToString { it.genreName }
160+ status = this @DetailsDto.publicationStatus .toStatus()
74161 }
75162
76- private fun String.toStatus (): Int {
77- return when (this ) {
78- " ONGOING" -> SManga .ONGOING
79- " ENDED" -> SManga .COMPLETED
80- " HIATUS" -> SManga .ON_HIATUS
81- else -> SManga .UNKNOWN
82- }
163+ private fun String.toStatus (): Int = when (this .uppercase()) {
164+ " ONGOING" -> SManga .ONGOING
165+ " COMPLETED" -> SManga .COMPLETED
166+ " HIATUS" -> SManga .ON_HIATUS
167+ " CANCELLED" -> SManga .CANCELLED
168+ else -> SManga .UNKNOWN
83169 }
84170}
85171
86172@Serializable
87173class ChapterDto (
88- val content : List <Book >,
174+ @SerialName(" series_books" )
175+ val seriesBooks : List <Book >,
89176) {
90177 @Serializable
91178 class Book (
179+ @SerialName(" book_id" )
92180 val id : String ,
93181 @SerialName(" series_id" )
94- val seriesId : String ,
182+ val seriesId : String? = null ,
95183 val title : String ,
96- @SerialName(" release_date " )
97- val releaseDate : String? ,
98- @SerialName(" pages_count " )
184+ @SerialName(" created_at " )
185+ val createdAt : String? ,
186+ @SerialName(" page_count " )
99187 val pagesCount : Int ,
100- @SerialName(" number_sort " )
188+ @SerialName(" sort_no " )
101189 val number : Float ,
190+ @SerialName(" chapter_no" )
191+ val chapterNo : String? ,
192+ @SerialName(" volume_no" )
193+ val volumeNo : String? ,
102194 ) {
103- fun toSChapter (useSourceChapterNumber : Boolean = false): SChapter = SChapter .create().apply {
104- url = " $seriesId ; $id ; $pagesCount "
105- name = title
106- date_upload = dateFormat.tryParse(releaseDate )
195+ fun toSChapter (actualSeriesId : String , useSourceChapterNumber : Boolean = false): SChapter = SChapter .create().apply {
196+ url = " /series/ $actualSeriesId /reader/ $id "
197+ name = buildChapterName()
198+ date_upload = dateFormat.tryParse(createdAt )
107199 if (useSourceChapterNumber) {
108200 chapter_number = number
109201 }
110202 }
203+
204+ private fun buildChapterName (): String = if (! chapterNo.isNullOrBlank()) {
205+ if (title.isNotBlank()) {
206+ " Chapter $chapterNo : $title "
207+ } else {
208+ " Chapter $chapterNo "
209+ }
210+ } else {
211+ title
212+ }
111213 }
112214
113215 companion object {
114- val dateFormat = SimpleDateFormat (" yyyy-MM-dd" , Locale .ENGLISH )
216+ val dateFormat = SimpleDateFormat (" yyyy-MM-dd'T'HH:mm:ss " , Locale .ENGLISH )
115217 }
116218}
117219
@@ -121,6 +223,19 @@ class ChallengeDto(
121223 val accessToken : String ,
122224 @SerialName(" cache_url" )
123225 val cacheUrl : String ,
124- @SerialName(" page_mapping" )
125- val pageMapping : Map <Int , String >,
226+ val pages : List <PageDto >,
227+ )
228+
229+ @Serializable
230+ class PageDto (
231+ @SerialName(" page_number" )
232+ val pageNumber : Int ,
233+ @SerialName(" page_uuid" )
234+ val pageUuid : String ,
235+ )
236+
237+ @Serializable
238+ class IntegrityDto (
239+ val token : String ,
240+ val exp : Long ,
126241)
0 commit comments