Artist filter support
This commit is contained in:
@@ -15,6 +15,7 @@ public data class MangaListFilter(
|
||||
@JvmField val year: Int = YEAR_UNKNOWN,
|
||||
@JvmField val yearFrom: Int = YEAR_UNKNOWN,
|
||||
@JvmField val yearTo: Int = YEAR_UNKNOWN,
|
||||
@JvmField val author: String? = null,
|
||||
) {
|
||||
|
||||
private fun isNonSearchOptionsEmpty(): Boolean = tags.isEmpty() &&
|
||||
@@ -27,7 +28,8 @@ public data class MangaListFilter(
|
||||
yearFrom == YEAR_UNKNOWN &&
|
||||
yearTo == YEAR_UNKNOWN &&
|
||||
types.isEmpty() &&
|
||||
demographics.isEmpty()
|
||||
demographics.isEmpty() &&
|
||||
author.isNullOrEmpty()
|
||||
|
||||
public fun isEmpty(): Boolean = isNonSearchOptionsEmpty() && query.isNullOrEmpty()
|
||||
|
||||
|
||||
@@ -47,4 +47,10 @@ public data class MangaListFilterCapabilities @InternalParsersApi constructor(
|
||||
* @see [MangaListFilterOptions.availableLocales]
|
||||
*/
|
||||
val isOriginalLocaleSupported: Boolean = false,
|
||||
|
||||
/**
|
||||
* Whether parser supports searching by author name
|
||||
* @see [MangaListFilter.author]
|
||||
*/
|
||||
val isAuthorSearchSupported: Boolean = false,
|
||||
)
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
|
||||
import org.koitharu.kotatsu.parsers.exception.TooManyRequestExceptions
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Collections.emptyList
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -54,6 +55,7 @@ internal class ExHentaiParser(
|
||||
isTagsExclusionSupported = true,
|
||||
isSearchSupported = true,
|
||||
isSearchWithFiltersSupported = true,
|
||||
isAuthorSearchSupported = true,
|
||||
)
|
||||
|
||||
override val isAuthorized: Boolean
|
||||
@@ -172,8 +174,8 @@ internal class ExHentaiParser(
|
||||
url = href,
|
||||
publicUrl = a.absUrl("href"),
|
||||
rating = td2.selectFirst("div.ir")?.parseRating() ?: RATING_UNKNOWN,
|
||||
isNsfw = true,
|
||||
coverUrl = td1.selectFirst("img")?.absUrl("src").orEmpty(),
|
||||
contentRating = ContentRating.ADULT,
|
||||
coverUrl = td1.selectFirst("img")?.attrAsAbsoluteUrlOrNull("src"),
|
||||
tags = tagsDiv.parseTags(),
|
||||
state = null,
|
||||
author = tagsDiv.getElementsContainingOwnText("artist:").first()
|
||||
@@ -190,9 +192,18 @@ 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")
|
||||
val gd3 = root.getElementById("gd3")
|
||||
val lang = gd3
|
||||
?.selectFirst("tr:contains(Language)")
|
||||
?.selectFirst(".gdt2")?.ownTextOrNull()
|
||||
val uploadDate = gd3
|
||||
?.selectFirst("tr:contains(Posted)")
|
||||
?.selectFirst(".gdt2")?.ownTextOrNull()
|
||||
.let { SimpleDateFormat("yyyy-MM-dd HH:mm", sourceLocale).tryParse(it) }
|
||||
val uploader = gd3
|
||||
?.getElementsByAttributeValueContaining("href", "/uploader/")
|
||||
?.firstOrNull()
|
||||
?.ownTextOrNull()
|
||||
val tags = tagList?.parseTags().orEmpty()
|
||||
|
||||
return manga.copy(
|
||||
@@ -223,9 +234,9 @@ internal class ExHentaiParser(
|
||||
number = i.toFloat(),
|
||||
volume = 0,
|
||||
url = url,
|
||||
uploadDate = 0L,
|
||||
uploadDate = uploadDate,
|
||||
source = source,
|
||||
scanlator = null,
|
||||
scanlator = uploader,
|
||||
branch = lang,
|
||||
)
|
||||
}
|
||||
@@ -415,6 +426,11 @@ internal class ExHentaiParser(
|
||||
joiner.append(lc.toLanguagePath())
|
||||
joiner.append("\"$")
|
||||
}
|
||||
if (!author.isNullOrEmpty()) {
|
||||
joiner.add("artist:\"")
|
||||
joiner.append(author)
|
||||
joiner.append("\"$")
|
||||
}
|
||||
return joiner.complete().nullIfEmpty()
|
||||
}
|
||||
|
||||
|
||||
@@ -103,12 +103,13 @@ internal abstract class GroupleParser(
|
||||
} else {
|
||||
advancedSearch(offset, order, filter).parseHtml()
|
||||
}
|
||||
val tiles =
|
||||
root.selectFirst("div.tiles.row") ?: if (root.select(".alert").any { it.ownText() == NOTHING_FOUND }) {
|
||||
val tiles = root.selectFirst("div.tiles.row")
|
||||
if (tiles == null) {
|
||||
if (!root.getElementsContainingOwnText(NOTHING_FOUND).isNullOrEmpty()) {
|
||||
return emptyList()
|
||||
} else {
|
||||
root.parseFailed("No tiles found")
|
||||
}
|
||||
root.parseFailed("No tiles found")
|
||||
}
|
||||
return tiles.select("div.tile").mapNotNull(::parseManga)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user