|
|
|
@ -9,6 +9,8 @@ import org.koitharu.kotatsu.parsers.util.*
|
|
|
|
import java.text.SimpleDateFormat
|
|
|
|
import java.text.SimpleDateFormat
|
|
|
|
import java.util.*
|
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private const val DEF_BRANCH_NAME = "Основний переклад"
|
|
|
|
|
|
|
|
|
|
|
|
@MangaSourceParser("MANGAINUA", "MANGA/in/UA", "uk")
|
|
|
|
@MangaSourceParser("MANGAINUA", "MANGA/in/UA", "uk")
|
|
|
|
class MangaInUaParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGAINUA) {
|
|
|
|
class MangaInUaParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGAINUA) {
|
|
|
|
|
|
|
|
|
|
|
|
@ -21,41 +23,41 @@ class MangaInUaParser(override val context: MangaLoaderContext) : MangaParser(Ma
|
|
|
|
offset: Int,
|
|
|
|
offset: Int,
|
|
|
|
query: String?,
|
|
|
|
query: String?,
|
|
|
|
tags: Set<MangaTag>?,
|
|
|
|
tags: Set<MangaTag>?,
|
|
|
|
sortOrder: SortOrder?
|
|
|
|
sortOrder: SortOrder?,
|
|
|
|
): List<Manga> {
|
|
|
|
): List<Manga> {
|
|
|
|
val page = (offset / 24f).toIntUp().inc()
|
|
|
|
val page = (offset / 24f).toIntUp().inc()
|
|
|
|
val searchPage = (offset / 10f).toIntUp().inc()
|
|
|
|
val searchPage = (offset / 10f).toIntUp().inc()
|
|
|
|
val url = when {
|
|
|
|
val url = when {
|
|
|
|
!query.isNullOrEmpty() -> ("/index.php?do=search" +
|
|
|
|
!query.isNullOrEmpty() -> (
|
|
|
|
|
|
|
|
"/index.php?do=search" +
|
|
|
|
"&subaction=search" +
|
|
|
|
"&subaction=search" +
|
|
|
|
"&search_start=${searchPage}" +
|
|
|
|
"&search_start=$searchPage" +
|
|
|
|
"&full_search=1" +
|
|
|
|
"&full_search=1" +
|
|
|
|
"&story=${query}" +
|
|
|
|
"&story=$query" +
|
|
|
|
"&titleonly=3").withDomain()
|
|
|
|
"&titleonly=3"
|
|
|
|
|
|
|
|
).withDomain()
|
|
|
|
tags.isNullOrEmpty() -> "/mangas/page/$page".withDomain()
|
|
|
|
tags.isNullOrEmpty() -> "/mangas/page/$page".withDomain()
|
|
|
|
tags.size == 1 -> "${tags.first().key}/page/$page"
|
|
|
|
tags.size == 1 -> "${tags.first().key}/page/$page"
|
|
|
|
tags.size > 1 -> throw IllegalArgumentException("This source supports only 1 genre")
|
|
|
|
tags.size > 1 -> throw IllegalArgumentException("This source supports only 1 genre")
|
|
|
|
else -> "/mangas/page/${page}".withDomain()
|
|
|
|
else -> "/mangas/page/$page".withDomain()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
val doc = context.httpGet(url).parseHtml()
|
|
|
|
val doc = context.httpGet(url).parseHtml()
|
|
|
|
val container = doc.body().getElementById("dle-content") ?: parseFailed("Container not found")
|
|
|
|
val container = doc.body().getElementById("dle-content") ?: parseFailed("Container not found")
|
|
|
|
val items = container.select("div.col-6")
|
|
|
|
val items = container.select("div.col-6")
|
|
|
|
return items.mapNotNull { item ->
|
|
|
|
return items.mapNotNull { item ->
|
|
|
|
val href = item.selectFirst("a")?.attrAsRelativeUrl("href") ?: return@mapNotNull null
|
|
|
|
val href = item.selectFirst("a")?.attrAsRelativeUrl("href") ?: return@mapNotNull null
|
|
|
|
val listCover = item.selectFirst("header.card__cover")?.selectFirst("img")?.attrAsAbsoluteUrlOrNull("data-src")
|
|
|
|
|
|
|
|
val searchCover = item.selectFirst("header.card__cover")?.selectFirst("img")?.attrAsAbsoluteUrlOrNull("src").orEmpty()
|
|
|
|
|
|
|
|
Manga(
|
|
|
|
Manga(
|
|
|
|
id = generateUid(href),
|
|
|
|
id = generateUid(href),
|
|
|
|
title = item.selectFirst("h3.card__title")?.text() ?: return@mapNotNull null,
|
|
|
|
title = item.selectFirst("h3.card__title")?.text() ?: return@mapNotNull null,
|
|
|
|
coverUrl = listCover ?: searchCover,
|
|
|
|
coverUrl = item.selectFirst("header.card__cover")?.selectFirst("img")?.run {
|
|
|
|
|
|
|
|
attrAsAbsoluteUrlOrNull("data-src") ?: attrAsAbsoluteUrlOrNull("src")
|
|
|
|
|
|
|
|
}.orEmpty(),
|
|
|
|
altTitle = null,
|
|
|
|
altTitle = null,
|
|
|
|
author = null,
|
|
|
|
author = null,
|
|
|
|
rating = runCatching {
|
|
|
|
rating = item.selectFirst("div.card__short-rate--num")
|
|
|
|
item.selectFirst("div.card__short-rate--num")
|
|
|
|
?.text()
|
|
|
|
?.text()
|
|
|
|
?.toFloatOrNull()
|
|
|
|
?.toFloatOrNull()
|
|
|
|
?.div(10F) ?: RATING_UNKNOWN,
|
|
|
|
?.div(10F)
|
|
|
|
|
|
|
|
}.getOrNull() ?: RATING_UNKNOWN,
|
|
|
|
|
|
|
|
url = href,
|
|
|
|
url = href,
|
|
|
|
isNsfw = item.selectFirst("ul.card__list")?.select("li")?.lastOrNull()?.text() == "18+",
|
|
|
|
isNsfw = item.selectFirst("ul.card__list")?.select("li")?.lastOrNull()?.text() == "18+",
|
|
|
|
tags = runCatching {
|
|
|
|
tags = runCatching {
|
|
|
|
@ -79,31 +81,48 @@ class MangaInUaParser(override val context: MangaLoaderContext) : MangaParser(Ma
|
|
|
|
val root =
|
|
|
|
val root =
|
|
|
|
doc.body().getElementById("dle-content") ?: parseFailed("Cannot find root")
|
|
|
|
doc.body().getElementById("dle-content") ?: parseFailed("Cannot find root")
|
|
|
|
val dateFormat = SimpleDateFormat("dd.MM.yyyy", Locale.US)
|
|
|
|
val dateFormat = SimpleDateFormat("dd.MM.yyyy", Locale.US)
|
|
|
|
|
|
|
|
val chaptersRoot = root.selectFirst(".linkstocomics")
|
|
|
|
|
|
|
|
var prevChapterName: String? = null
|
|
|
|
|
|
|
|
var i = 0
|
|
|
|
return manga.copy(
|
|
|
|
return manga.copy(
|
|
|
|
description = root.selectFirst("div.item__full-description")?.text(),
|
|
|
|
description = root.selectFirst("div.item__full-description")?.text(),
|
|
|
|
largeCoverUrl = root.selectFirst("div.item__full-sidebar--poster")?.selectFirst("img")?.attrAsAbsoluteUrl("src").orEmpty(),
|
|
|
|
largeCoverUrl = root.selectFirst("div.item__full-sidebar--poster")?.selectFirst("img")
|
|
|
|
chapters = root.select("div.linkstocomics").mapIndexedNotNull { i, item ->
|
|
|
|
?.attrAsAbsoluteUrlOrNull("src"),
|
|
|
|
val href = item?.selectFirst("a")?.attr("href")
|
|
|
|
chapters = chaptersRoot?.select("div.ltcitems")?.mapNotNull { item ->
|
|
|
|
?: return@mapIndexedNotNull null
|
|
|
|
val href = item?.selectFirst("a")?.attrAsRelativeUrlOrNull("href")
|
|
|
|
|
|
|
|
?: return@mapNotNull null
|
|
|
|
|
|
|
|
val isAlternative = item.styleValueOrNull("background") != null
|
|
|
|
|
|
|
|
val name = item.selectFirst("a")?.text().orEmpty()
|
|
|
|
|
|
|
|
if (!isAlternative) i++
|
|
|
|
MangaChapter(
|
|
|
|
MangaChapter(
|
|
|
|
id = generateUid(href),
|
|
|
|
id = generateUid(href),
|
|
|
|
name = item.selectFirst("a")?.text().orEmpty(),
|
|
|
|
name = if (isAlternative) {
|
|
|
|
number = i + 1,
|
|
|
|
prevChapterName ?: return@mapNotNull null
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
prevChapterName = name
|
|
|
|
|
|
|
|
name
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
number = i,
|
|
|
|
url = href,
|
|
|
|
url = href,
|
|
|
|
scanlator = null,
|
|
|
|
scanlator = null,
|
|
|
|
branch = null,
|
|
|
|
branch = if (isAlternative) {
|
|
|
|
|
|
|
|
name.substringAfterLast(':').trim()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
DEF_BRANCH_NAME
|
|
|
|
|
|
|
|
},
|
|
|
|
uploadDate = dateFormat.tryParse(item.selectFirst("div.ltcright")?.text()),
|
|
|
|
uploadDate = dateFormat.tryParse(item.selectFirst("div.ltcright")?.text()),
|
|
|
|
source = source,
|
|
|
|
source = source,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
},
|
|
|
|
}.orEmpty(),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
|
|
|
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
|
|
|
val fullUrl = chapter.url.withDomain()
|
|
|
|
val fullUrl = chapter.url.withDomain()
|
|
|
|
val doc = context.httpGet(fullUrl).parseHtml()
|
|
|
|
val doc = context.httpGet(fullUrl).parseHtml()
|
|
|
|
val root = doc.body().getElementById("comics") ?: parseFailed("Root not found")
|
|
|
|
val root =
|
|
|
|
return root.select("ul.xfieldimagegallery").map { ul ->
|
|
|
|
doc.body().getElementById("comics")?.selectFirst("ul.xfieldimagegallery") ?: parseFailed("Root not found")
|
|
|
|
|
|
|
|
return root.select("li").map { ul ->
|
|
|
|
val img = ul.selectFirst("img") ?: parseFailed("Page image not found")
|
|
|
|
val img = ul.selectFirst("img") ?: parseFailed("Page image not found")
|
|
|
|
val url = img.attrAsAbsoluteUrl("data-src")
|
|
|
|
val url = img.attrAsAbsoluteUrl("data-src")
|
|
|
|
MangaPage(
|
|
|
|
MangaPage(
|
|
|
|
@ -119,9 +138,10 @@ class MangaInUaParser(override val context: MangaLoaderContext) : MangaParser(Ma
|
|
|
|
override suspend fun getTags(): Set<MangaTag> {
|
|
|
|
override suspend fun getTags(): Set<MangaTag> {
|
|
|
|
val domain = getDomain()
|
|
|
|
val domain = getDomain()
|
|
|
|
val doc = context.httpGet("https://$domain/mangas").parseHtml()
|
|
|
|
val doc = context.httpGet("https://$domain/mangas").parseHtml()
|
|
|
|
val root = doc.body().getElementById("menu_1")?.selectFirst("div.menu__wrapper") ?: parseFailed("Cannot find root")
|
|
|
|
val root =
|
|
|
|
return root.select("li").mapToSet { li ->
|
|
|
|
doc.body().getElementById("menu_1")?.selectFirst("div.menu__wrapper") ?: parseFailed("Cannot find root")
|
|
|
|
val a = li.selectFirst("a") ?: parseFailed("a is null")
|
|
|
|
return root.select("li").mapNotNullToSet { li ->
|
|
|
|
|
|
|
|
val a = li.selectFirst("a") ?: return@mapNotNullToSet null
|
|
|
|
MangaTag(
|
|
|
|
MangaTag(
|
|
|
|
title = a.ownText(),
|
|
|
|
title = a.ownText(),
|
|
|
|
key = a.attr("href").removeSuffix("/"),
|
|
|
|
key = a.attr("href").removeSuffix("/"),
|
|
|
|
|