diff --git a/.gitignore b/.gitignore index 04c03155..e5843e14 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ .idea/compiler.xml .idea/jarRepositories.xml .idea/modules.xml +.idea/ktlint-plugin.xml .idea/*.iml .idea/modules *.iml @@ -76,4 +77,4 @@ build/ .idea/codeStyles/ src/test/resources/cookies.txt -local.properties \ No newline at end of file +local.properties diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index e805548a..8d81632f 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/build.gradle b/build.gradle index 3650828c..0e41be7a 100644 --- a/build.gradle +++ b/build.gradle @@ -2,8 +2,8 @@ import tasks.ReportGenerateTask plugins { id 'java-library' - id 'org.jetbrains.kotlin.jvm' version '1.9.20' - id 'com.google.devtools.ksp' version '1.9.20-1.0.14' + id 'org.jetbrains.kotlin.jvm' version '1.9.22' + id 'com.google.devtools.ksp' version '1.9.22-1.0.16' id 'maven-publish' } @@ -55,16 +55,16 @@ afterEvaluate { dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3' implementation 'com.squareup.okhttp3:okhttp:4.12.0' - implementation 'com.squareup.okio:okio:3.6.0' - api 'org.jsoup:jsoup:1.16.2' + implementation 'com.squareup.okio:okio:3.7.0' + api 'org.jsoup:jsoup:1.17.2' implementation 'org.json:json:20231013' implementation 'androidx.collection:collection-ktx:1.3.0' ksp project(':kotatsu-parsers-ksp') - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0' - testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.0' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.0' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.1' + testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.1' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.1' testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3' testImplementation 'io.webfolder:quickjs:1.1.0' } diff --git a/kotatsu-parsers-ksp/build.gradle b/kotatsu-parsers-ksp/build.gradle index 87e55c15..f589f01d 100644 --- a/kotatsu-parsers-ksp/build.gradle +++ b/kotatsu-parsers-ksp/build.gradle @@ -3,5 +3,5 @@ plugins { } dependencies { - implementation 'com.google.devtools.ksp:symbol-processing-api:1.9.20-1.0.14' + implementation 'com.google.devtools.ksp:symbol-processing-api:1.9.22-1.0.16' } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/ErrorMessages.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/ErrorMessages.kt index ade47d3b..57ae550d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/ErrorMessages.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/ErrorMessages.kt @@ -4,6 +4,8 @@ object ErrorMessages { const val FILTER_MULTIPLE_STATES_NOT_SUPPORTED = "Multiple states are not supported by this source" const val FILTER_MULTIPLE_GENRES_NOT_SUPPORTED = "Multiple genres are not supported by this source" + const val FILTER_MULTIPLE_CONTENT_RATING_NOT_SUPPORTED = + "Multiple Content Rating are not supported by this source" const val FILTER_BOTH_LOCALE_GENRES_NOT_SUPPORTED = "Filtering by both genres and locale is not supported by this source" const val FILTER_BOTH_STATES_GENRES_NOT_SUPPORTED = diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt index 5ee0df95..8de5048c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt @@ -33,11 +33,25 @@ abstract class MangaParser @InternalParsersApi constructor( open val availableStates: Set get() = emptySet() + + open val availableContentRating: Set + get() = emptySet() + /** * Whether parser supports filtering by more than one tag */ open val isMultipleTagsSupported: Boolean = true + /** + * Whether parser supports tagsExclude field in filter + */ + open val isTagsExclusionSupported: Boolean = false + + /** + * Whether parser supports searching by string query using [MangaListFilter.Search] + */ + open val isSearchSupported: Boolean = true + @Deprecated( message = "Use availableSortOrders instead", replaceWith = ReplaceWith("availableSortOrders"), @@ -95,6 +109,7 @@ abstract class MangaParser @InternalParsersApi constructor( offset: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List = throw NotImplementedError("Please implement getList(offset, filter) instead") @@ -130,18 +145,51 @@ abstract class MangaParser @InternalParsersApi constructor( "org.koitharu.kotatsu.parsers.model.MangaListFilter", ), ) - open suspend fun getList(offset: Int, tags: Set?, sortOrder: SortOrder?): List { + open suspend fun getList( + offset: Int, + tags: Set?, + tagsExclude: Set?, + sortOrder: SortOrder?, + ): List { return getList( offset, - MangaListFilter.Advanced(sortOrder ?: defaultSortOrder, tags.orEmpty(), null, emptySet()), + MangaListFilter.Advanced( + sortOrder = sortOrder ?: defaultSortOrder, + tags = tags.orEmpty(), + tagsExclude = tagsExclude.orEmpty(), + locale = null, + states = emptySet(), + contentRating = emptySet(), + ), ) } + @Suppress("DEPRECATION") open suspend fun getList(offset: Int, filter: MangaListFilter?): List { return when (filter) { - is MangaListFilter.Advanced -> getList(offset, null, filter.tags, filter.sortOrder) - is MangaListFilter.Search -> getList(offset, filter.query, null, defaultSortOrder) - null -> getList(offset, null, null, defaultSortOrder) + is MangaListFilter.Advanced -> getList( + offset = offset, + query = null, + tags = filter.tags, + tagsExclude = filter.tagsExclude, + sortOrder = filter.sortOrder, + ) + + is MangaListFilter.Search -> getList( + offset = offset, + query = filter.query, + tags = null, + tagsExclude = null, + sortOrder = defaultSortOrder, + ) + + null -> getList( + offset = offset, + query = null, + tags = null, + tagsExclude = null, + sortOrder = defaultSortOrder, + ) } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/PagedMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/PagedMangaParser.kt index fffb1d01..6d638a2a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/PagedMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/PagedMangaParser.kt @@ -36,6 +36,7 @@ abstract class PagedMangaParser( offset: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List = throw UnsupportedOperationException("You should use getListPage for PagedMangaParser") @@ -43,14 +44,35 @@ abstract class PagedMangaParser( page: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List = throw NotImplementedError("Please implement getListPage(page, filter) instead") open suspend fun getListPage(page: Int, filter: MangaListFilter?): List { return when (filter) { - is MangaListFilter.Advanced -> getListPage(page, null, filter.tags, filter.sortOrder) - is MangaListFilter.Search -> getListPage(page, filter.query, null, defaultSortOrder) - null -> getListPage(page, null, null, defaultSortOrder) + is MangaListFilter.Advanced -> getListPage( + page = page, + query = null, + tags = filter.tags, + tagsExclude = filter.tagsExclude, + sortOrder = filter.sortOrder, + ) + + is MangaListFilter.Search -> getListPage( + page = page, + query = filter.query, + tags = null, + tagsExclude = null, + sortOrder = defaultSortOrder, + ) + + null -> getListPage( + page = page, + query = null, + tags = null, + tagsExclude = null, + sortOrder = defaultSortOrder, + ) } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/ContentRating.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/ContentRating.kt new file mode 100644 index 00000000..eb5c8614 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/ContentRating.kt @@ -0,0 +1,7 @@ +package org.koitharu.kotatsu.parsers.model + +enum class ContentRating { + SAFE, + SUGGESTIVE, + ADULT +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaListFilter.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaListFilter.kt index b861068d..2abe61f6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaListFilter.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaListFilter.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.parsers.model +import org.koitharu.kotatsu.parsers.MangaParser import java.util.* sealed interface MangaListFilter { @@ -8,6 +9,16 @@ sealed interface MangaListFilter { val sortOrder: SortOrder? + fun isValid(parser: MangaParser): Boolean = when (this) { + is Advanced -> (sortOrder in parser.availableSortOrders) && + (tags.size <= 1 || parser.isMultipleTagsSupported) && + (tagsExclude.isEmpty() || parser.isTagsExclusionSupported) && + (contentRating.isEmpty() || parser.availableContentRating.containsAll(contentRating)) && + (states.isEmpty() || parser.availableStates.containsAll(states)) + + is Search -> parser.isSearchSupported + } + data class Search( @JvmField val query: String, ) : MangaListFilter { @@ -20,10 +31,63 @@ sealed interface MangaListFilter { data class Advanced( override val sortOrder: SortOrder, @JvmField val tags: Set, + @JvmField val tagsExclude: Set, @JvmField val locale: Locale?, @JvmField val states: Set, + @JvmField val contentRating: Set, ) : MangaListFilter { - override fun isEmpty(): Boolean = tags.isEmpty() && locale == null && states.isEmpty() + override fun isEmpty(): Boolean = + tags.isEmpty() && tagsExclude.isEmpty() && locale == null && states.isEmpty() && contentRating.isEmpty() + + fun newBuilder() = Builder(sortOrder) + .tags(tags) + .tagsExclude(tagsExclude) + .locale(locale) + .states(states) + .contentRatings(contentRating) + + class Builder(sortOrder: SortOrder) { + + private var _sortOrder: SortOrder = sortOrder + private var _tags: Set? = null + private var _tagsExclude: Set? = null + private var _locale: Locale? = null + private var _states: Set? = null + private var _contentRating: Set? = null + + fun sortOrder(order: SortOrder) = apply { + _sortOrder = order + } + + fun tags(tags: Set?) = apply { + _tags = tags + } + + fun tagsExclude(tags: Set?) = apply { + _tagsExclude = tags + } + + fun locale(locale: Locale?) = apply { + _locale = locale + } + + fun states(states: Set?) = apply { + _states = states + } + + fun contentRatings(rating: Set?) = apply { + _contentRating = rating + } + + fun build() = Advanced( + sortOrder = _sortOrder, + tags = _tags.orEmpty(), + tagsExclude = _tagsExclude.orEmpty(), + locale = _locale, + states = _states.orEmpty(), + contentRating = _contentRating.orEmpty(), + ) + } } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaState.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaState.kt index 1d964722..3801ff04 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaState.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaState.kt @@ -1,5 +1,5 @@ package org.koitharu.kotatsu.parsers.model enum class MangaState { - ONGOING, FINISHED, ABANDONED, PAUSED + ONGOING, FINISHED, ABANDONED, PAUSED, UPCOMING } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/SortOrder.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/SortOrder.kt index 3c9a9091..7ef35ddd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/SortOrder.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/SortOrder.kt @@ -5,5 +5,6 @@ enum class SortOrder { POPULARITY, RATING, NEWEST, - ALPHABETICAL -} \ No newline at end of file + ALPHABETICAL, + ALPHABETICAL_DESC +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt index 6d422c83..fac5a58e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt @@ -35,6 +35,10 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser( override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + override val isTagsExclusionSupported = true + + override val availableContentRating: Set = EnumSet.of(ContentRating.SAFE) + override val configKeyDomain = ConfigKey.Domain( "bato.to", "batocomic.com", @@ -93,6 +97,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser( MangaState.FINISHED -> "completed" MangaState.ABANDONED -> "cancelled" MangaState.PAUSED -> "hiatus" + MangaState.UPCOMING -> "pending" }, ) } @@ -102,13 +107,29 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser( append(it.language) } + append("&genres=") if (filter.tags.isNotEmpty()) { - append("&genres=") appendAll(filter.tags, ",") { it.key } } + append("|") + if (filter.tagsExclude.isNotEmpty()) { + appendAll(filter.tagsExclude, ",") { it.key } + } + + if (filter.contentRating.isNotEmpty()) { + filter.contentRating.oneOrThrowIfMany()?.let { + append( + when (it) { + ContentRating.SAFE -> append(",gore,bloody,violence,ecchi,adult,mature,smut,hentai") + else -> append("") + }, + ) + } + } + append("&page=") - append(page) + append(page.toString()) } return parseList(url, page) @@ -120,7 +141,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser( append(domain) append("/browse?sort=update.za") append("&page=") - append(page) + append(page.toString()) } return parseList(url, page) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt index 7155c62a..4e5ebb54 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt @@ -31,7 +31,8 @@ internal class ComickFunParser(context: MangaLoaderContext) : PagedMangaParser(c SortOrder.RATING, ) - override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + override val availableStates: Set = + EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED) @Volatile private var cachedTags: SparseArrayCompat? = null @@ -75,6 +76,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : PagedMangaParser(c MangaState.FINISHED -> "2" MangaState.ABANDONED -> "3" MangaState.PAUSED -> "4" + else -> "" }, ) } @@ -117,8 +119,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : PagedMangaParser(c var alt = "" comic.getJSONArray("md_titles").mapJSON { alt += it.getString("title") + " - " } return manga.copy( - title = comic.getString("title"), - altTitle = alt, + altTitle = alt.ifEmpty { comic.getStringOrNull("title") }, isNsfw = jo.getBoolean("matureContent") || comic.getBoolean("hentai"), description = comic.getStringOrNull("parsed") ?: comic.getStringOrNull("desc"), tags = manga.tags + comic.getJSONArray("md_comic_md_genres").mapJSONToSet { @@ -186,7 +187,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : PagedMangaParser(c val chap = jo.getStringOrNull("chap") val locale = Locale.forLanguageTag(jo.getString("lang")) val group = jo.optJSONArray("group_name")?.joinToString(", ") - val branch = locale.getDisplayName(locale).toTitleCase(locale) + group + val branch = locale.getDisplayName(locale).toTitleCase(locale) + " (" + group + ")" MangaChapter( id = generateUid(jo.getLong("id")), name = buildString { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt index 5b540760..1b134fcb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt @@ -1,11 +1,11 @@ package org.koitharu.kotatsu.parsers.site.all import androidx.collection.ArrayMap +import androidx.collection.ArraySet import androidx.collection.SparseArrayCompat import androidx.collection.set -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import org.jsoup.internal.StringUtil import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParserAuthProvider @@ -26,9 +26,8 @@ internal class ExHentaiParser( context: MangaLoaderContext, ) : PagedMangaParser(context, MangaSource.EXHENTAI, pageSize = 25), MangaParserAuthProvider { - override val availableSortOrders: Set = Collections.singleton( - SortOrder.NEWEST, - ) + override val availableSortOrders: Set = setOf(SortOrder.NEWEST) + override val isTagsExclusionSupported: Boolean = true override val configKeyDomain: ConfigKey.Domain get() = ConfigKey.Domain( @@ -44,6 +43,7 @@ internal class ExHentaiParser( private var updateDm = false private val nextPages = SparseArrayCompat() private val suspiciousContentKey = ConfigKey.ShowSuspiciousContent(false) + private val tagsMap = SuspendLazy(::fetchTags) override val isAuthorized: Boolean get() { @@ -93,30 +93,25 @@ internal class ExHentaiParser( is MangaListFilter.Advanced -> { - append("&f_search=") - - var fCats = 0 - if (filter.tags.isNotEmpty()) { - filter.tags.forEach { - if (it.title.startsWith("- ")) { - it.key.toIntOrNull()?.let { fCats = fCats or it } ?: run { - search += it.key + " " - } - } else { - append(" tag:".urlEncoded()) - append(it.key) - } - } + filter.toSearchQuery()?.let { sq -> + append("&f_search=") + append(sq.urlEncoded()) } - if (filter.locale != null) { - append(" language:".urlEncoded()) - append(filter.locale.toLanguagePath()) + val catsOn = filter.tags.mapNotNullToSet { it.key.toIntOrNull() } + val catsOff = filter.tagsExclude.mapNotNullToSet { it.key.toIntOrNull() } + if (catsOff.size >= 10) { + return emptyList() + } + var fCats = catsOn.fold(0, Int::or) + if (fCats != 0) { + fCats = 1023 - fCats } + fCats = catsOff.fold(fCats, Int::or) if (fCats != 0) { append("&f_cats=") - append(1023 - fCats) + append(fCats) } } @@ -182,15 +177,14 @@ internal class ExHentaiParser( val title = root.getElementById("gd2") val tagList = root.getElementById("taglist") val tabs = doc.body().selectFirst("table.ptt")?.selectFirst("tr") - val lang = - root.getElementById("gd3")?.selectFirst("tr:contains(Language)")?.selectFirst(".gdt2")?.text() ?: "Unknown" + val lang = root.getElementById("gd3") + ?.selectFirst("tr:contains(Language)") + ?.selectFirst(".gdt2")?.ownTextOrNull() - val tagMap = getOrCreateTagMap() - val tagF = - tagList?.selectFirst("tr:contains(female:)")?.select("a")?.mapNotNullToSet { tagMap[it.text()] }.orEmpty() - val tagM = - tagList?.selectFirst("tr:contains(male:)")?.select("a")?.mapNotNullToSet { tagMap[it.text()] }.orEmpty() - val tags = tagF + tagM + val tagMap = tagsMap.get() + val tags = ArraySet() + tagList?.selectFirst("tr:contains(female:)")?.select("a")?.mapNotNullTo(tags) { tagMap[it.text()] } + tagList?.selectFirst("tr:contains(male:)")?.select("a")?.mapNotNullTo(tags) { tagMap[it.text()] } return manga.copy( title = title?.getElementById("gn")?.text()?.cleanupTitle() ?: manga.title, @@ -265,21 +259,17 @@ internal class ExHentaiParser( "unusual pupils,urination,vore,vtuber,widow,wings,witch,wolf girl,x-ray,yuri,zombie,sole male,males only,yaoi," + "tomgirl,tall man,oni,shotacon,prostate massage,policeman,males only,huge penis,fox boy,feminization,dog boy,dickgirl on male,big penis" - private var tagCache: ArrayMap? = null - private val mutex = Mutex() - override suspend fun getAvailableTags(): Set { - return getOrCreateTagMap().values.toSet() + return tagsMap.get().values.toSet() } - protected suspend fun getOrCreateTagMap(): Map = mutex.withLock { - tagCache?.let { return@withLock it } + private suspend fun fetchTags(): Map { val tagMap = ArrayMap() val tagElements = tags.split(",") for (el in tagElements) { if (el.isEmpty()) continue tagMap[el] = MangaTag( - title = el, + title = el.toTitleCase(Locale.ENGLISH), key = el, source = source, ) @@ -289,16 +279,14 @@ internal class ExHentaiParser( val root = doc.body().requireElementById("searchbox").selectFirstOrThrow("table") root.select("div.cs").mapNotNullToSet { div -> val id = div.id().substringAfterLast('_').toIntOrNull() ?: return@mapNotNullToSet null - val name = "- " + div.text().toTitleCase() + val name = div.text().toTitleCase(Locale.ENGLISH) tagMap[name] = MangaTag( - title = name, + title = "Kind: $name", key = id.toString(), source = source, ) } - - tagCache = tagMap - return@withLock tagMap + return tagMap } override suspend fun getAvailableLocales(): Set = setOf( @@ -403,4 +391,32 @@ internal class ExHentaiParser( ?.queryParameter("next") ?.toLongOrNull() ?: 1 } + + private fun MangaListFilter.Advanced.toSearchQuery(): String? { + val joiner = StringUtil.StringJoiner(" ") + for (tag in tags) { + if (tag.key.isNumeric()) { + continue + } + joiner.add("tag:\"") + joiner.append(tag.key) + joiner.append("\"$") + } + for (tag in tagsExclude) { + if (tag.key.isNumeric()) { + continue + } + joiner.add("-tag:\"") + joiner.append(tag.key) + joiner.append("\"$") + } + locale?.let { lc -> + joiner.add("language:\"") + joiner.append(lc.toLanguagePath()) + joiner.append("\"$") + } + return joiner.complete().takeUnless { it.isEmpty() } + } + + private fun String.isNumeric() = all { c -> c.isDigit() } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt index e1039ae4..70e245df 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt @@ -21,8 +21,6 @@ private const val CHAPTERS_FIRST_PAGE_SIZE = 120 private const val CHAPTERS_MAX_PAGE_SIZE = 500 private const val CHAPTERS_PARALLELISM = 3 private const val CHAPTERS_MAX_COUNT = 10_000 // strange api behavior, looks like a bug -private const val CONTENT_RATING = - "contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic" private const val LOCALE_FALLBACK = "en" @MangaSourceParser("MANGADEX", "MangaDex") @@ -32,7 +30,12 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context override val availableSortOrders: EnumSet = EnumSet.allOf(SortOrder::class.java) - override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + override val availableContentRating: Set = EnumSet.allOf(ContentRating::class.java) + + override val availableStates: Set = + EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED) + + override val isTagsExclusionSupported = true override suspend fun getList(offset: Int, filter: MangaListFilter?): List { @@ -44,28 +47,41 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context append(PAGE_SIZE) append("&offset=") append(offset) - append("&includes[]=cover_art&includes[]=author&includes[]=artist&") + append("&includes[]=cover_art&includes[]=author&includes[]=artist") when (filter) { is MangaListFilter.Search -> { - append("title=") + append("&title=") append(filter.query) - append('&') } is MangaListFilter.Advanced -> { - filter.tags.forEach { tag -> - append("includedTags[]=") - append(tag.key) - append('&') + filter.tags.forEach { + append("&includedTags[]=") + append(it.key) + } + + filter.tagsExclude.forEach { + append("&excludedTags[]=") + append(it.key) + } + + if (filter.contentRating.isNotEmpty()) { + filter.contentRating.forEach { + when (it) { + ContentRating.SAFE -> append("&contentRating[]=safe") + ContentRating.SUGGESTIVE -> append("&contentRating[]=suggestive&contentRating[]=erotica") + ContentRating.ADULT -> append("&contentRating[]=pornographic") + } + } } - append(CONTENT_RATING) append("&order") append( when (filter.sortOrder) { SortOrder.UPDATED -> "[latestUploadedChapter]=desc" SortOrder.RATING -> "[rating]=desc" SortOrder.ALPHABETICAL -> "[title]=asc" + SortOrder.ALPHABETICAL_DESC -> "[title]=desc" SortOrder.NEWEST -> "[createdAt]=desc" SortOrder.POPULARITY -> "[followedCount]=desc" }, @@ -77,6 +93,7 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context MangaState.FINISHED -> append("completed") MangaState.ABANDONED -> append("cancelled") MangaState.PAUSED -> append("hiatus") + else -> append("") } } filter.locale?.let { @@ -248,8 +265,7 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context append(limitedLimit) append("&includes[]=scanlation_group&order[volume]=asc&order[chapter]=asc&offset=") append(offset) - append('&') - append(CONTENT_RATING) + append("&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic") } val json = webClient.httpGet(url).parseJson() if (json.getString("result") == "ok") { 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 20eb19b0..e4cdabf0 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 @@ -20,6 +20,10 @@ internal class MangaPark(context: MangaLoaderContext) : override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + override val availableContentRating: Set = EnumSet.of(ContentRating.SAFE) + + override val isTagsExclusionSupported = true + override val configKeyDomain = ConfigKey.Domain("mangapark.net") private val tagsMap = SuspendLazy(::parseTags) @@ -42,9 +46,25 @@ internal class MangaPark(context: MangaLoaderContext) : is MangaListFilter.Advanced -> { + append("&genres=") if (filter.tags.isNotEmpty()) { - append("&genres=") - append(filter.tags.joinToString(",") { it.key }) + appendAll(filter.tags, ",") { it.key } + } + + append("|") + if (filter.tagsExclude.isNotEmpty()) { + appendAll(filter.tagsExclude, ",") { it.key } + } + + if (filter.contentRating.isNotEmpty()) { + filter.contentRating.oneOrThrowIfMany()?.let { + append( + when (it) { + ContentRating.SAFE -> append(",gore,bloody,violence,ecchi,adult,mature,smut,hentai") + else -> append("") + }, + ) + } } filter.states.oneOrThrowIfMany()?.let { @@ -55,6 +75,7 @@ internal class MangaPark(context: MangaLoaderContext) : MangaState.FINISHED -> "completed" MangaState.PAUSED -> "hiatus" MangaState.ABANDONED -> "cancelled" + MangaState.UPCOMING -> "pending" }, ) } @@ -67,6 +88,7 @@ internal class MangaPark(context: MangaLoaderContext) : SortOrder.NEWEST -> "field_create" SortOrder.ALPHABETICAL -> "field_name" SortOrder.RATING -> "field_score" + else -> "" }, ) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt index 8145040e..c985e8f9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt @@ -9,30 +9,14 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey -import org.koitharu.kotatsu.parsers.model.ContentType -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.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.mapJSONToSet import org.koitharu.kotatsu.parsers.util.json.toJSONList -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.oneOrThrowIfMany -import org.koitharu.kotatsu.parsers.util.parseHtml -import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl -import org.koitharu.kotatsu.parsers.util.toCamelCase import java.text.SimpleDateFormat -import java.util.EnumSet -import java.util.Locale +import java.util.* @MangaSourceParser("NINENINENINEHENTAI", "999Hentai", type = ContentType.HENTAI) internal class NineNineNineHentaiParser(context: MangaLoaderContext) : diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt index 667cc56a..940ac7b3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt @@ -25,6 +25,7 @@ internal class PapScan(context: MangaLoaderContext) : override val availableSortOrders: Set = EnumSet.of( SortOrder.POPULARITY, SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, ) override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { @@ -50,7 +51,8 @@ internal class PapScan(context: MangaLoaderContext) : append("&sortBy=") when (filter.sortOrder) { SortOrder.POPULARITY -> append("views") - SortOrder.ALPHABETICAL -> append("name") + SortOrder.ALPHABETICAL_DESC -> append("name&asc=false") + SortOrder.ALPHABETICAL -> append("name&asc=true") else -> append("updated") } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/id/KomikzoId.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/id/KomikzoId.kt index 6e2da189..7278e961 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/id/KomikzoId.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/id/KomikzoId.kt @@ -7,4 +7,4 @@ import org.koitharu.kotatsu.parsers.site.animebootstrap.AnimeBootstrapParser @MangaSourceParser("KOMIKZOID", "KomikzoId", "id") internal class KomikzoId(context: MangaLoaderContext) : - AnimeBootstrapParser(context, MangaSource.KOMIKZOID, "komikzoid.xyz") + AnimeBootstrapParser(context, MangaSource.KOMIKZOID, "komikzoid.id") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt index 90bb9c45..a4491c46 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt @@ -59,6 +59,7 @@ internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context MangaState.FINISHED -> "completed" MangaState.ABANDONED -> "droped" MangaState.PAUSED -> "onhold" + MangaState.UPCOMING -> "soon" }, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt index 252c6fcb..f7a7e334 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt @@ -20,7 +20,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex override val availableStates: Set = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED) - override val configKeyDomain = ConfigKey.Domain("team11x11.com") + override val configKeyDomain = ConfigKey.Domain("team11x11.fun") override val isMultipleTagsSupported = false override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt index f7e07905..bf5b76f7 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt @@ -31,6 +31,7 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context, offset: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { if (!query.isNullOrEmpty()) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt index f8b42850..40da667a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt @@ -19,6 +19,7 @@ internal class FlixScansOrg(context: MangaLoaderContext) : PagedMangaParser(cont override val availableSortOrders: Set = EnumSet.of(SortOrder.UPDATED) override val availableStates: Set = EnumSet.allOf(MangaState::class.java) override val configKeyDomain = ConfigKey.Domain("flixscans.org") + override val isSearchSupported = false override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt index 27b1d5e9..2e2b2634 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt @@ -68,6 +68,7 @@ class Manhwa18Parser(context: MangaLoaderContext) : append( when (filter.sortOrder) { SortOrder.ALPHABETICAL -> "az" + SortOrder.ALPHABETICAL_DESC -> "za" SortOrder.POPULARITY -> "top" SortOrder.UPDATED -> "update" SortOrder.NEWEST -> "new" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt index c1cbf3c0..73b7e760 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt @@ -20,7 +20,9 @@ internal class ReaperComics(context: MangaLoaderContext) : override val availableSortOrders: Set = EnumSet.of(SortOrder.UPDATED, SortOrder.ALPHABETICAL) - override val configKeyDomain = ConfigKey.Domain("reapercomics.com") + override val configKeyDomain = ConfigKey.Domain("reaperscans.com") + + override val isSearchSupported = false override val headers: Headers = Headers.Builder() .add("User-Agent", UserAgents.CHROME_DESKTOP) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt index 47ae240c..d7478d2e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt @@ -21,6 +21,8 @@ internal class TempleScanEsp(context: MangaLoaderContext) : override val configKeyDomain = ConfigKey.Domain("templescanesp.net") + override val isSearchSupported = false + override val headers: Headers = Headers.Builder() .add("User-Agent", UserAgents.CHROME_DESKTOP) .build() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt index 02ba7388..3a0c64bd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt @@ -26,6 +26,7 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser( override val availableSortOrders: Set = EnumSet.of( SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, SortOrder.UPDATED, SortOrder.NEWEST, SortOrder.POPULARITY, @@ -48,15 +49,14 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser( append("?order_item=") append( when (filter.sortOrder) { - SortOrder.POPULARITY -> "likes_count" - SortOrder.UPDATED -> "release_date" - SortOrder.NEWEST -> "creation" - SortOrder.ALPHABETICAL -> "alphabetically" - SortOrder.RATING -> "score" - + SortOrder.POPULARITY -> "likes_count&order_dir=desc" + SortOrder.UPDATED -> "release_date&order_dir=desc" + SortOrder.NEWEST -> "creation&order_dir=desc" + SortOrder.ALPHABETICAL -> "alphabetically&order_dir=asc" + SortOrder.ALPHABETICAL_DESC -> "alphabetically&order_dir=desc" + SortOrder.RATING -> "score&order_dir=desc" }, ) - append("&order_dir=desc") append("&filter_by=title") if (filter.tags.isNotEmpty()) { for (tag in filter.tags) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt index 7fa7a03d..1ae78131 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt @@ -25,6 +25,7 @@ internal abstract class FmreaderParser( SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, ) override val availableStates: Set = EnumSet.of( @@ -85,7 +86,8 @@ internal abstract class FmreaderParser( when (filter.sortOrder) { SortOrder.POPULARITY -> append("views") SortOrder.UPDATED -> append("last_update") - SortOrder.ALPHABETICAL -> append("name") + SortOrder.ALPHABETICAL -> append("name&sort_type=ASC") + SortOrder.ALPHABETICAL_DESC -> append("name&sort_type=DESC") else -> append("last_update") } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt index 676c5564..d2c963f4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt @@ -48,6 +48,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) : append( when (filter.sortOrder) { SortOrder.ALPHABETICAL -> "az" + SortOrder.ALPHABETICAL_DESC -> "za" SortOrder.POPULARITY -> "top" SortOrder.UPDATED -> "update" SortOrder.NEWEST -> "new" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt index 2ed70663..5c8521b5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt @@ -44,7 +44,8 @@ internal class OlimpoScans(context: MangaLoaderContext) : when (filter.sortOrder) { SortOrder.POPULARITY -> append("views") SortOrder.UPDATED -> append("last_update") - SortOrder.ALPHABETICAL -> append("name") + SortOrder.ALPHABETICAL -> append("name&sort_type=ASC") + SortOrder.ALPHABETICAL_DESC -> append("name&sort_type=DESC") else -> append("last_update") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt index ae86a442..f35c8cac 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt @@ -24,11 +24,15 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser( SortOrder.RATING, SortOrder.NEWEST, SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, ) override val configKeyDomain = ConfigKey.Domain("bentomanga.com", "www.bentomanga.com") - override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + override val availableStates: Set = + EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED) + + override val isTagsExclusionSupported = true init { paginator.firstPage = 0 @@ -47,21 +51,34 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser( is MangaListFilter.Advanced -> { - url.addQueryParameter( - "order_by", - when (filter.sortOrder) { - SortOrder.UPDATED -> "update" - SortOrder.POPULARITY -> "views" - SortOrder.RATING -> "top" - SortOrder.NEWEST -> "create" - SortOrder.ALPHABETICAL -> "name" - }, - ) + when (filter.sortOrder) { + SortOrder.UPDATED -> url.addQueryParameter("order_by", "update") + .addQueryParameter("order", "desc") + + SortOrder.POPULARITY -> url.addQueryParameter("order_by", "views") + .addQueryParameter("order", "desc") + + SortOrder.RATING -> url.addQueryParameter("order_by", "top") + .addQueryParameter("order", "desc") + + SortOrder.NEWEST -> url.addQueryParameter("order_by", "create") + .addQueryParameter("order", "desc") + + SortOrder.ALPHABETICAL -> url.addQueryParameter("order_by", "name") + .addQueryParameter("order", "asc") + + SortOrder.ALPHABETICAL_DESC -> url.addQueryParameter("order_by", "name") + .addQueryParameter("order", "desc") + } if (filter.tags.isNotEmpty()) { url.addQueryParameter("withCategories", filter.tags.joinToString(",") { it.key }) } + if (filter.tagsExclude.isNotEmpty()) { + url.addQueryParameter("withoutCategories", filter.tagsExclude.joinToString(",") { it.key }) + } + filter.states.oneOrThrowIfMany()?.let { url.addQueryParameter( "state", @@ -70,6 +87,7 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser( MangaState.FINISHED -> "2" MangaState.PAUSED -> "3" MangaState.ABANDONED -> "5" + else -> "1" }, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt index 7fbc5038..910add0e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt @@ -23,6 +23,8 @@ internal class FuryoSociety(context: MangaLoaderContext) : override val configKeyDomain = ConfigKey.Domain("furyosociety.com") + override val isSearchSupported = false + override val headers: Headers = Headers.Builder() .add("User-Agent", UserAgents.CHROME_DESKTOP) .build() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt index 0af98d46..ee92fe93 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt @@ -22,7 +22,10 @@ internal class LugnicaScans(context: MangaLoaderContext) : PagedMangaParser(cont SortOrder.UPDATED, ) - override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + override val availableStates: Set = + EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED) + + override val isSearchSupported = false override val configKeyDomain = ConfigKey.Domain("lugnica-scans.com") @@ -68,6 +71,7 @@ internal class LugnicaScans(context: MangaLoaderContext) : PagedMangaParser(cont MangaState.FINISHED -> append("1") MangaState.PAUSED -> append("4") MangaState.ABANDONED -> append("3") + else -> append("") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt index b5c13aff..d61b10e0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt @@ -182,8 +182,7 @@ internal class ScantradUnion(context: MangaLoaderContext) : PagedMangaParser(con override suspend fun getAvailableTags(): Set { val doc = webClient.httpGet("https://$domain/").parseHtml() val body = doc.body() - val root = body.select(".asp_gochosen")[1] - val list = root?.select("option").orEmpty() + val list = body.select(".asp_gochosen")[1].select("option").orEmpty() return list.mapToSet { li -> MangaTag( key = li.text().lowercase().replace(" ", "-"), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiUk.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiUk.kt deleted file mode 100644 index 643eeec7..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiUk.kt +++ /dev/null @@ -1,88 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.galleryadults.all - -import org.koitharu.kotatsu.parsers.ErrorMessages -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.site.galleryadults.GalleryAdultsParser -import org.koitharu.kotatsu.parsers.util.* -import java.util.* - -@MangaSourceParser("NHENTAIUK", "NHentai.uk", type = ContentType.HENTAI) -internal class NHentaiUk(context: MangaLoaderContext) : - GalleryAdultsParser(context, MangaSource.NHENTAIUK, "nhentai.uk", pageSize = 50) { - override val selectGallery = ".gallery" - override val selectGalleryLink = "a" - override val selectGalleryTitle = ".caption" - override val pathTagUrl = "/tags/popular?p=" - override val selectTags = "#tag-container" - override val selectTag = "div.tag-container:contains(Tags:) span.tags" - override val selectAuthor = "div.tag-container:contains(Artists:) a" - override val selectLanguageChapter = "div.tag-container:contains(Languages:) a" - override val idImg = "image-container" - - override suspend fun getAvailableLocales(): Set = setOf( - Locale.ENGLISH, - Locale.FRENCH, - Locale.JAPANESE, - Locale.CHINESE, - Locale("es"), - Locale("ru"), - Locale("ko"), - Locale.GERMAN, - Locale("pt"), - Locale.ITALIAN, - Locale("tr"), - ) - - override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { - - val url = buildString { - append("https://") - append(domain) - when (filter) { - - is MangaListFilter.Search -> { - throw IllegalArgumentException(ErrorMessages.SEARCH_NOT_SUPPORTED) - } - - is MangaListFilter.Advanced -> { - when { - filter.locale != null && filter.tags.isNotEmpty() -> { - throw IllegalArgumentException(ErrorMessages.FILTER_BOTH_LOCALE_GENRES_NOT_SUPPORTED) - } - - filter.locale != null -> { - append("/language") - append(filter.locale.toLanguagePath()) - append("/?p=") - } - - filter.tags.isNotEmpty() -> { - filter.tags.oneOrThrowIfMany()?.let { - append("/tag/") - append(it.key) - } - append("/?p=") - } - - else -> { - append("/home?p=") - } - } - } - - null -> append("/?") - } - append(page.toString()) - } - - return parseMangaList(webClient.httpGet(url).parseHtml()) - } - - override suspend fun getPageUrl(page: MangaPage): String { - val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() - val root = doc.body() - return root.requireElementById(idImg).selectFirstOrThrow("img").src() ?: root.parseFailed("Image src not found") - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt index 70bea32a..d7e3c676 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt @@ -27,7 +27,8 @@ internal abstract class HeanCms( SortOrder.POPULARITY, ) - override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + override val availableStates: Set = + EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED) override val headers: Headers = Headers.Builder() .add("User-Agent", UserAgents.CHROME_DESKTOP) @@ -56,18 +57,19 @@ internal abstract class HeanCms( MangaState.FINISHED -> "Completed" MangaState.ABANDONED -> "Dropped" MangaState.PAUSED -> "Hiatus" + else -> "" }, ) } - append("&order=desc") append("&orderBy=") when (filter.sortOrder) { - SortOrder.POPULARITY -> append("total_views") - SortOrder.UPDATED -> append("latest") - SortOrder.NEWEST -> append("created_at") - SortOrder.ALPHABETICAL -> append("title") - else -> append("latest") + SortOrder.POPULARITY -> append("total_views&order=desc") + SortOrder.UPDATED -> append("latest&order=desc") + SortOrder.NEWEST -> append("created_at&order=desc") + SortOrder.ALPHABETICAL -> append("title&order=desc") + SortOrder.ALPHABETICAL_DESC -> append("title&order=asc") + else -> append("latest&order=desc") } append("&series_type=Comic&perPage=12") append("&tags_ids=") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt index 64b7349a..0b73d6a0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt @@ -33,18 +33,19 @@ internal class YugenMangasEs(context: MangaLoaderContext) : MangaState.FINISHED -> "Completed" MangaState.ABANDONED -> "Dropped" MangaState.PAUSED -> "Hiatus" + else -> "" }, ) } - append("&order=desc") append("&orderBy=") when (filter.sortOrder) { - SortOrder.POPULARITY -> append("total_views") - SortOrder.UPDATED -> append("latest") - SortOrder.NEWEST -> append("created_at") - SortOrder.ALPHABETICAL -> append("title") - else -> append("latest") + SortOrder.POPULARITY -> append("total_views&order=desc") + SortOrder.UPDATED -> append("latest&order=desc") + SortOrder.NEWEST -> append("created_at&order=desc") + SortOrder.ALPHABETICAL -> append("title&order=desc") + SortOrder.ALPHABETICAL_DESC -> append("title&order=asc") + else -> append("latest&order=desc") } append("&series_type=Comic&perPage=12") append("&tags_ids=") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt index ecd00892..89dace41 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt @@ -23,6 +23,8 @@ internal abstract class HeanCmsAlt( override val availableSortOrders: Set = EnumSet.of(SortOrder.UPDATED) + override val isSearchSupported = false + protected open val listUrl = "/comics" protected open val datePattern = "MMMM d, yyyy" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt index c6a18378..4cdf67d6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt @@ -151,6 +151,15 @@ internal abstract class MadaraParser( "En attente", ) + @JvmField + protected val upcoming: Set = hashSetOf( + "Upcoming", + "upcoming", + "لم تُنشَر بعد", + "Prochainement", + "À venir", + ) + // Change these values only if the site does not support manga listings via ajax protected open val withoutAjax = false @@ -203,6 +212,7 @@ internal abstract class MadaraParser( MangaState.FINISHED -> append("end") MangaState.ABANDONED -> append("canceled") MangaState.PAUSED -> append("on-hold") + MangaState.UPCOMING -> append("upcoming") } } append("&") @@ -215,6 +225,7 @@ internal abstract class MadaraParser( SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") SortOrder.RATING -> append("rating") + else -> append("latest") } } @@ -255,6 +266,7 @@ internal abstract class MadaraParser( } SortOrder.RATING -> {} + else -> payload["vars[meta_key]"] = "_latest_update" } filter.states.forEach { @@ -264,6 +276,7 @@ internal abstract class MadaraParser( MangaState.FINISHED -> "end" MangaState.ABANDONED -> "canceled" MangaState.PAUSED -> "on-hold" + MangaState.UPCOMING -> "upcoming" } } } @@ -310,6 +323,7 @@ internal abstract class MadaraParser( in finished -> MangaState.FINISHED in abandoned -> MangaState.ABANDONED in paused -> MangaState.PAUSED + in upcoming -> MangaState.UPCOMING else -> null }, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/AkuManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/AkuManga.kt deleted file mode 100644 index d62e1a65..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/AkuManga.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -import java.util.Locale - -@MangaSourceParser("AKUMANGA", "AkuManga", "ar") -internal class AkuManga(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.AKUMANGA, "akumanga.com") { - override val sourceLocale: Locale = Locale.ENGLISH -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/FalconManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/FalconManga.kt deleted file mode 100644 index 1be5cdec..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/FalconManga.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("FALCONMANGA", "FalconManga", "ar") -internal class FalconManga(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.FALCONMANGA, "falconmanga.com") { - override val datePattern = "d MMMM، yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLeks.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLeks.kt deleted file mode 100644 index a0b58c74..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLeks.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGALEKS", "MangaLeks", "ar") -internal class MangaLeks(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGALEKS, "mangaleks.com") { - override val datePattern = "yyyy/MM/dd" - override val postReq = true -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/ShadowxManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/ShadowxManga.kt index b20bd21f..70f7a747 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/ShadowxManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/ShadowxManga.kt @@ -5,8 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("SHADOWXMANGA", "Shadow X Manga", "ar") +@MangaSourceParser("SHADOWXMANGA", "ShadowXManga", "ar") internal class ShadowxManga(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.SHADOWXMANGA, "shadowxmanga.com") { + MadaraParser(context, MangaSource.SHADOWXMANGA, "www.shadowxmanga.com") { override val datePattern = "yyyy/MM/dd" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/de/MangaLesen.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/de/MangaLesen.kt new file mode 100644 index 00000000..c740cf07 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/de/MangaLesen.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.de + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGALESEN", "MangaLesen", "de") +internal class MangaLesen(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.MANGALESEN, "mangalesen.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/CmReader.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/CmReader.kt deleted file mode 100644 index aee5e7f8..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/CmReader.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("CM_READER", "CmReader", "en") -internal class CmReader(context: MangaLoaderContext) : MadaraParser(context, MangaSource.CM_READER, "cmreader.info") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/FireScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/FireScans.kt index 633b2170..4643bc1d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/FireScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/FireScans.kt @@ -75,7 +75,7 @@ internal class FireScans(context: MangaLoaderContext) : } } - fun String.decodeHex(): ByteArray { + private fun String.decodeHex(): ByteArray { check(length % 2 == 0) { "Must have an even length" } return chunked(2).map { it.toInt(16).toByte() }.toByteArray() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt index fdca0963..815850b1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt @@ -68,6 +68,7 @@ internal class Hentai4Free(context: MangaLoaderContext) : SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") SortOrder.RATING -> append("rating") + else -> append("latest") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt index c5b561e3..d89eb5cc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt @@ -61,6 +61,7 @@ internal class IsekaiScanEuParser(context: MangaLoaderContext) : MangaState.FINISHED -> append("end") MangaState.ABANDONED -> append("canceled") MangaState.PAUSED -> append("on-hold") + MangaState.UPCOMING -> append("upcoming") } } append("&") @@ -73,6 +74,7 @@ internal class IsekaiScanEuParser(context: MangaLoaderContext) : SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") SortOrder.RATING -> append("rating") + else -> append("latest") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Jaiminisbox.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Jaiminisbox.kt deleted file mode 100644 index 6e7dcf8f..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Jaiminisbox.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("JAIMINISBOX", "JaiminisBox", "en") -internal class Jaiminisbox(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.JAIMINISBOX, "jaiminisbox.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/JiManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/JiManga.kt index a3f9d655..fe316e42 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/JiManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/JiManga.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("JIMANGA", "JiManga", "en") +@MangaSourceParser("JIMANGA", "S2Manga.io", "en") internal class JiManga(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.JIMANGA, "jimanga.com") + MadaraParser(context, MangaSource.JIMANGA, "s2manga.io") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga3s.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga3s.kt deleted file mode 100644 index b7b1b676..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga3s.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGA_3S", "Manga3s", "en") -internal class Manga3s(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_3S, "manga3s.com") { - override val tagPrefix = "manhwa-genre/" - override val datePattern = "MMMM dd, yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaCv.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaCv.kt deleted file mode 100644 index b5ebc368..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaCv.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGACV", "MangaCv", "en") -internal class MangaCv(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGACV, "mangacv.com", pageSize = 10) { - override val datePattern = "MMMM dd, yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt index d17a4199..d32a89e2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt @@ -62,6 +62,7 @@ internal class MangaDass(context: MangaLoaderContext) : SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") SortOrder.RATING -> append("rating") + else -> append("latest") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaOnline.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaOnline.kt deleted file mode 100644 index b6f3684b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaOnline.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGA_ONLINE", "MangaOnline.team", "en") -internal class MangaOnline(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGA_ONLINE, "mangaonline.team", 18) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRosie.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRosie.kt index e7faa2eb..43c943d0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRosie.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRosie.kt @@ -5,8 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("MANGAROSIE", "MangaRosie", "en") +@MangaSourceParser("MANGAROSIE", "Toon69", "en") internal class MangaRosie(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGAROSIE, "mangarosie.in", pageSize = 16) { + MadaraParser(context, MangaSource.MANGAROSIE, "toon69.com", pageSize = 16) { override val datePattern = "MMMM dd, yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTx.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTx.kt deleted file mode 100644 index c05e9812..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTx.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGATX", "MangaTx", "en") -internal class MangaTx(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGATX, "mangatx.com") { - override val datePattern = "MMMM dd, yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTxUnofficial.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTxUnofficial.kt index 8c611bc1..e7dd856d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTxUnofficial.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTxUnofficial.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("MANGATXUNOFFICIAL", "Manga-Tx.com", "en") +@MangaSourceParser("MANGATXUNOFFICIAL", "MangaEmpress", "en") internal class MangaTxUnofficial(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGATXUNOFFICIAL, "manga-tx.com") + MadaraParser(context, MangaSource.MANGATXUNOFFICIAL, "mangaempress.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangagoyaoi.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangagoyaoi.kt deleted file mode 100644 index 5c54f0b5..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangagoyaoi.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.ContentType -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGAGOYAOI", "MangaGoYaoi", "en", ContentType.HENTAI) -internal class Mangagoyaoi(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGAGOYAOI, "mangagoyaoi.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manganelo.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manganelo.kt deleted file mode 100644 index c713c642..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manganelo.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGANELO", "MangaNelo.biz", "en") -internal class Manganelo(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGANELO, "manganelo.biz", 10) { - override val postReq = true -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangastic.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangastic.kt deleted file mode 100644 index 61c734a2..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangastic.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGASTIC", "Mangastic", "en") -internal class Mangastic(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGASTIC, "mangastic.cc", 20) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhuaDex.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhuaDex.kt deleted file mode 100644 index 34febb34..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhuaDex.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANHUADEX", "ManhuaDex", "en") -internal class ManhuaDex(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANHUADEX, "manhuadex.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuamix.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuamix.kt deleted file mode 100644 index 4685237e..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuamix.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANHUAMIX", "ManhuaMix", "en") -internal class Manhuamix(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANHUAMIX, "manhuamix.com", 20) { - override val tagPrefix = "manhua-genre/" - override val listUrl = "manhua/" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwa2Read.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwa2Read.kt deleted file mode 100644 index 92da295b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwa2Read.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANHWA2READ", "Manhwa2read", "en") -internal class Manhwa2Read(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANHWA2READ, "manhwa2read.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StManhwa.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StManhwa.kt deleted file mode 100644 index b4d6ea8e..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StManhwa.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("STMANHWA", "1stManhwa", "en") -internal class StManhwa(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.STMANHWA, "1stmanhwa.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StkissMangaTv.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StkissMangaTv.kt deleted file mode 100644 index a328d59b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StkissMangaTv.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("STKISSMANGA_TV", "1stKissManga.tv", "en") -internal class StkissMangaTv(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.STKISSMANGA_TV, "1stkissmanga.tv", 20) { - override val postReq = true -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ToonilyNet.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ToonilyNet.kt deleted file mode 100644 index 24e5b242..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ToonilyNet.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("TOONILYNET", "Toonily.net", "en") -internal class ToonilyNet(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.TOONILYNET, "toonily.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt index 75a84f59..0965e9d0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt @@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("TOPMANHUA", "TopManhua", "en") internal class TopManhua(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.TOPMANHUA, "www.topmanhua.com") { + MadaraParser(context, MangaSource.TOPMANHUA, "topmanhua.com") { override val tagPrefix = "manhua-genre/" override val datePattern = "MM/dd/yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ConsejoDeMatones.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/Kenhuav2Scan.kt similarity index 57% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ConsejoDeMatones.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/Kenhuav2Scan.kt index 4b8011f7..302b46d2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ConsejoDeMatones.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/Kenhuav2Scan.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("CONSEJODEMATONES", "ConsejoDeMatones", "es") -internal class ConsejoDeMatones(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.CONSEJODEMATONES, "www.consejodematones.xyz") +@MangaSourceParser("KENHUAV2SCANK", "Kenhuav2Scan", "es") +internal class Kenhuav2Scan(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.KENHUAV2SCANK, "kenhuav2scan.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/UniToonOficial.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/UniToonOficial.kt deleted file mode 100644 index 9cdc723d..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/UniToonOficial.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.es - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("UNITOONOFICIAL", "UniToonOficial", "es") -internal class UniToonOficial(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.UNITOONOFICIAL, "unitoonoficial.com") { - override val datePattern = "dd/MM/yyyy" - override val tagPrefix = "generos/" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/AstralManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/AstralManga.kt index fcf8e6ae..434e6251 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/AstralManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/AstralManga.kt @@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("ASTRALMANGA", "AstralManga", "fr") internal class AstralManga(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.ASTRALMANGA, "astral-manga.fr", pageSize = 12) { + MadaraParser(context, MangaSource.ASTRALMANGA, "astral-manga.fr") { override val datePattern = "dd/MM/yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/KaratcamScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/KaratcamScans.kt deleted file mode 100644 index ba3a27a6..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/KaratcamScans.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.fr - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("KARATCAMSCANS", "KaratcamScans", "fr") -internal class KaratcamScans(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.KARATCAMSCANS, "karatcam-scans.fr") { - override val tagPrefix = "webtoon-genre/" - override val listUrl = "webtoon/" - override val datePattern = "dd/MM/yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Hwago.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Hwago.kt deleted file mode 100644 index 05671175..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Hwago.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -import java.util.Locale - -@MangaSourceParser("HWAGO", "Hwago", "id") -internal class Hwago(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.HWAGO, "hwago.id", 10) { - override val listUrl = "komik/" - override val tagPrefix = "genre/" - override val sourceLocale: Locale = Locale.ENGLISH -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ImmortalUpdatesId.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ImmortalUpdatesId.kt deleted file mode 100644 index 514833e2..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ImmortalUpdatesId.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -import java.util.Locale - -@MangaSourceParser("IMMORTALUPDATESID", "ImmortalUpdates", "id") -internal class ImmortalUpdatesId(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.IMMORTALUPDATESID, "immortalupdates.id") { - override val datePattern = "d MMMM yyyy" - override val sourceLocale: Locale = Locale.ENGLISH -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Komiksay.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Komiksay.kt deleted file mode 100644 index 58ee0ace..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Komiksay.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -import java.util.Locale - -@MangaSourceParser("KOMIKSA", "KomikSay", "id") -internal class Komiksay(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.KOMIKSA, "komiksay.site") { - override val tagPrefix = "komik-genre/" - override val listUrl = "komik/" - override val datePattern = "MMMM d" - override val sourceLocale: Locale = Locale.ENGLISH -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Shinigami.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Shinigami.kt index 6739b151..82e954d7 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Shinigami.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/Shinigami.kt @@ -2,14 +2,24 @@ package org.koitharu.kotatsu.parsers.site.madara.id import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -import java.util.Locale +import java.util.* @MangaSourceParser("SHINIGAMI", "Shinigami", "id") internal class Shinigami(context: MangaLoaderContext) : MadaraParser(context, MangaSource.SHINIGAMI, "shinigami.moe", 10) { + + private val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_MOBILE) override val tagPrefix = "genre/" override val listUrl = "series/" override val sourceLocale: Locale = Locale.ENGLISH + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/ZeroScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/BurningScans.kt similarity index 53% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/ZeroScan.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/BurningScans.kt index 83073e38..d340bcec 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/ZeroScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/BurningScans.kt @@ -5,9 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("ZEROSCAN", "ZeroScan", "pt") -internal class ZeroScan(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.ZEROSCAN, "zeroscan.com.br") { - override val postReq = true - override val datePattern: String = "dd/MM/yyyy" +@MangaSourceParser("BURNINGSCANS", "BurningScans", "pt") +internal class BurningScans(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.BURNINGSCANS, "burningscans.com") { + override val datePattern = "dd/MM/yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/LadyestelarScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/LadyestelarScan.kt deleted file mode 100644 index c2943ab9..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/LadyestelarScan.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.pt - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("LADYESTELARSCAN", "Lady Estelar Scan", "pt") -internal class LadyestelarScan(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.LADYESTELARSCAN, "ladyestelarscan.com.br", 10) { - override val datePattern: String = "dd/MM/yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/VortceScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/VortceScan.kt deleted file mode 100644 index fed78399..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/VortceScan.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.pt - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("VORTCESCAN", "VortceScan", "pt") -internal class VortceScan(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.VORTCESCAN, "vortcescan.com.br", pageSize = 10) { - override val datePattern: String = "d 'de' MMMMM 'de' yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Cizgiromanarsivi.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Cizgiromanarsivi.kt deleted file mode 100644 index fc91634e..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Cizgiromanarsivi.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.tr - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("CIZGIROMANARSIVI", "Cizgiromanarsivi", "tr") -internal class Cizgiromanarsivi(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.CIZGIROMANARSIVI, "cizgiromanarsivi.com", 24) { - override val stylePage = "" - override val tagPrefix = "kategori/" - override val listUrl = "seri/" - override val datePattern = "dd/MM/yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/DomalFansb.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/DomalFansb.kt index 1cb2141d..952be460 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/DomalFansb.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/DomalFansb.kt @@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("DOMALFANSB", "DomalFansub", "tr") internal class DomalFansb(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.DOMALFANSB, "domalfansb.com") { + MadaraParser(context, MangaSource.DOMALFANSB, "domalfansub.com.tr") { override val datePattern = "d MMMM yyyy" override val tagPrefix = "manga-turleri/" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GhostFansub.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GhostFansub.kt index 3f90eae7..2d3a2b78 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GhostFansub.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GhostFansub.kt @@ -7,5 +7,5 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("GHOSTFANSUB", "GhostFansub", "tr") internal class GhostFansub(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.GHOSTFANSUB, "ghostfansub.online", 18) + MadaraParser(context, MangaSource.GHOSTFANSUB, "ghostfansub.co", 18) // you now need to log in to access content diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MangaDiyari.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MangaDiyari.kt deleted file mode 100644 index 1b2c5af4..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MangaDiyari.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.tr - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MANGADIYARI", "MangaDiyari", "tr") -internal class MangaDiyari(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGADIYARI, "manga-diyari.com", 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MangaWow.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MangaWow.kt index 84b7185c..0057ff43 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MangaWow.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MangaWow.kt @@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("MANGAWOW", "MangaWow", "tr") internal class MangaWow(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGAWOW, "mangawow.com", 18) { + MadaraParser(context, MangaSource.MANGAWOW, "mangawow.org", 18) { override val datePattern = "d MMMM yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Tonizutoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Tonizutoon.kt index 8fa2e4cd..f84c5642 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Tonizutoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Tonizutoon.kt @@ -6,6 +6,8 @@ import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("TONIZUTOON", "TonizuToon", "tr", ContentType.HENTAI) +@MangaSourceParser("TONIZUTOON", "ToniZu.com", "tr", ContentType.HENTAI) internal class Tonizutoon(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.TONIZUTOON, "tonizutoon.com") + MadaraParser(context, MangaSource.TONIZUTOON, "tonizu.com") { + override val datePattern = "dd/mm/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Webtoonevreni.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Webtoonevreni.kt deleted file mode 100644 index 572cde39..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Webtoonevreni.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.tr - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("WEBTOONEVRENI", "WebtoonEvreni", "tr") -internal class Webtoonevreni(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.WEBTOONEVRENI, "webtoonevreni.net", 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Mi2Manga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Mi2Manga.kt deleted file mode 100644 index 82b6cb56..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Mi2Manga.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara.vi - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MadaraParser - -@MangaSourceParser("MI2MANGA", "Mi2Manga", "vi") -internal class Mi2Manga(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MI2MANGA, "www.mi2manga2.com") { - override val listUrl = "truyen-tranh/" - override val tagPrefix = "the-loai/" - override val datePattern = "d MMMM, yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt index 6a67b7e2..cfbb886f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt @@ -9,9 +9,9 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.util.* import java.util.EnumSet -@MangaSourceParser("SAYTRUYENHAY", "Saytruyenhay", "vi") +@MangaSourceParser("SAYTRUYENHAY", "PheTruyen", "vi") internal class Saytruyenhay(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.SAYTRUYENHAY, "saytruyenhay.com", 40) { + MadaraParser(context, MangaSource.SAYTRUYENHAY, "phetruyen.pro", 40) { override val tagPrefix = "genre/" override val withoutAjax = true diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt index 0c7d3665..40aef21e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt @@ -76,6 +76,7 @@ internal abstract class MadthemeParser( SortOrder.ALPHABETICAL -> append("name") // On some sites without tags or searches, the alphabetical option is empty. SortOrder.NEWEST -> append("created_at") SortOrder.RATING -> append("rating") + else -> append("updated_at") } if (filter.tags.isNotEmpty()) { filter.tags.forEach { @@ -196,7 +197,10 @@ internal abstract class MadthemeParser( protected open suspend fun getChapters(doc: Document): List { val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> + val slug = doc.selectFirstOrThrow("script:containsData(bookSlug)").data().substringAfter("bookSlug = \"") + .substringBefore("\";") + val docChapter = webClient.httpGet("https://$domain/api/manga/$slug/chapters?source=detail").parseHtml() + return docChapter.select(selectChapter).mapChapters(reversed = true) { i, li -> val a = li.selectFirstOrThrow("a") val href = a.attrAsRelativeUrl("href") val dateText = li.selectFirst(selectDate)?.text() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt index 0ebbcb33..fa8a1b8c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt @@ -1,22 +1,51 @@ package org.koitharu.kotatsu.parsers.site.madtheme.en +import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madtheme.MadthemeParser +import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl import org.koitharu.kotatsu.parsers.util.domain import org.koitharu.kotatsu.parsers.util.generateUid +import org.koitharu.kotatsu.parsers.util.mapChapters import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl +import java.text.SimpleDateFormat @MangaSourceParser("MANGAJINX", "MangaJinx", "en") internal class MangaJinx(context: MangaLoaderContext) : MadthemeParser(context, MangaSource.MANGAJINX, "mangajinx.com") { override val listUrl = "search" + override suspend fun getChapters(doc: Document): List { + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + val id = doc.selectFirstOrThrow("script:containsData(bookId)").data().substringAfter("bookId = ") + .substringBefore(";") + val docChapter = webClient.httpGet("https://$domain/service/backend/chaplist/?manga_id=$id").parseHtml() + return docChapter.select(selectChapter).mapChapters(reversed = true) { i, li -> + val a = li.selectFirstOrThrow("a") + val href = a.attrAsRelativeUrl("href") + val dateText = li.selectFirst(selectDate)?.text() + MangaChapter( + id = generateUid(href), + name = li.selectFirstOrThrow(".chapter-title").text(), + number = i + 1, + url = href, + uploadDate = parseChapterDate( + dateFormat, + dateText, + ), + source = source, + scanlator = null, + branch = null, + ) + } + } + override suspend fun getPages(chapter: MangaChapter): List { val chapterUrl = chapter.url.toAbsoluteUrl(domain) val docs = webClient.httpGet(chapterUrl).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt index da959f84..0d73749c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.madtheme.en +import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.site.madtheme.MadthemeParser import org.koitharu.kotatsu.parsers.util.* +import java.text.SimpleDateFormat import java.util.Locale @MangaSourceParser("MANHUASCAN", "ManhuaScan.io", "en") @@ -35,6 +37,7 @@ internal class ManhuaScan(context: MangaLoaderContext) : SortOrder.ALPHABETICAL -> append("name") SortOrder.NEWEST -> append("created_at") SortOrder.RATING -> append("rating") + else -> append("updated_at") } if (filter.tags.isNotEmpty()) { filter.tags.forEach { @@ -93,6 +96,31 @@ internal class ManhuaScan(context: MangaLoaderContext) : } } + override suspend fun getChapters(doc: Document): List { + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + val id = doc.selectFirstOrThrow("script:containsData(bookId)").data().substringAfter("bookId = ") + .substringBefore(";") + val docChapter = webClient.httpGet("https://$domain/service/backend/chaplist/?manga_id=$id").parseHtml() + return docChapter.select(selectChapter).mapChapters(reversed = true) { i, li -> + val a = li.selectFirstOrThrow("a") + val href = a.attrAsRelativeUrl("href") + val dateText = li.selectFirst(selectDate)?.text() + MangaChapter( + id = generateUid(href), + name = li.selectFirstOrThrow(".chapter-title").text(), + number = i + 1, + url = href, + uploadDate = parseChapterDate( + dateFormat, + dateText, + ), + source = source, + scanlator = null, + branch = null, + ) + } + } + override suspend fun getPages(chapter: MangaChapter): List { val chapterUrl = chapter.url.toAbsoluteUrl(domain) val docs = webClient.httpGet(chapterUrl).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/MangakakalotTv.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/MangakakalotTv.kt index 2c545e17..0affb736 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/MangakakalotTv.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/MangakakalotTv.kt @@ -14,7 +14,7 @@ import java.util.EnumSet internal class MangakakalotTv(context: MangaLoaderContext) : MangaboxParser(context, MangaSource.MANGAKAKALOTTV) { - override val configKeyDomain = ConfigKey.Domain("ww6.mangakakalot.tv") + override val configKeyDomain = ConfigKey.Domain("ww7.mangakakalot.tv") override val searchUrl = "/search/" override val listUrl = "/manga_list" override val availableSortOrders: Set = EnumSet.of( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt index 861de4eb..67e2317f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt @@ -30,7 +30,13 @@ internal abstract class MangaReaderParser( override val configKeyDomain = ConfigKey.Domain(domain) override val availableSortOrders: Set - get() = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.NEWEST) + get() = EnumSet.of( + SortOrder.UPDATED, + SortOrder.POPULARITY, + SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, + SortOrder.NEWEST, + ) override val availableStates: Set get() = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED) @@ -63,6 +69,7 @@ internal abstract class MangaReaderParser( append( when (filter.sortOrder) { SortOrder.ALPHABETICAL -> "title" + SortOrder.ALPHABETICAL_DESC -> "titlereverse" SortOrder.NEWEST -> "latest" SortOrder.POPULARITY -> "popular" SortOrder.UPDATED -> "update" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/GalaxyAction.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/GalaxyAction.kt deleted file mode 100644 index 32c55b4b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/GalaxyAction.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("GALAXYACTION", "GalaxyAction", "ar") -internal class GalaxyAction(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.GALAXYACTION, "galaxyaction.site", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/MangaProtm.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/MangaProtm.kt deleted file mode 100644 index ed0d1e4c..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/MangaProtm.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("MANGAPROTM", "MangaPro", "ar") -internal class MangaProtm(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANGAPROTM, "mangapro.co", pageSize = 20, searchPageSize = 20) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Oxapk.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Oxapk.kt deleted file mode 100644 index 455dfd6d..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Oxapk.kt +++ /dev/null @@ -1,89 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.Manga -import org.koitharu.kotatsu.parsers.model.MangaChapter -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.model.WordSet -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -import org.koitharu.kotatsu.parsers.util.* -import java.text.DateFormat -import java.text.SimpleDateFormat -import java.util.* - -@MangaSourceParser("OXAPK", "Oxapk", "ar") -internal class Oxapk(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.OXAPK, "oxapk.com", pageSize = 24, searchPageSize = 10) { - - override val sourceLocale: Locale = Locale.ENGLISH - - override suspend fun getDetails(manga: Manga): Manga { - val docs = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() - val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - val chapters = docs.select("#chapterlist > ul > li").mapChapters(reversed = true) { index, element -> - val url = element.selectFirst("a")?.attrAsRelativeUrl("href") ?: return@mapChapters null - MangaChapter( - id = generateUid(url), - name = docs.selectFirst("a.chapter-link-item")?.ownText().orEmpty(), - url = url, - number = index + 1, - scanlator = null, - uploadDate = parseChapterDate( - dateFormat, - element.selectFirst("div.chapter-link-time")?.text(), - ), - branch = null, - source = source, - ) - } - return parseInfo(docs, manga, chapters) - } - - private fun parseChapterDate(dateFormat: DateFormat, date: String?): Long { - date ?: return 0 - return when { - date.endsWith("منذ ", ignoreCase = true) -> { - parseRelativeDate(date) - } - - else -> dateFormat.tryParse(date) - } - } - - private fun parseRelativeDate(date: String): Long { - val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0 - val cal = Calendar.getInstance() - - return when { - WordSet("أيام").anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis - - WordSet("hour", "hours").anyWordIn(date) -> cal.apply { - add( - Calendar.HOUR, - -number, - ) - }.timeInMillis - - WordSet( - "mins", - ).anyWordIn(date) -> cal.apply { - add( - Calendar.MINUTE, - -number, - ) - }.timeInMillis - - WordSet("second").anyWordIn(date) -> cal.apply { - add( - Calendar.SECOND, - -number, - ) - }.timeInMillis - - WordSet("أشهر").anyWordIn(date) -> cal.apply { add(Calendar.MONTH, -number) }.timeInMillis - WordSet("year").anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis - else -> 0 - } - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/OzulShojo.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/OzulShojo.kt deleted file mode 100644 index 38ad6245..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/OzulShojo.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("OZULSHOJO", "OzulShojo", "ar") -internal class OzulShojo(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.OZULSHOJO, "ozulshojo.com", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/SpiderScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/SpiderScans.kt deleted file mode 100644 index 6152f1ed..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/SpiderScans.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.ar - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("SPIDERSCANS", "SpiderScans", "ar") -internal class SpiderScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.SPIDERSCANS, "spiderscans.com", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/SwaTeam.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/SwaTeam.kt index f672d1c5..0a055730 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/SwaTeam.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/SwaTeam.kt @@ -36,6 +36,7 @@ internal class SwaTeam(context: MangaLoaderContext) : append( when (filter.sortOrder) { SortOrder.ALPHABETICAL -> "a-z" + SortOrder.ALPHABETICAL_DESC -> "z-a" SortOrder.NEWEST -> "added" SortOrder.POPULARITY -> "popular" SortOrder.UPDATED -> "update" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/AquaManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/AquaManga.kt deleted file mode 100644 index 5c9616df..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/AquaManga.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("AQUAMANGA_LIVE", "AquaManga.live", "en") -internal class AquaManga(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.AQUAMANGA_LIVE, "aquamanga.live", pageSize = 30, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt index 06d5448a..aef8f554 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt @@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("ARVENSCANS", "ArvenScans", "en") internal class ArvenScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.ARVENSCANS, "arvenscans.com", pageSize = 20, searchPageSize = 10) { + MangaReaderParser(context, MangaSource.ARVENSCANS, "arvenscans.org", pageSize = 20, searchPageSize = 10) { override val listUrl = "/series" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Edomae.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Edomae.kt deleted file mode 100644 index f51a8bad..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Edomae.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("EDOMAE", "Edomae", "en") -internal class Edomae(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.EDOMAE, "edomae.co", pageSize = 20, searchPageSize = 10) { - override val encodedSrc = true - override val selectScript = "#content script" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt index 86628692..dd936eb8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt @@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("KAISCANS", "KaiScans", "en") internal class KaiScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.KAISCANS, "www.kaiscans.com", pageSize = 20, searchPageSize = 10) { + MangaReaderParser(context, MangaSource.KAISCANS, "kaiscans.com", pageSize = 20, searchPageSize = 10) { override val listUrl = "/series" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LyraScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LyraScans.kt deleted file mode 100644 index 4a1566e4..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LyraScans.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("LYRASCANS", "LyraScans", "en") -internal class LyraScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.LYRASCANS, "lyrascans.com", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaLover.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaLover.kt index 08fcdd9a..b6e2f581 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaLover.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaLover.kt @@ -8,6 +8,6 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("MANHWALOVER", "ManhwaLover", "en", ContentType.HENTAI) internal class ManhwaLover(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANHWALOVER, "manhwalover.com", pageSize = 20, searchPageSize = 20) { + MangaReaderParser(context, MangaSource.MANHWALOVER, "www.manhwalover.com", pageSize = 20, searchPageSize = 20) { override val datePattern = "MMM d, yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/OpScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/OpScans.kt deleted file mode 100644 index e6744ba0..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/OpScans.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("OPSCANS", "OpScanlations", "en") -internal class OpScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.OPSCANS, "opscanlations.com", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/OzulScansEn.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/OzulScansEn.kt deleted file mode 100644 index b6aa46ca..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/OzulScansEn.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("OZULSCANSEN", "OzulScans", "en") -internal class OzulScansEn(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.OZULSCANSEN, "ozulscansen.com", pageSize = 30, searchPageSize = 10) { - override val listUrl = "/comics" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Phantomscans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Phantomscans.kt deleted file mode 100644 index 2fa6f91b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Phantomscans.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("PHANTOMSCANS", "PhantomScans", "en") -internal class Phantomscans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.PHANTOMSCANS, "phantomscans.com", pageSize = 20, searchPageSize = 20) { - override val datePattern = "MMM d, yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/QueenScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/QueenScans.kt deleted file mode 100644 index dc6d11d6..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/QueenScans.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.en - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("QUEENSCANS", "QueenScans", "en") -internal class QueenScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.QUEENSCANS, "fairymanga.com", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt index ce364b48..3c675e90 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt @@ -19,6 +19,7 @@ internal class RizzComic(context: MangaLoaderContext) : override val availableSortOrders: Set = EnumSet.of(SortOrder.ALPHABETICAL) override val availableStates: Set = emptySet() override val isMultipleTagsSupported = false + override val isSearchSupported = false // TODO Query created in json override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/AiyuMangaScanlation.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/AiyuMangaScanlation.kt index 86eb461c..4ea0e9db 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/AiyuMangaScanlation.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/AiyuMangaScanlation.kt @@ -7,4 +7,4 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("AIYUMANGASCANLATION", "AiyuManhua", "es") internal class AiyuMangaScanlation(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.AIYUMANGASCANLATION, "aiyumanhua.com", 20, 10) + MangaReaderParser(context, MangaSource.AIYUMANGASCANLATION, "www.aiyumanhua.com", 20, 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MangaReaderpro.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MangaReaderpro.kt deleted file mode 100644 index 38c28038..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MangaReaderpro.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.es - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -import java.util.Locale - -@MangaSourceParser("MANGAREADERPRO", "MangaReaderPro", "es") -internal class MangaReaderpro(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANGAREADERPRO, "mangareaderpro.com", pageSize = 20, searchPageSize = 10) { - override val sourceLocale: Locale = Locale.ENGLISH -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MangaShiina.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MangaShiina.kt index 15ff0102..9b7ad34e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MangaShiina.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MangaShiina.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -@MangaSourceParser("MANGASHIINA", "MangaShiina", "es") +@MangaSourceParser("MANGASHIINA", "MangaMukai.com", "es") internal class MangaShiina(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANGASHIINA, "mangashiina.com", pageSize = 20, searchPageSize = 10) + MangaReaderParser(context, MangaSource.MANGASHIINA, "mangamukai.com", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/Tresdaos.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/Tresdaos.kt new file mode 100644 index 00000000..bfb97499 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/Tresdaos.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.es + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + +@MangaSourceParser("TRESDAOS", "Tresdaos", "es") +internal class Tresdaos(context: MangaLoaderContext) : + MangaReaderParser(context, MangaSource.TRESDAOS, "tresdaos.com", 20, 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/ManhwaFreakFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/ManhwaFreakFr.kt deleted file mode 100644 index ff49525b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/ManhwaFreakFr.kt +++ /dev/null @@ -1,215 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.fr - -import org.jsoup.nodes.Document -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -import org.koitharu.kotatsu.parsers.util.* -import java.text.DateFormat -import java.text.SimpleDateFormat -import java.util.Calendar -import java.util.Locale - -@MangaSourceParser("MANHWA_FREAK_FR", "ManhwaFreak.fr", "fr") -internal class ManhwaFreakFr(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANHWA_FREAK_FR, "manhwafreak.fr", pageSize = 0, searchPageSize = 10) { - - override val selectMangaList = ".listupd .lastest-serie" - override val selectMangaListImg = "img" - override val sourceLocale: Locale = Locale.ENGLISH - override val availableStates: Set = emptySet() - override val isMultipleTagsSupported = false - - override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { - val url = buildString { - append("https://") - append(domain) - - when (filter) { - - is MangaListFilter.Search -> { - append("/page/") - append(page.toString()) - append("/?s=") - append(filter.query.urlEncoded()) - } - - is MangaListFilter.Advanced -> { - if (page > 1) { - return emptyList() - } - - if (filter.tags.isNotEmpty()) { - filter.tags.oneOrThrowIfMany()?.let { - append("/genres/?genre=") - append(it.key) - } - } else { - append(listUrl) - append("/?order=") - append( - when (filter.sortOrder) { - SortOrder.ALPHABETICAL -> "az" - SortOrder.NEWEST -> "new" - SortOrder.POPULARITY -> "views" - SortOrder.UPDATED -> "" - else -> "" - }, - ) - } - } - - null -> { - append(listUrl) - } - } - } - return parseMangaList(webClient.httpGet(url).parseHtml()) - } - - override suspend fun getAvailableTags(): Set { - val doc = webClient.httpGet("https://$domain/genres/").parseHtml() - return doc.select("ul.genre-list li a").mapNotNullToSet { a -> - val href = a.attr("href").substringAfterLast("=") - MangaTag( - key = href, - title = a.text(), - source = source, - ) - } - } - - override suspend fun getDetails(manga: Manga): Manga { - val docs = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() - val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - val chapters = docs.select("div.chapter-li a").mapChapters(reversed = true) { index, a -> - val url = a.attrAsRelativeUrl("href") - val dateText = a.selectFirst(".chapter-info p.new")?.text() ?: a.select(".chapter-info p")[1].text() - MangaChapter( - id = generateUid(url), - name = a.selectFirst(".chapter-info p:contains(Chapter)")?.text() ?: "Chapter ${index + 1}", - url = url, - number = index + 1, - scanlator = null, - uploadDate = if (dateText == "NEW") { - parseChapterDate( - dateFormat, - "today", - ) - } else { - parseChapterDate( - dateFormat, - dateText, - ) - }, - branch = null, - source = source, - ) - } - return parseInfo(docs, manga, chapters) - } - - override suspend fun parseInfo(docs: Document, manga: Manga, chapters: List): Manga { - val tagMap = getOrCreateTagMap() - val selectTag = docs.requireElementById("info").select("div:contains(Genre) > p:last-child").text().split(",") - val tags = selectTag.mapNotNullToSet { tagMap[it] } - val mangaState = docs.requireElementById("info").select("div:contains(Status) > p:last-child").text().let { - when (it) { - "Ongoing" -> MangaState.ONGOING - "Completed" -> MangaState.FINISHED - else -> null - } - } - val author = docs.requireElementById("info").select("div:contains(Author(s)) > p:last-child").text() - return manga.copy( - altTitle = docs.requireElementById("info").select("div:contains(Alternative) > p:last-child").text(), - description = docs.requireElementById("summary").html(), - state = mangaState, - author = author, - isNsfw = manga.isNsfw, - tags = tags, - chapters = chapters, - ) - } - - private fun parseChapterDate(dateFormat: DateFormat, date: String?): Long { - // Clean date (e.g. 5th December 2019 to 5 December 2019) before parsing it - val d = date?.lowercase() ?: return 0 - return when { - d.endsWith(" ago") -> parseRelativeDate(date) - // Handle 'yesterday' and 'today', using midnight - d.startsWith("year") -> Calendar.getInstance().apply { - add(Calendar.DAY_OF_MONTH, -1) // yesterday - set(Calendar.HOUR_OF_DAY, 0) - set(Calendar.MINUTE, 0) - set(Calendar.SECOND, 0) - set(Calendar.MILLISECOND, 0) - }.timeInMillis - - d.startsWith("today") -> Calendar.getInstance().apply { - set(Calendar.HOUR_OF_DAY, 0) - set(Calendar.MINUTE, 0) - set(Calendar.SECOND, 0) - set(Calendar.MILLISECOND, 0) - }.timeInMillis - - date.contains(Regex("""\d(st|nd|rd|th)""")) -> date.split(" ").map { - if (it.contains(Regex("""\d\D\D"""))) { - it.replace(Regex("""\D"""), "") - } else { - it - } - }.let { dateFormat.tryParse(it.joinToString(" ")) } - - else -> dateFormat.tryParse(date) - } - } - - // Parses dates in this form: - // 21 hours ago - private fun parseRelativeDate(date: String): Long { - val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0 - val cal = Calendar.getInstance() - return when { - WordSet( - "day", - "days", - "d", - ).anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis - - WordSet( - "hour", - "hours", - "h", - ).anyWordIn(date) -> cal.apply { - add( - Calendar.HOUR, - -number, - ) - }.timeInMillis - - WordSet( - "minute", - "minutes", - "mins", - ).anyWordIn(date) -> cal.apply { - add( - Calendar.MINUTE, - -number, - ) - }.timeInMillis - - WordSet("second").anyWordIn(date) -> cal.apply { - add( - Calendar.SECOND, - -number, - ) - }.timeInMillis - - WordSet("month", "months").anyWordIn(date) -> cal.apply { add(Calendar.MONTH, -number) }.timeInMillis - WordSet("year").anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis - else -> 0 - } - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Boosei.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Boosei.kt deleted file mode 100644 index 9b0c4073..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Boosei.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("BOOSEI", "Boosei", "id") -internal class Boosei(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.BOOSEI, "boosei.net", pageSize = 30, searchPageSize = 30) { - override val datePattern = "MMM d, yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikDewasaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikDewasaParser.kt index e9d66852..cdb659bd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikDewasaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikDewasaParser.kt @@ -7,9 +7,9 @@ import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import java.util.* -@MangaSourceParser("KOMIKDEWASA", "KomikDewasa.Club", "id", ContentType.HENTAI) +@MangaSourceParser("KOMIKDEWASA", "komikRemaja.cfd", "id", ContentType.HENTAI) internal class KomikDewasaParser(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.KOMIKDEWASA, "komikremaja.club", pageSize = 20, searchPageSize = 10) { + MangaReaderParser(context, MangaSource.KOMIKDEWASA, "komikremaja.cfd", pageSize = 20, searchPageSize = 10) { override val listUrl: String = "/komik" override val sourceLocale: Locale = Locale.ENGLISH } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikLokalParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikLokalParser.kt index 807d1b61..0d450330 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikLokalParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikLokalParser.kt @@ -6,9 +6,9 @@ import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import java.util.* -@MangaSourceParser("KOMIKLOKAL", "KomikLokal", "id") +@MangaSourceParser("KOMIKLOKAL", "KomikMirror", "id") internal class KomikLokalParser(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.KOMIKLOKAL, "komikmirror.art", pageSize = 20, searchPageSize = 10) { + MangaReaderParser(context, MangaSource.KOMIKLOKAL, "komikmirror.sbs", pageSize = 20, searchPageSize = 10) { override val datePattern = "MMM d, yyyy" override val sourceLocale: Locale = Locale.ENGLISH } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikMangaParser.kt deleted file mode 100644 index 7e386f8a..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikMangaParser.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -import java.util.* - -@MangaSourceParser("KOMIKMANGA", "KomikManga", "id") -internal class KomikMangaParser(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.KOMIKMANGA, "komikhentai.co", pageSize = 20, searchPageSize = 10) { - override val listUrl = "/project" - override val datePattern = "MMM d, yyyy" - override val sourceLocale: Locale = Locale.ENGLISH - -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikManhwa.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikManhwa.kt deleted file mode 100644 index 1ac0a1f8..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikManhwa.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.ContentType -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("KOMIKMANHWA", "KomikManhwa", "id", ContentType.HENTAI) -internal class KomikManhwa(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.KOMIKMANHWA, "komikmanhwa.me", pageSize = 20, searchPageSize = 20) { - override val listUrl = "/series" - override val datePattern = "MMM d, yyyy" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikSan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikSan.kt index 9074f62c..5d2f385d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikSan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikSan.kt @@ -41,6 +41,7 @@ internal class KomikSan(context: MangaLoaderContext) : append( when (filter.sortOrder) { SortOrder.ALPHABETICAL -> "title" + SortOrder.ALPHABETICAL_DESC -> "titlereverse" SortOrder.NEWEST -> "latest" SortOrder.POPULARITY -> "popular" SortOrder.UPDATED -> "update" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/SugarLab.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikSay.kt similarity index 56% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/SugarLab.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikSay.kt index 3e66916a..84ef81b5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/SugarLab.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikSay.kt @@ -2,13 +2,12 @@ package org.koitharu.kotatsu.parsers.site.mangareader.id import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import java.util.* -@MangaSourceParser("SUGARLAB", "SugarLab", "id", ContentType.HENTAI) -internal class SugarLab(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.SUGARLAB, "sugarlab.my.id", pageSize = 20, searchPageSize = 10) { +@MangaSourceParser("KOMIKSAY", "KomikSay", "id") +internal class KomikSay(context: MangaLoaderContext) : + MangaReaderParser(context, MangaSource.KOMIKSAY, "komiksay.info", pageSize = 30, searchPageSize = 10) { override val sourceLocale: Locale = Locale.ENGLISH } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt index eb91b5ac..f6ba0c98 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt @@ -44,6 +44,7 @@ internal class Komikcast(context: MangaLoaderContext) : append( when (filter.sortOrder) { SortOrder.ALPHABETICAL -> "&orderby=titleasc" + SortOrder.ALPHABETICAL_DESC -> "&orderby=titledesc" SortOrder.POPULARITY -> "&orderby=popular" SortOrder.UPDATED -> "" // To get the Updated list, you don't need "orderby" in the url. else -> "" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Mangakyo.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Mangakyo.kt index 3661827e..b9b1c6e9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Mangakyo.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Mangakyo.kt @@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("MANGAKYO", "MangaKyo", "id") internal class Mangakyo(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANGAKYO, "mangakyo.org", pageSize = 40, searchPageSize = 20) { + MangaReaderParser(context, MangaSource.MANGAKYO, "mangakyo.vip", pageSize = 40, searchPageSize = 20) { override val listUrl = "/komik" override val datePattern = "MMM d, yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaIndoIcu.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaIndoIcu.kt index e808542b..0e806718 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaIndoIcu.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaIndoIcu.kt @@ -7,8 +7,8 @@ import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import java.util.* -@MangaSourceParser("MANHWAINDOICU", "ManhwaIndo.icu", "id", ContentType.HENTAI) +@MangaSourceParser("MANHWAINDOICU", "ManhwaIndo.sbs", "id", ContentType.HENTAI) internal class ManhwaIndoIcu(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANHWAINDOICU, "manhwaindo.icu", pageSize = 30, searchPageSize = 10) { + MangaReaderParser(context, MangaSource.MANHWAINDOICU, "manhwaindo.sbs", pageSize = 30, searchPageSize = 10) { override val sourceLocale: Locale = Locale.ENGLISH } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaLand.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaLand.kt index 78732d5b..50856a1e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaLand.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwaLand.kt @@ -5,10 +5,7 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -import java.util.* @MangaSourceParser("MANHWALAND", "ManhwaLand", "id", ContentType.HENTAI) internal class ManhwaLand(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANHWALAND, "manhwaland.lat", pageSize = 20, searchPageSize = 10) { - override val sourceLocale: Locale = Locale.ENGLISH -} + MangaReaderParser(context, MangaSource.MANHWALAND, "62.182.80.253", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwadesuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwadesuParser.kt index 76678bd0..602c5001 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwadesuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/ManhwadesuParser.kt @@ -8,6 +8,6 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("MANHWADESU", "ManhwaDesu", "id", ContentType.HENTAI) internal class ManhwadesuParser(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MANHWADESU, "manhwadesu.one", pageSize = 20, searchPageSize = 10) { + MangaReaderParser(context, MangaSource.MANHWADESU, "manhwadesu.bio", pageSize = 20, searchPageSize = 10) { override val listUrl = "/komik" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Melokomik.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Melokomik.kt index 45501337..503ed2a5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Melokomik.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Melokomik.kt @@ -4,10 +4,7 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -import java.util.Locale -@MangaSourceParser("MELOKOMIK", "Warpasar", "id") +@MangaSourceParser("MELOKOMIK", "Wowomik", "id") internal class Melokomik(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MELOKOMIK, "warpasar.com", pageSize = 20, searchPageSize = 10) { - override val sourceLocale: Locale = Locale.ENGLISH -} + MangaReaderParser(context, MangaSource.MELOKOMIK, "wowomik.com", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ja/MangaMate.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ja/MangaMate.kt index 7ab9ad17..c50fb8a9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ja/MangaMate.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ja/MangaMate.kt @@ -11,6 +11,4 @@ internal class MangaMate(context: MangaLoaderContext) : MangaReaderParser(context, MangaSource.MANGAMATE, "manga-mate.org", pageSize = 10, searchPageSize = 10) { override val datePattern = "M月 d, yyyy" override val sourceLocale: Locale = Locale.ENGLISH - override val encodedSrc = true - } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/SpartanManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/SpartanManga.kt deleted file mode 100644 index 95f8fb64..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/SpartanManga.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.tr - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("SPARTANMANGA", "SpartanManga", "tr") -internal class SpartanManga(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.SPARTANMANGA, "spartanmanga.com.tr", pageSize = 40, searchPageSize = 20) - diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt index 9d025b62..921dc68c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt @@ -97,14 +97,15 @@ internal abstract class MmrcmsParser( append(listUrl) append("/?page=") append(page.toString()) - append("&asc=true&author=&tag=&alpha=&cat=") + append("&author=&tag=&alpha=&cat=") filter.tags.oneOrThrowIfMany()?.let { append(it.key) } append("&sortBy=") when (filter.sortOrder) { - SortOrder.POPULARITY -> append("views") - SortOrder.ALPHABETICAL -> append("name") + SortOrder.POPULARITY -> append("views&asc=true") + SortOrder.ALPHABETICAL -> append("name&asc=true") + SortOrder.ALPHABETICAL_DESC -> append("name&asc=false") else -> append("name") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt index 395b6d09..6adc09be 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt @@ -7,8 +7,8 @@ import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.* //the search doesn't work on the source. -@MangaSourceParser("JPSCANVF", "JpScan-vf", "fr") +@MangaSourceParser("JPSCANVF", "LireScanVf.com", "fr") internal class JpScanVf(context: MangaLoaderContext) : - MmrcmsParser(context, MangaSource.JPSCANVF, "jpscan-vf.net") { + MmrcmsParser(context, MangaSource.JPSCANVF, "lirescanvf.com") { override val sourceLocale: Locale = Locale.ENGLISH } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt deleted file mode 100644 index efbf5e5f..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mmrcms.fr - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser -import java.util.Locale - -@MangaSourceParser("SCAN_FR_ORG", "Scan-Fr.org", "fr") -internal class ScanFrOrg(context: MangaLoaderContext) : - MmrcmsParser(context, MangaSource.SCAN_FR_ORG, "www.scan-fr.org") { - - override val sourceLocale: Locale = Locale.ENGLISH - override val selectChapter = "ul.chapterszozo li" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt index 477f8cf7..cd5dc7cb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt @@ -14,11 +14,18 @@ import java.util.* class LerManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.LERMANGA, 24) { override val availableSortOrders: Set = - EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.RATING) + EnumSet.of( + SortOrder.UPDATED, + SortOrder.POPULARITY, + SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, + SortOrder.RATING, + ) override val configKeyDomain = ConfigKey.Domain("lermanga.org") override val isMultipleTagsSupported = false + override val isSearchSupported = false override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { @@ -52,6 +59,7 @@ class LerManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaSou SortOrder.UPDATED -> "modified&order=desc" SortOrder.POPULARITY -> "views&order=desc" SortOrder.ALPHABETICAL -> "title&order=asc" + SortOrder.ALPHABETICAL_DESC -> "title&order=desc" SortOrder.RATING -> "rating&order=desc" else -> "modified&order=desc" }, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/DesuMeParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/DesuMeParser.kt index 15db547e..49660567 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/DesuMeParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/DesuMeParser.kt @@ -37,6 +37,7 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont page: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { if (query != null && page != searchPaginator.firstPage) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/NudeMoonParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/NudeMoonParser.kt index abdd1c87..90a8e628 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/NudeMoonParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/NudeMoonParser.kt @@ -17,6 +17,7 @@ internal class NudeMoonParser( ) : MangaParser(context, MangaSource.NUDEMOON), MangaParserAuthProvider { override val configKeyDomain = ConfigKey.Domain( + "x.nude-moon.fun", "nude-moon.org", "nude-moon.net", ) @@ -48,6 +49,7 @@ internal class NudeMoonParser( offset: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { val domain = domain diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt index 95ac1174..b4b54239 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt @@ -77,6 +77,7 @@ internal class RemangaParser( page: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { copyCookies() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/AllHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/AllHentaiParser.kt index c6cd0de9..58de9974 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/AllHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/AllHentaiParser.kt @@ -19,7 +19,12 @@ internal class AllHentaiParser( context: MangaLoaderContext, ) : GroupleParser(context, MangaSource.ALLHENTAI, 1) { - override val configKeyDomain = ConfigKey.Domain("24.allhen.online", "z.allhen.online", "2023.allhen.online") + override val configKeyDomain = ConfigKey.Domain( + "20.allhen.online", + "24.allhen.online", + "z.allhen.online", + "2023.allhen.online", + ) override val defaultIsNsfw = true override val authUrl: String diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/GroupleParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/GroupleParser.kt index 3cedf4e5..172be900 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/GroupleParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/grouple/GroupleParser.kt @@ -276,6 +276,7 @@ internal abstract class GroupleParser( SortOrder.UPDATED -> "updated" SortOrder.NEWEST -> "created" SortOrder.RATING -> "votes" + else -> null } private suspend fun advancedSearch(domain: String, tags: Set): Response { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt index ab88a623..66b1ba86 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt @@ -32,6 +32,7 @@ internal abstract class ChanParser( offset: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { val domain = domain @@ -80,7 +81,7 @@ internal abstract class ChanParser( description = root.getElementById("description")?.html()?.substringBeforeLast(" - val href = tr?.selectFirst("a")?.attrAsRelativeUrlOrNull("href") + val href = tr.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: return@mapChapters null MangaChapter( id = generateUid(href), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/HenChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/HenChanParser.kt index a9ec7b7e..9d25acb4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/HenChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/HenChanParser.kt @@ -12,13 +12,14 @@ import java.util.* internal class HenChanParser(context: MangaLoaderContext) : ChanParser(context, MangaSource.HENCHAN) { override val configKeyDomain = ConfigKey.Domain( - "x.henchan.pro", + "xxxx.henchan.pro", + "xxl.hentaichan.live", "xxx.henchan.pro", "y.hentaichan.live", "xxx.hentaichan.live", "xx.hentaichan.live", + "x.henchan.pro", "hentaichan.live", - "hentaichan.pro", ) override val availableSortOrders: Set = EnumSet.of( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt index ca87f21b..9676c21e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt @@ -13,6 +13,7 @@ import org.koitharu.kotatsu.parsers.util.* internal class YaoiChanParser(context: MangaLoaderContext) : ChanParser(context, MangaSource.YAOICHAN) { override val configKeyDomain = ConfigKey.Domain( + "v2.yaoi-chan.me", "v1.yaoi-chan.me", "yaoi-chan.me", ) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/MangaLibParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/MangaLibParser.kt index adcad3b9..20b3e65b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/MangaLibParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/MangaLibParser.kt @@ -44,6 +44,7 @@ internal open class MangaLibParser( page: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { if (!query.isNullOrEmpty()) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScanVfOrg.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt similarity index 88% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScanVfOrg.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt index 026e537c..6142f05a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScanVfOrg.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt @@ -1,11 +1,10 @@ -package org.koitharu.kotatsu.parsers.site.fr +package org.koitharu.kotatsu.parsers.site.scan import androidx.collection.ArrayMap import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.koitharu.kotatsu.parsers.ErrorMessages import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* @@ -13,14 +12,17 @@ import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* -@MangaSourceParser("SCANVFORG", "ScanVfOrg", "fr") -internal class ScanVfOrg(context: MangaLoaderContext) : - PagedMangaParser(context, MangaSource.SCANVFORG, 0) { +internal abstract class ScanParser( + context: MangaLoaderContext, + source: MangaSource, + domain: String, + pageSize: Int = 0, +) : PagedMangaParser(context, source, pageSize) { override val availableSortOrders: Set = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.RATING) - - override val configKeyDomain = ConfigKey.Domain("scanvf.org") + override val isSearchSupported = false + override val configKeyDomain = ConfigKey.Domain(domain) override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { @@ -69,7 +71,7 @@ internal class ScanVfOrg(context: MangaLoaderContext) : id = generateUid(href), url = href, publicUrl = href.toAbsoluteUrl(div.host ?: domain), - coverUrl = div.selectFirst("img")?.src().orEmpty(), + coverUrl = div.selectFirst("img")?.attr("data-src")?.replace("\t", "").orEmpty(), title = div.selectFirstOrThrow(".link-series h3").text().orEmpty(), altTitle = null, rating = RATING_UNKNOWN, @@ -111,16 +113,16 @@ internal class ScanVfOrg(context: MangaLoaderContext) : val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val dateFormat = SimpleDateFormat("MM-dd-yyyy", sourceLocale) val tagMap = getOrCreateTagMap() - val selectTag = doc.select(".card-series-detail .col-6:contains(Categories) div") + val selectTag = doc.select(".card-series-detail .col-6:contains(Categorie) div") val tags = selectTag.mapNotNullToSet { tagMap[it.text()] } return manga.copy( rating = doc.selectFirst(".card-series-detail .rate-value span")?.ownText()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN, tags = tags, - author = doc.selectFirst(".card-series-detail .col-6:contains(Auteur) div")?.text(), + author = doc.selectFirst(".card-series-detail .col-6:contains(Autore) div")?.text(), altTitle = doc.selectFirst(".card div.col-12.mb-4 h2")?.text().orEmpty(), description = doc.selectFirst(".card div.col-12.mb-4 p")?.html().orEmpty(), - chapters = doc.select(".list-books .col-chapter").mapChapters(reversed = true) { i, div -> + chapters = doc.select(".chapters-list .col-chapter").mapChapters(reversed = true) { i, div -> val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") MangaChapter( id = generateUid(href), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/fr/ScanVfOrg.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/fr/ScanVfOrg.kt new file mode 100644 index 00000000..41e367d7 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/fr/ScanVfOrg.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.scan.fr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.scan.ScanParser + +@MangaSourceParser("SCANVFORG", "ScanVf.org", "fr") +internal class ScanVfOrg(context: MangaLoaderContext) : + ScanParser(context, MangaSource.SCANVFORG, "scanvf.org") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt new file mode 100644 index 00000000..27997be0 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.scan.it + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.scan.ScanParser + +@MangaSourceParser("SCANITA", "ScanIta.org", "it") +internal class ScanIta(context: MangaLoaderContext) : + ScanParser(context, MangaSource.SCANITA, "scanita.org") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt index 0d732396..f2477e69 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt @@ -19,7 +19,7 @@ class TrWebtoon(context: MangaLoaderContext) : override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("trwebtoon.com") override val availableSortOrders: Set = - EnumSet.of(SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.UPDATED) + EnumSet.of(SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.ALPHABETICAL_DESC, SortOrder.UPDATED) override val availableStates: Set = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED) @@ -77,6 +77,7 @@ class TrWebtoon(context: MangaLoaderContext) : when (filter.sortOrder) { SortOrder.POPULARITY -> append("views&short_type=DESC") SortOrder.ALPHABETICAL -> append("name&short_type=ASC") + SortOrder.ALPHABETICAL_DESC -> append("name&short_type=DESC") else -> append("views&short_type=DESC") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt index cb41dc3a..0135f814 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt @@ -14,7 +14,7 @@ class YaoiFlix(context: MangaLoaderContext) : PagedMangaParser(context, MangaSou override val availableSortOrders: Set = EnumSet.of(SortOrder.UPDATED) - override val configKeyDomain = ConfigKey.Domain("www.yaoiflix.pro") + override val configKeyDomain = ConfigKey.Domain("www.yaoiflix.live") override val isMultipleTagsSupported = false diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HentaiUkrParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HentaiUkrParser.kt index a5cd7080..d681cc0b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HentaiUkrParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HentaiUkrParser.kt @@ -67,7 +67,13 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS ) } - override suspend fun getList(offset: Int, query: String?, tags: Set?, sortOrder: SortOrder): List { + override suspend fun getList( + offset: Int, + query: String?, + tags: Set?, + tagsExclude: Set?, + sortOrder: SortOrder, + ): List { // Get all manga val json = allManga.get().toMutableList() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HoneyMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HoneyMangaParser.kt index 0184d186..85550e8a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HoneyMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/HoneyMangaParser.kt @@ -80,6 +80,7 @@ class HoneyMangaParser(context: MangaLoaderContext) : PagedMangaParser(context, page: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { val body = JSONObject() @@ -157,9 +158,7 @@ class HoneyMangaParser(context: MangaLoaderContext) : PagedMangaParser(context, } override suspend fun getPages(chapter: MangaChapter): List { - val body = JSONObject() - body.put("chapterId", chapter.url) - val content = webClient.httpPost(framesApi, body).parseJson().getJSONObject("resourceIds") + val content = webClient.httpGet("$framesApi/${chapter.url}").parseJson().getJSONObject("resourceIds") val baseUrl = imageStorageUrl.tryGet().getOrDefault(IMAGE_BASEURL_FALLBACK) return List(content.length()) { i -> val item = content.getString(i.toString()) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/MangaInUaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/MangaInUaParser.kt index 3b1fc2c6..99799bd1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/MangaInUaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/uk/MangaInUaParser.kt @@ -34,6 +34,7 @@ class MangaInUaParser(context: MangaLoaderContext) : PagedMangaParser( page: Int, query: String?, tags: Set?, + tagsExclude: Set?, sortOrder: SortOrder, ): List { val url = when { @@ -94,7 +95,7 @@ class MangaInUaParser(context: MangaLoaderContext) : PagedMangaParser( "news_id" to linkToComics.attrOrThrow("data-news_id"), "news_category" to linkToComics.attrOrThrow("data-news_category"), "this_link" to "", - "user_hashs" to userHash, + "user_hash" to userHash, ), ).parseHtml() val chapterNodes = chaptersDoc.select(".ltcitems") @@ -105,7 +106,7 @@ class MangaInUaParser(context: MangaLoaderContext) : PagedMangaParser( largeCoverUrl = root.selectFirst("div.item__full-sidebar--poster")?.selectFirst("img") ?.attrAsAbsoluteUrlOrNull("src"), chapters = chapterNodes.mapChapters { _, item -> - val href = item?.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: return@mapChapters null + val href = item.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: return@mapChapters null val isAlternative = item.styleValueOrNull("background") != null val name = item.selectFirst("a")?.text().orEmpty() if (!isAlternative) i++ diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt index 5b398558..d5ea7409 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt @@ -23,7 +23,7 @@ private const val SEARCH_PAGE_SIZE = 10 @MangaSourceParser("HENTAIVN", "HentaiVN", "vi", type = ContentType.HENTAI) class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSource.HENTAIVN) { - override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("hentaivn.autos", "hentaivn.tv") + override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("hentaivn.red", "hentaivn.autos", "hentaivn.tv") // hentaivn has created 2 different interfaces for mobile and desktop, and Cloudflare detects whether it's mobile or not even with a desktop user agent. override val headers: Headers = Headers.Builder().add("User-Agent", UserAgents.CHROME_MOBILE).build() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt index bd61e0aa..98669335 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt @@ -16,6 +16,7 @@ internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context, override val availableSortOrders: Set = EnumSet.of( SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, SortOrder.UPDATED, SortOrder.NEWEST, SortOrder.POPULARITY, @@ -76,6 +77,7 @@ internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context, SortOrder.UPDATED -> append("-updated_at") SortOrder.NEWEST -> append("-created_at") SortOrder.ALPHABETICAL -> append("name") + SortOrder.ALPHABETICAL_DESC -> append("-name") else -> append("-updated_at") } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt index 02fa5fc0..e8c1effe 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt @@ -17,7 +17,7 @@ import java.util.* class TruyentranhLHParser(context: MangaLoaderContext) : PagedMangaParser(context, source = MangaSource.TRUYENTRANHLH, pageSize = 18) { - override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("truyentranhlh.net") + override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("truyenlh.com") override val availableSortOrders: Set = EnumSet.allOf(SortOrder::class.java) override val availableStates: Set = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED) @@ -46,6 +46,7 @@ class TruyentranhLHParser(context: MangaLoaderContext) : SortOrder.RATING -> "like" SortOrder.POPULARITY -> "top" SortOrder.ALPHABETICAL -> "az" + SortOrder.ALPHABETICAL_DESC -> "za" }, ) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nettruyenmax.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nettruyenmax.kt index 070093fb..f9164c5c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nettruyenmax.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nettruyenmax.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser -@MangaSourceParser("NETTRUYENMAX", "NettruyenMax", "vi") +@MangaSourceParser("NETTRUYENMAX", "NettruyenBing", "vi") internal class Nettruyenmax(context: MangaLoaderContext) : - WpComicsParser(context, MangaSource.NETTRUYENMAX, "www.nettruyenus.com", 36) + WpComicsParser(context, MangaSource.NETTRUYENMAX, "www.nettruyenbing.com", 36) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nhattruyenmin.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nhattruyenmin.kt index daf35440..b471d526 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nhattruyenmin.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/Nhattruyenmin.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser -@MangaSourceParser("NHATTRUYENMIN", "NhattruyenMin", "vi") +@MangaSourceParser("NHATTRUYENMIN", "NhattruyenPlus", "vi") internal class Nhattruyenmin(context: MangaLoaderContext) : - WpComicsParser(context, MangaSource.NHATTRUYENMIN, "nhattruyenmin.com") + WpComicsParser(context, MangaSource.NHATTRUYENMIN, "nhattruyenplus.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt index 7fd208ae..eef2cc74 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt @@ -213,6 +213,7 @@ internal abstract class ZeistMangaParser( ?: doc.selectFirst("div.y6x11p:contains(Yazar) .dt") val desc = doc.getElementById("synopsis") ?: doc.getElementById("Sinopse") ?: doc.getElementById("sinopas") + ?: doc.selectFirst(".sinopsis") val chaptersDeferred = async { loadChapters(manga.url, doc) } manga.copy( author = author?.text(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ar/Mangaatrend.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ar/Mangaatrend.kt index e1f0b591..ebf47a34 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ar/Mangaatrend.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ar/Mangaatrend.kt @@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser @MangaSourceParser("MANGAATREND", "MangaATrend", "ar") internal class Mangaatrend(context: MangaLoaderContext) : - ZeistMangaParser(context, MangaSource.MANGAATREND, "mangaatrend.net") { + ZeistMangaParser(context, MangaSource.MANGAATREND, "www.mangaatrend.net") { override val selectPage = "#seoneurons-target img" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/HyoManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/HyoManga.kt deleted file mode 100644 index d0ee010b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/HyoManga.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.zeistmanga.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser - -@MangaSourceParser("HYOMANGA", "HyoManga", "id") -internal class HyoManga(context: MangaLoaderContext) : - ZeistMangaParser(context, MangaSource.HYOMANGA, "www.hyomanga.my.id") { - override val mangaCategory = "Manga" -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/KomikGes.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/KomikGes.kt new file mode 100644 index 00000000..1d143e0e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/KomikGes.kt @@ -0,0 +1,67 @@ +package org.koitharu.kotatsu.parsers.site.zeistmanga.id + +import org.jsoup.nodes.Document +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaChapter +import org.koitharu.kotatsu.parsers.model.MangaPage +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser +import org.koitharu.kotatsu.parsers.util.* +import org.koitharu.kotatsu.parsers.util.json.toJSONList +import java.text.SimpleDateFormat + +@MangaSourceParser("KOMIKGES", "KomikGes", "id") +internal class KomikGes(context: MangaLoaderContext) : + ZeistMangaParser(context, MangaSource.KOMIKGES, "www.komikges.my.id") { + + override suspend fun loadChapters(mangaUrl: String, doc: Document): List { + val feed = doc.selectFirstOrThrow(".episode-list script").html().substringAfter("('").substringBefore("');") + val url = buildString { + append("https://") + append(domain) + append("/feeds/posts/default/-/") + append(feed) + append("?alt=json&orderby=published&max-results=9999") + } + val json = + webClient.httpGet(url).parseJson().getJSONObject("feed").getJSONArray("entry").toJSONList().reversed() + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + return json.mapIndexedNotNull { i, j -> + val name = j.getJSONObject("title").getString("\$t") + val href = + j.getJSONArray("link").toJSONList().first { it.getString("rel") == "alternate" }.getString("href") + val dateText = j.getJSONObject("published").getString("\$t").substringBefore("T") + val slug = mangaUrl.substringAfterLast('/') + val slugChapter = href.substringAfterLast('/') + if (slug == slugChapter) { + return@mapIndexedNotNull null + } + MangaChapter( + id = generateUid(href), + url = href, + name = name, + number = i + 1, + branch = null, + uploadDate = dateFormat.tryParse(dateText), + scanlator = null, + source = source, + ) + } + } + + override suspend fun getPages(chapter: MangaChapter): List { + val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml() + return doc.selectFirstOrThrow("script:containsData(let data_content =)").data() + .split("src\\x3d\\x22").drop(1) + .map { img -> + val url = img.substringBefore("\\x22") + MangaPage( + id = generateUid(url), + url = url, + preview = null, + source = source, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/MonzeeKomik.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/MonzeeKomik.kt new file mode 100644 index 00000000..36e2d10f --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/MonzeeKomik.kt @@ -0,0 +1,74 @@ +package org.koitharu.kotatsu.parsers.site.zeistmanga.id + +import org.jsoup.nodes.Document +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaChapter +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser +import org.koitharu.kotatsu.parsers.util.domain +import org.koitharu.kotatsu.parsers.util.generateUid +import org.koitharu.kotatsu.parsers.util.json.toJSONList +import org.koitharu.kotatsu.parsers.util.parseJson +import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow +import org.koitharu.kotatsu.parsers.util.tryParse +import java.text.SimpleDateFormat + +@MangaSourceParser("MONZEEKOMIK", "MonzeeKomik", "id") +internal class MonzeeKomik(context: MangaLoaderContext) : + ZeistMangaParser(context, MangaSource.MONZEEKOMIK, "www.monzeekomik.my.id") { + override val selectPage = "article#reader img" + + override suspend fun loadChapters(mangaUrl: String, doc: Document): List { + + + val chapterRegex = """clwd\.run\('([^']+)'""".toRegex() + val scriptSelector = "#clwd > script" + val script = doc.selectFirstOrThrow(scriptSelector) + val feedFind = chapterRegex + .find(script.html()) + ?.groupValues?.get(1) + ?: throw Exception("Failed to find chapter feed") + + val feedClean = feedFind.removeSuffix(")") // clean + + val feed = if (feedClean == "Reincarnation Colosseum") // hot fix + { + "I Have 90 Billion Licking Gold" + } else { + feedClean + } + + val url = buildString { + append("https://") + append(domain) + append("/feeds/posts/default/-/") + append(feed) + append("?alt=json&orderby=published&max-results=9999") + } + val json = + webClient.httpGet(url).parseJson().getJSONObject("feed").getJSONArray("entry").toJSONList().reversed() + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + return json.mapIndexedNotNull { i, j -> + val name = j.getJSONObject("title").getString("\$t") + val href = + j.getJSONArray("link").toJSONList().first { it.getString("rel") == "alternate" }.getString("href") + val dateText = j.getJSONObject("published").getString("\$t").substringBefore("T") + val slug = mangaUrl.substringAfterLast('/') + val slugChapter = href.substringAfterLast('/') + if (slug == slugChapter) { + return@mapIndexedNotNull null + } + MangaChapter( + id = generateUid(href), + url = href, + name = name, + number = i + 1, + branch = null, + uploadDate = dateFormat.tryParse(dateText), + scanlator = null, + source = source, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/ZScanlation.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/ZScanlation.kt new file mode 100644 index 00000000..708163e5 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/ZScanlation.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.zeistmanga.pt + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.ContentType +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser + +@MangaSourceParser("ZSCANLATION", "ZScanlation", "pt", ContentType.HENTAI) +internal class ZScanlation(context: MangaLoaderContext) : + ZeistMangaParser(context, MangaSource.ZSCANLATION, "www.zscanlation.com") { + override val sateOngoing: String = "Em Lançamento" + override val sateFinished: String = "Completo" + override val sateAbandoned: String = "Dropado" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt index 6c928a53..aff9aa4f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt @@ -72,6 +72,7 @@ internal abstract class ZMangaParser( SortOrder.POPULARITY -> append("popular") SortOrder.UPDATED -> append("update") SortOrder.ALPHABETICAL -> append("title") + SortOrder.ALPHABETICAL_DESC -> append("titlereverse") SortOrder.NEWEST -> append("latest") SortOrder.RATING -> append("rating") } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/NeuManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/NeuManga.kt deleted file mode 100644 index ad303a69..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/NeuManga.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.zmanga.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.zmanga.ZMangaParser - -@MangaSourceParser("NEU_MANGA", "NeuManga.net", "id") -internal class NeuManga(context: MangaLoaderContext) : - ZMangaParser(context, MangaSource.NEU_MANGA, "neumanga.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/util/MangaParserEnv.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/util/MangaParserEnv.kt index 8d2045b6..d3e5ee7f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/util/MangaParserEnv.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/util/MangaParserEnv.kt @@ -68,6 +68,15 @@ fun Set?.oneOrThrowIfMany(): MangaState? { } } +@InternalParsersApi +fun Set?.oneOrThrowIfMany(): ContentRating? { + return when { + isNullOrEmpty() -> null + size == 1 -> first() + else -> throw IllegalArgumentException(ErrorMessages.FILTER_MULTIPLE_CONTENT_RATING_NOT_SUPPORTED) + } +} + val MangaParser.domain: String get() { return config[configKeyDomain] diff --git a/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt b/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt index b086e735..813d53ae 100644 --- a/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt +++ b/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt @@ -28,7 +28,7 @@ internal class MangaParserTest { @MangaSources fun list(source: MangaSource) = runTest(timeout = timeout) { val parser = context.newParserInstance(source) - val list = parser.getList(0, sortOrder = SortOrder.POPULARITY, tags = null) + val list = parser.getList(0, sortOrder = SortOrder.POPULARITY, tags = null, tagsExclude = null) checkMangaList(list, "list") assert(list.all { it.source == source }) } @@ -61,7 +61,11 @@ internal class MangaParserTest { offset = 0, filter = MangaListFilter.Advanced( sortOrder = SortOrder.POPULARITY, - tags = emptySet(), locale = null, states = emptySet(), + tags = emptySet(), + locale = null, + states = emptySet(), + tagsExclude = emptySet(), + contentRating = emptySet(), ), ).minByOrNull { it.title.length @@ -92,7 +96,7 @@ internal class MangaParserTest { assert(tags.all { it.source == source }) val tag = tags.last() - val list = parser.getList(offset = 0, tags = setOf(tag), sortOrder = null) + val list = parser.getList(offset = 0, tags = setOf(tag), null, sortOrder = null) checkMangaList(list, "${tag.title} (${tag.key})") assert(list.all { it.source == source }) } @@ -101,17 +105,13 @@ internal class MangaParserTest { @MangaSources fun tagsMultiple(source: MangaSource) = runTest(timeout = timeout) { val parser = context.newParserInstance(source) + if (!parser.isMultipleTagsSupported) return@runTest val tags = parser.getAvailableTags().shuffled().take(2).toSet() - val list = try { - parser.getList(offset = 0, tags = tags, sortOrder = null) - } catch (e: IllegalArgumentException) { - if (e.message == "Multiple genres are not supported by this source") { - return@runTest - } else { - throw e - } - } + val filter = MangaListFilter.Advanced.Builder(parser.availableSortOrders.first()) + .tags(tags) + .build() + val list = parser.getList(0, filter) checkMangaList(list, "${tags.joinToString { it.title }} (${tags.joinToString { it.key }})") assert(list.all { it.source == source }) } @@ -127,8 +127,10 @@ internal class MangaParserTest { val filter = MangaListFilter.Advanced( sortOrder = parser.availableSortOrders.first(), tags = setOf(), + tagsExclude = setOf(), locale = locales.random(), states = setOf(), + contentRating = setOf(), ) val list = parser.getList(offset = 0, filter) checkMangaList(list, filter.locale.toString()) @@ -140,7 +142,7 @@ internal class MangaParserTest { @MangaSources fun details(source: MangaSource) = runTest(timeout = timeout) { val parser = context.newParserInstance(source) - val list = parser.getList(0, sortOrder = SortOrder.POPULARITY, tags = null) + val list = parser.getList(0, sortOrder = SortOrder.POPULARITY, tags = null, tagsExclude = null) val manga = list[3] parser.getDetails(manga).apply { assert(!chapters.isNullOrEmpty()) { "Chapters are null or empty" } @@ -169,7 +171,7 @@ internal class MangaParserTest { @MangaSources fun pages(source: MangaSource) = runTest(timeout = timeout) { val parser = context.newParserInstance(source) - val list = parser.getList(0, sortOrder = SortOrder.UPDATED, tags = null) + val list = parser.getList(0, sortOrder = SortOrder.UPDATED, tags = null, tagsExclude = null) val manga = list.first() val chapter = parser.getDetails(manga).chapters?.firstOrNull() ?: error("Chapter is null at ${manga.publicUrl}") val pages = parser.getPages(chapter)