MangaTaro: migrate to new chapter endpoint (#11636)
This commit is contained in:
parent
1aa1119924
commit
60e78280c8
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'MangaTaro'
|
extName = 'MangaTaro'
|
||||||
extClass = '.MangaTaro'
|
extClass = '.MangaTaro'
|
||||||
extVersionCode = 5
|
extVersionCode = 6
|
||||||
isNsfw = false
|
isNsfw = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -112,3 +112,19 @@ class Thumbnail(
|
|||||||
class Rendered(
|
class Rendered(
|
||||||
val rendered: String,
|
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,
|
||||||
|
)
|
||||||
|
|||||||
@ -28,7 +28,12 @@ import org.jsoup.Jsoup
|
|||||||
import org.jsoup.parser.Parser
|
import org.jsoup.parser.Parser
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import java.lang.UnsupportedOperationException
|
import java.lang.UnsupportedOperationException
|
||||||
|
import java.security.MessageDigest
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.TimeZone
|
||||||
|
|
||||||
class MangaTaro : HttpSource() {
|
class MangaTaro : HttpSource() {
|
||||||
|
|
||||||
@ -232,37 +237,55 @@ class MangaTaro : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListRequest(manga: SManga): Request {
|
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> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
countViews(response.request.url.fragment!!)
|
countViews(response.request.url.queryParameter("manga_id")!!)
|
||||||
|
|
||||||
val document = response.asJsoup()
|
val data = response.parseAs<ChapterList>()
|
||||||
val placeholders = listOf("", "N/A", "—")
|
|
||||||
|
val placeholders = listOf(null, "", "N/A", "—")
|
||||||
var hasScanlator = false
|
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 {
|
SChapter.create().apply {
|
||||||
setUrlWithoutDomain(it.absUrl("href"))
|
setUrlWithoutDomain(it.url)
|
||||||
val details = it.select("> div + div > div")
|
|
||||||
name = buildString {
|
name = buildString {
|
||||||
append(it.attr("title"))
|
append("Chapter ")
|
||||||
details[1].text().also { title ->
|
append(it.chapter)
|
||||||
|
it.title.also { title ->
|
||||||
if (title !in placeholders) {
|
if (title !in placeholders) {
|
||||||
append(": ", title)
|
append(": ", title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it.attr("data-group-name").let { group ->
|
it.groupName.let { group ->
|
||||||
if (group !in placeholders) {
|
if (group !in placeholders) {
|
||||||
scanlator = group
|
scanlator = group
|
||||||
hasScanlator = true
|
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 ->
|
private fun String.toSlug() = toHttpUrl().let { url ->
|
||||||
val path = url.pathSegments.filter(String::isNotBlank)
|
val path = url.pathSegments.filter(String::isNotBlank)
|
||||||
|
|
||||||
@ -301,17 +334,19 @@ class MangaTaro : HttpSource() {
|
|||||||
?: return 0L
|
?: return 0L
|
||||||
|
|
||||||
when (unit) {
|
when (unit) {
|
||||||
"h" -> calendar.add(Calendar.HOUR, -amount.toInt())
|
"second" -> calendar.add(Calendar.SECOND, -amount.toInt())
|
||||||
"d" -> calendar.add(Calendar.DAY_OF_YEAR, -amount.toInt())
|
"minute" -> calendar.add(Calendar.MINUTE, -amount.toInt())
|
||||||
"w" -> calendar.add(Calendar.WEEK_OF_YEAR, -amount.toInt())
|
"hour" -> calendar.add(Calendar.HOUR, -amount.toInt())
|
||||||
"mo" -> calendar.add(Calendar.MONTH, -amount.toInt())
|
"day" -> calendar.add(Calendar.DAY_OF_YEAR, -amount.toInt())
|
||||||
"y" -> calendar.add(Calendar.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
|
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) {
|
private fun countViews(postId: String) {
|
||||||
val payload = """{"post_id":"$postId"}"""
|
val payload = """{"post_id":"$postId"}"""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user