Small refactor
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package org.koitharu.kotatsu.parsers.bitmap
|
package org.koitharu.kotatsu.parsers.bitmap
|
||||||
|
|
||||||
interface Bitmap {
|
interface Bitmap {
|
||||||
|
|
||||||
val width: Int
|
val width: Int
|
||||||
val height: Int
|
val height: Int
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ data class Rect(
|
|||||||
val right: Int = 0,
|
val right: Int = 0,
|
||||||
val bottom: Int = 0,
|
val bottom: Int = 0,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val width: Int
|
val width: Int
|
||||||
get() = right - left
|
get() = right - left
|
||||||
|
|
||||||
val height: Int
|
val height: Int
|
||||||
get() = bottom - top
|
get() = bottom - top
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site.all
|
package org.koitharu.kotatsu.parsers.site.all
|
||||||
|
|
||||||
|
import androidx.collection.MutableIntObjectMap
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.koitharu.kotatsu.parsers.*
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
|
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||||
|
import org.koitharu.kotatsu.parsers.PagedMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.bitmap.Bitmap
|
import org.koitharu.kotatsu.parsers.bitmap.Bitmap
|
||||||
import org.koitharu.kotatsu.parsers.bitmap.Rect
|
import org.koitharu.kotatsu.parsers.bitmap.Rect
|
||||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||||
@@ -17,7 +20,8 @@ import javax.crypto.spec.SecretKeySpec
|
|||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@MangaSourceParser("MANGAREADERTO", "MangaReader.To")
|
@MangaSourceParser("MANGAREADERTO", "MangaReader.To")
|
||||||
class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGAREADERTO, 16), Interceptor {
|
class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGAREADERTO, 16),
|
||||||
|
Interceptor {
|
||||||
|
|
||||||
override val configKeyDomain = ConfigKey.Domain("mangareader.to")
|
override val configKeyDomain = ConfigKey.Domain("mangareader.to")
|
||||||
|
|
||||||
@@ -26,7 +30,7 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
SortOrder.RATING,
|
SortOrder.RATING,
|
||||||
SortOrder.UPDATED,
|
SortOrder.UPDATED,
|
||||||
SortOrder.NEWEST,
|
SortOrder.NEWEST,
|
||||||
SortOrder.ALPHABETICAL
|
SortOrder.ALPHABETICAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val availableStates: Set<MangaState> = EnumSet.allOf(MangaState::class.java)
|
override val availableStates: Set<MangaState> = EnumSet.allOf(MangaState::class.java)
|
||||||
@@ -38,7 +42,7 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
MangaTag(
|
MangaTag(
|
||||||
title = it.ownText().trim(),
|
title = it.ownText().trim(),
|
||||||
key = it.attr("data-id"),
|
key = it.attr("data-id"),
|
||||||
source = source
|
source = source,
|
||||||
)
|
)
|
||||||
}.associateBy { it.title }
|
}.associateBy { it.title }
|
||||||
}
|
}
|
||||||
@@ -57,6 +61,7 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
addQueryParameter("keyword", filter.query)
|
addQueryParameter("keyword", filter.query)
|
||||||
addQueryParameter("page", page.toString())
|
addQueryParameter("page", page.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
is MangaListFilter.Advanced -> {
|
is MangaListFilter.Advanced -> {
|
||||||
addPathSegment("filter")
|
addPathSegment("filter")
|
||||||
addQueryParameter("page", page.toString())
|
addQueryParameter("page", page.toString())
|
||||||
@@ -69,7 +74,7 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
SortOrder.NEWEST -> "release-date"
|
SortOrder.NEWEST -> "release-date"
|
||||||
SortOrder.ALPHABETICAL -> "name-az"
|
SortOrder.ALPHABETICAL -> "name-az"
|
||||||
else -> "default"
|
else -> "default"
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
addQueryParameter("genres", filter.tags.joinToString(",") { it.key })
|
addQueryParameter("genres", filter.tags.joinToString(",") { it.key })
|
||||||
addQueryParameter(
|
addQueryParameter(
|
||||||
@@ -81,9 +86,10 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
MangaState.PAUSED -> "3"
|
MangaState.PAUSED -> "3"
|
||||||
MangaState.UPCOMING -> "5"
|
MangaState.UPCOMING -> "5"
|
||||||
null -> ""
|
null -> ""
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
null -> {
|
null -> {
|
||||||
addPathSegment("filter")
|
addPathSegment("filter")
|
||||||
addQueryParameter("page", page.toString())
|
addQueryParameter("page", page.toString())
|
||||||
@@ -108,31 +114,32 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
isNsfw = false,
|
isNsfw = false,
|
||||||
rating = RATING_UNKNOWN,
|
rating = RATING_UNKNOWN,
|
||||||
state = null,
|
state = null,
|
||||||
tags = emptySet()
|
tags = emptySet(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getRelatedManga(seed: Manga): List<Manga> {
|
override suspend fun getRelatedManga(seed: Manga): List<Manga> {
|
||||||
val document = webClient.httpGet(seed.url.toAbsoluteUrl(domain)).parseHtml()
|
val document = webClient.httpGet(seed.url.toAbsoluteUrl(domain)).parseHtml()
|
||||||
return document.select(".block_area_authors-other .manga_list-sbs .manga-poster, .featured-block-ul .manga-poster").map {
|
return document.select(".block_area_authors-other .manga_list-sbs .manga-poster, .featured-block-ul .manga-poster")
|
||||||
val mangaUrl = it.attrAsRelativeUrl("href")
|
.map {
|
||||||
val thumb = it.select("img")
|
val mangaUrl = it.attrAsRelativeUrl("href")
|
||||||
Manga(
|
val thumb = it.select("img")
|
||||||
id = generateUid(mangaUrl),
|
Manga(
|
||||||
url = mangaUrl,
|
id = generateUid(mangaUrl),
|
||||||
publicUrl = mangaUrl.toAbsoluteUrl(domain),
|
url = mangaUrl,
|
||||||
title = thumb.attr("alt"),
|
publicUrl = mangaUrl.toAbsoluteUrl(domain),
|
||||||
coverUrl = thumb.attr("src"),
|
title = thumb.attr("alt"),
|
||||||
source = source,
|
coverUrl = thumb.attr("src"),
|
||||||
altTitle = null,
|
source = source,
|
||||||
author = null,
|
altTitle = null,
|
||||||
isNsfw = false,
|
author = null,
|
||||||
rating = RATING_UNKNOWN,
|
isNsfw = false,
|
||||||
state = null,
|
rating = RATING_UNKNOWN,
|
||||||
tags = emptySet()
|
state = null,
|
||||||
)
|
tags = emptySet(),
|
||||||
}
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getDetails(manga: Manga): Manga {
|
override suspend fun getDetails(manga: Manga): Manga {
|
||||||
@@ -165,16 +172,18 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
author = document.select("div.anisc-info a[href*=/author/]").joinToString { it.ownText().replace(", ", " ") },
|
author = document.select("div.anisc-info a[href*=/author/]")
|
||||||
|
.joinToString { it.ownText().replace(", ", " ") },
|
||||||
description = document.select("div.description").text(),
|
description = document.select("div.description").text(),
|
||||||
chapters = parseChapters(document),
|
chapters = parseChapters(document),
|
||||||
source = source
|
source = source,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseChapters(document: Document): List<MangaChapter> {
|
private fun parseChapters(document: Document): List<MangaChapter> {
|
||||||
val total = document.select(".chapters-list-ul > ul > li.chapter-item, .volume-list-ul div.lang-volumes > div.item").size
|
val total =
|
||||||
val chapters = ArrayList<MangaChapter>(total)
|
document.select(".chapters-list-ul > ul > li.chapter-item, .volume-list-ul div.lang-volumes > div.item").size
|
||||||
|
val chapters = ChaptersListBuilder(total)
|
||||||
|
|
||||||
document.select(".chapters-list-ul > ul").forEach { ul ->
|
document.select(".chapters-list-ul > ul").forEach { ul ->
|
||||||
ul.select("li.chapter-item").reversed().forEach { li ->
|
ul.select("li.chapter-item").reversed().forEach { li ->
|
||||||
@@ -190,8 +199,8 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
scanlator = null,
|
scanlator = null,
|
||||||
uploadDate = 0L,
|
uploadDate = 0L,
|
||||||
branch = createBranchName(ul.id().substringBefore("-chapters"), "Chapters"),
|
branch = createBranchName(ul.id().substringBefore("-chapters"), "Chapters"),
|
||||||
source = source
|
source = source,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,19 +213,19 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
MangaChapter(
|
MangaChapter(
|
||||||
id = generateUid(url),
|
id = generateUid(url),
|
||||||
name = name,
|
name = name,
|
||||||
number = numRegex.find(name)!!.groupValues[1].toFloat(),
|
number = numRegex.find(name)?.groupValues?.getOrNull(1)?.toFloatOrNull() ?: 0f,
|
||||||
volume = 0,
|
volume = 0,
|
||||||
url = url,
|
url = url,
|
||||||
scanlator = null,
|
scanlator = null,
|
||||||
uploadDate = 0L,
|
uploadDate = 0L,
|
||||||
branch = createBranchName(div.id().substringBefore("-volumes"), "Volumes"),
|
branch = createBranchName(div.id().substringBefore("-volumes"), "Volumes"),
|
||||||
source = source
|
source = source,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return chapters
|
return chapters.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createBranchName(lang: String, type: String): String {
|
private fun createBranchName(lang: String, type: String): String {
|
||||||
@@ -246,7 +255,7 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
url
|
url
|
||||||
},
|
},
|
||||||
preview = null,
|
preview = null,
|
||||||
source = source
|
source = source,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,7 +269,7 @@ class MangaReaderToParser(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
return context.redrawImageResponse(response, ::descramble)
|
return context.redrawImageResponse(response, ::descramble)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val memo = hashMapOf<Int, IntArray>()
|
private val memo = MutableIntObjectMap<IntArray>()
|
||||||
|
|
||||||
private fun descramble(bitmap: Bitmap): Bitmap {
|
private fun descramble(bitmap: Bitmap): Bitmap {
|
||||||
val width = bitmap.width
|
val width = bitmap.width
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
|
|||||||
import org.koitharu.kotatsu.parsers.model.*
|
import org.koitharu.kotatsu.parsers.model.*
|
||||||
import org.koitharu.kotatsu.parsers.site.heancms.HeanCms
|
import org.koitharu.kotatsu.parsers.site.heancms.HeanCms
|
||||||
import org.koitharu.kotatsu.parsers.util.*
|
import org.koitharu.kotatsu.parsers.util.*
|
||||||
import org.koitharu.kotatsu.parsers.util.json.getFloatOrDefault
|
import org.koitharu.kotatsu.parsers.util.json.*
|
||||||
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
|
||||||
import org.koitharu.kotatsu.parsers.util.json.mapJSON
|
|
||||||
import org.koitharu.kotatsu.parsers.util.json.unescapeJson
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@MangaSourceParser("MODESCANLATOR", "ModeScanlator", "pt")
|
@MangaSourceParser("MODESCANLATOR", "ModeScanlator", "pt")
|
||||||
internal class ModeScanlator(context: MangaLoaderContext) : HeanCms(context, MangaSource.MODESCANLATOR, "modescanlator.com") {
|
internal class ModeScanlator(
|
||||||
|
context: MangaLoaderContext,
|
||||||
|
) : HeanCms(context, MangaSource.MODESCANLATOR, "modescanlator.com") {
|
||||||
|
|
||||||
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
||||||
val url = buildString {
|
val url = buildString {
|
||||||
append("https://api.")
|
append("https://api.")
|
||||||
@@ -49,10 +49,11 @@ internal class ModeScanlator(context: MangaLoaderContext) : HeanCms(context, Man
|
|||||||
SortOrder.ALPHABETICAL_DESC -> append("title&order=asc")
|
SortOrder.ALPHABETICAL_DESC -> append("title&order=asc")
|
||||||
else -> append("latest&order=desc")
|
else -> append("latest&order=desc")
|
||||||
}
|
}
|
||||||
append("&series_type=All&perPage=$pageSize")
|
append("&series_type=All&perPage=")
|
||||||
|
append(pageSize)
|
||||||
append("&tags_ids=")
|
append("&tags_ids=")
|
||||||
append("[".urlEncoded())
|
append("[".urlEncoded())
|
||||||
append(filter.tags.joinToString(",") { it.key })
|
filter.tags.joinTo(this, ",") { it.key }
|
||||||
append("]".urlEncoded())
|
append("]".urlEncoded())
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -60,7 +61,7 @@ internal class ModeScanlator(context: MangaLoaderContext) : HeanCms(context, Man
|
|||||||
null -> {}
|
null -> {}
|
||||||
}
|
}
|
||||||
append("&page=")
|
append("&page=")
|
||||||
append(page.toString())
|
append(page)
|
||||||
}
|
}
|
||||||
val json = webClient.httpGet(url).parseJson()
|
val json = webClient.httpGet(url).parseJson()
|
||||||
return json.getJSONArray("data").mapJSON { j ->
|
return json.getJSONArray("data").mapJSON { j ->
|
||||||
@@ -78,10 +79,10 @@ internal class ModeScanlator(context: MangaLoaderContext) : HeanCms(context, Man
|
|||||||
url = urlManga.toRelativeUrl(domain),
|
url = urlManga.toRelativeUrl(domain),
|
||||||
publicUrl = urlManga,
|
publicUrl = urlManga,
|
||||||
rating = j.getFloatOrDefault("rating", RATING_UNKNOWN) / 5f,
|
rating = j.getFloatOrDefault("rating", RATING_UNKNOWN) / 5f,
|
||||||
isNsfw = true,
|
isNsfw = isNsfwSource,
|
||||||
coverUrl = cover,
|
coverUrl = cover,
|
||||||
tags = setOf(),
|
tags = setOf(),
|
||||||
state = when (j.getString("status")) {
|
state = when (j.getStringOrNull("status")) {
|
||||||
"Ongoing" -> MangaState.ONGOING
|
"Ongoing" -> MangaState.ONGOING
|
||||||
"Completed" -> MangaState.FINISHED
|
"Completed" -> MangaState.FINISHED
|
||||||
"Dropped" -> MangaState.ABANDONED
|
"Dropped" -> MangaState.ABANDONED
|
||||||
@@ -100,7 +101,8 @@ internal class ModeScanlator(context: MangaLoaderContext) : HeanCms(context, Man
|
|||||||
val url = buildString {
|
val url = buildString {
|
||||||
append("https://api.")
|
append("https://api.")
|
||||||
append(domain)
|
append(domain)
|
||||||
append("/chapter/query?perPage=9999&series_id=" + manga.id)
|
append("/chapter/query?perPage=9999&series_id=")
|
||||||
|
append(manga.id)
|
||||||
}
|
}
|
||||||
val json = webClient.httpGet(url).parseJson()
|
val json = webClient.httpGet(url).parseJson()
|
||||||
val dateFormat = SimpleDateFormat(datePattern, Locale.ENGLISH)
|
val dateFormat = SimpleDateFormat(datePattern, Locale.ENGLISH)
|
||||||
@@ -135,14 +137,12 @@ internal class ModeScanlator(context: MangaLoaderContext) : HeanCms(context, Man
|
|||||||
val tags = doc.select("script").firstNotNullOf { script ->
|
val tags = doc.select("script").firstNotNullOf { script ->
|
||||||
regex.find(script.html())?.groupValues?.getOrNull(1)
|
regex.find(script.html())?.groupValues?.getOrNull(1)
|
||||||
}.unescapeJson()
|
}.unescapeJson()
|
||||||
return JSONArray(tags).mapJSON {
|
return JSONArray(tags).mapJSONToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.getInt("id").toString(),
|
key = it.getInt("id").toString(),
|
||||||
title = it.getString("name").toTitleCase(sourceLocale),
|
title = it.getString("name").toTitleCase(sourceLocale),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
}.toSet()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user