[ImHentai] add ContentTypes

add new ContentTypes
[iken] add SearchWithFilters, ContentTypes
[keyoapp] add SearchWithFilters
[likemanga] add POPULARITY_TODAY, POPULARITY_WEEK, POPULARITY_MONTH, SearchWithFilters
devi 2 years ago
parent 091c5247d5
commit d32d1f5044

@ -26,6 +26,11 @@ public enum class ContentType {
/** /**
* Use this type if no other suits your needs. For example, for an indie manga * Use this type if no other suits your needs. For example, for an indie manga
*/ */
OTHER,
ONE_SHOT, ONE_SHOT,
DOUJINSHI,
IMAGE_SET,
ARTIST_CG,
GAME_CG,
OTHER,
} }

@ -33,6 +33,14 @@ internal class ImHentai(context: MangaLoaderContext) :
availableLocales = setOf( availableLocales = setOf(
Locale.ENGLISH, Locale.JAPANESE, Locale("es"), Locale.FRENCH, Locale("kr"), Locale.GERMAN, Locale("ru"), Locale.ENGLISH, Locale.JAPANESE, Locale("es"), Locale.FRENCH, Locale("kr"), Locale.GERMAN, Locale("ru"),
), ),
availableContentTypes = EnumSet.of(
ContentType.MANGA,
ContentType.DOUJINSHI,
ContentType.COMICS,
ContentType.IMAGE_SET,
ContentType.ARTIST_CG,
ContentType.GAME_CG,
),
) )
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) { override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -63,6 +71,24 @@ internal class ImHentai(context: MangaLoaderContext) :
append(filter.tags.joinToString(separator = ",") { it.key }) append(filter.tags.joinToString(separator = ",") { it.key })
} }
var types = "&m=1&d=1&w=1&i=1&a=1&g=1"
if (filter.types.isNotEmpty()) {
types = "&m=0&d=0&w=0&i=0&a=0&g=0"
filter.types.forEach {
when (it) {
ContentType.MANGA -> types = types.replace("&m=0", "&m=1")
ContentType.DOUJINSHI -> types = types.replace("&d=0", "&d=1")
ContentType.COMICS -> types = types.replace("&w=0", "&w=1")
ContentType.IMAGE_SET -> types = types.replace("&i=0", "&i=1")
ContentType.ARTIST_CG -> types = types.replace("&a=0", "&a=1")
ContentType.GAME_CG -> types = types.replace("&g=0", "&g=1")
else -> {}
}
}
}
append(types)
var lang = "&en=1&jp=1&es=1&fr=1&kr=1&de=1&ru=1" var lang = "&en=1&jp=1&es=1&fr=1&kr=1&de=1&ru=1"
filter.locale?.let { filter.locale?.let {
lang = "&en=0&jp=0&es=0&fr=0&kr=0&de=0&ru=0" lang = "&en=0&jp=0&es=0&fr=0&kr=0&de=0&ru=0"

@ -62,7 +62,7 @@ internal class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaPars
ContentType.MANHUA, ContentType.MANHUA,
ContentType.NOVEL, ContentType.NOVEL,
ContentType.ONE_SHOT, ContentType.ONE_SHOT,
ContentType.HENTAI, ContentType.DOUJINSHI,
ContentType.OTHER, ContentType.OTHER,
), ),
) )
@ -116,7 +116,7 @@ internal class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaPars
ContentType.MANHUA -> "manhua" ContentType.MANHUA -> "manhua"
ContentType.NOVEL -> "novel" ContentType.NOVEL -> "novel"
ContentType.ONE_SHOT -> "one_shot" ContentType.ONE_SHOT -> "one_shot"
ContentType.HENTAI -> "doujinshi" ContentType.DOUJINSHI -> "doujinshi"
ContentType.OTHER -> "oel" ContentType.OTHER -> "oel"
else -> "" else -> ""
}, },

@ -38,7 +38,7 @@ internal class DoujinDesuParser(context: MangaLoaderContext) :
availableContentTypes = EnumSet.of( availableContentTypes = EnumSet.of(
ContentType.MANGA, ContentType.MANGA,
ContentType.MANHWA, ContentType.MANHWA,
ContentType.HENTAI, ContentType.DOUJINSHI,
), ),
) )
@ -92,7 +92,7 @@ internal class DoujinDesuParser(context: MangaLoaderContext) :
when (it) { when (it) {
ContentType.MANGA -> "Manga" ContentType.MANGA -> "Manga"
ContentType.MANHWA -> "Manhwa" ContentType.MANHWA -> "Manhwa"
ContentType.HENTAI -> "Doujinshi" ContentType.DOUJINSHI -> "Doujinshi"
else -> "" else -> ""
}, },
) )

