MangaTaro: migrate to new chapter endpoint (#11636)

This commit is contained in:
AwkwardPeak7 2025-11-14 22:29:44 +05:00 committed by Draff
parent 1aa1119924
commit 60e78280c8
Signed by: Draff
GPG Key ID: E8A89F3211677653
3 changed files with 70 additions and 19 deletions

View File

@ -1,7 +1,7 @@
ext {
extName = 'MangaTaro'
extClass = '.MangaTaro'
extVersionCode = 5
extVersionCode = 6
isNsfw = false
}

View File

@ -112,3 +112,19 @@ class Thumbnail(
class Rendered(
val rendered: String,
)
@Serializable
class ChapterList(
val chapters: List<Chapter>,
)
@Serializable
class Chapter(
val url: String,
val chapter: String,
val title: String? = null,
val date: String,
@SerialName("group_name")
val groupName: String? = null,
val language: String,
)

View File

@ -28,7 +28,12 @@ import org.jsoup.Jsoup
import org.jsoup.parser.Parser
import rx.Observable
import java.lang.UnsupportedOperationException
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.TimeZone
class MangaTaro : HttpSource() {
@ -232,37 +237,55 @@ class MangaTaro : HttpSource() {
}
override fun chapterListRequest(manga: SManga): Request {
val (id, slug) = manga.url.parseAs<MangaUrl>()
val timestamp = System.currentTimeMillis() / 1000
val token = md5(
"${timestamp}mng_ch_${isoDateFormatter.format(Date())}",
).substring(0, 16)
val mangaId = manga.url.parseAs<MangaUrl>().id
return GET("$baseUrl/manga/$slug#$id", headers)
val url = "$baseUrl/auth/manga-chapters".toHttpUrl().newBuilder().apply {
addQueryParameter("manga_id", mangaId)
addQueryParameter("offset", "0")
addQueryParameter("limit", "9999")
addQueryParameter("order", "DESC")
addQueryParameter("_t", token)
addQueryParameter("_ts", timestamp.toString())
}.build()
return GET(url, headers)
}
override fun chapterListParse(response: Response): List<SChapter> {
countViews(response.request.url.fragment!!)
countViews(response.request.url.queryParameter("manga_id")!!)
val document = response.asJsoup()
val placeholders = listOf("", "N/A", "")
val data = response.parseAs<ChapterList>()
val placeholders = listOf(null, "", "N/A", "")
var hasScanlator = false
val chapters = document.select(".chapter-list a").map {
// currently there is only English chapters on the site, at least from a quick look.
// if they ever have multiple languages, we would need to make this a source factory
val chapters = data.chapters.filter {
it.language == "en"
}.map {
SChapter.create().apply {
setUrlWithoutDomain(it.absUrl("href"))
val details = it.select("> div + div > div")
setUrlWithoutDomain(it.url)
name = buildString {
append(it.attr("title"))
details[1].text().also { title ->
append("Chapter ")
append(it.chapter)
it.title.also { title ->
if (title !in placeholders) {
append(": ", title)
}
}
}
it.attr("data-group-name").let { group ->
it.groupName.let { group ->
if (group !in placeholders) {
scanlator = group
hasScanlator = true
}
}
date_upload = details[3].text().parseRelativeDate()
date_upload = it.date.parseRelativeDate()
}
}
@ -285,6 +308,16 @@ class MangaTaro : HttpSource() {
}
}
fun md5(input: String): String {
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(input.toByteArray())
return digest.joinToString("") { "%02x".format(it) }
}
private val isoDateFormatter = SimpleDateFormat("yyyyMMddHH", Locale.US).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
private fun String.toSlug() = toHttpUrl().let { url ->
val path = url.pathSegments.filter(String::isNotBlank)
@ -301,17 +334,19 @@ class MangaTaro : HttpSource() {
?: return 0L
when (unit) {
"h" -> calendar.add(Calendar.HOUR, -amount.toInt())
"d" -> calendar.add(Calendar.DAY_OF_YEAR, -amount.toInt())
"w" -> calendar.add(Calendar.WEEK_OF_YEAR, -amount.toInt())
"mo" -> calendar.add(Calendar.MONTH, -amount.toInt())
"y" -> calendar.add(Calendar.YEAR, -amount.toInt())
"second" -> calendar.add(Calendar.SECOND, -amount.toInt())
"minute" -> calendar.add(Calendar.MINUTE, -amount.toInt())
"hour" -> calendar.add(Calendar.HOUR, -amount.toInt())
"day" -> calendar.add(Calendar.DAY_OF_YEAR, -amount.toInt())
"week" -> calendar.add(Calendar.WEEK_OF_YEAR, -amount.toInt())
"month" -> calendar.add(Calendar.MONTH, -amount.toInt())
"year" -> calendar.add(Calendar.YEAR, -amount.toInt())
}
return calendar.timeInMillis
}
private val relativeDateRegex = Regex("""(\d+)(h|d|w|mo|y) ago""")
private val relativeDateRegex = Regex("""(\d+)\s+(second|minute|hour|day|week|month|year)s?\s+ago""")
private fun countViews(postId: String) {
val payload = """{"post_id":"$postId"}"""