K Manga: implement "latest" support (#11100)

K-Manga: implement "latest" support
This commit is contained in:
Trevor Paley 2025-10-17 10:35:33 -07:00 committed by Draff
parent e3449dfb65
commit 880b04047e
Signed by: Draff
GPG Key ID: E8A89F3211677653
3 changed files with 61 additions and 4 deletions

View File

@ -1,7 +1,7 @@
ext {
extName = 'K Manga'
extClass = '.KManga'
extVersionCode = 1
extVersionCode = 2
isNsfw = false
}

View File

@ -26,6 +26,18 @@ class TitleDetail(
@SerialName("banner_image_url") val bannerImageUrl: String? = null,
)
@Serializable
class LatestTitleListResponse(
@SerialName("title_list") val titleList: List<LatestTitleDetail>,
)
@Serializable
class LatestTitleDetail(
@SerialName("title_id") val titleId: Int,
@SerialName("title_name") val titleName: String,
@SerialName("thumbnail_rect_image_url") val thumbnailImageUrl: String? = null,
)
@Serializable
class BirthdayCookie(val value: String, val expires: Long)

View File

@ -31,14 +31,18 @@ import okio.ByteString.Companion.encodeUtf8
import rx.Observable
import java.net.URLDecoder
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.GregorianCalendar
import java.util.Locale
import java.util.TimeZone
class KManga : HttpSource() {
override val name = "K Manga"
override val baseUrl = "https://kmanga.kodansha.com"
override val lang = "en"
override val supportsLatest = false
override val supportsLatest = true
private val apiUrl = "https://api.kmanga.kodansha.com"
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
@ -102,6 +106,49 @@ class KManga : HttpSource() {
return MangasPage(mangas, hasNextPage)
}
// Latest
override fun latestUpdatesRequest(page: Int): Request {
val calendar = GregorianCalendar(TimeZone.getTimeZone("Asia/Tokyo")).apply {
time = Date()
add(Calendar.DAY_OF_MONTH, -(page - 1))
// Manga seems to usually update at 10 AM JST, so if we're before that time we should go
// back a day since we don't expect there to have been any updates today yet.
if (get(Calendar.HOUR_OF_DAY) < 10) {
add(Calendar.DAY_OF_MONTH, -1)
}
}
val dateString = buildString {
append(calendar.get(Calendar.YEAR))
append('-')
append((calendar.get(Calendar.MONTH) + 1).toString().padStart(2, '0'))
append('-')
append(calendar.get(Calendar.DAY_OF_MONTH).toString().padStart(2, '0'))
}
val url = apiUrl.toHttpUrl().newBuilder()
.addPathSegments("web/top/updated/title")
.addQueryParameter("base_date", dateString)
.build()
return hashedGet(url)
}
override fun latestUpdatesParse(response: Response): MangasPage {
val result = response.parseAs<LatestTitleListResponse>()
val manga = result.titleList.map { manga ->
SManga.create().apply {
url = "/title/${manga.titleId}"
title = manga.titleName
thumbnail_url = manga.thumbnailImageUrl
}
}
return MangasPage(manga, true)
}
// Search
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return if (query.startsWith(PREFIX_SEARCH)) {
@ -388,7 +435,5 @@ class KManga : HttpSource() {
}
// Unsupported
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException()
override fun latestUpdatesParse(response: Response) = throw UnsupportedOperationException()
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException()
}