|
|
|
@ -3,7 +3,6 @@ package org.koitharu.kotatsu.parsers.site.nepnep
|
|
|
|
import okhttp3.Headers
|
|
|
|
import okhttp3.Headers
|
|
|
|
import org.json.JSONArray
|
|
|
|
import org.json.JSONArray
|
|
|
|
import org.json.JSONObject
|
|
|
|
import org.json.JSONObject
|
|
|
|
import org.jsoup.nodes.Document
|
|
|
|
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaParser
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaParser
|
|
|
|
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
|
|
|
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
|
|
|
@ -13,8 +12,6 @@ import org.koitharu.kotatsu.parsers.util.*
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.toJSONList
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.toJSONList
|
|
|
|
import org.koitharu.kotatsu.parsers.util.SoftSuspendLazy
|
|
|
|
|
|
|
|
import org.koitharu.kotatsu.parsers.util.SuspendLazy
|
|
|
|
|
|
|
|
import java.text.SimpleDateFormat
|
|
|
|
import java.text.SimpleDateFormat
|
|
|
|
import java.util.*
|
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
|
|
|
|
@ -27,7 +24,8 @@ internal abstract class NepnepParser(
|
|
|
|
|
|
|
|
|
|
|
|
override val configKeyDomain = ConfigKey.Domain(domain)
|
|
|
|
override val configKeyDomain = ConfigKey.Domain(domain)
|
|
|
|
|
|
|
|
|
|
|
|
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.POPULARITY, SortOrder.UPDATED)
|
|
|
|
override val availableSortOrders: Set<SortOrder> =
|
|
|
|
|
|
|
|
EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.POPULARITY, SortOrder.UPDATED)
|
|
|
|
override val availableStates: Set<MangaState> = EnumSet.allOf(MangaState::class.java)
|
|
|
|
override val availableStates: Set<MangaState> = EnumSet.allOf(MangaState::class.java)
|
|
|
|
override val isTagsExclusionSupported = true
|
|
|
|
override val isTagsExclusionSupported = true
|
|
|
|
|
|
|
|
|
|
|
|
@ -35,22 +33,20 @@ internal abstract class NepnepParser(
|
|
|
|
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
|
|
|
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
|
|
|
.build()
|
|
|
|
.build()
|
|
|
|
|
|
|
|
|
|
|
|
private lateinit var docCache: Document
|
|
|
|
private val searchDoc = SoftSuspendLazy {
|
|
|
|
private var mangaListCache: List<Manga> = emptyList()
|
|
|
|
webClient.httpGet("https://$domain/search/").parseHtml()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
data class MangaWithLastUpdate(
|
|
|
|
data class MangaWithLastUpdate(
|
|
|
|
val manga: Manga,
|
|
|
|
val manga: Manga,
|
|
|
|
val lastUpdate: Long,
|
|
|
|
val lastUpdate: Long,
|
|
|
|
val views: String
|
|
|
|
val views: String,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
override suspend fun getList(offset: Int, filter: MangaListFilter?): List<Manga> {
|
|
|
|
|
|
|
|
val doc = if (::docCache.isInitialized) {
|
|
|
|
|
|
|
|
docCache
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
webClient.httpGet("https://$domain/search/").parseHtml()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val json = JSONArray(doc.selectFirstOrThrow("script:containsData(MainFunction)").data()
|
|
|
|
override suspend fun getList(offset: Int, filter: MangaListFilter?): List<Manga> {
|
|
|
|
|
|
|
|
val doc = searchDoc.get()
|
|
|
|
|
|
|
|
val json = JSONArray(
|
|
|
|
|
|
|
|
doc.selectFirstOrThrow("script:containsData(MainFunction)").data()
|
|
|
|
.substringAfter("vm.Directory = ")
|
|
|
|
.substringAfter("vm.Directory = ")
|
|
|
|
.substringBefore("vm.GetIntValue")
|
|
|
|
.substringBefore("vm.GetIntValue")
|
|
|
|
.trim()
|
|
|
|
.trim()
|
|
|
|
@ -70,10 +66,12 @@ internal abstract class NepnepParser(
|
|
|
|
when (filter) {
|
|
|
|
when (filter) {
|
|
|
|
|
|
|
|
|
|
|
|
is MangaListFilter.Search -> {
|
|
|
|
is MangaListFilter.Search -> {
|
|
|
|
if (m.getString("s").contains(filter.query, ignoreCase = true) || (m.getJSONArray("al").length() > 0 && m.getJSONArray("al").getString(0).contains(filter.query, ignoreCase = true))
|
|
|
|
if (m.getString("s").contains(filter.query, ignoreCase = true) || (m.getJSONArray("al")
|
|
|
|
|
|
|
|
.length() > 0 && m.getJSONArray("al").getString(0)
|
|
|
|
|
|
|
|
.contains(filter.query, ignoreCase = true))
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
mangaWithLastUpdateList.add(
|
|
|
|
mangaWithLastUpdateList.add(
|
|
|
|
MangaWithLastUpdate(addManga(href, imgUrl, m), lastUpdate, views)
|
|
|
|
MangaWithLastUpdate(addManga(href, imgUrl, m), lastUpdate, views),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -83,8 +81,14 @@ internal abstract class NepnepParser(
|
|
|
|
val tagsExcluded = filter.tagsExclude
|
|
|
|
val tagsExcluded = filter.tagsExclude
|
|
|
|
val tagsJson = m.getJSONArray("g").toString()
|
|
|
|
val tagsJson = m.getJSONArray("g").toString()
|
|
|
|
|
|
|
|
|
|
|
|
val tagsMatched = tags.isEmpty() || tags.all { tag -> tagsJson.contains(tag.key, ignoreCase = true) }
|
|
|
|
val tagsMatched =
|
|
|
|
val tagsExcludeMatched = tagsExcluded.isEmpty() || tagsExcluded.none { tag -> tagsJson.contains(tag.key, ignoreCase = true) }
|
|
|
|
tags.isEmpty() || tags.all { tag -> tagsJson.contains(tag.key, ignoreCase = true) }
|
|
|
|
|
|
|
|
val tagsExcludeMatched = tagsExcluded.isEmpty() || tagsExcluded.none { tag ->
|
|
|
|
|
|
|
|
tagsJson.contains(
|
|
|
|
|
|
|
|
tag.key,
|
|
|
|
|
|
|
|
ignoreCase = true,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
val statesMatched = filter.states.isEmpty() || filter.states.any { state ->
|
|
|
|
val statesMatched = filter.states.isEmpty() || filter.states.any { state ->
|
|
|
|
m.getString("ps").contains(
|
|
|
|
m.getString("ps").contains(
|
|
|
|
when (state) {
|
|
|
|
when (state) {
|
|
|
|
@ -99,7 +103,7 @@ internal abstract class NepnepParser(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tagsMatched && tagsExcludeMatched && statesMatched) {
|
|
|
|
if (tagsMatched && tagsExcludeMatched && statesMatched) {
|
|
|
|
mangaWithLastUpdateList.add(
|
|
|
|
mangaWithLastUpdateList.add(
|
|
|
|
MangaWithLastUpdate(addManga(href, imgUrl, m), lastUpdate, views)
|
|
|
|
MangaWithLastUpdate(addManga(href, imgUrl, m), lastUpdate, views),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -108,7 +112,7 @@ internal abstract class NepnepParser(
|
|
|
|
|
|
|
|
|
|
|
|
null -> {
|
|
|
|
null -> {
|
|
|
|
mangaWithLastUpdateList.add(
|
|
|
|
mangaWithLastUpdateList.add(
|
|
|
|
MangaWithLastUpdate(addManga(href, imgUrl, m), lastUpdate, views)
|
|
|
|
MangaWithLastUpdate(addManga(href, imgUrl, m), lastUpdate, views),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -123,7 +127,8 @@ internal abstract class NepnepParser(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mangaWithLastUpdateList.map { it.manga }.subList(offset, (offset + 30).coerceAtMost(mangaWithLastUpdateList.size))
|
|
|
|
return mangaWithLastUpdateList.map { it.manga }
|
|
|
|
|
|
|
|
.subList(offset, (offset + 30).coerceAtMost(mangaWithLastUpdateList.size))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun addManga(href: String, imgUrl: String, m: JSONObject): Manga {
|
|
|
|
private fun addManga(href: String, imgUrl: String, m: JSONObject): Manga {
|
|
|
|
@ -145,11 +150,7 @@ internal abstract class NepnepParser(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override suspend fun getAvailableTags(): Set<MangaTag> {
|
|
|
|
override suspend fun getAvailableTags(): Set<MangaTag> {
|
|
|
|
val doc = if (::docCache.isInitialized) {
|
|
|
|
val doc = searchDoc.get()
|
|
|
|
docCache
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
webClient.httpGet("https://$domain/search/").parseHtml()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
val tags = doc.selectFirstOrThrow("script:containsData(vm.AvailableFilters)").data()
|
|
|
|
val tags = doc.selectFirstOrThrow("script:containsData(vm.AvailableFilters)").data()
|
|
|
|
.substringAfter("\"Genre\"")
|
|
|
|
.substringAfter("\"Genre\"")
|
|
|
|
.substringAfter('[')
|
|
|
|
.substringAfter('[')
|
|
|
|
|