[Manga4Life] Refactoring and fixes
This commit is contained in:
@@ -4,19 +4,21 @@ import okhttp3.Headers
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaParser
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.PagedMangaParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.network.UserAgents
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import org.koitharu.kotatsu.parsers.util.json.*
|
||||
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed
|
||||
import org.koitharu.kotatsu.parsers.util.json.toJSONList
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
|
||||
@MangaSourceParser("MANGA4LIFE", "Manga4Life", "en")
|
||||
internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGA4LIFE, 0) {
|
||||
internal class Manga4Life(context: MangaLoaderContext) : MangaParser(context, MangaSource.MANGA4LIFE) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
|
||||
@@ -26,30 +28,19 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
.build()
|
||||
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
|
||||
if (page > 1) {
|
||||
override suspend fun getList(offset: Int, query: String?, tags: Set<MangaTag>?, sortOrder: SortOrder): List<Manga> {
|
||||
if (offset > 0) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val url = buildString {
|
||||
append("https://$domain/search/")
|
||||
}
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
val doc = webClient.httpGet("https://$domain/search/").parseHtml()
|
||||
val json = JSONArray(
|
||||
doc.selectFirstOrThrow("script:containsData(MainFunction)").data()
|
||||
.substringAfter("vm.Directory = ").substringBefore("vm.GetIntValue").trim()
|
||||
.replace(";", " "),
|
||||
.replace(';', ' '),
|
||||
)
|
||||
|
||||
|
||||
val manga = ArrayList<Manga>()
|
||||
val manga = ArrayList<Manga>(json.length())
|
||||
|
||||
for (i in 0 until json.length()) {
|
||||
val m = json.getJSONObject(i)
|
||||
@@ -60,7 +51,7 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
manga.add(
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
title = m.getString("i").replace("-", " "),
|
||||
title = m.getString("i").replace('-', ' '),
|
||||
altTitle = null,
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(domain),
|
||||
@@ -88,7 +79,7 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
manga.add(
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
title = m.getString("i").replace("-", " "),
|
||||
title = m.getString("i").replace('-', ' '),
|
||||
altTitle = null,
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(domain),
|
||||
@@ -106,7 +97,7 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
manga.add(
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
title = m.getString("i").replace("-", " "),
|
||||
title = m.getString("i").replace('-', ' '),
|
||||
altTitle = null,
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(domain),
|
||||
@@ -130,9 +121,12 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/search/").parseHtml()
|
||||
val tags = doc.selectFirstOrThrow("script:containsData(vm.AvailableFilters)").data()
|
||||
.substringAfter("\"Genre\" \t\t: [").substringBefore("]").replace("'", "").split(",")
|
||||
.substringAfter("\"Genre\" \t\t: [")
|
||||
.substringBefore(']')
|
||||
.replace("'", "")
|
||||
.split(',')
|
||||
|
||||
return tags.mapNotNullToSet { tag ->
|
||||
return tags.mapToSet { tag ->
|
||||
MangaTag(
|
||||
key = tag,
|
||||
title = tag,
|
||||
@@ -147,7 +141,7 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
val chapter = JSONArray(
|
||||
JSONArray(
|
||||
doc.selectFirstOrThrow("script:containsData(MainFunction)").data()
|
||||
.substringAfter("vm.Chapters = ").substringBefore(";"),
|
||||
.substringAfter("vm.Chapters = ").substringBefore(';'),
|
||||
).toJSONList().reversed(),
|
||||
)
|
||||
|
||||
@@ -167,7 +161,7 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
},
|
||||
tags = doc.select(".list-group-item:contains(Genre(s):) a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").substringAfterLast("="),
|
||||
key = a.attr("href").substringAfterLast('='),
|
||||
title = a.text(),
|
||||
source = source,
|
||||
)
|
||||
@@ -178,7 +172,7 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
chapters = chapter.mapJSONIndexed { i, j ->
|
||||
val indexChapter = j.getString("Chapter")!!
|
||||
val url = "/read-online/" + manga.url.substringAfter("/manga/") + chapterURLEncode(indexChapter)
|
||||
val name = j.getString("ChapterName").let {
|
||||
val name = j.getStringOrNull("ChapterName").let {
|
||||
if (it.isNullOrEmpty() || it == "null") "${j.getString("Type")} ${
|
||||
chapterImage(
|
||||
indexChapter,
|
||||
@@ -186,7 +180,7 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
)
|
||||
}" else it
|
||||
}
|
||||
val date = j.getString("Date")
|
||||
val date = j.getStringOrNull("Date")
|
||||
MangaChapter(
|
||||
id = generateUid(url),
|
||||
name = name,
|
||||
@@ -207,14 +201,12 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
if (1 != t) {
|
||||
index = "-index-$t"
|
||||
}
|
||||
val dgt = if (e.toInt() < 100100) {
|
||||
4
|
||||
} else if (e.toInt() < 101000) {
|
||||
3
|
||||
} else if (e.toInt() < 110000) {
|
||||
2
|
||||
} else {
|
||||
1
|
||||
val ei = e.toInt()
|
||||
val dgt = when {
|
||||
ei < 100100 -> 4
|
||||
ei < 101000 -> 3
|
||||
ei < 110000 -> 2
|
||||
else -> 1
|
||||
}
|
||||
val n = e.substring(dgt, e.length - 1)
|
||||
var suffix = ""
|
||||
@@ -232,12 +224,10 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
val a = e.substring(1, e.length - 1).let { if (cleanString) it.replace(chapterImageRegex, "") else it }
|
||||
// If b is not zero, indicates chapter has decimal numbering
|
||||
val b = e.substring(e.length - 1).toInt()
|
||||
return if (b == 0 && a.isNotEmpty()) {
|
||||
a
|
||||
} else if (b == 0 && a.isEmpty()) {
|
||||
"0"
|
||||
} else {
|
||||
"$a.$b"
|
||||
return when {
|
||||
b == 0 && a.isNotEmpty() -> a
|
||||
b == 0 && a.isEmpty() -> "0"
|
||||
else -> "$a.$b"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,19 +236,20 @@ internal class Manga4Life(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
val script = doc.selectFirstOrThrow("script:containsData(MainFunction)").data()
|
||||
val curChapter = JSONObject(
|
||||
doc.selectFirstOrThrow("script:containsData(MainFunction)").data().substringAfter("vm.CurChapter = ")
|
||||
.substringBefore(";"),
|
||||
doc.selectFirstOrThrow("script:containsData(MainFunction)").data()
|
||||
.substringAfter("vm.CurChapter = ")
|
||||
.substringBefore(';'),
|
||||
)
|
||||
val pageTotal = curChapter.getString("Page")!!.toInt()
|
||||
val host = "https://" +
|
||||
script
|
||||
.substringAfter("vm.CurPathName = \"", "")
|
||||
.substringBefore("\"")
|
||||
.also {
|
||||
if (it.isEmpty()) {
|
||||
throw Exception("Manga4Life is overloaded and blocking Tachiyomi right now. Wait for unblock.")
|
||||
}
|
||||
script
|
||||
.substringAfter("vm.CurPathName = \"", "")
|
||||
.substringBefore('"')
|
||||
.also {
|
||||
if (it.isEmpty()) {
|
||||
throw Exception("Manga4Life is overloaded and blocking Tachiyomi right now. Wait for unblock.")
|
||||
}
|
||||
}
|
||||
val titleURI = script.substringAfter("vm.IndexName = \"").substringBefore("\"")
|
||||
val seasonURI = curChapter.getString("Directory")!!
|
||||
.let { if (it.isEmpty()) "" else "$it/" }
|
||||
|
||||
Reference in New Issue
Block a user