[mangaDex] Fix SortOrder and remove YearRange

[Bato] add OriginalLocale
[MangaPark] add OriginalLocale, SearchWithFilters
[Comick] add SearchWithFilters
[NineMangaParser] add SearchWithFilters
[AnimeBootstrap] add SearchWithFilters , ContentTypes
[madara] add Year, SearchWithFilters, SortOrder.RELEVANCE
[TeamXNovel] add ContentTypes , SearchWithFilters
master
devi 2 years ago
parent f2354957e6
commit d1f9b0d829

@ -49,10 +49,10 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
}
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.NEWEST,
SortOrder.ALPHABETICAL,
SortOrder.UPDATED,
SortOrder.NEWEST,
SortOrder.POPULARITY,
SortOrder.ALPHABETICAL,
SortOrder.POPULARITY_YEAR,
SortOrder.POPULARITY_MONTH,
SortOrder.POPULARITY_WEEK,
@ -65,6 +65,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isOriginalLocaleSupported = true,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -165,6 +166,15 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
}
filter.originalLocale?.let {
append("&origs=")
if (it.language == "in") {
append("id")
} else {
append(it.language)
}
}
append("&genres=")
if (filter.tags.isNotEmpty()) {
appendAll(filter.tags, ",") { it.key }

@ -34,13 +34,12 @@ internal class ComickFunParser(context: MangaLoaderContext) :
SortOrder.NEWEST,
)
private val tagsArray = SuspendLazy(::loadTags)
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = true,
isYearRangeSupported = true,
)
@ -66,13 +65,11 @@ internal class ComickFunParser(context: MangaLoaderContext) :
.addQueryParameter("tachiyomi", "true")
.addQueryParameter("limit", pageSize.toString())
.addQueryParameter("page", page.toString())
when {
!filter.query.isNullOrEmpty() -> {
filter.query?.let {
url.addQueryParameter("q", filter.query)
}
else -> {
filter.tags.forEach {
url.addQueryParameter("genres", it.key)
}
@ -84,10 +81,10 @@ internal class ComickFunParser(context: MangaLoaderContext) :
url.addQueryParameter(
"sort",
when (order) {
SortOrder.POPULARITY -> "view"
SortOrder.UPDATED -> "uploaded"
SortOrder.NEWEST -> "created_at"
SortOrder.POPULARITY -> "view"
SortOrder.RATING -> "rating"
SortOrder.UPDATED -> "uploaded"
else -> "uploaded"
},
)
@ -138,8 +135,7 @@ internal class ComickFunParser(context: MangaLoaderContext) :
},
)
}
}
}
val ja = webClient.httpGet(url.build()).parseJsonArray()
val tagsMap = tagsArray.get()
return ja.mapJSON { jo ->
@ -193,6 +189,45 @@ internal class ComickFunParser(context: MangaLoaderContext) :
)
}
private suspend fun getChapters(hid: String): List<MangaChapter> {
val ja = webClient.httpGet(
url = "https://api.${domain}/comic/$hid/chapters?limit=$CHAPTERS_LIMIT",
).parseJson().getJSONArray("chapters")
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
return ja.toJSONList().reversed().mapChapters { _, jo ->
val vol = jo.getIntOrDefault("vol", 0)
val chap = jo.getFloatOrDefault("chap", 0f)
val locale = Locale.forLanguageTag(jo.getString("lang"))
val group = jo.optJSONArray("group_name")?.joinToString(", ")
val branch = buildString {
append(locale.getDisplayName(locale).toTitleCase(locale))
if (!group.isNullOrEmpty()) {
append(" (")
append(group)
append(')')
}
}
MangaChapter(
id = generateUid(jo.getLong("id")),
name = buildString {
if (vol > 0) {
append("Vol ").append(vol).append(' ')
}
append("Chap ").append(chap)
jo.getStringOrNull("title")?.let { append(": ").append(it) }
},
number = chap,
volume = vol,
url = jo.getString("hid"),
scanlator = jo.optJSONArray("group_name")?.asIterable<String>()?.joinToString()
?.takeUnless { it.isBlank() },
uploadDate = dateFormat.tryParse(jo.getString("created_at").substringBefore('T')),
branch = branch,
source = source,
)
}
}
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val jo = webClient.httpGet(
"https://api.${domain}/chapter/${chapter.url}?tachiyomi=true",
@ -208,6 +243,8 @@ internal class ComickFunParser(context: MangaLoaderContext) :
}
}
private val tagsArray = SuspendLazy(::loadTags)
private suspend fun fetchAvailableTags(): Set<MangaTag> {
val sparseArray = tagsArray.get()
val set = ArraySet<MangaTag>(sparseArray.size())
@ -233,45 +270,6 @@ internal class ComickFunParser(context: MangaLoaderContext) :
return tags
}
private suspend fun getChapters(hid: String): List<MangaChapter> {
val ja = webClient.httpGet(
url = "https://api.${domain}/comic/$hid/chapters?limit=$CHAPTERS_LIMIT",
).parseJson().getJSONArray("chapters")
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
return ja.toJSONList().reversed().mapChapters { _, jo ->
val vol = jo.getIntOrDefault("vol", 0)
val chap = jo.getFloatOrDefault("chap", 0f)
val locale = Locale.forLanguageTag(jo.getString("lang"))
val group = jo.optJSONArray("group_name")?.joinToString(", ")
val branch = buildString {
append(locale.getDisplayName(locale).toTitleCase(locale))
if (!group.isNullOrEmpty()) {
append(" (")
append(group)
append(')')
}
}
MangaChapter(
id = generateUid(jo.getLong("id")),
name = buildString {
if (vol > 0) {
append("Vol ").append(vol).append(' ')
}
append("Chap ").append(chap)
jo.getStringOrNull("title")?.let { append(": ").append(it) }
},
number = chap,
volume = vol,
url = jo.getString("hid"),
scanlator = jo.optJSONArray("group_name")?.asIterable<String>()?.joinToString()
?.takeUnless { it.isBlank() },
uploadDate = dateFormat.tryParse(jo.getString("created_at").substringBefore('T')),
branch = branch,
source = source,
)
}
}
private fun JSONObject.selectGenres(tags: SparseArrayCompat<MangaTag>): Set<MangaTag> {
val array = optJSONArray("genres") ?: return emptySet()
val res = ArraySet<MangaTag>(array.length())

@ -44,6 +44,22 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context
keys.add(preferredServerKey)
}
override val availableSortOrders: EnumSet<SortOrder> = EnumSet.of(
SortOrder.UPDATED,
SortOrder.UPDATED_ASC,
SortOrder.POPULARITY,
SortOrder.POPULARITY_ASC,
SortOrder.RATING,
SortOrder.RATING_ASC,
SortOrder.NEWEST,
SortOrder.NEWEST_ASC,
SortOrder.ALPHABETICAL,
SortOrder.ALPHABETICAL_DESC,
SortOrder.ADDED,
SortOrder.ADDED_ASC,
SortOrder.RELEVANCE,
)
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
@ -54,8 +70,6 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context
isOriginalLocaleSupported = true,
)
override val availableSortOrders: EnumSet<SortOrder> = EnumSet.allOf(SortOrder::class.java)
override suspend fun getFilterOptions(): MangaListFilterOptions = coroutineScope {
val localesDeferred = async { fetchAvailableLocales() }
val tagsDeferred = async { fetchAvailableTags() }

@ -16,16 +16,23 @@ import java.util.*
internal class MangaPark(context: MangaLoaderContext) :
PagedMangaParser(context, MangaParserSource.MANGAPARK, pageSize = 36) {
override val configKeyDomain = ConfigKey.Domain("mangapark.net")
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
keys.add(userAgentKey)
}
override val availableSortOrders: Set<SortOrder> =
EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
override val configKeyDomain = ConfigKey.Domain("mangapark.net")
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = true,
isOriginalLocaleSupported = true,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -56,13 +63,6 @@ internal class MangaPark(context: MangaLoaderContext) :
),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
keys.add(userAgentKey)
}
private val tagsMap = SuspendLazy(::parseTags)
init {
context.cookieJar.insertCookies(domain, "nsfw", "2")
}
@ -73,14 +73,11 @@ internal class MangaPark(context: MangaLoaderContext) :
append(domain)
append("/search?page=")
append(page.toString())
when {
!filter.query.isNullOrEmpty() -> {
filter.query?.let {
append("&word=")
append(filter.query.urlEncoded())
}
else -> {
append("&genres=")
if (filter.tags.isNotEmpty()) {
appendAll(filter.tags, ",") { it.key }
@ -132,7 +129,10 @@ internal class MangaPark(context: MangaLoaderContext) :
append("&lang=")
append(it.language)
}
}
filter.originalLocale?.let {
append("&orig=")
append(it.language)
}
}
@ -156,6 +156,8 @@ internal class MangaPark(context: MangaLoaderContext) :
}
}
private val tagsMap = SuspendLazy(::parseTags)
private suspend fun parseTags(): Map<String, MangaTag> {
val tagElements = webClient.httpGet("https://$domain/search").parseHtml()
.select("div.flex-col:contains(Genres) div.whitespace-nowrap")
@ -217,13 +219,18 @@ internal class MangaPark(context: MangaLoaderContext) :
private fun parseChapterDate(dateFormat: DateFormat, date: String?): Long {
val d = date?.lowercase() ?: return 0
return when {
d.endsWith(" ago") -> parseRelativeDate(date)
d.startsWith("just now") -> Calendar.getInstance().apply {
WordSet(" ago").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("just now").startsWith(d) -> {
Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
}
else -> dateFormat.tryParse(date)
}

@ -44,6 +44,7 @@ internal abstract class NineMangaParser(
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchWithFiltersSupported = true,
isSearchSupported = true,
)
@ -69,19 +70,18 @@ internal abstract class NineMangaParser(
val url = buildString {
append("https://")
append(domain)
when {
!filter.query.isNullOrEmpty() -> {
append("/search/?name_sel=&wd=")
if (filter.tags.isNotEmpty() || filter.tagsExclude.isNotEmpty() || filter.states.isNotEmpty() || !filter.query.isNullOrEmpty()) {
append("/search/")
append("?page=")
append(page.toString())
filter.query?.let {
append("&name_sel=contain&wd=")
append(filter.query.urlEncoded())
append("&page=")
append(page)
append(".html")
}
else -> {
if (filter.tags.isNotEmpty() || filter.tagsExclude.isNotEmpty() || filter.states.isNotEmpty()) {
append("/search/?category_id=")
append("&category_id=")
append(filter.tags.joinToString(separator = ",") { it.key })
append("&out_category_id=")
@ -95,13 +95,10 @@ internal abstract class NineMangaParser(
else -> append("either")
}
}
append("&page=")
} else {
append("/category/index_")
}
append(page.toString())
append(".html")
}
}
}
val doc = webClient.httpGet(url).parseHtml()

@ -43,10 +43,16 @@ internal abstract class AnimeBootstrapParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isSearchSupported = true,
isSearchWithFiltersSupported = true,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableContentTypes = EnumSet.of(
ContentType.MANGA,
ContentType.MANHWA,
ContentType.MANHUA,
),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
@ -58,19 +64,28 @@ internal abstract class AnimeBootstrapParser(
append(page.toString())
append("&type=all")
when {
!filter.query.isNullOrEmpty() -> {
filter.query?.let {
append("&search=")
append(filter.query.urlEncoded())
}
else -> {
filter.tags.oneOrThrowIfMany()?.let {
append("&categorie=")
append(it.key)
}
filter.types.oneOrThrowIfMany()?.let {
append("&type=")
append(
when (it) {
ContentType.MANGA -> "manga"
ContentType.MANHWA -> "manhwa"
ContentType.MANHUA -> "manhua"
else -> "all"
},
)
}
append("&sort=")
when (order) {
SortOrder.POPULARITY -> append("view")
@ -81,8 +96,6 @@ internal abstract class AnimeBootstrapParser(
}
}
}
}
val doc = webClient.httpGet(url).parseHtml()
return doc.select("div.col-6 div.product__item").map { div ->

@ -4,6 +4,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import org.json.JSONArray
import org.json.JSONObject
import org.koitharu.kotatsu.parsers.Broken
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.PagedMangaParser
@ -15,6 +16,7 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed
import java.text.SimpleDateFormat
import java.util.*
@Broken
@MangaSourceParser("FLIXSCANS", "FlixScans.net", "ar")
internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.FLIXSCANS, 18) {

@ -28,54 +28,56 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isSearchSupported = true,
isSearchWithFiltersSupported = true,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED),
availableContentTypes = EnumSet.of(
ContentType.MANGA,
ContentType.MANHWA,
ContentType.MANHUA,
),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)
when {
!filter.query.isNullOrEmpty() -> {
append("/?search=")
append(filter.query.urlEncoded())
if (page > 1) {
append("&page=")
append(page.toString())
}
if (order == SortOrder.UPDATED) {
if (filter.tags.isNotEmpty() || filter.demographics.isNotEmpty()) {
throw IllegalArgumentException("Updated sorting does not support other sorting filters")
}
else -> {
if (filter.tags.isNotEmpty()) {
val tag = filter.tags.oneOrThrowIfMany()
append("/series?genre=")
append(tag?.key.orEmpty())
if (page > 1) {
append("&page=")
append("/?page=")
append(page.toString())
}
append("&")
} else {
when (order) {
SortOrder.POPULARITY -> append("/series")
SortOrder.UPDATED -> append("/")
else -> append("/")
}
if (page > 1) {
append("?page=")
append("/series?page=")
append(page.toString())
append("&")
} else {
append("?")
filter.query?.let {
append("&search=")
append(filter.query.urlEncoded())
}
filter.tags.oneOrThrowIfMany()?.let {
append("&genre=")
append(it.key)
}
filter.types.forEach {
append("&type=")
append(
when (it) {
ContentType.MANGA -> "مانجا ياباني"
ContentType.MANHWA -> "مانهوا كورية"
ContentType.MANHUA -> "مانها صيني"
else -> ""
},
)
}
if (order == SortOrder.POPULARITY || filter.tags.isNotEmpty()) {
filter.states.oneOrThrowIfMany()?.let {
append("status=")
append(
@ -89,8 +91,6 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex
}
}
}
}
}
val doc = webClient.httpGet(url).parseHtml()
return doc.select("div.listupd .bs .bsx").ifEmpty {
doc.select("div.post-body .box")

@ -252,7 +252,9 @@ internal abstract class FmreaderParser(
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago", " atrás", " h", " d").endsWith(d) -> { parseRelativeDate(d) }
WordSet(" ago", " atrás", " h", " d").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("today").startsWith(d) -> {
Calendar.getInstance().apply {
@ -281,18 +283,25 @@ internal abstract class FmreaderParser(
return when {
WordSet("second")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("min", "minute", "minutes", "minuto", "minutos")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("hour", "hours", "hora", "horas", "h")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("day", "days", "día", "dia")
.anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
WordSet("week", "weeks", "semana", "semanas")
.anyWordIn(date) -> cal.apply { add(Calendar.WEEK_OF_YEAR, -number) }.timeInMillis
WordSet("month", "months", "mes", "meses")
.anyWordIn(date) -> cal.apply { add(Calendar.MONTH, -number) }.timeInMillis
WordSet("year", "año", "años")
.anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis
else -> 0
}
}

@ -267,7 +267,9 @@ internal abstract class KeyoappParser(
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago").endsWith(d) -> { parseRelativeDate(d) }
WordSet(" ago").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("today").startsWith(d) -> {
Calendar.getInstance().apply {
@ -296,16 +298,22 @@ internal abstract class KeyoappParser(
return when {
WordSet("second")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("minute", "minutes")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("hour", "hours")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("day", "days")
.anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -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
}
}

@ -40,6 +40,8 @@ internal abstract class MadaraParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = !withoutAjax,
isSearchSupported = true,
isSearchWithFiltersSupported = true,
isYearSupported = true,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -51,8 +53,7 @@ internal abstract class MadaraParser(
override val availableSortOrders: Set<SortOrder> = setupAvailableSortOrders()
private fun setupAvailableSortOrders(): Set<SortOrder> {
return if(!withoutAjax)
{
return if (!withoutAjax) {
EnumSet.of(
SortOrder.UPDATED,
SortOrder.UPDATED_ASC,
@ -64,10 +65,17 @@ internal abstract class MadaraParser(
SortOrder.ALPHABETICAL_DESC,
SortOrder.RATING,
SortOrder.RATING_ASC,
SortOrder.RELEVANCE,
)
} else {
EnumSet.of(
SortOrder.UPDATED,
SortOrder.POPULARITY,
SortOrder.NEWEST,
SortOrder.ALPHABETICAL,
SortOrder.RATING,
SortOrder.RELEVANCE,
)
}else
{
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
}
}
@ -219,27 +227,13 @@ internal abstract class MadaraParser(
append("https://")
append(domain)
when {
!filter.query.isNullOrEmpty() -> {
if (pages > 1) {
append("/page/")
append(pages.toString())
}
append("/?s=")
append(filter.query.urlEncoded())
append("&post_type=wp-manga")
}
else -> {
if (pages > 1) {
append("/page/")
append(pages.toString())
}
append("/?s=")
//Support query
//append(filter.query.urlEncoded())
append(filter.query?.urlEncoded())
append("&post_type=wp-manga")
@ -273,11 +267,10 @@ internal abstract class MadaraParser(
)
}
// Support year
//filter.year?.let {
// append("&release=")
// append(filter.year)
//}
if (filter.year != 0) {
append("&release=")
append(filter.year.toString())
}
// Support author
//filter.author?.let {
@ -299,10 +292,8 @@ internal abstract class MadaraParser(
SortOrder.NEWEST -> append("new-manga")
SortOrder.ALPHABETICAL -> append("alphabet")
SortOrder.RATING -> append("rating")
// SortOrder.RELEVANCE -> {}
else -> append("latest")
}
}
SortOrder.RELEVANCE -> {}
else -> {}
}
}
return parseMangaList(webClient.httpGet(url).parseHtml())
@ -312,20 +303,10 @@ internal abstract class MadaraParser(
payload["page"] = page.toString()
when {
!filter.query.isNullOrEmpty() -> {
filter.query?.let {
payload["vars[s]"] = filter.query.urlEncoded()
}
else -> {
// Support query
// filter.query.let {
// payload["vars[s]"] = filter.query.urlEncoded()
// }
if (filter.tags.isNotEmpty()) {
payload["vars[tax_query][0][taxonomy]"] = "wp-manga-genre"
payload["vars[tax_query][0][field]"] = "slug"
@ -344,12 +325,11 @@ internal abstract class MadaraParser(
payload["vars[tax_query][1][operator]"] = "NOT IN"
}
// Support year
//filter.year?.let {
// payload["vars[tax_query][2][taxonomy]"] = wp-manga-release
// payload["vars[tax_query][2][field]"] = slug
// payload["vars[tax_query][2][terms][]"] = filter.year
//}
if (filter.year != 0) {
payload["vars[tax_query][2][taxonomy]"] = "wp-manga-release"
payload["vars[tax_query][2][field]"] = "slug"
payload["vars[tax_query][2][terms][]"] = filter.year.toString()
}
// Support author
// filter.author.let {
@ -368,8 +348,7 @@ internal abstract class MadaraParser(
// payload["vars[tax_query][4][operator]"] = "IN"
//}
/// for add filter.year need to add || filter.year
if (filter.tags.isNotEmpty() || filter.tagsExclude.isNotEmpty()) {
if (filter.tags.isNotEmpty() || filter.tagsExclude.isNotEmpty() || filter.year != 0) {
payload["vars[tax_query][relation]"] = "AND"
}
@ -434,11 +413,11 @@ internal abstract class MadaraParser(
payload["vars[orderby][query_total_reviews]"] = "ASC"
}
// SortOrder.RELEVANCE -> {
// payload["vars[orderby]"] = ""
// }
SortOrder.RELEVANCE -> {
payload["vars[orderby]"] = ""
}
else -> payload["vars[meta_key]"] = "_latest_update"
else -> payload["vars[orderby]"] = ""
}
filter.states.forEach {
@ -463,8 +442,6 @@ internal abstract class MadaraParser(
else -> ""
}
}
}
}
return parseMangaList(
webClient.httpPost(
@ -749,8 +726,10 @@ internal abstract class MadaraParser(
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago", "atrás", " hace", " publicado"," назад", " önce", " trước", "مضت",
" h", " d", " días", " jour", " horas", " heure", " mins", " minutos", " minute", " mois").endsWith(d) -> {
WordSet(
" ago", "atrás", " hace", " publicado", " назад", " önce", " trước", "مضت",
" h", " d", " días", " jour", " horas", " heure", " mins", " minutos", " minute", " mois",
).endsWith(d) -> {
parseRelativeDate(d)
}
@ -805,16 +784,22 @@ internal abstract class MadaraParser(
return when {
WordSet("detik", "segundo", "second", "ثوان")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("menit", "dakika", "min", "minute", "minutes", "minuto", "mins", "phút", "минут", "دقيقة")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("jam", "saat", "heure", "hora", "horas", "hour", "hours", "h", "ساعات", "ساعة")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("hari", "gün", "jour", "día", "dia", "day", "days", "d", "день")
.anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
WordSet("month", "months", "أشهر", "mois")
.anyWordIn(date) -> cal.apply { add(Calendar.MONTH, -number) }.timeInMillis
WordSet("year")
.anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis
else -> 0
}
}

@ -274,7 +274,9 @@ internal abstract class MadthemeParser(
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago", " h", " d").endsWith(d) -> { parseRelativeDate(d) }
WordSet(" ago", " h", " d").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("today").startsWith(d) -> {
Calendar.getInstance().apply {
@ -303,16 +305,22 @@ internal abstract class MadthemeParser(
return when {
WordSet("second")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("min", "minute", "minutes")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("hour", "hours", "h")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("day", "days")
.anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -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
}
}

@ -18,7 +18,7 @@ internal class Hanman18(context: MangaLoaderContext) :
Manga18Parser(context, MangaParserSource.HANMAN18, "hanman18.com") {
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet()
availableTags = emptySet(),
)
override suspend fun getChapters(doc: Document): List<MangaChapter> {

@ -265,7 +265,9 @@ internal abstract class MangaboxParser(
protected fun parseChapterDate(dateFormat: DateFormat, date: String?): Long {
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago", " h", " d").endsWith(d) -> { parseRelativeDate(d) }
WordSet(" ago", " h", " d").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("today").startsWith(d) -> {
Calendar.getInstance().apply {
@ -294,16 +296,22 @@ internal abstract class MangaboxParser(
return when {
WordSet("second")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("min", "minute", "minutes")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("hour", "hours", "h")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("day", "days")
.anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -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
}
}

@ -243,8 +243,14 @@ internal abstract class OtakuSanctuaryParser(
protected fun parseChapterDate(dateFormat: DateFormat, date: String?): Long {
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago", " atrás").endsWith(d) -> { parseRelativeDate(d) }
WordSet("cách đây ").startsWith(d) -> { parseRelativeDate(d) }
WordSet(" ago", " atrás").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("cách đây ").startsWith(d) -> {
parseRelativeDate(d)
}
else -> dateFormat.tryParse(date)
}
}
@ -255,16 +261,22 @@ internal abstract class OtakuSanctuaryParser(
return when {
WordSet("second", "giây")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("min", "minute", "minutes", "phút")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("tiếng", "hour", "hours")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("day", "days", "d", "ngày")
.anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -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
}
}

@ -13,8 +13,9 @@ internal class MangaFr(context: MangaLoaderContext) :
override val listUrl = "/series"
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet()
availableTags = emptySet(),
)
override suspend fun getDetails(manga: Manga): Manga {
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
val dateFormat = SimpleDateFormat("MM-dd-yyyy", sourceLocale)

@ -280,7 +280,9 @@ internal abstract class WpComicsParser(
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago", " trước").endsWith(d) -> { parseRelativeDate(d) }
WordSet(" ago", " trước").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("today").startsWith(d) -> {
Calendar.getInstance().apply {
@ -309,14 +311,19 @@ internal abstract class WpComicsParser(
return when {
WordSet("second", "giây")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("min", "minute", "minutes", "mins", "phút")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("jam", "saat", "heure", "hora", "horas", "hour", "hours", "h", "giờ")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("day", "days", "d", "ngày")
.anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
WordSet("month", "months", "tháng")
.anyWordIn(date) -> cal.apply { add(Calendar.MONTH, -number) }.timeInMillis
WordSet("year", "năm").anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis
else -> 0
}

@ -252,7 +252,9 @@ internal abstract class ZMangaParser(
protected fun parseChapterDate(dateFormat: DateFormat, date: String?): Long {
val d = date?.lowercase() ?: return 0
return when {
WordSet(" ago", " h", " d").endsWith(d) -> { parseRelativeDate(d) }
WordSet(" ago", " h", " d").endsWith(d) -> {
parseRelativeDate(d)
}
WordSet("today").startsWith(d) -> {
Calendar.getInstance().apply {
@ -282,15 +284,20 @@ internal abstract class ZMangaParser(
return when {
WordSet("second")
.anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
WordSet("min", "minute", "minutes")
.anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("hour", "hours", "h")
.anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("day", "days").anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -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
}
}

Loading…
Cancel
Save