@ -30,8 +30,9 @@ internal abstract class IkenParser(
override val filterCapabilities: MangaListFilterCapabilities override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities( get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isSearchSupported = true, isSearchSupported = true,
isSearchWithFiltersSupported = true,
isMultipleTagsSupported = true,
) )
override suspend fun getFilterOptions() = MangaListFilterOptions( override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -42,6 +43,12 @@ internal abstract class IkenParser(
MangaState.ABANDONED, MangaState.ABANDONED,
MangaState.UPCOMING, MangaState.UPCOMING,
), ),
availableContentTypes = EnumSet.of(
ContentType.MANGA,
ContentType.MANHUA,
ContentType.MANHWA,
ContentType.OTHER,
),
) )
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> { override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
@ -51,20 +58,30 @@ internal abstract class IkenParser(
append("/api/query?page=") append("/api/query?page=")
append(page) append(page)
append("&perPage=18&searchTerm=") append("&perPage=18&searchTerm=")
when {
!filter.query.isNullOrEmpty() -> { filter.query?.let {
append(filter.query.urlEncoded()) append(filter.query.urlEncoded())
} }
else -> {
if (filter.tags.isNotEmpty()) { if (filter.tags.isNotEmpty()) {
append("&genreIds=") append("&genreIds=")
filter.tags.joinTo(this, ",") { it.key } filter.tags.joinTo(this, ",") { it.key }
} }
append("&seriesType=&seriesStatus=") append("&seriesType=")
filter.types.oneOrThrowIfMany()?.let {
append(
when (it) {
ContentType.MANGA -> "MANGA"
ContentType.MANHWA -> "MANHWA"
ContentType.MANHUA -> "MANHUA"
ContentType.OTHER -> "RUSSIAN"
else -> ""
},
)
}
append("&seriesStatus=")
filter.states.oneOrThrowIfMany()?.let { filter.states.oneOrThrowIfMany()?.let {
append( append(
when (it) { when (it) {
@ -77,8 +94,6 @@ internal abstract class IkenParser(
) )
} }
} }
}
}
return parseMangaList(webClient.httpGet(url).parseJson()) return parseMangaList(webClient.httpGet(url).parseJson())
} }

@ -7,4 +7,4 @@ import org.koitharu.kotatsu.parsers.site.iken.IkenParser
@MangaSourceParser("MANGAGALAXY", "MangaGalaxy", "en") @MangaSourceParser("MANGAGALAXY", "MangaGalaxy", "en")
internal class MangaGalaxyParser(context: MangaLoaderContext) : internal class MangaGalaxyParser(context: MangaLoaderContext) :
IkenParser(context, MangaParserSource.MANGAGALAXY, "mangagalaxy.org") IkenParser(context, MangaParserSource.MANGAGALAXY, "mangagalaxy.net")

@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.iken.IkenParser
@MangaSourceParser("PHILIASCANS", "PhiliaScans", "en") @MangaSourceParser("PHILIASCANS", "PhiliaScans", "en")
internal class PhiliaScans(context: MangaLoaderContext) : internal class PhiliaScans(context: MangaLoaderContext) :
IkenParser(context, MangaParserSource.PHILIASCANS, "vortextoon.com") { IkenParser(context, MangaParserSource.PHILIASCANS, "philiascans.com") {
override val selectPages = "main section img" override val selectPages = "main section img"
} }

@ -19,8 +19,20 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
MangaParser(context, MangaParserSource.NICOVIDEO_SEIGA), MangaParser(context, MangaParserSource.NICOVIDEO_SEIGA),
MangaParserAuthProvider { MangaParserAuthProvider {
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("nicovideo.jp")
override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP) override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
keys.add(userAgentKey)
}
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.UPDATED,
SortOrder.POPULARITY,
)
override val filterCapabilities: MangaListFilterCapabilities override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities( get() = MangaListFilterCapabilities(
isSearchSupported = true, isSearchSupported = true,
@ -30,11 +42,6 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
availableTags = fetchAvailableTags(), availableTags = fetchAvailableTags(),
) )
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
keys.add(userAgentKey)
}
override val authUrl: String override val authUrl: String
get() = "https://${getDomain("account")}/login?site=seiga" get() = "https://${getDomain("account")}/login?site=seiga"
@ -48,13 +55,6 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
return body.selectFirst("#userinfo > div > div > strong")?.text() ?: throw AuthRequiredException(source) return body.selectFirst("#userinfo > div > div > strong")?.text() ?: throw AuthRequiredException(source)
} }
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.UPDATED,
SortOrder.POPULARITY,
)
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("nicovideo.jp")
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> { override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val page = (offset / 20f).toIntUp().inc() val page = (offset / 20f).toIntUp().inc()
val domain = getDomain("seiga") val domain = getDomain("seiga")
@ -65,7 +65,6 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
else -> { else -> {
if (filter.tags.isNotEmpty()) { if (filter.tags.isNotEmpty()) {
filter.tags.oneOrThrowIfMany().let { filter.tags.oneOrThrowIfMany().let {
"https://$domain/manga/list?category=${it?.key}&page=$page&sort=${getSortKey(order)}" "https://$domain/manga/list?category=${it?.key}&page=$page&sort=${getSortKey(order)}"

@ -58,6 +58,7 @@ internal abstract class KeyoappParser(
override val filterCapabilities: MangaListFilterCapabilities override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities( get() = MangaListFilterCapabilities(
isSearchSupported = true, isSearchSupported = true,
isSearchWithFiltersSupported = true,
) )
override suspend fun getFilterOptions() = MangaListFilterOptions( override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -70,28 +71,20 @@ internal abstract class KeyoappParser(
val url = urlBuilder().apply { val url = urlBuilder().apply {
when { filter.query?.let {
!filter.query.isNullOrEmpty() -> {
addPathSegment("series")
query = filter.query query = filter.query
} }
else -> {
if (filter.tags.isNotEmpty()) {
filter.tags.oneOrThrowIfMany()?.let { filter.tags.oneOrThrowIfMany()?.let {
tag = it.title tag = it.title
} }
}
when (order) { when (order) {
SortOrder.UPDATED -> addPathSegment("latest") SortOrder.UPDATED -> addPathSegment("latest")
SortOrder.NEWEST -> addPathSegment("series") SortOrder.NEWEST -> addPathSegment("series")
else -> addPathSegment("latest") else -> addPathSegment("series")
} }
}
}
}.build() }.build()
return parseMangaList(webClient.httpGet(url).parseHtml(), tag, query) return parseMangaList(webClient.httpGet(url).parseHtml(), tag, query)

@ -30,11 +30,19 @@ internal abstract class LikeMangaParser(
} }
override val availableSortOrders: Set<SortOrder> = override val availableSortOrders: Set<SortOrder> =
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST) EnumSet.of(
SortOrder.UPDATED,
SortOrder.POPULARITY,
SortOrder.NEWEST,
SortOrder.POPULARITY_TODAY,
SortOrder.POPULARITY_WEEK,
SortOrder.POPULARITY_MONTH,
)
override val filterCapabilities: MangaListFilterCapabilities override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities( get() = MangaListFilterCapabilities(
isSearchSupported = true, isSearchSupported = true,
isSearchWithFiltersSupported = true,
) )
override suspend fun getFilterOptions() = MangaListFilterOptions( override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -48,22 +56,23 @@ internal abstract class LikeMangaParser(
append(domain) append(domain)
append("/?act=search") append("/?act=search")
when { filter.query?.let {
!filter.query.isNullOrEmpty() -> {
append("&f") append("&f")
append("[keyword]".urlEncoded()) append("[keyword]".urlEncoded())
append("=") append("=")
append(filter.query.urlEncoded()) append(filter.query.urlEncoded())
} }
else -> {
append("&f") append("&f")
append("[sortby]".urlEncoded()) append("[sortby]".urlEncoded())
append("=") append("=")
when (order) { when (order) {
SortOrder.POPULARITY -> append("hot")
SortOrder.UPDATED -> append("lastest-chap") SortOrder.UPDATED -> append("lastest-chap")
SortOrder.NEWEST -> append("lastest-manga") SortOrder.NEWEST -> append("lastest-manga")
SortOrder.POPULARITY -> append("top-manga")
SortOrder.POPULARITY_TODAY -> append("top-day")
SortOrder.POPULARITY_WEEK -> append("top-week")
SortOrder.POPULARITY_MONTH -> append("top-month")
else -> append("lastest-chap") else -> append("lastest-chap")
} }
@ -89,8 +98,6 @@ internal abstract class LikeMangaParser(
}, },
) )
} }
}
}
if (page > 1) { if (page > 1) {
append("&pageNum=") append("&pageNum=")

Loading…
Cancel
Save