diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt index 091852f6..20eb19b0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt @@ -2,8 +2,6 @@ package org.koitharu.kotatsu.parsers.site.all import androidx.collection.ArrayMap import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser @@ -16,7 +14,7 @@ import java.util.* @MangaSourceParser("MANGAPARK", "MangaPark") internal class MangaPark(context: MangaLoaderContext) : - PagedMangaParser(context, MangaSource.MANGAPARK, pageSize = 15) { + PagedMangaParser(context, MangaSource.MANGAPARK, pageSize = 36) { override val availableSortOrders: Set = EnumSet.allOf(SortOrder::class.java) @@ -24,6 +22,8 @@ internal class MangaPark(context: MangaLoaderContext) : override val configKeyDomain = ConfigKey.Domain("mangapark.net") + private val tagsMap = SuspendLazy(::parseTags) + init { context.cookieJar.insertCookies(domain, "nsfw", "2") } @@ -101,18 +101,14 @@ internal class MangaPark(context: MangaLoaderContext) : } } - private var tagCache: ArrayMap? = null - private val mutex = Mutex() - override suspend fun getAvailableTags(): Set { - return getOrCreateTagMap().values.toSet() + return tagsMap.get().values.toSet() } - private suspend fun getOrCreateTagMap(): Map = mutex.withLock { - tagCache?.let { return@withLock it } - val tagMap = ArrayMap() + private suspend fun parseTags(): Map { val tagElements = webClient.httpGet("https://$domain/search").parseHtml() .select("div.flex-col:contains(Genres) div.whitespace-nowrap") + val tagMap = ArrayMap(tagElements.size) for (el in tagElements) { val name = el.selectFirstOrThrow("span.whitespace-nowrap").text() if (name.isEmpty()) continue @@ -122,8 +118,7 @@ internal class MangaPark(context: MangaLoaderContext) : source = source, ) } - tagCache = tagMap - return@withLock tagMap + return tagMap } override suspend fun getAvailableLocales(): Set = setOf( @@ -151,11 +146,10 @@ internal class MangaPark(context: MangaLoaderContext) : override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() - val tagMap = getOrCreateTagMap() + val tagMap = tagsMap.get() val selectTag = doc.select("div[q:key=30_2] span.whitespace-nowrap") val tags = selectTag.mapNotNullToSet { tagMap[it.text()] } - val nsfw = - tags.contains(MangaTag("Hentai", "hentai", source)) || tags.contains(MangaTag("Adult", "adult", source)) + val nsfw = tags.any { t -> t.key == "hentai" || t.key == "adult" } val dateFormat = SimpleDateFormat("dd/MM/yyyy", sourceLocale) manga.copy( altTitle = doc.selectFirst("div[q:key=tz_2]")?.text().orEmpty(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPlusParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPlusParser.kt index d9a39f50..1796e65a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPlusParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPlusParser.kt @@ -12,26 +12,13 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey -import org.koitharu.kotatsu.parsers.model.Manga -import org.koitharu.kotatsu.parsers.model.MangaChapter -import org.koitharu.kotatsu.parsers.model.MangaListFilter -import org.koitharu.kotatsu.parsers.model.MangaPage -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.model.MangaState -import org.koitharu.kotatsu.parsers.model.MangaTag -import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN -import org.koitharu.kotatsu.parsers.model.SortOrder -import org.koitharu.kotatsu.parsers.util.SuspendLazy -import org.koitharu.kotatsu.parsers.util.domain -import org.koitharu.kotatsu.parsers.util.generateUid +import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.getStringOrNull import org.koitharu.kotatsu.parsers.util.json.mapJSON import org.koitharu.kotatsu.parsers.util.json.mapJSONNotNull import org.koitharu.kotatsu.parsers.util.json.toJSONList -import org.koitharu.kotatsu.parsers.util.parseJson -import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl -import org.koitharu.kotatsu.parsers.util.toTitleCase -import java.util.UUID +import java.util.* internal abstract class MangaPlusParser( context: MangaLoaderContext, @@ -39,9 +26,10 @@ internal abstract class MangaPlusParser( private val sourceLang: String, ) : MangaParser(context, source), Interceptor { + private val apiUrl = "https://jumpg-webapi.tokyo-cdn.com/api" override val configKeyDomain = ConfigKey.Domain("mangaplus.shueisha.co.jp") - override val availableSortOrders = setOf( + override val availableSortOrders: Set = EnumSet.of( SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.ALPHABETICAL, @@ -106,16 +94,19 @@ internal abstract class MangaPlusParser( return mapNotNull { val language = it.getStringOrNull("language") ?: "ENGLISH" - if (language != sourceLang) + if (language != sourceLang) { return@mapNotNull null + } val name = it.getString("name") val author = it.getString("author") - .split("/").joinToString(transform = String::trim) + .split('/') + .joinToString(transform = String::trim) // filter out any other title or author which doesn't match search input - if (query != null && !(name.contains(query, true) || author.contains(query, true))) + if (query != null && !(name.contains(query, true) || author.contains(query, true))) { return@mapNotNull null + } val titleId = it.getInt("titleId").toString() @@ -164,12 +155,10 @@ internal abstract class MangaPlusParser( json.getJSONArray("chapterListGroup"), title.getStringOrNull("language") ?: "ENGLISH", ), - state = if (completed) { - MangaState.FINISHED - } else if (hiatus) { - MangaState.PAUSED - } else { - MangaState.ONGOING + state = when { + completed -> MangaState.FINISHED + hiatus -> MangaState.PAUSED + else -> MangaState.ONGOING }, ) } @@ -182,10 +171,9 @@ internal abstract class MangaPlusParser( it.optJSONArray("lastChapterList")?.toJSONList().orEmpty() } - return chapterList.mapNotNull { chapter -> + return chapterList.mapChapters { _, chapter -> val chapterId = chapter.getInt("chapterId").toString() - val subtitle = chapter.getStringOrNull("subTitle") - ?: return@mapNotNull null + val subtitle = chapter.getStringOrNull("subTitle") ?: return@mapChapters null MangaChapter( id = generateUid(chapterId), @@ -275,10 +263,6 @@ internal abstract class MangaPlusParser( } } - companion object { - private const val apiUrl = "https://jumpg-webapi.tokyo-cdn.com/api" - } - @MangaSourceParser("MANGAPLUSPARSER_EN", "MANGA Plus English", "en") class English(context: MangaLoaderContext) : MangaPlusParser( context,