Mangafire: fix manga chapters load (#18298)
* Mangafire: fix manga and chapters load * Mangafire: increase version code
This commit is contained in:
parent
1da48fa265
commit
9a48fc85ca
|
@ -85,15 +85,15 @@ open class MangaFire(
|
||||||
return GET(urlBuilder.build(), headers)
|
return GET(urlBuilder.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = ".mangas.items .inner"
|
|
||||||
|
|
||||||
override fun searchMangaNextPageSelector() = ".page-item.active + .page-item .page-link"
|
override fun searchMangaNextPageSelector() = ".page-item.active + .page-item .page-link"
|
||||||
|
|
||||||
|
override fun searchMangaSelector() = ".original.card-lg .unit .inner"
|
||||||
|
|
||||||
override fun searchMangaFromElement(element: Element) =
|
override fun searchMangaFromElement(element: Element) =
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
element.selectFirst("a.color-light")!!.let {
|
element.selectFirst(".info > a")!!.let {
|
||||||
url = it.attr("href")
|
setUrlWithoutDomain(it.attr("href"))
|
||||||
title = it.attr("title")
|
title = it.ownText()
|
||||||
}
|
}
|
||||||
element.selectFirst(Evaluator.Tag("img"))!!.let {
|
element.selectFirst(Evaluator.Tag("img"))!!.let {
|
||||||
thumbnail_url = it.attr("src")
|
thumbnail_url = it.attr("src")
|
||||||
|
@ -101,25 +101,26 @@ open class MangaFire(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
||||||
val root = document.selectFirst(".detail .top .wrapper")!!
|
val root = document.selectFirst(".info")!!
|
||||||
val mangaTitle = root.selectFirst(Evaluator.Class("name"))!!.ownText()
|
val mangaTitle = root.child(1).ownText()
|
||||||
title = mangaTitle
|
title = mangaTitle
|
||||||
description = document.run {
|
description = document.run {
|
||||||
val description = selectFirst(Evaluator.Class("summary"))!!.ownText()
|
val description = selectFirst(Evaluator.Class("description"))!!.ownText()
|
||||||
when (val altTitle = root.selectFirst(Evaluator.Class("al-name"))!!.ownText()) {
|
when (val altTitle = root.child(2).ownText()) {
|
||||||
"", mangaTitle -> description
|
"", mangaTitle -> description
|
||||||
else -> "$description\n\nAlternative Title: $altTitle"
|
else -> "$description\n\nAlternative Title: $altTitle"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thumbnail_url = root.selectFirst(Evaluator.Tag("img"))!!.attr("src")
|
thumbnail_url = document.selectFirst(".poster")!!
|
||||||
status = when (root.selectFirst(Evaluator.Class("status"))!!.ownText()) {
|
.selectFirst("img")!!.attr("src")
|
||||||
|
status = when (root.child(0).ownText()) {
|
||||||
"Completed" -> SManga.COMPLETED
|
"Completed" -> SManga.COMPLETED
|
||||||
"Releasing" -> SManga.ONGOING
|
"Releasing" -> SManga.ONGOING
|
||||||
"On_hiatus" -> SManga.ON_HIATUS
|
"On_hiatus" -> SManga.ON_HIATUS
|
||||||
"Discontinued" -> SManga.CANCELLED
|
"Discontinued" -> SManga.CANCELLED
|
||||||
else -> SManga.UNKNOWN
|
else -> SManga.UNKNOWN
|
||||||
}
|
}
|
||||||
with(root.selectFirst(Evaluator.Class("more-info"))!!) {
|
with(document.selectFirst(Evaluator.Class("meta"))!!) {
|
||||||
author = selectFirst("span:contains(Author:) + span")?.text()
|
author = selectFirst("span:contains(Author:) + span")?.text()
|
||||||
val type = selectFirst("span:contains(Type:) + span")?.text()
|
val type = selectFirst("span:contains(Type:) + span")?.text()
|
||||||
val genres = selectFirst("span:contains(Genres:) + span")?.text()
|
val genres = selectFirst("span:contains(Genres:) + span")?.text()
|
||||||
|
@ -132,20 +133,39 @@ open class MangaFire(
|
||||||
|
|
||||||
override fun chapterListRequest(mangaUrl: String, type: String): Request {
|
override fun chapterListRequest(mangaUrl: String, type: String): Request {
|
||||||
val id = mangaUrl.substringAfterLast('.')
|
val id = mangaUrl.substringAfterLast('.')
|
||||||
return GET("$baseUrl/ajax/read/$id/list?viewby=$type", headers)
|
return GET("$baseUrl/ajax/manga/$id/$type/$langCode", headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseChapterElements(response: Response, isVolume: Boolean): List<Element> {
|
override fun parseChapterElements(response: Response, isVolume: Boolean): List<Element> {
|
||||||
val result = json.decodeFromString<ResponseDto<ChapterListDto>>(response.body.string()).result
|
val result = json.decodeFromString<ResponseDto<String>>(response.body.string()).result
|
||||||
val container = result.parseHtml(if (isVolume) volumeType else chapterType)
|
val document = Jsoup.parse(result)
|
||||||
?.selectFirst(".numberlist[data-lang=$langCode]")
|
|
||||||
?: return emptyList()
|
val elements = document.select("ul li")
|
||||||
return container.children().map { it.child(0) }
|
if (elements.size > 0) {
|
||||||
|
val linkToFirstChapter = elements[0].selectFirst(Evaluator.Tag("a"))!!.attr("href")
|
||||||
|
val mangaId = linkToFirstChapter.toString().substringAfter('.').substringBefore('/')
|
||||||
|
|
||||||
|
val request = GET("$baseUrl/ajax/read/$mangaId/chapter/$langCode", headers)
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
val res = json.decodeFromString<ResponseDto<ChapterIdsDto>>(response.body.string()).result.html
|
||||||
|
val chapterInfoDocument = Jsoup.parse(res)
|
||||||
|
val chapters = chapterInfoDocument.select("ul li")
|
||||||
|
for ((i, it) in elements.withIndex()) {
|
||||||
|
it.attr("data-id", chapters[i].select("a").attr("data-id"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return elements.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class ChapterIdsDto(
|
||||||
|
val html: String,
|
||||||
|
val title_format: String,
|
||||||
|
)
|
||||||
|
|
||||||
override fun updateChapterList(manga: SManga, chapters: List<SChapter>) {
|
override fun updateChapterList(manga: SManga, chapters: List<SChapter>) {
|
||||||
val document = client.newCall(mangaDetailsRequest(manga)).execute().asJsoup()
|
val document = client.newCall(mangaDetailsRequest(manga)).execute().asJsoup()
|
||||||
val elements = document.selectFirst(".chapter-list[data-name=$langCode]")!!.children()
|
val elements = document.selectFirst(".scroll-sm")!!.children()
|
||||||
val chapterCount = chapters.size
|
val chapterCount = chapters.size
|
||||||
if (elements.size != chapterCount) throw Exception("Chapter count doesn't match. Try updating again.")
|
if (elements.size != chapterCount) throw Exception("Chapter count doesn't match. Try updating again.")
|
||||||
val dateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.US)
|
val dateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.US)
|
||||||
|
@ -180,6 +200,20 @@ open class MangaFire(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class PageListDto(private val images: List<List<JsonPrimitive>>) {
|
||||||
|
val pages get() = images.map {
|
||||||
|
Image(it[0].content, it[2].int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Image(val url: String, val offset: Int)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class ResponseDto<T>(
|
||||||
|
val result: T,
|
||||||
|
val status: Int,
|
||||||
|
)
|
||||||
|
|
||||||
override fun getFilterList() =
|
override fun getFilterList() =
|
||||||
FilterList(
|
FilterList(
|
||||||
Filter.Header("NOTE: Ignored if using text search!"),
|
Filter.Header("NOTE: Ignored if using text search!"),
|
||||||
|
@ -191,22 +225,4 @@ open class MangaFire(
|
||||||
ChapterCountFilter(),
|
ChapterCountFilter(),
|
||||||
SortFilter(),
|
SortFilter(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class ChapterListDto(private val html: String, private val link_format: String) {
|
|
||||||
fun parseHtml(type: String): Document? {
|
|
||||||
if ("LANG/$type-NUMBER" !in link_format) return null
|
|
||||||
return Jsoup.parseBodyFragment(html)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class PageListDto(private val images: List<List<JsonPrimitive>>) {
|
|
||||||
val pages get() = images.map { Image(it[0].content, it[2].int) }
|
|
||||||
}
|
|
||||||
|
|
||||||
class Image(val url: String, val offset: Int)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class ResponseDto<T>(val result: T)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class MangaReaderGenerator : ThemeSourceGenerator {
|
||||||
baseUrl = "https://mangafire.to",
|
baseUrl = "https://mangafire.to",
|
||||||
langs = listOf("en", "es", "es-419", "fr", "ja", "pt", "pt-BR"),
|
langs = listOf("en", "es", "es-419", "fr", "ja", "pt", "pt-BR"),
|
||||||
isNsfw = true,
|
isNsfw = true,
|
||||||
overrideVersionCode = 1,
|
overrideVersionCode = 2,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue