|
|
|
@ -1,5 +1,6 @@
|
|
|
|
package org.koitharu.kotatsu.parsers.site
|
|
|
|
package org.koitharu.kotatsu.parsers.site
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import androidx.collection.ArrayMap
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
|
|
|
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
|
|
|
import org.koitharu.kotatsu.parsers.PagedMangaParser
|
|
|
|
import org.koitharu.kotatsu.parsers.PagedMangaParser
|
|
|
|
@ -24,6 +25,8 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont
|
|
|
|
SortOrder.ALPHABETICAL,
|
|
|
|
SortOrder.ALPHABETICAL,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private val tagsCache = SuspendLazy(::fetchTags)
|
|
|
|
|
|
|
|
|
|
|
|
override suspend fun getListPage(
|
|
|
|
override suspend fun getListPage(
|
|
|
|
page: Int,
|
|
|
|
page: Int,
|
|
|
|
query: String?,
|
|
|
|
query: String?,
|
|
|
|
@ -54,10 +57,12 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont
|
|
|
|
?: throw ParseException("Invalid response", url)
|
|
|
|
?: throw ParseException("Invalid response", url)
|
|
|
|
val total = json.length()
|
|
|
|
val total = json.length()
|
|
|
|
val list = ArrayList<Manga>(total)
|
|
|
|
val list = ArrayList<Manga>(total)
|
|
|
|
|
|
|
|
val tagsMap = tagsCache.tryGet().getOrNull()
|
|
|
|
for (i in 0 until total) {
|
|
|
|
for (i in 0 until total) {
|
|
|
|
val jo = json.getJSONObject(i)
|
|
|
|
val jo = json.getJSONObject(i)
|
|
|
|
val cover = jo.getJSONObject("image")
|
|
|
|
val cover = jo.getJSONObject("image")
|
|
|
|
val id = jo.getLong("id")
|
|
|
|
val id = jo.getLong("id")
|
|
|
|
|
|
|
|
val genres = jo.getString("genres").split(',')
|
|
|
|
list += Manga(
|
|
|
|
list += Manga(
|
|
|
|
url = "/manga/api/$id",
|
|
|
|
url = "/manga/api/$id",
|
|
|
|
publicUrl = jo.getString("url"),
|
|
|
|
publicUrl = jo.getString("url"),
|
|
|
|
@ -73,7 +78,13 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont
|
|
|
|
rating = jo.getDouble("score").toFloat().coerceIn(0f, 1f),
|
|
|
|
rating = jo.getDouble("score").toFloat().coerceIn(0f, 1f),
|
|
|
|
id = generateUid(id),
|
|
|
|
id = generateUid(id),
|
|
|
|
isNsfw = false,
|
|
|
|
isNsfw = false,
|
|
|
|
tags = emptySet(),
|
|
|
|
tags = if (!tagsMap.isNullOrEmpty()) {
|
|
|
|
|
|
|
|
genres.mapNotNullToSet { g ->
|
|
|
|
|
|
|
|
tagsMap[g.trim().toTitleCase()]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
emptySet()
|
|
|
|
|
|
|
|
},
|
|
|
|
author = null,
|
|
|
|
author = null,
|
|
|
|
description = jo.getString("description"),
|
|
|
|
description = jo.getString("description"),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
@ -133,12 +144,27 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override suspend fun getTags(): Set<MangaTag> {
|
|
|
|
override suspend fun getTags(): Set<MangaTag> {
|
|
|
|
|
|
|
|
return tagsCache.get().values.toSet()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun getSortKey(sortOrder: SortOrder) =
|
|
|
|
|
|
|
|
when (sortOrder) {
|
|
|
|
|
|
|
|
SortOrder.ALPHABETICAL -> "name"
|
|
|
|
|
|
|
|
SortOrder.POPULARITY -> "popular"
|
|
|
|
|
|
|
|
SortOrder.UPDATED -> "updated"
|
|
|
|
|
|
|
|
SortOrder.NEWEST -> "id"
|
|
|
|
|
|
|
|
else -> "updated"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private suspend fun fetchTags(): Map<String, MangaTag> {
|
|
|
|
val doc = webClient.httpGet("https://${domain}/manga/").parseHtml()
|
|
|
|
val doc = webClient.httpGet("https://${domain}/manga/").parseHtml()
|
|
|
|
val root = doc.body().requireElementById("animeFilter")
|
|
|
|
val root = doc.body().requireElementById("animeFilter")
|
|
|
|
.selectFirstOrThrow(".catalog-genres")
|
|
|
|
.selectFirstOrThrow(".catalog-genres")
|
|
|
|
return root.select("li").mapToSet {
|
|
|
|
val li = root.select("li")
|
|
|
|
|
|
|
|
val result = ArrayMap<String, MangaTag>(li.size)
|
|
|
|
|
|
|
|
li.forEach {
|
|
|
|
val input = it.selectFirstOrThrow("input")
|
|
|
|
val input = it.selectFirstOrThrow("input")
|
|
|
|
MangaTag(
|
|
|
|
val tag = MangaTag(
|
|
|
|
source = source,
|
|
|
|
source = source,
|
|
|
|
key = input.attr("data-genre-slug").ifEmpty {
|
|
|
|
key = input.attr("data-genre-slug").ifEmpty {
|
|
|
|
it.parseFailed("data-genre-slug is empty")
|
|
|
|
it.parseFailed("data-genre-slug is empty")
|
|
|
|
@ -147,15 +173,8 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont
|
|
|
|
it.parseFailed("data-genre-name is empty")
|
|
|
|
it.parseFailed("data-genre-name is empty")
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
result[tag.title] = tag
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
private fun getSortKey(sortOrder: SortOrder) =
|
|
|
|
|
|
|
|
when (sortOrder) {
|
|
|
|
|
|
|
|
SortOrder.ALPHABETICAL -> "name"
|
|
|
|
|
|
|
|
SortOrder.POPULARITY -> "popular"
|
|
|
|
|
|
|
|
SortOrder.UPDATED -> "updated"
|
|
|
|
|
|
|
|
SortOrder.NEWEST -> "id"
|
|
|
|
|
|
|
|
else -> "updated"
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|