Small refactor

master
Koitharu 2 years ago
parent a0f9bc032d
commit 350bc0ad58
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -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() }
} }
} }

Loading…
Cancel
Save