Fix all parsers issues
This commit is contained in:
@@ -93,7 +93,7 @@ abstract class ChanRepository : RemoteMangaRepository() {
|
|||||||
val json = data.substring(pos).substringAfter('[').substringBefore(';')
|
val json = data.substring(pos).substringAfter('[').substringBefore(';')
|
||||||
.substringBeforeLast(']')
|
.substringBeforeLast(']')
|
||||||
return json.split(",").mapNotNull {
|
return json.split(",").mapNotNull {
|
||||||
it.trim().removeSurrounding('"').takeUnless(String::isBlank)
|
it.trim().removeSurrounding('"','\'').takeUnless(String::isBlank)
|
||||||
}.map { url ->
|
}.map { url ->
|
||||||
MangaPage(
|
MangaPage(
|
||||||
id = url.longHashCode(),
|
id = url.longHashCode(),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.koitharu.kotatsu.core.exceptions.ParseException
|
|||||||
import org.koitharu.kotatsu.core.model.Manga
|
import org.koitharu.kotatsu.core.model.Manga
|
||||||
import org.koitharu.kotatsu.core.model.MangaChapter
|
import org.koitharu.kotatsu.core.model.MangaChapter
|
||||||
import org.koitharu.kotatsu.core.model.MangaSource
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaTag
|
||||||
import org.koitharu.kotatsu.utils.ext.longHashCode
|
import org.koitharu.kotatsu.utils.ext.longHashCode
|
||||||
import org.koitharu.kotatsu.utils.ext.parseHtml
|
import org.koitharu.kotatsu.utils.ext.parseHtml
|
||||||
import org.koitharu.kotatsu.utils.ext.withDomain
|
import org.koitharu.kotatsu.utils.ext.withDomain
|
||||||
@@ -18,22 +19,27 @@ class HenChanRepository : ChanRepository() {
|
|||||||
val doc = loaderContext.httpGet(manga.url).parseHtml()
|
val doc = loaderContext.httpGet(manga.url).parseHtml()
|
||||||
val root =
|
val root =
|
||||||
doc.body().getElementById("dle-content") ?: throw ParseException("Cannot find root")
|
doc.body().getElementById("dle-content") ?: throw ParseException("Cannot find root")
|
||||||
|
val readLink = manga.url.replace("manga", "online")
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
description = root.getElementById("description")?.html()?.substringBeforeLast("<div"),
|
description = root.getElementById("description")?.html()?.substringBeforeLast("<div"),
|
||||||
largeCoverUrl = root.getElementById("cover")?.attr("src")?.withDomain(domain),
|
largeCoverUrl = root.getElementById("cover")?.attr("src")?.withDomain(domain),
|
||||||
chapters = root.getElementById("right").select("table.table_cha").flatMap { table ->
|
tags = root.selectFirst("div.sidetags")?.select("li.sidetag")?.map {
|
||||||
table.select("div.manga2")
|
val a = it.children().last()
|
||||||
}.mapNotNull { it.selectFirst("a") }.reversed().mapIndexedNotNull { i, a ->
|
MangaTag(
|
||||||
val href = a.attr("href")
|
title = a.text(),
|
||||||
?.withDomain(domain) ?: return@mapIndexedNotNull null
|
key = a.attr("href").substringAfterLast('/'),
|
||||||
MangaChapter(
|
|
||||||
id = href.longHashCode(),
|
|
||||||
name = a.text().trim(),
|
|
||||||
number = i + 1,
|
|
||||||
url = href,
|
|
||||||
source = source
|
source = source
|
||||||
)
|
)
|
||||||
}
|
}?.toSet() ?: manga.tags,
|
||||||
|
chapters = listOf(
|
||||||
|
MangaChapter(
|
||||||
|
id = readLink.longHashCode(),
|
||||||
|
url = readLink,
|
||||||
|
source = source,
|
||||||
|
number = 1,
|
||||||
|
name = manga.title
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,39 @@
|
|||||||
package org.koitharu.kotatsu.core.parser.site
|
package org.koitharu.kotatsu.core.parser.site
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.core.exceptions.ParseException
|
||||||
|
import org.koitharu.kotatsu.core.model.Manga
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaChapter
|
||||||
import org.koitharu.kotatsu.core.model.MangaSource
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.utils.ext.longHashCode
|
||||||
|
import org.koitharu.kotatsu.utils.ext.parseHtml
|
||||||
|
import org.koitharu.kotatsu.utils.ext.withDomain
|
||||||
|
|
||||||
class YaoiChanRepository : ChanRepository() {
|
class YaoiChanRepository : ChanRepository() {
|
||||||
|
|
||||||
override val source = MangaSource.YAOICHAN
|
override val source = MangaSource.YAOICHAN
|
||||||
override val defaultDomain = "yaoi-chan.me"
|
override val defaultDomain = "yaoi-chan.me"
|
||||||
|
|
||||||
|
override suspend fun getDetails(manga: Manga): Manga {
|
||||||
|
val domain = conf.getDomain(defaultDomain)
|
||||||
|
val doc = loaderContext.httpGet(manga.url).parseHtml()
|
||||||
|
val root =
|
||||||
|
doc.body().getElementById("dle-content") ?: throw ParseException("Cannot find root")
|
||||||
|
return manga.copy(
|
||||||
|
description = root.getElementById("description")?.html()?.substringBeforeLast("<div"),
|
||||||
|
largeCoverUrl = root.getElementById("cover")?.attr("src")?.withDomain(domain),
|
||||||
|
chapters = root.select("table.table_cha").flatMap { table ->
|
||||||
|
table.select("div.manga")
|
||||||
|
}.mapNotNull { it.selectFirst("a") }.reversed().mapIndexedNotNull { i, a ->
|
||||||
|
val href = a.attr("href")
|
||||||
|
?.withDomain(domain) ?: return@mapIndexedNotNull null
|
||||||
|
MangaChapter(
|
||||||
|
id = href.longHashCode(),
|
||||||
|
name = a.text().trim(),
|
||||||
|
number = i + 1,
|
||||||
|
url = href,
|
||||||
|
source = source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.parsers
|
|
||||||
|
|
||||||
interface MangaParserTest {
|
|
||||||
|
|
||||||
fun testMangaList()
|
|
||||||
|
|
||||||
fun testMangaDetails()
|
|
||||||
|
|
||||||
fun testMangaPages()
|
|
||||||
|
|
||||||
fun testTags()
|
|
||||||
}
|
|
||||||
@@ -6,23 +6,23 @@ import java.net.URL
|
|||||||
|
|
||||||
object AssertX {
|
object AssertX {
|
||||||
|
|
||||||
fun assertContentType(url: String, type: String, subtype: String? = null) {
|
fun assertContentType(url: String, type: String, subtype: String? = null) {
|
||||||
Assert.assertFalse("URL is empty", url.isEmpty())
|
Assert.assertFalse("URL is empty", url.isEmpty())
|
||||||
val cn = URL(url).openConnection() as HttpURLConnection
|
val cn = URL(url).openConnection() as HttpURLConnection
|
||||||
cn.requestMethod = "HEAD"
|
cn.requestMethod = "HEAD"
|
||||||
cn.connect()
|
cn.connect()
|
||||||
when (val code = cn.responseCode) {
|
when (val code = cn.responseCode) {
|
||||||
HttpURLConnection.HTTP_MOVED_PERM,
|
HttpURLConnection.HTTP_MOVED_PERM,
|
||||||
HttpURLConnection.HTTP_MOVED_TEMP -> assertContentType(cn.getHeaderField("Location"), type, subtype)
|
HttpURLConnection.HTTP_MOVED_TEMP -> assertContentType(cn.getHeaderField("Location"), type, subtype)
|
||||||
HttpURLConnection.HTTP_OK -> {
|
HttpURLConnection.HTTP_OK -> {
|
||||||
val ct = cn.contentType.substringBeforeLast(';').split("/")
|
val ct = cn.contentType.substringBeforeLast(';').split("/")
|
||||||
Assert.assertEquals(type, ct.first())
|
Assert.assertEquals(type, ct.first())
|
||||||
if (subtype != null) {
|
if (subtype != null) {
|
||||||
Assert.assertEquals(subtype, ct.last())
|
Assert.assertEquals(subtype, ct.last())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> Assert.fail("Invalid response code $code")
|
else -> Assert.fail("Invalid response code $code")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user