MangaRead parser #17
parent
a8c22de601
commit
2135195f27
@ -0,0 +1,165 @@
|
||||
package org.koitharu.kotatsu.core.parser.site
|
||||
|
||||
import androidx.collection.arraySetOf
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.ParseException
|
||||
import org.koitharu.kotatsu.core.model.*
|
||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||
import org.koitharu.kotatsu.domain.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.utils.ext.*
|
||||
|
||||
class MangareadRepository(
|
||||
loaderContext: MangaLoaderContext
|
||||
) : RemoteMangaRepository(loaderContext) {
|
||||
|
||||
override val source = MangaSource.MANGAREAD
|
||||
|
||||
override val sortOrders = arraySetOf(SortOrder.UPDATED, SortOrder.POPULARITY)
|
||||
|
||||
override suspend fun getList(
|
||||
offset: Int,
|
||||
query: String?,
|
||||
sortOrder: SortOrder?,
|
||||
tag: MangaTag?
|
||||
): List<Manga> {
|
||||
if (offset % PAGE_SIZE != 0) {
|
||||
return emptyList()
|
||||
}
|
||||
val domain = conf.getDomain(DOMAIN)
|
||||
val payload = createRequestTemplate()
|
||||
payload["page"] = (offset / PAGE_SIZE).toString()
|
||||
payload["vars[meta_key]"] = when (sortOrder) {
|
||||
SortOrder.POPULARITY -> "_wp_manga_views"
|
||||
SortOrder.UPDATED -> "_latest_update"
|
||||
else -> "_wp_manga_views"
|
||||
}
|
||||
payload["vars[wp-manga-genre]"] = tag?.key.orEmpty()
|
||||
payload["vars[s]"] = query.orEmpty()
|
||||
val doc = loaderContext.httpPost(
|
||||
"https://${domain}/wp-admin/admin-ajax.php",
|
||||
payload
|
||||
).parseHtml()
|
||||
return doc.select("div.row.c-tabs-item__content").map { div ->
|
||||
val href = div.selectFirst("a").absUrl("href")
|
||||
val summary = div.selectFirst(".tab-summary")
|
||||
Manga(
|
||||
id = href.longHashCode(),
|
||||
url = href,
|
||||
coverUrl = div.selectFirst("img").absUrl("src"),
|
||||
title = summary.selectFirst("h3").text(),
|
||||
rating = div.selectFirst("span.total_votes")?.ownText()
|
||||
?.toFloatOrNull()?.div(5f) ?: -1f,
|
||||
tags = summary.selectFirst(".mg_genres").select("a").mapToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||
title = a.text(),
|
||||
source = MangaSource.MANGAREAD
|
||||
)
|
||||
},
|
||||
author = summary.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
||||
state = when (summary.selectFirst(".mg_status")?.selectFirst(".summary-content")
|
||||
?.ownText()?.trim()) {
|
||||
"OnGoing" -> MangaState.ONGOING
|
||||
"Completed" -> MangaState.FINISHED
|
||||
else -> null
|
||||
},
|
||||
source = MangaSource.MANGAREAD
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
val domain = conf.getDomain(DOMAIN)
|
||||
val doc = loaderContext.httpGet("https://$domain/manga/").parseHtml()
|
||||
val root = doc.body().getElementById("main-sidebar")
|
||||
.selectFirst(".genres_wrap")
|
||||
.selectFirst("ul")
|
||||
return root.select("li").mapToSet { li ->
|
||||
val a = li.selectFirst("a")
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||
title = a.text(),
|
||||
source = MangaSource.MANGAREAD
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val domain = conf.getDomain(DOMAIN)
|
||||
val doc = loaderContext.httpGet(manga.url).parseHtml()
|
||||
val root = doc.body().selectFirst("div.profile-manga")
|
||||
?.selectFirst("div.summary_content")
|
||||
?.selectFirst("div.post-content")
|
||||
?: throw ParseException("Root not found")
|
||||
val root2 = doc.body().selectFirst("div.content-area")
|
||||
?.selectFirst("div.c-page")
|
||||
?: throw ParseException("Root2 not found")
|
||||
val mangaId = doc.getElementsByAttribute("data-postid").firstOrNull()
|
||||
?.attr("data-postid")?.toLongOrNull()
|
||||
?: throw ParseException("Cannot obtain manga id")
|
||||
val doc2 = loaderContext.httpPost(
|
||||
"https://${domain}/wp-admin/admin-ajax.php",
|
||||
mapOf(
|
||||
"action" to "manga_get_chapters",
|
||||
"manga" to mangaId.toString()
|
||||
)
|
||||
).parseHtml()
|
||||
return manga.copy(
|
||||
tags = root.selectFirst("div.genres-content")?.select("a")
|
||||
?.mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||
title = a.text(),
|
||||
source = MangaSource.MANGAREAD
|
||||
)
|
||||
} ?: manga.tags,
|
||||
description = root2.selectFirst("div.description-summary")
|
||||
?.selectFirst("div.summary__content")
|
||||
?.select("p")?.drop(1)
|
||||
?.joinToString { it.html() },
|
||||
chapters = doc2.select("li").asReversed().mapIndexed { i, li ->
|
||||
val a = li.selectFirst("a")
|
||||
val href = a.absUrl("href")
|
||||
MangaChapter(
|
||||
id = href.longHashCode(),
|
||||
name = a.ownText(),
|
||||
number = i + 1,
|
||||
url = href,
|
||||
source = MangaSource.MANGAREAD
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val doc = loaderContext.httpGet(chapter.url).parseHtml()
|
||||
val root = doc.body().selectFirst("div.main-col-inner")
|
||||
?.selectFirst("div.reading-content")
|
||||
?: throw ParseException("Root not found")
|
||||
return root.select("div.page-break").map { div ->
|
||||
val img = div.selectFirst("img")
|
||||
val url = img.absUrl("src")
|
||||
MangaPage(
|
||||
id = url.longHashCode(),
|
||||
url = url,
|
||||
source = MangaSource.MANGAREAD
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreatePreferences() = arraySetOf(R.string.key_parser_domain)
|
||||
|
||||
private companion object {
|
||||
|
||||
private const val PAGE_SIZE = 12
|
||||
private const val DOMAIN = "www.mangaread.org"
|
||||
|
||||
private fun createRequestTemplate() =
|
||||
"action=madara_load_more&page=1&template=madara-core%2Fcontent%2Fcontent-search&vars%5Bs%5D=&vars%5Borderby%5D=meta_value_num&vars%5Bpaged%5D=1&vars%5Btemplate%5D=search&vars%5Bmeta_query%5D%5B0%5D%5Brelation%5D=AND&vars%5Bmeta_query%5D%5Brelation%5D=OR&vars%5Bpost_type%5D=wp-manga&vars%5Bpost_status%5D=publish&vars%5Bmeta_key%5D=_latest_update&vars%5Border%5D=desc&vars%5Bmanga_archives_item_layout%5D=default"
|
||||
.split('&')
|
||||
.map {
|
||||
val pos = it.indexOf('=')
|
||||
it.substring(0, pos) to it.substring(pos + 1)
|
||||
}.toMutableMap()
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue